From 1b380ca340d52906065ee1413e16b9373db11bcc Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Fri, 27 Jul 2007 13:54:26 +0000 Subject: [PATCH 001/214] - move libgcrypt shared library to /%{_lib} (#249815) --- libgcrypt.spec | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index ddba6d3..ceb82d3 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.2.4 -Release: 1 +Release: 2 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com @@ -48,6 +48,31 @@ sed -i -e 's,^libdir="/usr/lib.*"$,libdir="/usr/lib",g' $RPM_BUILD_ROOT/%{_bindi rm -f ${RPM_BUILD_ROOT}/%{_infodir}/dir ${RPM_BUILD_ROOT}/%{_libdir}/*.la /sbin/ldconfig -n $RPM_BUILD_ROOT/%{_libdir} +# Relocate the shared libraries to /%{_lib}. +mkdir -p $RPM_BUILD_ROOT/%{_lib} +for shlib in $RPM_BUILD_ROOT/%{_libdir}/*.so* ; do + if test -L "$shlib" ; then + rm "$shlib" + else + mv "$shlib" $RPM_BUILD_ROOT/%{_lib}/ + fi +done +# Figure out where /%{_lib} is relative to %{_libdir}. +touch $RPM_BUILD_ROOT/root_marker +relroot=.. +while ! test -f $RPM_BUILD_ROOT/%{_libdir}/$relroot/root_marker ; do + relroot=$relroot/.. +done +# Overwrite development symlinks. +pushd $RPM_BUILD_ROOT/%{_libdir} +for shlib in $relroot/%{_lib}/lib*.so.* ; do + shlib=`echo "$shlib" | sed -e 's,//,/,g'` + target=`basename "$shlib" | sed -e 's,\.so.*,,g'`.so + ln -sf $shlib $target +done +popd +rm -f $RPM_BUILD_ROOT/root_marker + %clean rm -fr $RPM_BUILD_ROOT @@ -67,7 +92,7 @@ exit 0 %files %defattr(-,root,root) -%{_libdir}/*.so.* +/%{_lib}/*.so.* #%{_libdir}/%{name} %files devel @@ -82,6 +107,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Fri Jul 27 2007 Nalin Dahyabhai - 1.2.4-2 +- move libgcrypt shared library to /%{_lib} (#249815) + * Tue Feb 6 2007 Nalin Dahyabhai - 1.2.4-1 - update to 1.2.4 From db8737b2358325ef2618caa1cc5ade92a3cbc3ae Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 30 Jul 2007 13:41:49 +0000 Subject: [PATCH 002/214] - disable static libraries (part of #249815) --- libgcrypt.spec | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index ceb82d3..915f4f9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.2.4 -Release: 2 +Release: 3 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com @@ -32,7 +32,7 @@ applications using libgcrypt. #%patch0 -p1 -b .lib64 %build -%configure --disable-asm +%configure --disable-asm --disable-static make make check @@ -99,7 +99,6 @@ exit 0 %defattr(-,root,root) %{_bindir}/%{name}-config %{_includedir}/* -%{_libdir}/*.a %{_libdir}/*.so %{_datadir}/aclocal/* #%{_datadir}/%{name} @@ -107,6 +106,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Mon Jul 30 2007 Nalin Dahyabhai - 1.2.4-3 +- disable static libraries (part of #249815) + * Fri Jul 27 2007 Nalin Dahyabhai - 1.2.4-2 - move libgcrypt shared library to /%{_lib} (#249815) From b03ca4732ba6082935b2fe4fe620f141f314d02f Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 16 Aug 2007 15:27:13 +0000 Subject: [PATCH 003/214] - clarify license - force use of the linux /dev/random RNG, to avoid accidentally falling back to others which would affect the license of the resulting library --- libgcrypt.spec | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 915f4f9..12d5e51 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -5,7 +5,7 @@ Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com Patch0: libgcrypt-1.2.2-lib64.patch -License: LGPL +License: LGPLv2+ Summary: A general-purpose cryptography library. BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildRequires: libgpg-error-devel pkgconfig @@ -32,7 +32,7 @@ applications using libgcrypt. #%patch0 -p1 -b .lib64 %build -%configure --disable-asm --disable-static +%configure --disable-asm --disable-static --enable-random=linux make make check @@ -106,6 +106,11 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Thu Aug 16 2007 Nalin Dahyabhai - 1.2.4-4 +- clarify license +- force use of the linux /dev/random RNG, to avoid accidentally falling back + to others which would affect the license of the resulting library + * Mon Jul 30 2007 Nalin Dahyabhai - 1.2.4-3 - disable static libraries (part of #249815) From a88fef19534aec73b0cb8e3eec75d2c4e846ae82 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 16 Aug 2007 15:28:29 +0000 Subject: [PATCH 004/214] - doh, actually bump the revision number --- libgcrypt.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 12d5e51..db4d90e 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.2.4 -Release: 3 +Release: 4 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com From 710edd985ee95e37624af03ec08ff6f064a3bdfd Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Wed, 22 Aug 2007 21:16:43 +0000 Subject: [PATCH 005/214] - add missing gawk buildrequirement - switch from explicitly specifying the /dev/random RNG to just verifying that the non-LGPL ones were disabled by the configure script --- libgcrypt.spec | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index db4d90e..5c5b8ad 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,14 +1,13 @@ Name: libgcrypt Version: 1.2.4 -Release: 4 +Release: 5 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com -Patch0: libgcrypt-1.2.2-lib64.patch License: LGPLv2+ Summary: A general-purpose cryptography library. BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildRequires: libgpg-error-devel pkgconfig +BuildRequires: gawk libgpg-error-devel pkgconfig Group: System Environment/Libraries %package devel @@ -29,10 +28,12 @@ applications using libgcrypt. %prep %setup -q -#%patch0 -p1 -b .lib64 %build -%configure --disable-asm --disable-static --enable-random=linux +%configure --disable-asm --disable-static --enable-noexecstack +# Verify that RNG methods which aren't LGPL aren't enabled. +grep '^#define USE_RNDUNIX 0$' config.h +grep '^#define USE_RNDW32 0$' config.h make make check @@ -106,6 +107,11 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Wed Aug 22 2007 Nalin Dahyabhai - 1.2.4-5 +- add missing gawk buildrequirement +- switch from explicitly specifying the /dev/random RNG to just verifying + that the non-LGPL ones were disabled by the configure script + * Thu Aug 16 2007 Nalin Dahyabhai - 1.2.4-4 - clarify license - force use of the linux /dev/random RNG, to avoid accidentally falling back From 4b681a494d33e4e327bf21cbc0acf6614a6904f6 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Mon, 15 Oct 2007 19:00:34 +0000 Subject: [PATCH 006/214] makefile update to properly grab makefile.common --- Makefile | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index a1d653c..4de825d 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,21 @@ # Makefile for source rpm: libgcrypt -# $Id$ +# $Id: Makefile,v 1.1 2004/09/09 07:25:33 cvsdist Exp $ NAME := libgcrypt SPECFILE = $(firstword $(wildcard *.spec)) -include ../common/Makefile.common +define find-makefile-common +for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done +endef + +MAKEFILE_COMMON := $(shell $(find-makefile-common)) + +ifeq ($(MAKEFILE_COMMON),) +# attempt a checkout +define checkout-makefile-common +test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2 +endef + +MAKEFILE_COMMON := $(shell $(checkout-makefile-common)) +endif + +include $(MAKEFILE_COMMON) From 9f9b613bc098fe9c9acf1a5c2e4f7c33a7b0ed66 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Tue, 16 Oct 2007 17:05:10 +0000 Subject: [PATCH 007/214] - use ldconfig to build the soname symlink for packaging along with the shared library (#334731)) --- libgcrypt.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 5c5b8ad..a853eb7 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.2.4 -Release: 5 +Release: 6 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com @@ -72,6 +72,8 @@ for shlib in $relroot/%{_lib}/lib*.so.* ; do ln -sf $shlib $target done popd +# Add soname symlink. +/sbin/ldconfig -n $RPM_BUILD_ROOT/%{_lib}/ rm -f $RPM_BUILD_ROOT/root_marker %clean @@ -107,6 +109,10 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Tue Oct 16 2007 Nalin Dahyabhai - 1.2.4-6 +- use ldconfig to build the soname symlink for packaging along with the + shared library (#334731) + * Wed Aug 22 2007 Nalin Dahyabhai - 1.2.4-5 - add missing gawk buildrequirement - switch from explicitly specifying the /dev/random RNG to just verifying From 1aebb276b2bb7fe9c46fad1263aa2de19c4d795d Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 10 Dec 2007 20:37:29 +0000 Subject: [PATCH 008/214] - update --- wk@g10code.com | 2575 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 1979 insertions(+), 596 deletions(-) diff --git a/wk@g10code.com b/wk@g10code.com index 3482c48..5e193e3 100644 --- a/wk@g10code.com +++ b/wk@g10code.com @@ -2,41 +2,43 @@ Login: wk Name: Werner Koch No project. No plan. Public key: -pub 1024D/621CC013 1998-07-07 Werner Koch -uid Werner Koch -uid Werner Koch + pub 1024D/5B0358A2 1999-03-15 [expires: 2011-07-11] + uid Werner Koch + uid Werner Koch + uid Werner Koch + uid Werner Koch + sub 1024D/010A57ED 2004-03-21 [expires: 2007-12-31] + sub 2048R/C3680A6E 2006-01-01 [expires: 2007-12-31] + + pub 1024R/1CE0C630 2006-01-01 [expires: 2008-12-31] + uid Werner Koch (dist sig) + + pub 1024R/37D92FFB 2003-11-17 [expires: 2009-12-31] + uid g10 Code (code signing key 1) + + pub 1024D/57548DCD 1998-07-07 [expired: 2005-12-31] + uid Werner Koch (gnupg sig) + -pub 1024D/5B0358A2 1999-03-15 Werner Koch -uid Werner Koch +5B0358A2 is my main key. +1CE0C630 is used to sign software distributions. +37D92FFB is used to sign certain source files. +57548DCD was used to sign GNU crypto software; + it has been superseded by 1CE0C630. -pub 768R/0C9857A5 1995-09-30 Werner Koch (mein alter key) -uid Werner Koch - -pub 1024D/57548DCD 1998-07-07 Werner Koch (gnupg sig) - - -621CC013 is my every days working key - use this one! -5B0358A2 is my certification key. -0C9857A5 is my old PGP 2 key - don't use it. -57548DCD is used to sign GNU crypto software. - -I use a separate certification key (5B0358A2) to sign my other keys. -This key is stored at a more or less secure place and only used on a -spare laptop which is not connected to any network. If you find a key +Please note that I use a subkey for signing messages; some old OpenPGP +implementations may not be able to check such a signature. The primary +key is stored at a more or less secure place and only used on a spare +laptop which is not connected to any network. If you find a key certified by this one, you can be sure that I personally met this person and checked the name part of the user ID against an official looking passport or another suitable photo id. My signature does not say anything about the email address (I merely check that the address looks plausible). -The working key (621cc013) has several subkeys; an OpenPGP -implementation should automagically select the most recent one for -encryption. Note, that the certification and the GNU signature key -can't be used for encryption becuase they are sign-only keys. - -----BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.2.1 (GNU/Linux) +Version: GnuPG v1.4.7 (GNU/Linux) mQGiBDWiHh4RBAD+l0rg5p9rW4M3sKvmeyzhs2mDxhRKDTVVUnTwpMIR2kIA9pT4 3No/coPajDvhZTaDM/vSz25IZDZWJ7gEu86RpoEdtr/eK8GuDcgsWvFs5+YpCDwW @@ -47,578 +49,1959 @@ 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 +LBwm9h9ywufXJQuVAJ9RMq6lpPqnDly6UCKz+kGt0EplyIhmBBMRAgAeAwsKAwMV +AwIDFgIBAheAAhkBBQJAXdnoBQkTa4v/ABIHZUdQRwABAQkQXeJJllsDWKLs0gCg +y5RdOqhFvwUFYWj+dHb4LGt7xi0AoKduFxGMuM/loPShQnjvk/VVFesAiF4EExEC +AB4DCwoDAxUDAgMWAgECF4ACGQEFAkBd2egFCRNri/8ACgkQXeJJllsDCRDs0gCg +y5RdOqhFvwUFYWj+dHb4LGt7xi0AoKduFxGMuM/loPShQnjvk/VVFesAiQEVAwUQ +O0HCUNImKUTOasbBAQFLZwgAkgMC/ximskOjL/CxghgdkSWkDFdpEr3XYhzUdLes +WgN4AM28mGZZKA9la7dXXRrKYkxhX8mpL4C3Q9LnrafP+Zn1c8mTuNIxX86j7iZA +IksoZ4D2csN8NSMYT9pKK6jZP1IOckCFBBI0W/yMGUGulDitWj4TwIArf2xQkV73 +//////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////// +/////////////////////////////////////////////4hGBBMRAgAGBQJDRBuk +AAoJEOrUtZD2iZvAafoAoKReCbMFRrpwzb2tS7M6iHDbN9E+AJoDy8nLf8A4f/EV +m8OJWOf1pPKQGIhGBBARAgAGBQJEBYJRAAoJEG9dWWgc1S3oeAEAoJ5eVEYwpcqY +78oHQ+2EWJ2R06BjAJ9mWcCCynLCjGXBJoYq6YLVaFCIFIhGBBARAgAGBQJEBgo0 +AAoJEJrJ0ixjXGNLQMMAoIh/01hmpfi1faVNvL22r7ihJjZNAJ9D9+xBrz0F2TMg +YmUjGBlCIcwS2ohMBBIRAgAMBQJEBisnBYMGUqnBAAoJEN/mV5IylcXNlHAAoLcf +b8fPerFL+kZ/yqTlqUFFW/FuAKC2IZto5Zu7WYDUrn28L1sh2LZe/IhMBBIRAgAM +BQJEBitnBYMGUqmBAAoJEKDlFb85iAlULdYAoOSbU4vrwlbc3XzB5hJVNFjbNYOe +AJ9pvj47lRFbnCyttUM2oKQiwW5AyohjBBMRAgAjAheAAhkBBQkTa4v/BQJCWUBy +BQsHCgMCAxUCAwMWAgECHgEACgkQXeJJllsDCRA6xwCfV3paxYsk7KQmrtOUxNmZ +b004OQoAn3uq9imOpgxqsXhXaLfz5IqZu5O7iJwEEwECAAYFAkQNdeYACgkQ/dJ0 +ek5GOmql+gQAmRKGvqN8lINhyZL1ClLN9+X5BTOGyxi6Fb8SBBqElGbHVJwLncxn +LmElgudpGPyAS1wZ+9aymUjUkPyVltA/lw6AzkLfqlFGG2MnOVi3WejwcyhSbL+L +XJ3N6CLRpVajI5j8+mHWe9Cdo2NGwMHfgIg7xeZOgeJZixPEe3Zhvh2JAhwEEAEC +AAYFAkQPSIoACgkQGioH6hxXudmtvRAAiX8daFke18xh6V0P3tFtkzZo3xCGfqus +uoAHmgByNeZmhoFLyA+UgUUGJTKiLOIgVxmcZ5srr61I0dsY95iE/LCzzcqWsfWC +mbr/3d/nrhPa31rGfucT95wxC4SeOXxBhfmd0muB/ZRhqGnHE1VXPHuDYBF70Z9J +Sy3Tpdcx6eDvG/rfY2qUqiLn5wi2EG6EyAUJNXJ0GMcv2qoBGvOITtBpvnQJAniy +120ig36q/SCggdM2nr+UIDnLBo+p4gvmfqLEZ3S4z/RCApKfoqFOiWK7P7N42My/ +iQyZAEn/kjiCm1s470LMqXAJZC20e7ZxJoLxputm1Nd4LL8oP0n6xYQiOXxgsRzK +abBb8ZYHoYujGEMcODqXSEvsES7kP2DMenYBwmT/ceqk41VCV4w4eYQscDCuVm0/ +oxoqlcplLPaoptyvES0VjlLwW8LeMzc3AMPOnxYamBvMYlBpoN2VmG5dDbnFCPtc +o9LPuMYfBh+KWQ4m7tQbwP689bcR1d85hyBZIRBkojz3C8FRZQZcs6VK5n8tKV63 +YsDSacbfcoFEN54uOeVZsLEqR9vCG98g4/nxcGWwveXY/9nyqw8HaeFxisl0xkmK +sP+KqPNt2dfdqBi1PjNhO0NmViCa68kJRwWkdkOtxIaKYab7w454D7A+YwaX8ptM +m3jwFqX5bUOJAiIEEAECAAwFAkQFDZkFgwZTx08ACgkQbjbvGsyNqzDkcBAAhZmu +EA5Pk1Dzd1QYLex2ZoN/XrXaZZ3WpcKlQSPvz5uuW9PV7lh8ixgHCTPZPh1EvrKl +aVtgciIxlUSPQTAdTVdDK9V/zUhV918GG1KpWvaf+cgCv2kdF/V9+iNQhrpPPxuw +J1TfByzSfqdHyIuXrao2BzhdMtXPf3wFY6CtFKCZ+FoShsV2Fl3SsJRpxz0JnqJY +N9njPTIYCrrR1Np+u5CcMO4e2erl0IXaffDQmeJMZFJ1fiZwJIpyZYOS61T2kUz4 +6Y7RkV0kO0nWuQiv6UAAmr1DlE9WtpdbqJVDTFQUW39o2kfOBXQrHz1NqfVxu4/a +sNCMmp/yK6RK3paN6AyD0Jhm1ipAOySNsVsMbvWZ1q9rlaPWscCslcJVw0t30a7t +U/DtQtF0nL8HJE8fdRXaKihHlCxU8UEhKDjM+R9wMPDkDdaY03jz7e+2N1lVQqQG +VAGvNkUBdpaOqwwtJDoAF8OeBfJX+zFS9whvBSQjPimxnQ9B+qdZwTuO3uFrGrXS +dtCGKsrrwXOZnJNU4lNK8BxPUQwGtgAEj/5zPLb4T4Lxsm9aDiHwFuYR2AQuO79Q +68CbMGYr4i7JdSudLg8hHsBQT8ZweBBbUu+Qym2xGPMGbUOmeiIkNP6mlyY8TQG7 +5ZdfHr7/NExOtgzwPicrmz6RB5GuO30iMiMeqSSJAiIEEAECAAwFAkQFESIFgwZT +w8YACgkQHRqO3OFAoFTM5A//aNCnL0pwr+ZWsFiuCt5J8nqN2V7VeRoT2WdKF5HL +pIrlLLozUdd8S0Zi9u7PO8GLD9QOUGc4y+LnSTpDHb8u4t9OYrRNAocp6gIZmxjG +5KuLPSUBc9ct27p/G0yIpgtgECCP55fY1XRAhkNnXWLVzsueEFdhPieO0gPqeVqP +zfT+oDhx+bLVH0YtFxOYDeV2NewtUpuBnr4ZNRD0WrhW5F8yecuwqeFsF6YTHMsA +L96xmlzNe3wx0I+qvWP3qHGWZs9DBMroBXL9BhpyzWA2079YSUC2dwxwnGAVSAbY ++c4bHr3On/GL0nhfwiyaD+8zSYAOey3xgYKJeGIWSA7TvcRic83khBroQN5JLK3D +N+jM3JJqhj0zX/9kz29z7Up1cbnhJAEJKvPMhTh8VRafxHkYYMYqru+W+kkuHupC +YgoJu2DeInhclmDjiE8CKW18w5jNjr7zH6tN8P6dnOazUeJyevBfipXEGLA3TT2j +VFbf9zU7Cb7DaxMrqBaOSUpvp0LQkFT/weiyivKaMIyZ38HxNdfFAi4dTEFLHX+s +osZWUZEODZ1rxBmAyP3A/F75YJolHmoZc4w72d3QD4HGeVD/3cWnREu/wvdko/2F +ZACO8UvUAAP4UhXn9QO3a0+tFmCzkTuE+uuVrnfpT2a/4nRiJ4QADy0zwpTT9DPA +HZ+IRgQQEQIABgUCREihIgAKCRAFi1rNRBxfge9RAJ9elNg4P6EYwz1GpslAJj06 +Fq7VYQCdGtSSX7L2xWY45o0QUEfU0nQVh0mIRgQQEQIABgUCREjJ+QAKCRCnL/Zs +Qr1kXRdpAJ9QH3CweThQQgRcKs51pa6ig43RvwCeNdI5Nb+4SMtOEn+vCZZkbkkZ +TZaIRgQQEQIABgUCRFsJZQAKCRB/3j6P8z4/xk2AAJ4wsIbdZzp82lspsNIhHurH +VwUjgACfXS1Jg0jHmufMTiJSSd73hpD2mZKIRgQQEQIABgUCRGCHvQAKCRD9AQSw +4jPImI7/AKCyxcVN5/xT6dsgrzxbi/nXuHLNegCcD98a67j7vpc2SujQQHzY2IFv +rWWIRgQQEQIABgUCRGCItQAKCRD9AQSw4jPImHp8AJ9XcTvscy3DOWTayYxhHC/q +VDKb0gCbBd5nO24QFPTZyXcDoXIR0hgm14CIRgQTEQIABgUCRE/tdQAKCRA/0h0q +mjpVWG8XAJ9+ukhr7X2AcbdJuxDSRCwyUmYO1wCffLzymfNFEzhtNOZtaQF1bAHl +v3OITAQQEQIADAUCRF3UigWDBfsAXgAKCRBbqJPk7D6Y33KuAJ9RAKZvdGKCczUu ++oNwzVggwGE+qACg02JOmubDdtMdXDmj/uKkqmafukqITAQQEQIADAUCRF8XTgWD +Bfm9mgAKCRC8EAnaDpclP/ebAJ9ONfFPcQ8MAds2/dYUmViFlAIKKgCgkDyxYaAY +eCh89VLSpsbbymWNDFmITAQSEQIADAUCRF22QgWDBfsepgAKCRAyNS1FZ/eCZB3D +AJ9KBPUTTAcmJLEQ+fOcWNOJwpF2JACfaUv3jKhFU5tMS1cemDujhEiF89CI3AQQ +AQIABgUCRFC2nQAKCRDR2VIECemh1RMWBf0aP1ofgRg0fXsVu0wVJIN1H7n+uOIY +WEVnPf/ZvtXAmr1P9koiOAl24jEWnpZA6hxzsC1zWEmGi0Zw96EhuFusDesRoQIE +ZnNh92qm4uk0hJ0S2JItWs2H2wxc9oGAJOAICqxO80gDBJICwqqMdbevRgwHFmgc +cMYpnE6YSrXgPVgC+dQNKBiPpm4HOL86EEMzD2blzqk5YSngn7efbDwWtDSABQby +9QCRptwKQYOzHCi4gaK/g8I9K9dJf5IFXSyJARwEEAECAAYFAkRbcFcACgkQZ02H +1ZEZDvnSNAf8CLIb+JRnGn8LqL/RmX51Ds8pPzOtmgwWNgDf5pIZm5jTtZH5o7z0 +qZ5FLBFok64+Gtusjh3q/RONlvZH7wF4Tg07Hsx13t8Ie3wNrhfjkScpEDK0UtOf +FzOICVZTqjIVrex04yxDO+yV7reBm4AsWsqIEfOrwKY3cEiHpGd5/lC+wHIk9WxJ +LbwjachXEwVnILZLHWZFFVXLYJigHwQjyu2keZZqx2tQcS6woZR8+XMy7WVD4D+D +Db/BcWNjiSsqbwaH1FFqOqRpkOuHwt7JLxsdXavmRRkve8bIICb+SaM5Fy9/YYKT +TcfT7WZ+KhcKSq95wxKWnSFAbILVzFvIAoicBBMBAgAGBQJElY7IAAoJENwG3M95 +JPpzBwMD/2VB1PQa9R5MbuIFSHXQztimwz6joPetCi7fmJczzTYGCg7PdEprwJQq +H3dmAGieogM/o5NuuV2SGMdIDao3cYhCLFAQtIHCCMVQovqcDR5gSyDpD1j86x31 +OU7lMb6/YKoTcOTsoQ/zshz9I3stwo2gH6n84ZpskH5JR6iw9LgaiEYEEBECAAYF +AkS9USsACgkQxKXVjqqse7z4uwCfSobUmYCrjQx18yvZI2MMVIZCSnkAnjvQJfqP +XmH2Po11vZMNiRIX8hmDiEYEEBECAAYFAkS9OqsACgkQOOnzljbgEa9T0QCcCGOA +6GP6/I9Qp9CO3JU2k2gSi4wAoKiUukIn5lcTF7yrbiw5ZYZg5LiWiEYEEBECAAYF +AkTCe2sACgkQQggFxokHT60sKgCgnK85XyCxKr4itQm1t9ycMcYCO4wAnjMiXOIv +dR1bzKum0oCd7XAgkCtaiEYEEBECAAYFAkSNRFUACgkQp6+YGoOsM0qlWgCghjwM +VOscLRd9u4vRAW3EK7shbVQAn3YjbCUTJdUkM+NIE8CRT3+0vQhAiEYEEBECAAYF +AkVXpxMACgkQ9LSwzHl+v6s6AwCeIMTlicVjKpG+5bmJF3lU8d4EsasAnjdIZ//X +QTCVlBWswexfk+fnOGxfiEwEExECAAwFAkTKoAoFgwWONN4ACgkQDQUpyRODzWtt +HgCeM1Lxur1xrAH8yGJHmmjVZrYWgWoAoIDCzJbJzfIdRC3b2ltUMuJj9rW2iLwE +EAECAAYFAkVbQNQACgkQ7aIelLVlcW9CzQT8DE/+9x8eHNJRYPMpXRp5Y6K3idr8 +ZR5qwGCe8HejIX2pRnQ1rLfOerofNu067dhsaJ0Zg0O30K+QFgfFLT3WKVszGJGq +GWxGYFAcof0dc0I5KUxWY4uUe9TjWILdbIKJuo5Lpu8AqGcCQHHd68GY8KyH1eTQ +L/R5xNkuCqCrgP6LzVzF1RnnmbDwkQ/Yv+/dfx0x6aRRhe86l3fcoEVXHYhbBBMR +AgAbBQI27UjqBQkMyXyAAwsKAwMVAwIDFgIBAheAAAoJEF3iSZZbA1iitdYAn1IJ +bSJ46kvsBjq8X44hoybDZlbWAKCS2jR5Z+CmMC5WDqNepHXAe3alA4hGBBARAgAG +BQJF7HurAAoJEM/oSL/8Z4Wi+XoAoM2fLIgxw1153EnODrrHXDJ77k3mAKCUenHB +3eaF/Kh22kX1wHKAuaZbbohGBBARAgAGBQJF7eQvAAoJEHe+WRN3SdnZs/AAnAvH +b0KGLdRdjXYeblfUmO3Fhq1DAJ9ZJ3fwyt8ziybro7B/sa7Rob9C94hGBBARAgAG +BQI3NyPFAAoJEPbu3yAYS8TZh2UAoJVmzw85yHJzsXQ1vpO2IAPfv59NAJ9WY0oi +Yqb3q1MSxBRwG0gViNCJ7YhGBBARAgAGBQI3OvmjAAoJEHUPZJXInZM+hosAnRnt +Ckj/70shGTPxgpUF74zA+EbzAKCcMkyHXIz2W0Isw3gDt27Z9ggsE4hGBBARAgAG +BQI4FA4ZAAoJEGAHkIBzx/NPiNoAnR3kwD7rJhHzdm3ZIo6VtYKcQbxqAJ9ZMy+z +IO7QuKapasNn1d5EVMtWuYhGBBARAgAGBQI4KmIeAAoJEOPyWFQSjw55D5AAoJs5 +OxzJSdYdKsOjh8jLQxOESOE6AJ4vgpvtNaR384dBJxUE7yxNTPT7aIhGBBARAgAG +BQI5yjsOAAoJECu7Q6bwnq8Krl8An21vcRhdgB0GpAT2pIetcSpgvFhBAJ908rX2 +Oaq048SI9h2RSjeULkKWEohGBBARAgAGBQI5yosvAAoJEBemQW33lI/aJm0An2EG +MaYqXTBgcWzXfI2y/UQ5h95zAKCE5mZwycF86Rzbki2PKN3OWIR184hGBBARAgAG +BQI5yp13AAoJEDX2YXxROu/ZXu4AoIEI7IxYY2iDtZVh3z7rJ9HanYUWAJ96zltF +0noeuFfaPlSLR9i2Z4JjQIhGBBARAgAGBQI5yzIoAAoJEFGs9q11voCXCFYAn0Ua +tBtnwnGThaHsvbmRgJFnLSrEAKC8OpVIXXmQ4FC6wwuzkESJOwpzLYhGBBARAgAG +BQI5z6dSAAoJEJFazEWo9ML9CKsAn1hjHomefMrLmQgD/SLF92inEj7XAKCZ6NQj +jowDIaFo1Ih3LYC2V/foE4hGBBARAgAGBQI50N/VAAoJEG8ji8JP2loMXyMAn2/x +njAA/MPOIauf2lEDAr1alGKgAJ9O0irlmLGSxFLj1iIGGNMqAcicb4hGBBARAgAG +BQI50gqxAAoJEL/hIGVrIUiavIwAn3X9tHarNyFjjx4BTHWG+VRflpCVAJ9Oarr8 +hwd17oPHLMVoOkcEn0AUwYhGBBARAgAGBQI6TMtFAAoJEO1Ggcm/Pfm0VK0AoOmq +M6WIghAz1QB3ueP/P6uPBSz/AJ4r4hvX48SJz2kigfi10ZkI3Noy2YhGBBARAgAG +BQI6iYHfAAoJEGKIBNsg/Gz2BmoAoIDLKhiTetSbjkJGOTIim+FD0KQcAJ4jWMEG +/oZRMyRe6pzxAodDAMavDohGBBARAgAGBQI6wQjUAAoJELdWp4yIKmxLt9IAnRLE +nhbSeSs4g+ZfwrwIVWbfZZ0FAJ0a5m1fB5J3V6d/gzaERILHGZP65YhGBBARAgAG +BQI6wdEpAAoJENLwolOfiErIj5IAnjhWsrezZHMpsEwtlCjY48rpDQ7wAKC6v2zk +zWRArc7WCDA0Nla82d5uiohGBBARAgAGBQI69XmLAAoJEOwOr3E2d4Al3a0AoJZS +Mehtg5CkhigYWAoLMssBQVy1AJ9jyRqwjqL9C0vIwjA9l6OE+6n7I4hGBBARAgAG +BQI69ZsBAAoJECwYoCq0xfN/hOAAn32uMmiej4+LhWWO3Vbojn5LqExPAJ4iHcNA +1ZBwbsZTafTwIJYc7chPqIhGBBARAgAGBQI7RW07AAoJEOd14yTbQbOHsd8An1yz +zbHDOFMbZstP7eWIIPZQ1hEAAJ0d/T/XibRHgbTD32xBmHNdAAao5IhGBBARAgAG +BQI7RdkAAAoJECP6tfsIFswbiYAAniGpPgPfCIXlUqMFxuCeo8wQON/TAJ9iBQPB +AfxJENa5+zhJhTV/vjzWcohGBBARAgAGBQI7RfEWAAoJECeGwkR/ikAX0sIAmgL5 +u6S/i4qGI/6CgwUNaSQI/lKjAJ9dFvESq2G5TGeC9dUdkzvcTrxZ+ohGBBARAgAG +BQI7SA8WAAoJEAYGnPKWlFfwy1gAoIn2x7UoudCcZkq9fFqH3lXFXAF1AKCbPfWh ++v7fYJDt+Go144iEMXNKjIhGBBARAgAGBQI7SCdfAAoJENdZXTdLcpYlMeYAoIG4 +Rtbs73YBzWPKAreHHOk3x1ERAKCbkcPKtpG87Z7fE0OJo4kyDXAV84hGBBARAgAG +BQI7ScGgAAoJEFCP02O8k2g5D44AnA0iUFGQQT/+Tr1uPENwVJFJEUkJAJ9TI6nu +FkxRBAPByuYfig3KkdGmSIhGBBARAgAGBQI7ShVXAAoJEJYkg+FWYsc0mAoAniab +ffCzKtNqvVtWyuYj1LwpHLEmAJ9XahXKF3LV1ZzI+d8/M3wGltAXMIhGBBARAgAG +BQI7SxcHAAoJEA6nVrUUSEP1zBkAnR9bvbZrVGGNxMVS3U/x9iCEAlNzAKCOvWOG +de0Q4eAY9oJicJhAJnw8G4hGBBARAgAGBQI7TBfKAAoJENcNX1hgPNB49psAn2s7 +nWGUjJkFjvOcWb4NLkwd64WUAJ9w0sq718SKZr9AnJwbVELuTdtZEohGBBARAgAG +BQI7UbllAAoJEOQ7FTzLRn4nGywAnjaUSTkvQGe6u24V9rASYJSi5aE7AKC5uRU5 +2OogMknz2WZcAFXhOszCcIhGBBARAgAGBQI7UsQ/AAoJEDv2CcaLr829RewAn1af +L4cQFgnkWTdyJ5b2C68RU54OAJ9UDuvg90FI1/tGETWd7aWQ00nekIhGBBARAgAG +BQI7V0JfAAoJEHkWLzb39qrZJTcAn3IOE7LNwvTX+jYsjgB4VzuCS4bZAJ9OeSB2 ++ItiDuU0C0kItLZOJLWVX4hGBBARAgAGBQI7ZzpZAAoJEMALDTYh5T69nGoAoNOy +DdfzGl5/vMneDXKff+9t4BAYAJ4zQqBgAHHG7wglRNvbFwTQL1KPDIhGBBARAgAG +BQI7mESOAAoJEJAtvZGMOKkKasAAn3MgeJKyRasnh6Cs0WA6lvCQ1Hb3AJ9qWt1A +3ijOxVXvC4AkMs9DHDOCaohGBBARAgAGBQI8B/tdAAoJENrSsF1fPDGFRfIAnjKG +GhTe7/1Q5rmLfhtQVw8c3LrrAJ0fHwHCMgY0n3wdMhCMGgOzvV+2cYhGBBARAgAG +BQI8CBHSAAoJEGpYgt+EQEYCfc4An0tStG0TlUgfvcF+IPsRBNKYRAE6AJ93rUiz +BOYc7IrCETI1LBmwQ3u/mohGBBARAgAGBQI8I7VUAAoJEERyU/QK/Qyo7/kAmwRN +5UTM8isU2z1Hfb/pwfBFar+HAJ9A8T5ACJLq4gLsLTowsqUwzcncsYhGBBARAgAG +BQI8XatAAAoJEO7w2zSzISYDcL8AnjHNEJjktHLSTl9SfWtw1pDMlHX+AJ94iLJW +e7LZDDotVXchOX0dmA7zRYhGBBARAgAGBQI8cOPjAAoJEBjNJaUi84rzZZ4Ani3Z +JEZHMh1SrbZemfSEBMRPoGjbAJ0ZKPuwUDruY1zHxmq4NaxNsw4bBYhGBBARAgAG +BQI8cScSAAoJELHEcxc+e0tz5CcAoN6nqXU7IjSrhmAumtUZSWUwapIhAJ9husqb +wqVgC+Ny1mzG8sn/62MUqIhGBBARAgAGBQI8cUGCAAoJEDoapjWQmlQGL2wAoM/Z +l86P5wuuJsdNyBYC/KBbgQISAKC/dTSC18RmK5GjpzPtgottFLwN2YhGBBARAgAG +BQI8c3iDAAoJEKPgudJ6NPreSe0AoKUgoBkPHjHn77A7BdA5RGc7gBzaAKCtUxcL +iu2aMFECclqdbSg7TQ28d4hGBBARAgAGBQI8foHzAAoJEI47c57dK8yd/3YAoJwz +Jy52t8j7JMXlX99sA20xy8X9AJ41gsOJX2GrktC7phr/bhzfT2hK4YhGBBARAgAG +BQI8gGPBAAoJENeDa2wM2SDnRD4AoLeQ4mX0RZL8wD3nEQwiKd6TnVMJAJ449Qgx +Pis4NkYivWe90DPAdCeHa4hGBBARAgAGBQI8gXeZAAoJEP97262ZQ+PfpZsAn0vW +qc/oBB7EVehC0uDbQi76ybEZAJ9wHsaYrHT/vCsKJYnicGlT4rTdoIhGBBARAgAG +BQI8jMwkAAoJEIW5kHXCkQ5BqIgAmgKq8F5+pH92g+8LLNa4EJqwrSSiAKCFOron +6MQbm6dvmI1upI255BTA9IhGBBARAgAGBQI8lzQ6AAoJEKHoAnDadDOWhq4AniwU +UPAgFczzvDk89kzBamCyGxa3AKCtqiaqI5hdvkx7RQh89IYYgQHpDYhGBBARAgAG +BQI8lzY4AAoJEINou1lm+8GMc8cAn3K2eck8I5/UodUv8i9zASgbPLsVAJ9KQuBo +CLG22sXH9UAOQGMBYj3DxIhGBBARAgAGBQI8sTgxAAoJECV7eU7GbKA9KVYAn0yC +fPDhTRZZ1BaDWXpg3W3eGahLAJ9cuWcgpeUmJKhUxolbZILSCBISu4hGBBARAgAG +BQI8sYLgAAoJEHrriu1HOknJwYAAn1JUK6w1G+/G/dyRL04QP39WWp5CAJ4uOPGc +WoMz454/7x998iteGoJ6tIhGBBARAgAGBQI8sY+DAAoJEKHFknzOXc4OKooAnR64 +2KrjbtmqYVoIBuRNBuswluTBAJ9TUCZipExFLG2p21TgcdRucL2JHohGBBARAgAG +BQI8soc7AAoJEFZRM6RQ1Ku5PfYAnjCXOSrwtoAB4AlY7+h5+wCoGPqzAJ0RSK47 +p29Uoe++eNlEaFgFZrjzdIhGBBARAgAGBQI88iBUAAoJEF9fNO6guz3r/T4An3Ft +eQ9nEuFE5J9dQUqp/qYKwOCiAKCsyw3O/F9zhQ81V0zr5PFfPTrIRohGBBARAgAG +BQI9bhyMAAoJECjG9WuBfDVoTz0AmgKaxb4IBBwU1Ufils5tGd5fYoyyAJwMNkLS +dTJZ89HLTcEicDkTPO/wEYhGBBARAgAGBQI9hEZLAAoJENQ8swWV/so0s8gAoI1C +i9wh9lGHIhAGq2VPR9GWCCFkAJwOiNWidBYFohdm3f44FmgS9o7XeIhGBBARAgAG +BQI9heVOAAoJEHWXOhDW0ISm7f4An25SkqiaIaoWhWsLVz7PE19VKmP7AJ46sLpo +RTeGAAHs9+oCLUwfQcXJiYhGBBARAgAGBQI+NwZiAAoJEJEIIZ7c3okKnhgAn0ss +iItbz54kDqvMS34Iw8RZJFRGAKCUhWx/Loa8ATGvGjiEZIzfbkXWNohGBBARAgAG +BQJFw8E9AAoJEI6qh0Q5KZ0x9aUAnRH3Am3KgMUSVESSGNrcPoedERQfAJ9dQHjn +N0aUe9tve7Q9LhV6GLFmRYhGBBARAgAGBQJFw8FIAAoJEPpEYiHEJCXtFn4AoONK +25yb2NNe2E1iX4JD6o49OYuyAKCWANajeEtPJPZl92cI+J3mf95c9IhGBBARAgAG +BQJFw8FRAAoJENQGMhwHT16EZrkAnRIN5dDSCkglQ2Np+U5yhcWZklHzAJ9Jd59z +z/N2Y2xwmnw3UsSAgBvZKIhGBBARAgAGBQJFw8FYAAoJEC0JcXhKCKrfPTwAn3JW +FQ92VKe9lFsOEafQvkspSV7yAJ97j7dfPPsMl4nr/vA0JsuxhymL5ohGBBARAgAG +BQJF6vbAAAoJEE44UvTDfB0JHeIAmQEfdsSzRZbzKOLcEZhboeuuwUQMAKDA2j8I +/9v8LC9JQvz2zgOi/aFYA4hGBBIRAgAGBQI9BFveAAoJEI/xGsXf6A+y79gAn1AA +l5dIQ3xnhHWxo4SGv4UmmQq5AJsFeEnXiZwaF1dtlQRHpJk38xyhxIhGBBMRAgAG +BQI8r1OKAAoJEOqcZuq5+NbZhHsAmweBWes+nZkidnqQSHXqEvChyzYRAJ9mXFAy +n7haVVQ7lf2zIaY22xyUSIhGBBMRAgAGBQI9BbMDAAoJEKFjDI904LdmuOoAnRcE +ls3xJsrr3455jT8wsr3TtkdnAKCUZdSG5f9oT143p5dX9PKUC04WQIhGBBMRAgAG +BQI9BkQfAAoJECm+XSJo/VSfBRwAnA43cgjzFo0m61yglRYw7bmqZeNvAJ0UiO3t +VWESXFXRpqwLZrt+tBq0KYhGBBMRAgAGBQI9if0nAAoJEO+Cd8r+mR6YOKIAoI/A +ZZWEyREObBetkHdqvaNhTSfHAJ9iv+86cvTPzooPsiGKH2jfuX51FIhGBBMRAgAG +BQI+MpIjAAoJEGqrWicBf1a9TJoAn3DXzjpuv8KB6RLbhVYGF71IdLRuAJ0UzwcH +XphxVYjqIzSdIJVnJP/OHIhGBBMRAgAGBQJFWDxNAAoJEFT0YWrrvC8mnaoAnipW +WPVkP9awoBdE5ER7lDPFW4gdAJ9SUcy8250qLpN7nPFS7iXto7XmZ4hMBBARAgAM +BQI9ARP/BYMGtbFqAAoJEBQRON2j5F1mrY0AnRfegzNpHa3kxm1kyo0zE7sAdwLW +AKDsUxREaMlAp+507Lnw+EKcSJCQoohMBBARAgAMBQI9hgLlBYMGMMKEAAoJEFPi +hU4L4fDj/pYAn0y40X1YoUTUEPzFSLh7bXrF/7P+AJ9WQbYfBthLwn4jlNiqDo5d +zGVCeIhMBBIRAgAMBQI+XnGLBYMFWFPeAAoJEFBeiEci519LoAMAoJ2eTZwVid4/ +f+7Jc4OSMv6VOlHrAKC2jSYlIFX4Pod7j+L1CYbpvdT/24hMBBIRAgAMBQI/ewk6 +BYMEO7wvAAoJEFuz9RlYFnkav2QAni+pVSpBNYhYgv2KJ5Qcy6jQHVZIAKCAR/FW +A1y0SIAacn0ncHNWMU3gw4hMBBMRAgAMBQI9B00XBYMGr3hSAAoJEDxiytjk1DJN +iDIAn1F5GX5mazBSImDvBf52kDAbP/eFAJ9l639rmiEmKz7nSG0ZMWJvkdja2YhM +BBMRAgAMBQI9eHiyBYMGPky3AAoJENAanBlNdmzeq7gAoItrhY4eEstCo8ne+tHb +36Wv/Y7TAJ4x8j0NLR2EqkmQw/amkL2/xdz5TIhMBBMRAgAMBQI9eTETBYMGPZRW +AAoJEHBcU4nVwbNYWpUAoIkeRk0seH0gqpIpM6zjjlwKJw1XAJ0RUNd3ZpIy3Ecu +BPG8S7ZvMT8gHYhMBBMRAgAMBQI9g63zBYMGMxd2AAoJEALW7SHjLE9LoM0AmgOd +Ep8nrvNp7YdIpDVZ8xw+FtHgAJwPVsRgZpqb1mDquSzk8tn1Xtj/hIhMBBMRAgAM +BQI9hfwKBYMGMMlfAAoJEPVrJqOmOZ5z2XIAn1L8TV46FmBLAGCc98/jFg3hq3yU +AJ97JVxfXHndjgDd2IGGTU5SAu1FGohMBBMRAgAMBQI9iBDkBYMGLrSFAAoJEINl +y9zdTU7+0FQAoK/gvz+4Khg7qWEwttY5dO5j3xv3AKC2fc5Jq9WBega+7M1CpLEm +p+n8LYhMBBMRAgAMBQI9iDsABYMGLoppAAoJEB29XnWDmeG7ljMAn39GGHRWe4HX +Naowmnlw4Qny3tDgAJ9Tibmf3ihpPotFf0nC6TjC5/0ggohMBBMRAgAMBQI9tsGe +BYMGAAPLAAoJEFZBJvIp8ZvR8ooAn2jW48iJR2APXAL/LC5M+bh0aE3uAJ0cgz3w +BYgT2WYcCTQ5ZkxAqJVy/4hMBBMRAgAMBQI+9iKdBYMEwKLMAAoJEKH27pQkC0w9 +tU0An3CrstzBIyUa4pAwYCraSD9WrdnEAJsEZWTXijk9FCeETbdqYgB6kw+O4IhM +BBMRAgAMBQI+9s+8BYMEv/WtAAoJEAWLWs1EHF+B/44An2kF1vi746CWnFTWK3cY +V1GMdmvuAKDEFf8vs43J2jUW2Ux+rp6uHwQweYhMBBMRAgAMBQI/BauXBYMEsRnS +AAoJEE64NOjizPAPidcAoJrnKT/a3NTY8zxwxTXEKJEW6f0RAJ0b3LVv/AMA2h/2 +7UIz7V4EBgm6z4kAlQMFEDuB4BNSrOsu06QsYQEB6AYD/iRZgJ2U+hTGt879PPwL +W1y7dQFbjMHqbyyM7eml9ZbC+m+jqNvMsniFCR5qvStMgbXuUZGGpd41mL5+vqF0 +wwM00nBQe+rr5grY2oMPCSEJRNtHEamOsbc4GP59nrwbUhA7MKPSrPCvh9bvh+XQ +7MSlar9eVBkqvnYmKdaKI1ioiQEVAwUQN0Pe01KAV0R2U0AdAQHIcQf/Ykx+DvUa +CLIYlMrEIDKZ3J/aPbJ8frAjvzYkrgFZXhzQT9Xfyr6OkhiyWKFX23yzzDVcrmeI +xovCUI7IFY6QM/d5yHr4Y8+18HdyaUvaFLz3o9ZnVp1AeAJ5CkHzfufnrKPRpOzg +vXFqttJVPbaVTAyJTo/Bh0fZGHyeHwW83QhmxuWfac6PveoA1DM1+Wax5QoXVeHh +yTzIutF3ivpqaHEBUB9xgVEk3jN0svdyaGCS3QANmXMDBecSPB0cfLtK8AmTV5w0 +4D2kWw4lu+fO593Vp+z8Jsbvwj7QkOGDvlnY3Crx4qOwqqI7TPP+8bnJZKd1m9aR +NbPcPdvXGvUh3YkBFQMFEDnKmFYaT4ZLvt9IMQEBgzsIAI6Cghnj5vIe4NnnTWBq +LKz0zHGfDzQjBE1zGaM4AmxHeaFr6LUWmZ7Wtgmco/7uYDqxO8/F0djzbbXp7h1Q +4ouctCsGmk0ddv8K6fVSetcC8v+M53J8fwvTcIPzLvWNmzEvBLi9eslja5umMaa1 +rGmmMuxtudTSO3LHl3FZ7gKMM5upPKLxMAgKlZeLOxFImzUEArg4B+InVHa+NdHw +56VGpab7BmH9cKobPd0W41O6TRGi5p5c/MxEh2Gnr/iaTFQH58P441qfe8cgrmpe ++ca3P2o/d2p66G71P7Eigg27Xg81vcWMo6mRrtp6Z/qwUeIlB2X/Y/4JcE9D1Zx/ +43+IRgQQEQIABgUCRe3bAQAKCRDRlQx2FhPo1W/MAJ4q/wKzyldDyA5ulwP75lUt +oVvZFwCeP2cZ/AsKHNKhpRPXATo2yEuh0hCIRgQQEQIABgUCRe34DwAKCRDemKiK +LdsArALbAJ9qjRySsTZ6mUBgGUn/5DmluHQ6WwCgrOEvwgZ5l3TNaewOCGFsJdp1 +a7GIawQTEQIAIwIXgAIZAQULBwoDAgMVAgMDFgIBAh4BBQJGtcWFBQkXLil/ABIH +ZUdQRwABAQkQXeJJllsDWKJBTACfQI8TnuVIxE88u2napOMyUfoWZSMAn2t47LUM +uyDEHRcYvEBiP/SRVvsrtBxXZXJuZXIgS29jaCA8d2tAZzEwY29kZS5jb20+iEYE +EBECAAYFAkCnUqEACgkQt+hxIz4tn22dOACgjeYArERuayyqZmozCahsgUyPihMA +n0PkgZDTwKgSw690xdLuR2rWJrPQiEYEExECAAYFAkDa3nAACgkQRTxFSQIw1gIZ +CQCg/jjaczO/s9GkLq/kftPN8A6kLr8AoPwGlVzoq5yWxhgCkEMfV+KItmDViEwE +EBECAAwFAkC/Rz8FgwmZjakACgkQ2S0k392WXIP5uwCfTlmW1u9U3nck5mCo6DeT +HNTmUvkAn2jnjXhvqKoLfS2ERRwQlFFAw6NRiEwEEBECAAwFAkDbVF4Fgwl9gIoA +CgkQ9ijrk0dDIGxiBQCeJIrdN0kFT16KL4COSILMmcjVxygAni6OinWWNJqCk+k+ +BNIvKpm+QKm2iEwEEBECAAwFAkDxIncFgwlnsnEACgkQkvv9V4b8pZK7gACgwOU8 +kI9ZBzryS+HxAeWEo4WjeC8Anjl67/wgPGr4XAS/XA1xmWzRwZiPiEwEEhECAAwF +AkCn2cEFgwmw+ycACgkQt5wosOl/hW1B0wCgiQGkFQEonh2cRtw1xXowakWqx/EA +njp2Du5T+xpOdf4O+JwV5DmtKqW+iEwEExECAAwFAkDcUg4Fgwl8gtoACgkQzQ+c +om69o1nN6gCfUXjD5LUESFXa08Px3pbfXidXAuAAoMJ1/H/oFgcer7t+tACN2vC8 +GGYsiEwEExECAAwFAkDkGbAFgwl0uzgACgkQHckf8471INHpVQCfV67np1keBn20 +I5JABN5Swm51B+EAnRxMBVbypQcppBhdWnxQadrjhHVqiEwEExECAAwFAkDuoKIF +gwlqNEYACgkQyA90Wa3Cns2o+wCgjBXhs2mEn9HFs5F8WR4AdTpWp0UAnj/Qls/Z +Rkcy/RAfAN12XgHOkpyciQEcBBMBAgAGBQJBCbyrAAoJEDP9cVf+zmZObXQH/Ari +1HO19gpBVVhiXet244TWsSe0UQ/fJXQfmqQiU+tc2LePaGA6JQQE0OAWm4n2tLPs +hncZwgaU/YiVP06JwbClpsC2gHzVLyskqTMj5sEsIrYnXEmyUh2OTYU7W74qMu7W +C7dFlhpg9zdsRNdea0QIjaHmE1rO8PD5BLUlMiSqv++GXdNj0kDGIvA0FaffSmGH +yRHO9EmHUQjnzi9FVvudNJ3o9imemgSyQltfIBz4FXZAs+T3miPnYzB4YAMU2/e6 +7JSrZYf0fUo/cyfA1F5PL77ChB8vOhscczIGvhxwLi4qWo6YFxn6SSYSPGslNEAt +6W7aq5SGlHtrS1yoXFKITAQTEQIADAUCQQ2nmQWDCUstTwAKCRArqCYCws6AmVYN +AJ97sTutwUKf3G4vlGH0wNVW54AljgCggvoJ1kiWCD0u38cbZ0MWDA/BuQaITAQT +EQIADAUCQRi7jAWDCUAZXAAKCRDVbigPid+NqwYUAKDJMU5Pc0w6jsM5vG6ViL5a +1iuKpQCfVjvjSGLh9Z4HICfmqhSPxut/bimITAQTEQIADAUCQSIxmgWDCTajTgAK +CRD4WZCwJIrrc7u/AJ48G0zmByG5ULeBcAw7uvUD+V7voACggwzSirrC6IedP91Q +AbznwLDT23SITAQQEQIADAUCQKhkvgWDCbBwKgAKCRASCWOdEUqoXF+eAJ9tdhKw +G0wzmFxQKyeb0i/IKYyGAACeO0N7ur7lxb8mbMTeKWUH67x9z0OITAQSEQIADAUC +QYTotgWDCNPsMgAKCRAYoMyNVwaktA75AKCxz4D9I71tjvz66XYpT7tIJzO2rwCd +FudPQbQecl1Bgx9+ssXkieDZ8/mIRgQQEQIABgUCQYPTmAAKCRD2iL9hpWJ7YSSG +AKDnzacy8VJNcNv890XT6RlMFBMIZACbBISRrsQzM7OgLER59l34ZCYR1xeIRgQT +EQIABgUCQYT5FwAKCRDdkeRRL5WCwVf8AJ9FgF6zBFZMc51ziAt5/FRVIZuPzACc +DcJYQXcxA4iklDkpIUsTbXTiHmuJAaIEEwECAAwFAkGFFhIFgwjTvtYACgkQ0mRm +ERmTqq0ZKQv/SpqLNjcjH6HA2P5QA3ywaE8tg0ZKc8KAvIsxx4HIk/t+kX3pOvLr +AhixUCxd2W24LrASwM2MhzvgUJ24BzQd+Gcnli7dyIn8O9H/++VucTWmn5HKxV/t +XcJU3EuA519IF3vq2CS1x9uyH5H6opHgm1aOiOQRP5cA6sINg2Pw/ec3EfPNg71Q +dIGw3OubjpEEU3G0ROHScPGaDN+7qLa+lLChExuL/f1UaUck1igDuK1Vl9nHwV5s +kD0pyKtEMa1Zyh+xSFZZ+dADYr5qE8jH43TFXO7GMpmhduRIL4sXDNqhgVQTo5wW +wGRRjjRCEI0ohZRfeRJlVRaujpa7AyW1ACRcb7TdrBKGClyKrNnej46ujzOYygRI +mX1zmhRa4h8nAem+vDtSsCtxkt1/ptw6MeUmoa/ZdJEkjF6JS0uCE+tkXymo3uPn +zIv3hALs+xAuxGRyAYun1pK/zs7tfMZT2eXI5LvBHnqlA8KWlM7y2bpySq4qHtPm +MiqezNWHa3jJiEwEExECAAwFAkGA8OwFgwjX4/wACgkQsYn2tNI6QchEuQCeN/pb +bqMBzHuAfWO/g9QfmlmVIW0An2WQXrXoE3xnVp2C85BtML2phOWPiEwEExECAAwF +AkGEAf8FgwjU0ukACgkQTjypAm4rQ9yB6ACfYnJx27fjxYsq+5UfQEemQt2VO3cA +nApE8yUw0B3ZpqCyfRo8JQIb/cJUiEwEExECAAwFAkGEvnwFgwjUFmwACgkQTbPZ +7n9FhNqFGgCeNgwyzTJY1OABEu/EoBXEUOENxdMAnA6Ul/yxKQihc39VvKQfpdwP +GUhRiEkEExECAAkFAkGD3AUCBwAACgkQQSganqDijRh6lQCgmgm1rqgdF3qYuDQn +/S1vFxggwpIAn1htaL3fD6o4LnT/8BIm6K6tPGPWiEwEExECAAwFAkGE6B8FgwjT +7MkACgkQLMilaHDIrOVJxQCeIJI+GgF1UfUOjkYsjkq260Q72OUAoL0ekc/ixpvh +4Vs0j1q9Wx0fpQUwiEwEExECAAwFAkGFXLkFgwjTeC8ACgkQT6RVPNdrU1mZHgCg +q9+wyMgDr96Ism0gY9OxSqMA+88Ani8EIVnKhI6trTzgZLZDrZ5pdzDuiEwEExEC +AAwFAkGEkIoFgwjURF4ACgkQlPH09zrL0iMiigCcCIbdWZPauTvF4Pn724WxH6Qe +d5EAmwcodEzOE/rElE7fqScRmudd8Ur7iEwEExECAAwFAkGFVkIFgwjTfqYACgkQ +qI/9z8xhHubw1wCfWLT8UnjyRQIuxGPPWjtGVeezdP4An2GJa9XsZW3yv2eOPAsP +93+npZtdiEwEExECAAwFAkGFRwQFgwjTjeQACgkQDecnbV4Fd/JDbACfW5h+kLB3 +Y0wokkr/sxy8RFXwp9kAnjMs2yoVbG2ZbkHQV2ZODRF66zuMiEYEEBECAAYFAkGG +D60ACgkQ6gnEQD//YGyIWQCgruyF9KSG2GuqPVQIsizCCV8rjPcAnRQsBzfw9QLM +960FP64YWUCqhYkYiEwEExECAAwFAkGG8eAFgwjR4wgACgkQbHYXjKDtmC3wYACg +1f05WHi83tg/PMHoBkqlngdDIuIAoK7KZ/to5FrkfNphn6Zo0fozB1n0iEwEExEC +AAwFAkGHwbsFgwjREy0ACgkQVm02LO4Jd+iS0wCfbUWuTf4DZrjdua5kNdfvk65g +ojgAoLHPPvTdAlVKacX/rnPD7c36LfuYiEwEExECAAwFAkGH6+oFgwjQ6P4ACgkQ +TTx8oVVPtMYoQQCfXmZAzk9EjL3qPz50zZgSUO8l3m4An0Xoqn603NHFaHfbBKdt +WGijlgl5iEwEExECAAwFAkGMPFkFgwjMmI8ACgkQiSG13M0VqIMbDQCfSxC8XNls +eJ9VQ50GJ66KwSDljmMAn33ApYFWTs8qa/EBIQSgqPlVEBO/iEYEExECAAYFAkGN +FPwACgkQ+C5cwEsrK56k8QCguxJO7l5effxWbaYOgeVko8HiQ80AoKSJGsOZGx1n +vQRKeRK/7DrZbB2piEwEExECAAwFAkGc8GEFgwi75IcACgkQV5nlLYTPmpDPdACf +bASh9WQ47r2zzcVcjlfbvsz2VvgAn0KtwOo73pm3e7aPO/mYlLsP4V9iiEwEExEC +AAwFAkGSMFkFgwjGpI8ACgkQ/2R3A0yRcenRkgCbB5vYhB0cv0S9X1y54Ci1KmaM +DNkAnjeOH5rAZQsOQZXoDJPzHNrjYpLciEwEExECAAwFAkGZWWUFgwi/e4MACgkQ +SvFUKpY6VLAkgACgiL8te7hejTXfDXRIOAZeVzd76/cAoJbmj0tdYt2QGc3j/4yM +nmXrKPC/iEYEExECAAYFAkGqFTYACgkQztt/8ZMtg2MVMgCfZevJcAcVXa4hUUJS +jkWo0j/b9MkAn2HZC4sNs9nMN1PvX95Ge39wfBEKiEwEEBECAAwFAkGsm40Fgwis +OVsACgkQLEmBxMM0hsB4NgCeLxvQw1g9MSpWY9+2VbSK/4vNd4EAnicGGKdS3Zy4 +8E4GBZr62ZmWjr/iiEwEEBECAAwFAkHCEoIFgwiWwmYACgkQGFnQH2d7oezd+QCe +JzuPIHb2H/PX1R9NYqC6z+63wFsAmgJUX4Ei+WzKGs2r8LVtIo03nc/niEwEEBEC +AAwFAkHCKOAFgwiWrAgACgkQgcL36+ITtpJ6eQCfQ5aTW9WLJNVWTdp4fi618YDd +nNEAn36Vz84EsZ0gpO0Je9S+geCrffj6iEwEEBECAAwFAkHCKTAFgwiWq7gACgkQ +a3Ds2V3D9HOXdgCg91Pqo7tiv00Je9XoTIJq82ug6gsAn2Q37v0WzuggX1xyzDSR +7oxz77owiEwEEBECAAwFAkIi82wFgwg14XwACgkQ2KgHx8zsInvpsgCfdHcjOaK7 +aK1MBAYBaWwkK4rfd7kAoKxblxsQzllz7sLvFbK7xG2ipuNJiEwEEBECAAwFAkIo +ngEFgwgwNucACgkQLADuUthSlVgXawCcCbstExBnVkd/fHvatuzJ3sJ0g0gAn1t1 +CmnaMwV/HVQlUhfqefYlVN3giEwEEhECAAwFAkGxhHAFgwinUHgACgkQAVLWA9/q +xLltoQCg24DNLxMnSOcPFPCNLTPkyyjyQu4AoIe0tZDEDS7mvM6RQaHREvCuFIOZ +iEwEExECAAwFAkGqMckFgwiuox8ACgkQdDpVTOTwh9cWbgCfaMETpI9v6LZgWuTC +zE7DceGsuW8AoIcBSwWGF0XkXpRYcvXfjvAg57+piEwEExECAAwFAkGrJUQFgwit +r6QACgkQzop515gBbccEhwCfZhBXUVoNKDbW5mpYGxfKrMfScIgAnj0XoOlYmWWN +N1hlKoSQrZSvh4FFiEwEExECAAwFAkG3PJoFgwihmE4ACgkQEfLcQ8rmNEIRiwCg +pAzSttJZSiGIffSr4/dixsFUVxAAoIwnyzPthchrUSMR10AvPAu8Czm9iEwEExEC +AAwFAkG4HyoFgwigtb4ACgkQ5Vyxg0d4n7u8mQCfdQ++3anppXuhZp6cQIp1DCCz +56AAnRA9B/n9ah1wL+IMjoBhFvgSW7JLiEwEExECAAwFAkG4K9cFgwigqREACgkQ +4We9YdVB4USYCgCeLsm06Ov/Yoi9lfn4UB0IX3qwBFgAoIPEVT2gGxQYua51y70p +jVYG6t4eiEwEExECAAwFAkG4Wg0FgwigetsACgkQBMQfNs0khKmYzACfZgUeTlim +mFrhBDEV6SsslxvVIGUAoKZR9c4+kfE0+BJ069AUZBkkeRKGiEwEExECAAwFAkG5 +dt4FgwifXgoACgkQPrq84hvwIdMBbgCeJhjUvC1klrCPhWqKhyfoKJE+hWYAnits +OnNDnjkKDdKta+mrdL23iPD5iEwEExECAAwFAkHCqnIFgwiWKnYACgkQPG1Ayb4v +CvZS9ACfROLs6kU6Z93eoFUJl5H1M3U/L3sAoIgAGfCxQ3sADvFiYg11GTGnDzff +iEwEExECAAwFAkHq47IFgwht8TYACgkQvdkzt4X+wX/UgACfeM81+Z/SliH++ZzO +my5ZR9ljTo8AnA5DGAsPAbdU7j1NN0NXUg53dNvkiEwEExECAAwFAkIIjHoFgwhQ +SG4ACgkQIqUcje1P4MASOwCeLyBkToAQ+3Bvup4B9POq1xipZNgAnAui9pLAdwaG +AZ8w5PFxuS2GoXxEiQIiBBABAgAMBQJBwiluBYMIlqt6AAoJEKrj5s5moURoJfgP +/iRGZnx4Oxi4qvDw5LTJQrc8j2TjDIEbFRCa4kqBcVEBsKRSkBMe9GHpleq5YVJV +uCRrLdx9sYt9laJPtMDP6Td6JVK2b8yTzymqVN+7alSrT/lumokX3O38v+LZpj/T +fQDiXmCwRxwKx3LkXUVdA9tgYVO+O08nHyEyy0AbvrUeFo6Jv8DY7yN3t/x6VkwZ +JO5u2wUnX8rY+jqzL/fKUmV+j8XOC+pMliO7gg+wiurjgPeTiRAMxqFTZbiTpytC +dxXvDbCoLTPGa5ki4KKjXDK9gbd7L+mM1+s56ZK4D+CaY3fy4Ekz68RAg+dR0myV +z0fZ4fitUoURBm6pST4dR3BVCEkp/BoyZKIaPg95emG0VzpreWp+GyI37uU6fOTR +1EwLFkQyAuMgLqkaq4nrXTOxgZFv++JcNSWI0Emh3sJ44dEfrnf/TRT1pqqHUqbY +d74Faa1m34rPDXRhSbyijHT8TpeUTgQvyn8s/W6/y9tobNNXFfk0iv2BWGuc5UMc +de2UVnFq2Dtku5I2QrqiKqxHbKfGTbKyZNATPKLbRQXGcfwgKxTJHIQNsmVt7BA+ +0lGeSelXpCGxQDptXK3JhgDdGQmpIOiMSACDPksv5mGbVO3P1xzDEljr9l6/OVJw +2sXE+fOZqi19Y+AWKzTIX48tkZO5/+CyyPzJgwBaGG0EiEYEExECAAYFAkIrN0cA +CgkQi0rEgawecV4jeQCdF+GUDJuQnCaFZqw6sNgZtol0UncAn1/VQvGDB0Or+JIt +HnUlCU98URNXiEwEExECAAwFAkGTrb0FgwjFJysACgkQ1mvqN8E/x7b7ygCaAyFq +MIKTMqQYuQ7hnGpMTx7FPmoAoJtfYoL1pFmVZ5Mhwkv9GFUee+HHiEwEExECAAwF +AkI2qnwFgwgiKmwACgkQ1cW3Q8Sn6j4gRACfQWmnt2z+J0tB79JQ50hNEVrYuKEA +oNAe1Y5xlLlDTSKJmnwjqnN0qaeriGMEExECACMCGwMCHgECF4AFCRNri/8FAkJZ +QHoFCwcKAwIDFQIDAxYCAQAKCRBd4kmWWwNYouXsAJ9nbkvbiJZvNlzwBL98x7YB ++u9fsgCfXE6vHv6DJk7Eh9CY+Gcdn6kCG8iITAQTEQIADAUCQiH+PQWDCDbWqwAK +CRDI2LksT3FGBT++AJ0YXuDdQkG9gLCd2GtU8U9mfoVhkQCeMEy9jGnsYm9H4uZO +h5Qmhfq4CnSITAQQEQIADAUCQiKA7gWDCDZT+gAKCRABxevYytjzo/hzAKC5qGd9 +qp9ZhihcmE8DXM0SRf0YAQCfQeLE1NJbgQ2jR7PNfTeSjumM6h6ITAQQEQIADAUC +QlONiwWDCAVHXQAKCRCW8016T/SGNQ0+AJ9ElmV4Cr+P/i1t6TgDf+WGBcmFrQCf +VpOjPRunwdJ/Y0GNbV669//hVkKITAQQEQIADAUCQpiOgAWDB8BGaAAKCRBNtucb +gGGoMG5SAKDIGnMHLyTs4rOOJisowYhZmqIyJgCeMd0d3Ojp0pxX4nd5/iGXdVwu +oN+ITAQSEQIADAUCQpYCpAWDB8LSRAAKCRCLlilD/CQ/POExAKCP6uvHPe0mBOua +HeDf7mshxYQRRgCeMo4WPMYv/tLIWWl6GHRdreg7r1aIgwQTEQIAQwUCQpWcwwWD +B8M4JTYaaHR0cDovL3d3dy52YW5oZXVzZGVuLmNvbS9wZ3Ata2V5LXNpZ25pbmct +cG9saWN5Lmh0bWwACgkQMBkOjB8o2K41QACeM8dkTb6oa86Q6RFgCaoIUxfD164A +niWvx0c+DTLzF40fwzqtKzBlp4dPiEYEEBECAAYFAkK6u70ACgkQHuBMgSRdZNRJ +JACfXkE6A31wuvpD2EfHi/sm2m3PlIwAoKvIqARunnuDjET8cpyOBtVOw/EeiEwE +EBECAAwFAkK9MmEFgweboocACgkQr2QksT29OyBNEACfbNEfltwRZ1RmZEkt9ZTw +OJSli5gAn3brUt3vc1JIxs8dlkwHV1fSJpH8iEwEEBECAAwFAkK9RW4Fgwebj3oA +CgkQ62zWxYk/rQd1UACgwJNmfL/Cs6bYMFPC1dRrNsf2GtAAnR6K37k2u63FX1lb +g4aSMLCcNviCiEYEEBECAAYFAkLQQZYACgkQWp20Ay6vTYBSnQCfStOrSvXsitfn +XHqS3nELWI9RVYwAn0g9x2ITbWAua/rx5t6YYLSduG5UiEYEEBECAAYFAkL2hiQA +CgkQic1LIWB1WeYKQACgxQLr6OPEtGuH4jCezv8goZ5hBA0AnA5k53eyGYXnbESu +LD9hfIgq9NegiEYEEBECAAYFAkL2jQ0ACgkQ1U6uS8mYcLH9uQCdFOloQMppwhQy +a4zvgrXaqDtaZBEAn2UhMGeO/7laTY+EkaOc0yWp1GCEiEwEEBECAAwFAkLlBZcF +gwdzz1EACgkQg2E6UBaCfQMWAwCgk0N+XcWaLDssH7wYu0EtOFW1kKUAn3Vq83yr +mg+F4TvieNmPhhqTP6W2iEYEExECAAYFAkLXaWIACgkQ38wGmSzEVdkS9ACgyXwp +lqKIDsyExNmuVkPUS1ld2HcAoJ5nKOY69/aMJMTABBH9tFyS4IUNiEwEEBECAAwF +AkLinZ0Fgwd2N0sACgkQ9D5yZjzIjAkhqgCgj/Uy+2Xvfw9FAwPdWSaC+o4AVUEA +oIvJ06LeJppo5EQqEt1mc8bYV1UjiEYEEBECAAYFAkL2U+oACgkQF4k5uXLdWDiF +nACfRaNxule5PGrfk8fkbzn3kF3z7HYAn1PJnIAlgYyhYDexETbeUykY+9GhiEwE +EhECAAwFAkLrbeoFgwdtZv4ACgkQwm9wFgHGy4MQfQCffyaecfqcThyxP9FNgZ2U +z4pBwAEAnjMFgtk5JN6gZ+Ztgqe+YyYrGvvuiEwEEhECAAwFAkLw+X4Fgwdn22oA +CgkQWNqWrwuQEUHBCgCgn3XtRj5qJxudfYkec540HnkoerEAnR2x0A8LAA49rsbh +CiLZlmTaaD67iEwEEhECAAwFAkL5sgwFgwdfItwACgkQ4hLd7psgZbfpmgCfT7Dp +lZrJNYP+jrldo14GO0v6fhIAn1YoULZuHQRmoQrsivlktn+DqE0viJwEEAECAAYF +AkMgr9AACgkQtGuSO22KvnH+kwQAvGUpmszwbYYMOOUmi5UTGjr+x1o7dXn2bQWI +dH0F4BfShvyvd3qBhb5OGrK8YFB7+cHJDD0A7NER+MZ5H/KnISdLyWA26y26EMDR +eou/dzasj3oWmfullh2ojIdCxzoB4VImXcQY1+Ui7d9a6y47inK9sMzK4pwt1PKt +ncBRu7yIRgQQEQIABgUCQyCwBQAKCRDFr3dKWFELWsr5AKDAC86WauiBT14jR5On +VnGnsoLRAACgjz2G91FPaDTx/m2uv3A8ztOUjpyITAQQEQIADAUCQyFMcQWDBzeI +dwAKCRAUqdRorfCKfwAGAJ4x76O8eVQAZ+ih39kA+LC3UoenFQCghSxjTY8eXfYm +bqv5JDsqpw8uvKWITAQTEQIADAUCQyGVQwWDBzc/pQAKCRC/69PGQc8DIlKCAJ48 +XCT4C5MEr2aGFSCVLw8yH4ATkQCfaGKSDz5JMkZZrulf6e9jbL4BvKmITAQQEQIA +DAUCQyN1TQWDBzVfmwAKCRCboJNrWjX9QlGNAJwLQeoR9MHMZMHjqR7bCtZFzhUj +QwCfToKGN6pqjOyCLvN7IQ2z7h2LkhOITAQQEQIADAUCQyN4BQWDBzVc4wAKCRAx +SLvvHu8m9ICtAJ0ZEDO5jWXB2WNTegwQyxtux80NKgCeK+5Wc0fx6k7pYpFEr8FD +27kT+EeITAQQEQIADAUCQyihNAWDBzAztAAKCRBJPvuOXWT4cIHtAJ9H/1j+01em +eRh+RaIbco3zA4/WSQCeI4bFDknxR3voTopq9KIMqyfH2LWISwQQEQIADAUCQyCo +RQWDBzgsowAKCRBsZO143jTvodBmAKCRj57Ry/Wj+QjnkIcY59xWkflc/gCWKqc6 +pOMWE+qXmcXH7/krMsmigIhMBBARAgAMBQJDIJ3pBYMHODb/AAoJEJT+3vmtNrUV +EqMAn2tfB5vASh1oiO58GdTVglwpxemTAJ4vMTAblcWzgebLUzm5wR+YWHWcyIhM +BBMRAgAMBQJDIKH3BYMHODLxAAoJEDA62eiAWc/cml8AoKPycGLkXCR5CLnzowu5 +RanuMzUmAJ4536g4hlcWwD0UlNDwUS2Si7+PpIhMBBMRAgAMBQJDJCP5BYMHNLDv +AAoJEHw0FqlEG6/3TzgAnR3zrBg3GhFvB+SCDgzVN04/OsJaAJ9RUl3WAyG3FCXo +dMKFGbjf0xwip4iiBBABAgAMBQJDJcl+BYMHMwtqAAoJEA348Hf+CljYb8YD/1rm +o9voXxBwcaaRAJ4yfRcbcm/HLiPh0/dmCu0wTymHxSpdZ5SvZzOfjukfqaKtn8Tm +ZFureVqdxtH0OBZZRyTyF+Gjk9ZVsTr61Dm4YM/H+ysJ4+eA6sAdeMPgC6wclg9/ +gi+WWVJtS7V3nrrhhvuJ+c19ZkdWKPaMz8Dm5EmjiEYEEBECAAYFAkNfjG8ACgkQ +5XoO79RjNtoAlACgvh0c/n14UuqSdhEdEYcIJa0I26MAoILg4M/a6XfYbAtVVpZr +DSBXdcUgiEwEExECAAwFAkNaAYIFgwb+02YACgkQM6232ZYRYVUJHgCfRWmbDkQr +vSP8VGvFRvv6yKqHOakAnirYhae+s2l7cz8i4c+p5/SS1AlhiEwEExECAAwFAkPT +bagFgwaFZ0AACgkQ5klUNHCsE9U6OQCfa19P0RExXxaWVzJr6uLzKP++g84AoII4 +kV7AALq9A77nWuXDojWnRko6iEYEEBECAAYFAkQFyuAACgkQ9Jgd/vNmD1MSmQCb +BDaC+ZKLDTgsnORWMhSuJwOVYEEAnA5xDXtgFTTmKdq9DzqTNNJYooBNiEYEEBEC +AAYFAkQGZN0ACgkQIIdHgCGsbMSo1wCfbfphH6CbnURMom7x+zWto4yrZOgAoM6M +fGeeWNKrBHJVFRloz6nBymqliEYEEBECAAYFAkQH63kACgkQ3HeLB051S+1XdwCd +F+gqQw9bVEQAv4Owg4O+PhjN8f0An3TH5zy+qfXlJXjNyvsRqR0QdCmZiJwEEwEC +AAYFAkQNdgcACgkQpOAUxG0aO7HojQQAhNhnA+DQVFiTuFsjOCl+IgeLqpVmZbD8 +Xl+KsoxedLDNtmnlAae7sJYqoFG71ohsYe7IK/9aQVtgdg1E0zo6+3LZ0z80+a0o +vYJqCrz4eQGDvPIHijRCy6Fq5XAxkZlKQzjMf6TO/RTdW8OJaf6Bq7GOZUr+In42 +2tNL09GQxRGJARwEEAECAAYFAkQG/cgACgkQ+fnDJwmNErN2BAgAvTZL4s77EgNX +G0EXvxlWGLx2nE5/p/XvRM609nQ8EAN/MA62y3UsEDlD02O6s2QpNEJGo+pSNdjd +rl0PDlF26JMVBwSwu32INFpkRhF5MWVSLABcumZBCHSkrRFNg5K9JPl/Ro6WVMs0 +52B9bUJIDc0FFJBVul6Cn8+sIkMTwO8SR8NHP0kUM2vPR1YeqTmrOEl2KT2OAjNQ +kvdUwmIVSsOQDx1TAhxe6xW0Fw0yJdptptqb7hnfj1CDHJjI/gfPV0jQsph9Yswr +vbPJfyfVZTkHiFmvaO/lxskRd3VVuY5ypMBdTmjLff6OUsAOj7wgrW/2lt29scbS +/h45ff62W4hGBBARAgAGBQJEKFdaAAoJEBH0xB6z+64zdUQAoJb2xLqGoCYadYF+ +EPTR8jtjBa1/AJ4nx+fHCKL0hKhLw24Pcud4cIxruYh6BBMRAgA6BQJEXmVAMxpo +dHRwOi8vd3d3LnNjLWRlbHBoaW4tZXNjaHdlaWxlci5kZS9wZ3AvaW5kZXguaHRt +bAAKCRCUj9ag4Q9QLk9yAKCrgj4tmqYZILNsxBDRoE2R7RFrfgCffb9k6Qh7bgjE +5z4d4J2JUYw1BmWIegQTEQIAOgUCRF5lZDMaaHR0cDovL3d3dy5zYy1kZWxwaGlu +LWVzY2h3ZWlsZXIuZGUvcGdwL2luZGV4Lmh0bWwACgkQtHXiB7q1gim7sQCgtNMb +kY+sT/f96U6cdwKJ7KJWmDMAn1lb/18BvTBt6SswNkjeZhNLe8HGiEYEExECAAYF +AkRc/SoACgkQiqNir+lyMs2qsACgj/FAXhQvFhCZatkr7qBCZFZi6UoAnjMyYanz +0Wham0ijrvH+POQuCKAOiEYEExECAAYFAkRc/TAACgkQp99YcnDUTCNgawCgxXQA +JhUO7Tdm7H24ppREANvrbVUAoLoBqUJjt1fxL0as+Bd7EIlMIIBwiGQEExECACQC +GwMGCwkIBwMCAxUCAwMWAgECHgECF4AFAkBd2fAFCRNri/8ACgkQXeJJllsDWKKt +2wCcDKNSTwgetpsMsBunlUrWw7HeUHcAn1Xlgp78HK4lRrhixrXWfkSCMzztiEYE +ExECAAYFAkNEG6QACgkQ6tS1kPaJm8CkLgCgjDYho969Plzpsry4gseTcvuJKn4A +njHztuclj6xEtiNi4fGGnvBYwsHDiEYEEBECAAYFAkQFglgACgkQb11ZaBzVLegG +TACeIjz0GchlygV1o/V0x4n1YRNrTf8AniulsCb2794jkbZcto6bKu0dvEuTiEYE +EBECAAYFAkQGCjQACgkQmsnSLGNcY0sWlwCgsctDOVPkeE+gomU0ss+KL4xVVsIA +oIykgUl8KUhwM6Q6ao4oDUAGuigriEwEEhECAAwFAkQGKycFgwZSqcEACgkQ3+ZX +kjKVxc3tagCdGRXffmqZnoc1y1LwzybdY8Eb2KkAoOqq45pa+1o8CY/05sTB9FOe +8FTjiEwEEhECAAwFAkQGK2cFgwZSqYEACgkQoOUVvzmICVSOKQCdGvyzSMVbLqao +vnQ8snuByodCJQ4An03szhMEVn9ZxpTkQQTaOx8E6SaviJwEEwECAAYFAkQNdeoA +CgkQ/dJ0ek5GOmrgowQAnzaCLzdqYkS9phkQs9nkIYjxCp/gmHCjqT0YwjS+LakE +In+URfDz80FCk1boXKDK6cF9fKieviwMlfDeymQFL05ROTBp0TtmVf1DXOzZSlDj +xaHHE9J+g87Xau7KJiJO1QiRk/8nMide8cLk4/9q+7v3rrJCLsXbX3VJDIYBMOCJ +AhwEEAECAAYFAkQPSJYACgkQGioH6hxXudn0rRAAgqzfBFuEnNCyqXu53IN5pGNA +fns0xf0SiwTkd4kixkxptAMEu+2AXkRqao9C9Gb9+dNrwzKRnKOt4GBEMKVHKxwy +LGzjss045fHvokNa7rvqIGMwZUXoqO/Nq6NeJXjCOtq67fOVGaWJgLoTrQl2rVAS +czA9025TtyhNnAL7J9Hd8ejwBOWms3Li2kXsSt+Uahp51Ji8qdDLB4iWCk6M6f99 +7dMS0gDIXsDEx1Vnqhx+NC7vJBkzvkV+9zWKmLK4Rk8X4gtcFlAjhBQMwf6045JJ +3KKfOcPfL7lxOp3Kep0Wu1Xbujh9gPiSM08qsvxPOGF8WiUfnEDJQz1EspqhorjQ +ciyP0C50rCe9YOTZEhPAxYn1Joa97GairZltw+sIUOobn4Rqh7hFQh59s0cncH62 +71XOZneJjZk9MgJWm13emNCuEXeb3GbIJzl7qgkQM7aNP62uKo6urT4Uyse8AVUp +fOwE/FvHSB+wIpt45R8Q33mRt4o7HwviPfbXE4l0QPWl1CZsbpBEjkBMHnDggFLE +1qY5WJAyRwRPZnE2uUlbVUI4a5ro8m3IzJArEci5AKdyCZ7K3RBlO7H19s+x7Nq1 +Tnc+xItH8MLGV3XRKKpULi5jlGkE6JVPIev/5etTNhW3ytNc8YActAVV8REE7FWT +Hhn7YjdgaB5cB1hvvxeJAiIEEAECAAwFAkQFDZkFgwZTx08ACgkQbjbvGsyNqzCm +JQ/+PX+TdvwduAAXMdVP6uTcpeCate28Rx7H+MSb1ueQdEWijv68K63ELO8FFsb9 +qb3QOypx3qjJsjMHP42ywPY2jc+DStyAk+8+EaBX0NAhaPivHsgj+7iFPttFPA+B +M8mQql7nnvH6HSYekVUb9pd8Dir/8JQp9uQbgXrlHl+bXs8k0DCMHfWJwgUiy0oU +NgqMWqyFPUfLvo4fzf5jnLjxxyh70GwasiXplJX3VxbxFXuJDjS5X0lRmDqx6jsB +ZnFIKS1IG71gH8qW3bnfbzxvLPKAkVaJotRjlFksOky0H3BdGrxY6wjqjZtgbHUl +sabVHPCcYHnjhGcobQTbc0S5vdGMBInIYg/hXC8bcXzXGgjJnNS2GKt4CGAA3Slu +Cxzyz2kIgL8aDtt3fyqC2eVoP9Qnw1GdyrrIEDMhb22LA8c1VY419vXYLp5C5jps +nPFUARmg0f7Un43/DG+0TV7VTT/ZMRELgeGZ8YrLTMpPdOnXV8DGZfpUAXj5fJ0Y +3rafj953GZLs0/hHmeZnj4P7oTaOKXQdJVYBOUsyORaX2akoE2rPMc/6fLC20qKE +eXuOoeREQX/uigzMRkS1fZT0coKtrl18DoPr1IyHq4BIellVhk03YG3vr/oKCo6S +qbCPGFV8UBpBn4pnb2lwESYsEODxIXguI2SHU2alYB7s6W6JAiIEEAECAAwFAkQF +ESIFgwZTw8YACgkQHRqO3OFAoFSZ2hAAtBOio22e1n/uT1XzaSg7V6Bs5BEKOHnN +GLKrntNfeZvJun24PBzZnQeJZIfkVdkKm1uv6e3d4B9Hv1F/f2sb5AYUq3RKqOXk +IKg4aNV1w/Mnon4+VNUq4FE4doi2exaSEmWrNoSs4QNXwWXQBuN+fUhUzlaRs8g7 +IOkTgEqeS2WpX63F7GqQyeoH9HwbYJWg8RyXH27ZBsm0aBafrN1XJ5IDIo8aZ0us +VtZoiAb86ymTrEfDhldnL4nG+CDJURSwcly6rgFHvo/l5DS0VF6X2M5ZJjp8ghM+ +NEZM4TkAxS2gvoAyagh/PQCMq8VXwfvFDhSw5E/NcrDrbiRGVnsOW67v4t5AxqrK +q2SAOd0h/z7mler2vrfrAltWc3vAl81OQNH02zzQRYtHizk/8gwpX01+/3eAgzN6 +v0tBruNwDULsgr/imNXQgG4TErxTE1Sx3eALhFybPA2ce+Od0ZWKJWDjJUuWJP0b +PQByEtHC7pknYN5FTxS+v6t9HBH2QOLwLY2UcuVvZNztrpHcAEhdu9oLIEQeXqaU +9ah+9MDD2M8ntmW864gacelAmFrkujOFQ/TMQRU7f3ttupDFExst/jYmnDXiU/7Y +u8sXAwAf+svGyZ3AILNtEmuzFUkjlK0GQItyK5ZfQ5reyncaaSLJcoE9SZU6wTJq +SPbLjJkWjnGIRgQQEQIABgUCREihKQAKCRAFi1rNRBxfgdElAJ0TEc/rMAUxLmEd +Pd7D1zKK+TImYgCfUuWcmjJ5bK5LkpE3ArkC5Qx2mhmIRgQQEQIABgUCREjJ/QAK +CRCnL/ZsQr1kXdVuAJ9Xaa9HTr1u0p59TK3aDeyzcMhgIQCfSUVDGu/mnaR5o/UB +5W6r4Z8+6DKIRgQQEQIABgUCRFsJZQAKCRB/3j6P8z4/xm1rAJ4zyJKiljgk2RiG +/X+w7hBpmCFGKQCgqWAH6dUwVP45AxpamVPvKZHknHSIRgQQEQIABgUCRGCHygAK +CRD9AQSw4jPImNSzAKCrRu+/tnGv/JoPRcjLDIxTgJy5UwCgvtbD+4rAsMiHP3Hs +99vpbKF/oFGIRgQTEQIABgUCRE/tdQAKCRA/0h0qmjpVWMz+AJ4vhWL0yH6Lhgpx +67MjBOWjsyltyQCeMtJT+8Q4BbRtKOGqmdAM2YU1I2iITAQQEQIADAUCRF3UigWD +BfsAXgAKCRBbqJPk7D6Y34fAAKDgH96/0zdktkGPyfNjfrEMvCHk8gCeJMe6QQfM +I8pTnEtKNzQRdWXEIVCITAQQEQIADAUCRF8XTgWDBfm9mgAKCRC8EAnaDpclPzgN +AJ0Q/hUqqpydYwAsisUDRiQ2V61YrQCfbn410oswpOWdvrlaHiZ4Molpi++ITAQS +EQIADAUCRF22QgWDBfsepgAKCRAyNS1FZ/eCZDHTAJ4poseKzcWwhfVChHKUhkEV +2cfCWACfRa0RsK3BqVjtHshBlED/wfHQUJSI3AQQAQIABgUCRFC2ogAKCRDR2VIE +Cemh1f+NBf4qBoeHsQ/XRB1Tvu00+xPuskX50oV88JnJb+0whE4FuZApjzIJ/PC/ +oxYu35qkE7fJ2Yuz3kHIjQSLerIX5GLKUv+HQcbSh8iF1Ru16Q1Vh2Qxx6+eia/T +p2EcaqPxsQeG4j0n7bojz12i8NuClZPCTf3gtS33sApHm3u9UxRmJlXGgKd4bfk0 +hITCxPwVJvkI73j5bJV/1OA+pq0aFTdeLXdRRIzzpeEIVPuBRW3tPmW05GKsYCBC +F7g80BpGzIOJARwEEAECAAYFAkRbcFcACgkQZ02H1ZEZDvkz0wgAvLzYHXOYF3yz +k3/rxnW7kbw3tE2dVpKWI5SHC2ttGdToCIlhm2gTBlPUG5t73XXIU3gldn+n5ys4 +gXI+G8mqNkfoOWvmev3IxQ/IyPcf0Rncire7kXyUZOrgNVGqh7ML425n2Tcqt5y7 +EvXLMa+3635+2LqYrUQKuUWwBllHLeA004fk71zvtYUDi6DD0idm3OVYuHaKLkVN +SfYTS3vzV+tOHvhaE1g7SNn1F7hssmG2ZB8KNI5r4hvAZnQ3YBSpvKa1wtHEjCz5 +BYocepbvh82d7DOk0UnGhVQBwybDuMpBAAtBc9Un0WLQu8NYA+90lhzsH/Yahbbv +Hn53gLyaG4icBBMBAgAGBQJElY7IAAoJENwG3M95JPpz8rMD/jcSqPB2Hg0EIbOk +GBxcosKeeOSFSwt0pRcpgfE2hVdUQtC7LB0DuGS9iRZfssvlSGfAeNGYTg3/wmjQ +LXW19Cv0KkQZtgf+oZMIY7Y/pQRfknvo3dPhN2HOjww2OTw+M4wSVusLQ0K4IImO +rLwwpd9tU2w0FOYW0BSNpjTYvLCoiEYEEBECAAYFAkS9UTAACgkQxKXVjqqse7wF +igCdFm25J6/2RCOsDei+Rn9GgYtXp38AnRjU3xD1sLVvdmtRBxlWIbxbU31NiEYE +EBECAAYFAkS9Os0ACgkQOOnzljbgEa+urACgoAXY/ZbGzpegZj/NB6m+oke0yQgA +oLB3Azqec5YwASNr1qYG4CmDLwxUiEYEEBECAAYFAkTCe3AACgkQQggFxokHT62+ +zQCgo7WiloETU27FIwbZ4hC4p7JX27AAoIzriN1/Vgiv11B9e/SPS/FJVtNQiEYE +EBECAAYFAkSNRGcACgkQp6+YGoOsM0qMhQCfWjOe+Sork+MqCpgK7Kk0jT6cB6AA +oJLajq72kMy1vGqOxpa+S7HWTqHAiEYEEBECAAYFAkVXpxUACgkQ9LSwzHl+v6tl +VgCeOgccXHclswT2GfCbz4aR8eo1oAcAn1m7qlWfgUnXjuos3O3NCy1nQZB2iEYE +EBECAAYFAkXse7AACgkQz+hIv/xnhaLWCQCgqR/D1hrBZKdrfe0RrhWxAUwmSY4A +oJDDbQSwlTS3vxN8mDIHVPFkJbo4iEYEEBECAAYFAkXt5D0ACgkQd75ZE3dJ2dla +ZACcD2VGVAf8HN6WDZEQdpfj8UU/ChgAoI8DF0QENzVNZ1h8b/CkmTSNNlYniEYE +EBECAAYFAkXDwT0ACgkQjqqHRDkpnTGbpACfeWu/HREjh5JIipF4dm5UvvigTi0A +njKzSkFYtykVa8zTqs0qO3+ccbB+iEYEEBECAAYFAkXDwUgACgkQ+kRiIcQkJe1J +hgCg6WAVzmkN6ogSTlaAp2YndfPS6IoAn07y6mFNfpjkrkKOVFQ4CsW2fkjIiEYE +EBECAAYFAkXDwVEACgkQ1AYyHAdPXoQMCACg0NuzOa62RHAjqQb9TVK1R5ieFY4A +niK82pcr9WPceRoRv+qaVtG65oSQiEYEEBECAAYFAkXDwVgACgkQLQlxeEoIqt8G +QACeMZ6OCkmknlP94JUuErXwnPQ8GlkAnifZ5tlSiq0tGhbUZu+aEIuhiwjfiEYE +EBECAAYFAkXq9sYACgkQTjhS9MN8HQm9AwCfRlxO7ZPW21pSwmxK00Qdt524PUgA +n203/xRA5X6gItj5JGY7ClML/89BiEYEExECAAYFAkVYPE0ACgkQVPRhauu8LyaW +VwCcCXxBQLPD0T0Q0BHtWf1et4ZFhHsAoIDmUcBV6ivz0xfV+frfF4F7lny5iEYE +EBECAAYFAkXt2wcACgkQ0ZUMdhYT6NUvEACggy4LTFVynfrNQ0/b9XQ3X4XeqP8A +n0QyOlyGn6UXlrId5rDjQUGOD8NViEYEEBECAAYFAkXt+BUACgkQ3pioii3bAKym +0ACgioqXaG/g+uu0SxnUTPJq+jTzcyAAniJbgn04w7W/ptifmxUecR7W0dfuiGME +ExECACMCGwMCHgECF4AFCwcKAwIDFQIDAxYCAQUCRrXFkQUJFy4pfwAKCRBd4kmW +WwNYomksAJ4q+Lv3fDvzDJl4JcOmzWHPsPg2QQCdHcj5DwCCM7YnRLiE58ApHdrg +11S0C1dlcm5lciBLb2NoiEYEEBECAAYFAjc3I8UACgkQ9u7fIBhLxNmHZQCglWbP +DznIcnOxdDW+k7YgA9+/n00An1ZjSiJipverUxLEFHAbSBWI0IntiEYEEBECAAYF +Ajc6+aMACgkQdQ9klcidkz6GiwCdGe0KSP/vSyEZM/GClQXvjMD4RvMAoJwyTIdc +jPZbQizDeAO3btn2CCwTiEYEEBECAAYFAjgUDhkACgkQYAeQgHPH80+I2gCdHeTA +PusmEfN2bdkijpW1gpxBvGoAn1kzL7Mg7tC4pqlqw2fV3kRUy1a5iEYEEBECAAYF +AjgqYh4ACgkQ4/JYVBKPDnkPkACgmzk7HMlJ1h0qw6OHyMtDE4RI4ToAni+Cm+01 +pHfzh0EnFQTvLE1M9PtoiEYEEBECAAYFAjnKOw4ACgkQK7tDpvCerwquXwCfbW9x +GF2AHQakBPakh61xKmC8WEEAn3TytfY5qrTjxIj2HZFKN5QuQpYSiEYEEBECAAYF +AjnKiy8ACgkQF6ZBbfeUj9ombQCfYQYxpipdMGBxbNd8jbL9RDmH3nMAoITmZnDJ +wXzpHNuSLY8o3c5YhHXziEYEEBECAAYFAjnKnXcACgkQNfZhfFE679le7gCggQjs +jFhjaIO1lWHfPusn0dqdhRYAn3rOW0XSeh64V9o+VItH2LZngmNAiEYEEBECAAYF +AjnLMigACgkQUaz2rXW+gJcIVgCfRRq0G2fCcZOFoey9uZGAkWctKsQAoLw6lUhd +eZDgULrDC7OQRIk7CnMtiEYEEBECAAYFAjnPp1IACgkQkVrMRaj0wv0IqwCfWGMe +iZ58ysuZCAP9IsX3aKcSPtcAoJno1COOjAMhoWjUiHctgLZX9+gTiEYEEBECAAYF +AjnQ39UACgkQbyOLwk/aWgxfIwCfb/GeMAD8w84hq5/aUQMCvVqUYqAAn07SKuWY +sZLEUuPWIgYY0yoByJxviEYEEBECAAYFAjnSCrEACgkQv+EgZWshSJq8jACfdf20 +dqs3IWOPHgFMdYb5VF+WkJUAn05quvyHB3Xug8csxWg6RwSfQBTBiEYEEBECAAYF +AjpMy0UACgkQ7UaByb89+bRUrQCg6aozpYiCEDPVAHe54/8/q48FLP8AniviG9fj +xInPaSKB+LXRmQjc2jLZiEYEEBECAAYFAjqJgd8ACgkQYogE2yD8bPYGagCggMsq +GJN61JuOQkY5MiKb4UPQpBwAniNYwQb+hlEzJF7qnPECh0MAxq8OiEYEEBECAAYF +AjrBCNQACgkQt1anjIgqbEu30gCdEsSeFtJ5KziD5l/CvAhVZt9lnQUAnRrmbV8H +kndXp3+DNoREgscZk/rliEYEEBECAAYFAjrB0SkACgkQ0vCiU5+ISsiPkgCeOFay +t7NkcymwTC2UKNjjyukNDvAAoLq/bOTNZECtztYIMDQ2VrzZ3m6KiEYEEBECAAYF +Ajr1eYsACgkQ7A6vcTZ3gCXdrQCgllIx6G2DkKSGKBhYCgsyywFBXLUAn2PJGrCO +ov0LS8jCMD2Xo4T7qfsjiEYEEBECAAYFAjr1mwEACgkQLBigKrTF83+E4ACffa4y +aJ6Pj4uFZY7dVuiOfkuoTE8AniIdw0DVkHBuxlNp9PAglhztyE+oiEYEEBECAAYF +AjtFbTsACgkQ53XjJNtBs4ex3wCfXLPNscM4Uxtmy0/t5Ygg9lDWEQAAnR39P9eJ +tEeBtMPfbEGYc10ABqjkiEYEEBECAAYFAjtF2QAACgkQI/q1+wgWzBuJgACeIak+ +A98IheVSowXG4J6jzBA439MAn2IFA8EB/EkQ1rn7OEmFNX++PNZyiEYEEBECAAYF +AjtF8RYACgkQJ4bCRH+KQBfSwgCaAvm7pL+LioYj/oKDBQ1pJAj+UqMAn10W8RKr +YblMZ4L11R2TO9xOvFn6iEYEEBECAAYFAjtIDxYACgkQBgac8paUV/DLWACgifbH +tSi50JxmSr18WofeVcVcAXUAoJs99aH6/t9gkO34ajXjiIQxc0qMiEYEEBECAAYF +AjtIJ18ACgkQ11ldN0tyliUx5gCggbhG1uzvdgHNY8oCt4cc6TfHUREAoJuRw8q2 +kbztnt8TQ4mjiTINcBXziEYEEBECAAYFAjtJwaAACgkQUI/TY7yTaDkPjgCcDSJQ +UZBBP/5OvW48Q3BUkUkRSQkAn1Mjqe4WTFEEA8HK5h+KDcqR0aZIiEYEEBECAAYF +AjtKFVcACgkQliSD4VZixzSYCgCeJpt98LMq02q9W1bK5iPUvCkcsSYAn1dqFcoX +ctXVnMj53z8zfAaW0BcwiEYEEBECAAYFAjtLFwcACgkQDqdWtRRIQ/XMGQCdH1u9 +tmtUYY3ExVLdT/H2IIQCU3MAoI69Y4Z17RDh4Bj2gmJwmEAmfDwbiEYEEBECAAYF +AjtMF8oACgkQ1w1fWGA80Hj2mwCfazudYZSMmQWO85xZvg0uTB3rhZQAn3DSyrvX +xIpmv0CcnBtUQu5N21kSiEYEEBECAAYFAjtRuWUACgkQ5DsVPMtGficbLACeNpRJ +OS9AZ7q7bhX2sBJglKLloTsAoLm5FTnY6iAySfPZZlwAVeE6zMJwiEYEEBECAAYF +AjtSxD8ACgkQO/YJxouvzb1F7ACfVp8vhxAWCeRZN3InlvYLrxFTng4An1QO6+D3 +QUjX+0YRNZ3tpZDTSd6QiEYEEBECAAYFAjtXQl8ACgkQeRYvNvf2qtklNwCfcg4T +ss3C9Nf6NiyOAHhXO4JLhtkAn055IHb4i2IO5TQLSQi0tk4ktZVfiEYEEBECAAYF +AjtnOlkACgkQwAsNNiHlPr2cagCg07IN1/MaXn+8yd4Ncp9/723gEBgAnjNCoGAA +ccbvCCVE29sXBNAvUo8MiEYEEBECAAYFAjuYRI4ACgkQkC29kYw4qQpqwACfcyB4 +krJFqyeHoKzRYDqW8JDUdvcAn2pa3UDeKM7FVe8LgCQyz0McM4JqiEYEEBECAAYF +AjwH+10ACgkQ2tKwXV88MYVF8gCeMoYaFN7v/VDmuYt+G1BXDxzcuusAnR8fAcIy +BjSffB0yEIwaA7O9X7ZxiEYEEBECAAYFAjwIEdIACgkQaliC34RARgJ9zgCfS1K0 +bROVSB+9wX4g+xEE0phEAToAn3etSLME5hzsisIRMjUsGbBDe7+aiEYEEBECAAYF +AjwjtVQACgkQRHJT9Ar9DKjv+QCbBE3lRMzyKxTbPUd9v+nB8EVqv4cAn0DxPkAI +kuriAuwtOjCypTDNydyxiEYEEBECAAYFAjxdq0AACgkQ7vDbNLMhJgNwvwCeMc0Q +mOS0ctJOX1J9a3DWkMyUdf4An3iIslZ7stkMOi1VdyE5fR2YDvNFiEYEEBECAAYF +Ajxw4+MACgkQGM0lpSLzivNlngCeLdkkRkcyHVKttl6Z9IQExE+gaNsAnRko+7BQ +Ou5jXMfGarg1rE2zDhsFiEYEEBECAAYFAjxxJxIACgkQscRzFz57S3PkJwCg3qep +dTsiNKuGYC6a1RlJZTBqkiEAn2G6ypvCpWAL43LWbMbyyf/rYxSoiEYEEBECAAYF +AjxxQYIACgkQOhqmNZCaVAYvbACgz9mXzo/nC64mx03IFgL8oFuBAhIAoL91NILX +xGYrkaOnM+2Ci20UvA3ZiEYEEBECAAYFAjxzeIMACgkQo+C50no0+t5J7QCgpSCg +GQ8eMefvsDsF0DlEZzuAHNoAoK1TFwuK7ZowUQJyWp1tKDtNDbx3iEYEEBECAAYF +Ajx+gfMACgkQjjtznt0rzJ3/dgCgnDMnLna3yPskxeVf32wDbTHLxf0AnjWCw4lf +YauS0LumGv9uHN9PaErhiEYEEBECAAYFAjyAY8EACgkQ14NrbAzZIOdEPgCgt5Di +ZfRFkvzAPecRDCIp3pOdUwkAnjj1CDE+Kzg2RiK9Z73QM8B0J4driEYEEBECAAYF +AjyBd5kACgkQ/3vbrZlD49+lmwCfS9apz+gEHsRV6ELS4NtCLvrJsRkAn3Aexpis +dP+8KwolieJwaVPitN2giEYEEBECAAYFAjyMzCQACgkQhbmQdcKRDkGoiACaAqrw +Xn6kf3aD7wss1rgQmrCtJKIAoIU6uifoxBubp2+YjW6kjbnkFMD0iEYEEBECAAYF +AjyXNDoACgkQoegCcNp0M5aGrgCeLBRQ8CAVzPO8OTz2TMFqYLIbFrcAoK2qJqoj +mF2+THtFCHz0hhiBAekNiEYEEBECAAYFAjyXNjgACgkQg2i7WWb7wYxzxwCfcrZ5 +yTwjn9Sh1S/yL3MBKBs8uxUAn0pC4GgIsbbaxcf1QA5AYwFiPcPEiEYEEBECAAYF +AjyxODEACgkQJXt5TsZsoD0pVgCfTIJ88OFNFlnUFoNZemDdbd4ZqEsAn1y5ZyCl +5SYkqFTGiVtkgtIIEhK7iEYEEBECAAYFAjyxguAACgkQeuuK7Uc6ScnBgACfUlQr +rDUb78b93JEvThA/f1ZankIAni448ZxagzPjnj/vH33yK14agnq0iEYEEBECAAYF +Ajyxj4MACgkQocWSfM5dzg4qigCdHrjYquNu2aphWggG5E0G6zCW5MEAn1NQJmKk +TEUsbanbVOBx1G5wvYkeiEYEEBECAAYFAjyyhzsACgkQVlEzpFDUq7k99gCeMJc5 +KvC2gAHgCVjv6Hn7AKgY+rMAnRFIrjunb1Sh77542URoWAVmuPN0iEYEEBECAAYF +AjzyIFQACgkQX1807qC7Pev9PgCfcW15D2cS4UTkn11BSqn+pgrA4KIAoKzLDc78 +X3OFDzVXTOvk8V89OshGiEYEEBECAAYFAj1uHIwACgkQKMb1a4F8NWhPPQCaAprF +vggEHBTVR+KWzm0Z3l9ijLIAnAw2QtJ1Mlnz0ctNwSJwORM87/ARiEYEEBECAAYF +Aj2ERksACgkQ1DyzBZX+yjSzyACgjUKL3CH2UYciEAarZU9H0ZYIIWQAnA6I1aJ0 +FgWiF2bd/jgWaBL2jtd4iEYEEBECAAYFAj2F5U4ACgkQdZc6ENbQhKbt/gCfblKS +qJohqhaFawtXPs8TX1UqY/sAnjqwumhFN4YAAez36gItTB9BxcmJiEYEEBECAAYF +Aj43BmIACgkQkQghntzeiQqeGACfSyyIi1vPniQOq8xLfgjDxFkkVEYAoJSFbH8u +hrwBMa8aOIRkjN9uRdY2iEYEEBECAAYFAj+Q/gkACgkQdt8qX2QD4/2oiwCfbZU8 +0h75YoE0cx5+E/ytzozrwxQAnjtYw4qDSX22n9sMhPW1CO8XZdXdiEYEEBECAAYF +AkCXK/YACgkQs9OWc5ZoRwHECACdHr0sI25gaWa1+uBYpkF3h7EWAnsAn31wzQoC +tVuJnd7dqqxn6nFacEHLiEYEEBECAAYFAkCnUqEACgkQt+hxIz4tn23BmgCfbd5O +5fC/zDHoS4VjKyQW39li0pwAnRaNn2SP7ThVdF7xjlueyhqPPvUPiEYEEhECAAYF +Aj0EW94ACgkQj/Eaxd/oD7Lv2ACfUACXl0hDfGeEdbGjhIa/hSaZCrkAmwV4SdeJ +nBoXV22VBEekmTfzHKHEiEYEExECAAYFAjyvU4oACgkQ6pxm6rn41tmEewCbB4FZ +6z6dmSJ2epBIdeoS8KHLNhEAn2ZcUDKfuFpVVDuV/bMhpjbbHJRIiEYEExECAAYF +Aj0FswMACgkQoWMMj3Tgt2a46gCdFwSWzfEmyuvfjnmNPzCyvdO2R2cAoJRl1Ibl +/2hPXjenl1f08pQLThZAiEYEExECAAYFAj0GRB8ACgkQKb5dImj9VJ8FHACcDjdy +CPMWjSbrXKCVFjDtuapl428AnRSI7e1VYRJcVdGmrAtmu360GrQpiEYEExECAAYF +Aj2J/ScACgkQ74J3yv6ZHpg4ogCgj8BllYTJEQ5sF62Qd2q9o2FNJ8cAn2K/7zpy +9M/Oig+yIYofaN+5fnUUiEYEExECAAYFAj4ykiMACgkQaqtaJwF/Vr1MmgCfcNfO +Om6/woHpEtuFVgYXvUh0tG4AnRTPBwdemHFViOojNJ0glWck/84ciEYEExECAAYF +Aj/F5joACgkQnkDjEAAKq6SChgCfViT5D2pKjVM9g+s3P+riRxshF3wAn0G9MGUz +O1YnhpTDmS7/I2WrLT36iEYEExECAAYFAj/QvIgACgkQ9MN1Y319OPMyOACgnMDI +EYY31K8RDRdITRYPyzg0aPMAnjkHIZ2QZ5cbeFv5LIQiAt/8WUluiEYEExECAAYF +AkDa3nAACgkQRTxFSQIw1gIEmQCgmo4Laf3buzEbtM746FMJeqy9aY0AniIpYHTJ +gFn20iSIwYlJ5JiNoWk3iEsEEhECAAwFAkCn2cEFgwmw+ycACgkQt5wosOl/hW1+ +GQCgxL4gvRYl/yXAZkXQztRWe1Ia4kYAmP8KsKNrVcT3k4XXah2XYPMN7CCITAQQ +EQIADAUCPQET/wWDBrWxagAKCRAUETjdo+RdZq2NAJ0X3oMzaR2t5MZtZMqNMxO7 +AHcC1gCg7FMURGjJQKfudOy58PhCnEiQkKKITAQQEQIADAUCPYYC5QWDBjDChAAK +CRBT4oVOC+Hw4/6WAJ9MuNF9WKFE1BD8xUi4e216xf+z/gCfVkG2HwbYS8J+I5TY +qg6OXcxlQniITAQQEQIADAUCP45usAWDBChWuQAKCRAKYuU0N6eRSQYxAKCmKHZy +5EYupyF671eAWW+lvnSS0gCeLMwyTHhyp8FqbJGfmDkEcURKFv6ITAQQEQIADAUC +P5J4BwWDBCRNYgAKCRDvy83/YfBbjOkoAJ9vyA2+SFX9sR1S1L9teAAzjxExrACe +MadTGJ3+vmBbybQzMcuOq9GA/8iITAQQEQIADAUCQL9HPwWDCZmNqQAKCRDZLSTf +3ZZcgzxlAJ94ZJIXvViFSYBCuTiwGH8JViHWVACfeF0eysjY5OZ+aOTjeEOOZ1tj +luaITAQQEQIADAUCQNtUXgWDCX2AigAKCRD2KOuTR0MgbAUIAJ4zEBlRY1zow2Rn +VnlJyV8+Zega2QCffe1gFTh83WIngScIyI9NSEcsNLqITAQQEQIADAUCQPEidwWD +CWeycQAKCRCS+/1Xhvylkt/8AJ4qxfg3sSNOlrujmtPxRQUISxWCnQCePI4fRvNx +zIXcP8AlFD/QW1Y66OiITAQSEQIADAUCPl5xiwWDBVhT3gAKCRBQXohHIudfS6AD +AKCdnk2cFYneP3/uyXODkjL+lTpR6wCgto0mJSBV+D6He4/i9QmG6b3U/9uITAQS +EQIADAUCP3sJOgWDBDu8LwAKCRBbs/UZWBZ5Gr9kAJ4vqVUqQTWIWIL9iieUHMuo +0B1WSACggEfxVgNctEiAGnJ9J3BzVjFN4MOITAQSEQIADAUCP4/uPwWDBCbXKgAK +CRAospXD9G6tuzd8AKCcP407jZCo64f6Ydsj2POiuw8X6gCeIdx30Zx8jzTtA9/C +WnzzqP29btmITAQSEQIADAUCP565+wWDBBgLbgAKCRDKsy6J6grA5DRrAJwLEBZB +jIKbb/ymMaPiu/U3ZykNzgCdED1+XXMe/3/RUsiTRvI0FdjtEXqITAQTEQIADAUC +PQdNFwWDBq94UgAKCRA8YsrY5NQyTYgyAJ9ReRl+ZmswUiJg7wX+dpAwGz/3hQCf +Zet/a5ohJis+50htGTFib5HY2tmITAQTEQIADAUCPXh4sgWDBj5MtwAKCRDQGpwZ +TXZs3qu4AKCLa4WOHhLLQqPJ3vrR29+lr/2O0wCeMfI9DS0dhKpJkMP2ppC9v8Xc ++UyITAQTEQIADAUCPXkxEwWDBj2UVgAKCRBwXFOJ1cGzWFqVAKCJHkZNLHh9IKqS +KTOs445cCicNVwCdEVDXd2aSMtxHLgTxvEu2bzE/IB2ITAQTEQIADAUCPYOt8wWD BjMXdgAKCRAC1u0h4yxPS6DNAJoDnRKfJ67zae2HSKQ1WfMcPhbR4ACcD1bEYGaa -m9Zg6rks5PLZ9V7Y/4SIRgQQEQIABgUCPW4cjAAKCRAoxvVrgXw1aE89AJoCmsW+ -CAQcFNVH4pbObRneX2KMsgCcDDZC0nUyWfPRy03BInA5Ezzv8BGIRgQTEQIABgUC -PQZEHwAKCRApvl0iaP1UnwUcAJwON3II8xaNJutcoJUWMO25qmXjbwCdFIjt7VVh -ElxV0aasC2a7frQatCmITAQTEQIADAUCPQdNFwWDBq94UgAKCRA8YsrY5NQyTYgy -AJ9ReRl+ZmswUiJg7wX+dpAwGz/3hQCfZet/a5ohJis+50htGTFib5HY2tmITAQT -EQIADAUCPXkxEwWDBj2UVgAKCRBwXFOJ1cGzWFqVAKCJHkZNLHh9IKqSKTOs445c -CicNVwCdEVDXd2aSMtxHLgTxvEu2bzE/IB2ITAQTEQIADAUCPXh4sgWDBj5MtwAK -CRDQGpwZTXZs3qu4AKCLa4WOHhLLQqPJ3vrR29+lr/2O0wCeMfI9DS0dhKpJkMP2 -ppC9v8Xc+UyIRgQQEQIABgUCPYRGSwAKCRDUPLMFlf7KNLPIAKCNQovcIfZRhyIQ -BqtlT0fRlgghZACcDojVonQWBaIXZt3+OBZoEvaO13iIRgQQEQIABgUCPYXlTgAK -CRB1lzoQ1tCEpu3+AJ9uUpKomiGqFoVrC1c+zxNfVSpj+wCeOrC6aEU3hgAB7Pfq -Ai1MH0HFyYmITAQTEQIADAUCPYX8CgWDBjDJXwAKCRD1ayajpjmec9lyAJ9S/E1e -OhZgSwBgnPfP4xYN4at8lACfeyVcX1x53Y4A3diBhk1OUgLtRRqITAQTEQIADAUC -PYgQ5AWDBi60hQAKCRCDZcvc3U1O/tBUAKCv4L8/uCoYO6lhMLbWOXTuY98b9wCg -tn3OSavVgXoGvuzNQqSxJqfp/C2ITAQQEQIADAUCPYYC5QWDBjDChAAKCRBT4oVO -C+Hw4/6WAJ9MuNF9WKFE1BD8xUi4e216xf+z/gCfVkG2HwbYS8J+I5TYqg6OXcxl -QniITAQTEQIADAUCPYg7AAWDBi6KaQAKCRAdvV51g5nhu5YzAJ9/Rhh0VnuB1zWq -MJp5cOEJ8t7Q4ACfU4m5n94oaT6LRX9Jwuk4wuf9IIKIRgQTEQIABgUCPYn9JwAK -CRDvgnfK/pkemDiiAKCPwGWVhMkRDmwXrZB3ar2jYU0nxwCfYr/vOnL0z86KD7Ih -ih9o37l+dRSITAQTEQIADAUCPbbBngWDBgADywAKCRBWQSbyKfGb0fKKAJ9o1uPI -iUdgD1wC/ywuTPm4dGhN7gCdHIM98AWIE9lmHAk0OWZMQKiVcv8= -=01kM +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 +nj+zW9f9Z2M0K2r+gldEC2Ew2yTl +=I1gH -----END PGP PUBLIC KEY BLOCK----- From 665b2f3567b96d93602ece0c742d31f00b2c8811 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 10 Dec 2007 21:10:52 +0000 Subject: [PATCH 009/214] update to 1.4.0 --- .cvsignore | 2 ++ libgcrypt.spec | 18 ++++++++++++------ sources | 4 ++-- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/.cvsignore b/.cvsignore index 65a9913..c45e700 100644 --- a/.cvsignore +++ b/.cvsignore @@ -7,3 +7,5 @@ libgcrypt-1.2.3.tar.bz2 libgcrypt-1.2.3.tar.bz2.sig libgcrypt-1.2.4.tar.bz2 libgcrypt-1.2.4.tar.bz2.sig +libgcrypt-1.4.0.tar.bz2 +libgcrypt-1.4.0.tar.bz2.sig diff --git a/libgcrypt.spec b/libgcrypt.spec index a853eb7..6df19ce 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.2.4 -Release: 6 +Version: 1.4.0 +Release: 1 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com @@ -30,11 +30,10 @@ applications using libgcrypt. %setup -q %build -%configure --disable-asm --disable-static --enable-noexecstack -# Verify that RNG methods which aren't LGPL aren't enabled. -grep '^#define USE_RNDUNIX 0$' config.h -grep '^#define USE_RNDW32 0$' config.h +%configure --disable-static --enable-noexecstack make + +%check make check %install @@ -58,12 +57,14 @@ for shlib in $RPM_BUILD_ROOT/%{_libdir}/*.so* ; do mv "$shlib" $RPM_BUILD_ROOT/%{_lib}/ fi done + # Figure out where /%{_lib} is relative to %{_libdir}. touch $RPM_BUILD_ROOT/root_marker relroot=.. while ! test -f $RPM_BUILD_ROOT/%{_libdir}/$relroot/root_marker ; do relroot=$relroot/.. done + # Overwrite development symlinks. pushd $RPM_BUILD_ROOT/%{_libdir} for shlib in $relroot/%{_lib}/lib*.so.* ; do @@ -72,6 +73,7 @@ for shlib in $relroot/%{_lib}/lib*.so.* ; do ln -sf $shlib $target done popd + # Add soname symlink. /sbin/ldconfig -n $RPM_BUILD_ROOT/%{_lib}/ rm -f $RPM_BUILD_ROOT/root_marker @@ -101,6 +103,7 @@ exit 0 %files devel %defattr(-,root,root) %{_bindir}/%{name}-config +%{_bindir}/dumpsexp %{_includedir}/* %{_libdir}/*.so %{_datadir}/aclocal/* @@ -109,6 +112,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Mon Dec 10 2007 Nalin Dahyabhai - 1.4.0-1 +- update to 1.4.0 + * Tue Oct 16 2007 Nalin Dahyabhai - 1.2.4-6 - use ldconfig to build the soname symlink for packaging along with the shared library (#334731) diff --git a/sources b/sources index ba81f61..d1ea17a 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -3675d3e74c3a44aed629d9b12a30bb51 libgcrypt-1.2.4.tar.bz2 -b6323d3acf8c08ad849e8090fb8986b9 libgcrypt-1.2.4.tar.bz2.sig +b013f798a1088afb07336bce5a9c24c5 libgcrypt-1.4.0.tar.bz2 +43e1b54d34732709bbec024512224450 libgcrypt-1.4.0.tar.bz2.sig From dac6bc70cdf04806e07f1712ce1484a41ca0a331 Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Tue, 19 Feb 2008 15:52:59 +0000 Subject: [PATCH 010/214] - Autorebuild for GCC 4.3 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6df19ce..2cdc83f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.0 -Release: 1 +Release: 2 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com @@ -112,6 +112,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Tue Feb 19 2008 Fedora Release Engineering - 1.4.0-2 +- Autorebuild for GCC 4.3 + * Mon Dec 10 2007 Nalin Dahyabhai - 1.4.0-1 - update to 1.4.0 From a562621b74512a75876c7ceb256c823bb8763b65 Mon Sep 17 00:00:00 2001 From: jorton Date: Thu, 3 Apr 2008 12:43:26 +0000 Subject: [PATCH 011/214] - add patch from upstream to fix severe performance regression in entropy gathering --- libgcrypt-1.4.0-randinit.patch | 90 ++++++++++++++++++++++++++++++++++ libgcrypt.spec | 8 ++- 2 files changed, 97 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.4.0-randinit.patch diff --git a/libgcrypt-1.4.0-randinit.patch b/libgcrypt-1.4.0-randinit.patch new file mode 100644 index 0000000..eb1c04d --- /dev/null +++ b/libgcrypt-1.4.0-randinit.patch @@ -0,0 +1,90 @@ +From gnutls-devel-bounces+joe=manyfish.co.uk@gnu.org Tue Jan 08 18:41:52 2008 +From: Werner Koch +To: Simon Josefsson +Mail-Followup-To: Simon Josefsson , + Guus Sliepen , gnutls-devel@gnu.org, + 343085@bugs.debian.org, gcrypt-devel@gnupg.org +Date: Tue, 08 Jan 2008 12:39:02 +0100 +Cc: Guus Sliepen , gcrypt-devel@gnupg.org, + gnutls-devel@gnu.org, 343085@bugs.debian.org +Subject: [patch] Re: Bug#448775: Uses too much entropy (Debian Bug #343085) +MIME-Version: 1.0 +Content-Transfer-Encoding: 8bit +Content-Type: text/plain; charset=utf-8 +Status: RO + +On Tue, 8 Jan 2008 11:59, wk@gnupg.org said: + +> Anyway there 3000 calls to /dev/urandom are far too many for an initial +> pool filling. I need to check this. + +Found it. The bug was introduced with libgcrypt 1.3.1. Here is a patch: + +2008-01-08 Werner Koch + + * random.c (add_randomness): Do not just increment + POOL_FILLED_COUNTER but update it by the actual amount of data. + +Index: cipher/random.c +=================================================================== +--- cipher/random.c (revision 1277) ++++ cipher/random.c (working copy) +@@ -1115,6 +1115,7 @@ + add_randomness (const void *buffer, size_t length, enum random_origins origin) + { + const unsigned char *p = buffer; ++ size_t count = 0; + + assert (pool_is_locked); + +@@ -1123,6 +1124,7 @@ + while (length-- ) + { + rndpool[pool_writepos++] ^= *p++; ++ count++; + if (pool_writepos >= POOLSIZE ) + { + /* It is possible that we are invoked before the pool is +@@ -1132,7 +1134,9 @@ + separately. See also the remarks about the seed file. */ + if (origin >= RANDOM_ORIGIN_SLOWPOLL && !pool_filled) + { +- if (++pool_filled_counter >= POOLSIZE) ++ pool_filled_counter += count; ++ count = 0; ++ if (pool_filled_counter >= POOLSIZE) + pool_filled = 1; + } + pool_writepos = 0; + + +Also commited to SVN. Old and new stats: + +$ LD_PRELOAD=/usr/local/lib/libgcrypt.so ./benchmark --verbose random +random 130ms 30ms +random usage: poolsize=600 mixed=972 polls=3000/200 added=4200/378400 + outmix=200 getlvl1=200/13600 getlvl2=0/0 + +$ ./benchmark --verbose random +random 40ms 30ms +random usage: poolsize=600 mixed=377 polls=25/200 added=1225/21400 + outmix=200 getlvl1=200/13600 getlvl2=0/0 + + + +Shalom-Salam, + + Werner + + + +-- +Die Gedanken sind frei. Auschnahme regelt ein Bundeschgesetz. + + + +_______________________________________________ +Gnutls-devel mailing list +Gnutls-devel@gnu.org +http://lists.gnu.org/mailman/listinfo/gnutls-devel + diff --git a/libgcrypt.spec b/libgcrypt.spec index 2cdc83f..fb09b02 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,9 +1,10 @@ Name: libgcrypt Version: 1.4.0 -Release: 2 +Release: 3 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com +Patch0: libgcrypt-1.4.0-randinit.patch License: LGPLv2+ Summary: A general-purpose cryptography library. BuildRoot: %{_tmppath}/%{name}-%{version}-root @@ -28,6 +29,7 @@ applications using libgcrypt. %prep %setup -q +%patch0 -p1 -b .randinit %build %configure --disable-static --enable-noexecstack @@ -112,6 +114,10 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Thu Apr 3 2008 Joe Orton 1.4.0-3 +- add patch from upstream to fix severe performance regression + in entropy gathering + * Tue Feb 19 2008 Fedora Release Engineering - 1.4.0-2 - Autorebuild for GCC 4.3 From 2a366c86385b74c4e9ee866f4813a04d109ac6b4 Mon Sep 17 00:00:00 2001 From: jorton Date: Thu, 3 Apr 2008 12:49:19 +0000 Subject: [PATCH 012/214] - apply patch correctly. --- libgcrypt.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index fb09b02..15f1a4e 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -29,7 +29,7 @@ applications using libgcrypt. %prep %setup -q -%patch0 -p1 -b .randinit +%patch0 -p0 -b .randinit %build %configure --disable-static --enable-noexecstack From cfb3452aec916d9bcb99ee99ae91e38ee12b1c3e Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Tue, 29 Apr 2008 18:05:46 +0000 Subject: [PATCH 013/214] - update to 1.4.1 - bump libgpgerror-devel requirement to 1.4, matching the requirement enforced by the configure script --- .cvsignore | 2 + libgcrypt-1.4.0-randinit.patch | 90 ---------------------------------- libgcrypt.spec | 14 ++++-- sources | 4 +- 4 files changed, 13 insertions(+), 97 deletions(-) delete mode 100644 libgcrypt-1.4.0-randinit.patch diff --git a/.cvsignore b/.cvsignore index c45e700..bdaed00 100644 --- a/.cvsignore +++ b/.cvsignore @@ -9,3 +9,5 @@ libgcrypt-1.2.4.tar.bz2 libgcrypt-1.2.4.tar.bz2.sig libgcrypt-1.4.0.tar.bz2 libgcrypt-1.4.0.tar.bz2.sig +libgcrypt-1.4.1.tar.bz2 +libgcrypt-1.4.1.tar.bz2.sig diff --git a/libgcrypt-1.4.0-randinit.patch b/libgcrypt-1.4.0-randinit.patch deleted file mode 100644 index eb1c04d..0000000 --- a/libgcrypt-1.4.0-randinit.patch +++ /dev/null @@ -1,90 +0,0 @@ -From gnutls-devel-bounces+joe=manyfish.co.uk@gnu.org Tue Jan 08 18:41:52 2008 -From: Werner Koch -To: Simon Josefsson -Mail-Followup-To: Simon Josefsson , - Guus Sliepen , gnutls-devel@gnu.org, - 343085@bugs.debian.org, gcrypt-devel@gnupg.org -Date: Tue, 08 Jan 2008 12:39:02 +0100 -Cc: Guus Sliepen , gcrypt-devel@gnupg.org, - gnutls-devel@gnu.org, 343085@bugs.debian.org -Subject: [patch] Re: Bug#448775: Uses too much entropy (Debian Bug #343085) -MIME-Version: 1.0 -Content-Transfer-Encoding: 8bit -Content-Type: text/plain; charset=utf-8 -Status: RO - -On Tue, 8 Jan 2008 11:59, wk@gnupg.org said: - -> Anyway there 3000 calls to /dev/urandom are far too many for an initial -> pool filling. I need to check this. - -Found it. The bug was introduced with libgcrypt 1.3.1. Here is a patch: - -2008-01-08 Werner Koch - - * random.c (add_randomness): Do not just increment - POOL_FILLED_COUNTER but update it by the actual amount of data. - -Index: cipher/random.c -=================================================================== ---- cipher/random.c (revision 1277) -+++ cipher/random.c (working copy) -@@ -1115,6 +1115,7 @@ - add_randomness (const void *buffer, size_t length, enum random_origins origin) - { - const unsigned char *p = buffer; -+ size_t count = 0; - - assert (pool_is_locked); - -@@ -1123,6 +1124,7 @@ - while (length-- ) - { - rndpool[pool_writepos++] ^= *p++; -+ count++; - if (pool_writepos >= POOLSIZE ) - { - /* It is possible that we are invoked before the pool is -@@ -1132,7 +1134,9 @@ - separately. See also the remarks about the seed file. */ - if (origin >= RANDOM_ORIGIN_SLOWPOLL && !pool_filled) - { -- if (++pool_filled_counter >= POOLSIZE) -+ pool_filled_counter += count; -+ count = 0; -+ if (pool_filled_counter >= POOLSIZE) - pool_filled = 1; - } - pool_writepos = 0; - - -Also commited to SVN. Old and new stats: - -$ LD_PRELOAD=/usr/local/lib/libgcrypt.so ./benchmark --verbose random -random 130ms 30ms -random usage: poolsize=600 mixed=972 polls=3000/200 added=4200/378400 - outmix=200 getlvl1=200/13600 getlvl2=0/0 - -$ ./benchmark --verbose random -random 40ms 30ms -random usage: poolsize=600 mixed=377 polls=25/200 added=1225/21400 - outmix=200 getlvl1=200/13600 getlvl2=0/0 - - - -Shalom-Salam, - - Werner - - - --- -Die Gedanken sind frei. Auschnahme regelt ein Bundeschgesetz. - - - -_______________________________________________ -Gnutls-devel mailing list -Gnutls-devel@gnu.org -http://lists.gnu.org/mailman/listinfo/gnutls-devel - diff --git a/libgcrypt.spec b/libgcrypt.spec index 15f1a4e..3ce1e3f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,14 +1,14 @@ Name: libgcrypt -Version: 1.4.0 -Release: 3 +Version: 1.4.1 +Release: 1 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com -Patch0: libgcrypt-1.4.0-randinit.patch +# Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. License: LGPLv2+ Summary: A general-purpose cryptography library. BuildRoot: %{_tmppath}/%{name}-%{version}-root -BuildRequires: gawk libgpg-error-devel pkgconfig +BuildRequires: gawk, libgpg-error-devel >= 1.4, pkgconfig Group: System Environment/Libraries %package devel @@ -29,7 +29,6 @@ applications using libgcrypt. %prep %setup -q -%patch0 -p0 -b .randinit %build %configure --disable-static --enable-noexecstack @@ -114,6 +113,11 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Tue Apr 29 2008 Nalin Dahyabhai 1.4.1-1 +- update to 1.4.1 +- bump libgpgerror-devel requirement to 1.4, matching the requirement enforced + by the configure script + * Thu Apr 3 2008 Joe Orton 1.4.0-3 - add patch from upstream to fix severe performance regression in entropy gathering diff --git a/sources b/sources index d1ea17a..ca0b193 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -b013f798a1088afb07336bce5a9c24c5 libgcrypt-1.4.0.tar.bz2 -43e1b54d34732709bbec024512224450 libgcrypt-1.4.0.tar.bz2.sig +26703ecef4bbe113b8e6a87572b80b32 libgcrypt-1.4.1.tar.bz2 +c219822f4b88e59bb6773f99c9cd73c9 libgcrypt-1.4.1.tar.bz2.sig From 569a4236d0135f726733cde8caf2a558dfa437c2 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 8 Sep 2008 23:05:08 +0000 Subject: [PATCH 014/214] update to 1.4.2 --- .cvsignore | 2 ++ libgcrypt.spec | 6 +++++- sources | 4 ++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/.cvsignore b/.cvsignore index bdaed00..48a7e6d 100644 --- a/.cvsignore +++ b/.cvsignore @@ -11,3 +11,5 @@ libgcrypt-1.4.0.tar.bz2 libgcrypt-1.4.0.tar.bz2.sig libgcrypt-1.4.1.tar.bz2 libgcrypt-1.4.1.tar.bz2.sig +libgcrypt-1.4.2.tar.bz2 +libgcrypt-1.4.2.tar.bz2.sig diff --git a/libgcrypt.spec b/libgcrypt.spec index 3ce1e3f..b567076 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.4.1 +Version: 1.4.2 Release: 1 Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -105,6 +105,7 @@ exit 0 %defattr(-,root,root) %{_bindir}/%{name}-config %{_bindir}/dumpsexp +%{_bindir}/hmac256 %{_includedir}/* %{_libdir}/*.so %{_datadir}/aclocal/* @@ -113,6 +114,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Mon Sep 8 2008 Nalin Dahyabhai 1.4.2-1 +- update to 1.4.2 + * Tue Apr 29 2008 Nalin Dahyabhai 1.4.1-1 - update to 1.4.1 - bump libgpgerror-devel requirement to 1.4, matching the requirement enforced diff --git a/sources b/sources index ca0b193..3e1cb76 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -26703ecef4bbe113b8e6a87572b80b32 libgcrypt-1.4.1.tar.bz2 -c219822f4b88e59bb6773f99c9cd73c9 libgcrypt-1.4.1.tar.bz2.sig +0d27005ff43ecf3d96ae02d99bf793ba libgcrypt-1.4.2.tar.bz2 +3645b7f13ffaa953a4cbfa294fb1a2f0 libgcrypt-1.4.2.tar.bz2.sig From 6e274ad21fab7af73d2aae1792cd699bdd68fb7b Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Mon, 15 Sep 2008 19:49:03 +0000 Subject: [PATCH 015/214] - invoke make with %%{?_smp_mflags} to build faster on multi-processor systems (Steve Grubb) --- libgcrypt.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index b567076..ed4015b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -32,7 +32,7 @@ applications using libgcrypt. %build %configure --disable-static --enable-noexecstack -make +make %{?_smp_mflags} %check make check @@ -114,6 +114,10 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Mon Sep 15 2008 Nalin Dahyabhai +- invoke make with %%{?_smp_mflags} to build faster on multi-processor + systems (Steve Grubb) + * Mon Sep 8 2008 Nalin Dahyabhai 1.4.2-1 - update to 1.4.2 From 0be77fc46278ab7e9f1b7fd6d3c68c1cd2a4c860 Mon Sep 17 00:00:00 2001 From: Nalin Dahyabhai Date: Thu, 18 Sep 2008 15:50:08 +0000 Subject: [PATCH 016/214] - update to 1.4.3 - own /etc/gcrypt - fix rpmlint warning about the summary by dropping the final '.' --- .cvsignore | 2 ++ libgcrypt.spec | 15 ++++++++++++--- sources | 4 ++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/.cvsignore b/.cvsignore index 48a7e6d..d18907d 100644 --- a/.cvsignore +++ b/.cvsignore @@ -13,3 +13,5 @@ libgcrypt-1.4.1.tar.bz2 libgcrypt-1.4.1.tar.bz2.sig libgcrypt-1.4.2.tar.bz2 libgcrypt-1.4.2.tar.bz2.sig +libgcrypt-1.4.3.tar.bz2 +libgcrypt-1.4.3.tar.bz2.sig diff --git a/libgcrypt.spec b/libgcrypt.spec index ed4015b..9945c74 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,12 +1,12 @@ Name: libgcrypt -Version: 1.4.2 -Release: 1 +Version: 1.4.3 +Release: 1%{?dist} Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. License: LGPLv2+ -Summary: A general-purpose cryptography library. +Summary: A general-purpose cryptography library BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildRequires: gawk, libgpg-error-devel >= 1.4, pkgconfig Group: System Environment/Libraries @@ -79,6 +79,10 @@ popd /sbin/ldconfig -n $RPM_BUILD_ROOT/%{_lib}/ rm -f $RPM_BUILD_ROOT/root_marker +# Create /etc/gcrypt (hardwired, not dependent on the configure invocation) so +# that _someone_ owns it. +mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt + %clean rm -fr $RPM_BUILD_ROOT @@ -98,6 +102,7 @@ exit 0 %files %defattr(-,root,root) +%dir /etc/gcrypt /%{_lib}/*.so.* #%{_libdir}/%{name} @@ -114,6 +119,10 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Thu Sep 18 2008 Nalin Dahyabhai 1.4.3-1 +- update to 1.4.3 +- own /etc/gcrypt + * Mon Sep 15 2008 Nalin Dahyabhai - invoke make with %%{?_smp_mflags} to build faster on multi-processor systems (Steve Grubb) diff --git a/sources b/sources index 3e1cb76..030af1e 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -0d27005ff43ecf3d96ae02d99bf793ba libgcrypt-1.4.2.tar.bz2 -3645b7f13ffaa953a4cbfa294fb1a2f0 libgcrypt-1.4.2.tar.bz2.sig +46e50e811ed51f1e0e8dd677dded967d libgcrypt-1.4.3.tar.bz2 +b6c8495eaeb912aa612196a849039e74 libgcrypt-1.4.3.tar.bz2.sig From 328eebcd5f2be87173bffd3639947b4a5048ae58 Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Tue, 21 Oct 2008 04:51:58 +0000 Subject: [PATCH 017/214] disable asm on sparc64 --- libgcrypt.spec | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 9945c74..3431ea9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.3 -Release: 1%{?dist} +Release: 2%{?dist} Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com @@ -31,7 +31,11 @@ applications using libgcrypt. %setup -q %build -%configure --disable-static --enable-noexecstack +%configure --disable-static \ +%ifarch sparc64 + --disable-asm \ +%endif + --enable-noexecstack make %{?_smp_mflags} %check @@ -119,6 +123,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Mon Oct 20 2008 Dennis Gilmore 1.4.3-2 +- disable asm on sparc64 + * Thu Sep 18 2008 Nalin Dahyabhai 1.4.3-1 - update to 1.4.3 - own /etc/gcrypt From 0b312a8bb40c07ef078c82273c4e63c6c4d6cd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Fri, 30 Jan 2009 10:53:38 +0000 Subject: [PATCH 018/214] - update to 1.4.4 - do not abort when the fips mode kernel flag is inaccessible due to permissions (#470219) - hobble the library to drop the ECC support --- .cvsignore | 18 +----------------- hobble-libgcrypt | 9 +++++++++ libgcrypt-1.2.2-lib64.patch | 14 -------------- libgcrypt-1.4.4-fips-no-access.patch | 13 +++++++++++++ libgcrypt.spec | 26 +++++++++++++++++++++----- sources | 3 +-- 6 files changed, 45 insertions(+), 38 deletions(-) create mode 100755 hobble-libgcrypt delete mode 100644 libgcrypt-1.2.2-lib64.patch create mode 100644 libgcrypt-1.4.4-fips-no-access.patch diff --git a/.cvsignore b/.cvsignore index d18907d..b8edc03 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1,17 +1 @@ -libgcrypt-1.2.0.tar.gz -libgcrypt-1.2.1.tar.bz2 -libgcrypt-1.2.1.tar.bz2.sig -libgcrypt-1.2.2.tar.bz2 -libgcrypt-1.2.2.tar.bz2.sig -libgcrypt-1.2.3.tar.bz2 -libgcrypt-1.2.3.tar.bz2.sig -libgcrypt-1.2.4.tar.bz2 -libgcrypt-1.2.4.tar.bz2.sig -libgcrypt-1.4.0.tar.bz2 -libgcrypt-1.4.0.tar.bz2.sig -libgcrypt-1.4.1.tar.bz2 -libgcrypt-1.4.1.tar.bz2.sig -libgcrypt-1.4.2.tar.bz2 -libgcrypt-1.4.2.tar.bz2.sig -libgcrypt-1.4.3.tar.bz2 -libgcrypt-1.4.3.tar.bz2.sig +libgcrypt-1.4.4-hobbled.tar.bz2 diff --git a/hobble-libgcrypt b/hobble-libgcrypt new file mode 100755 index 0000000..1062d6e --- /dev/null +++ b/hobble-libgcrypt @@ -0,0 +1,9 @@ +#!/bin/sh + +# Quit out if anything fails. +set -e -x + +# Clean out patent-or-otherwise-encumbered code. +# EC: ????????? ??/??/2015 + +rm -f cipher/ecc.c diff --git a/libgcrypt-1.2.2-lib64.patch b/libgcrypt-1.2.2-lib64.patch deleted file mode 100644 index 4f68d7b..0000000 --- a/libgcrypt-1.2.2-lib64.patch +++ /dev/null @@ -1,14 +0,0 @@ -We should suppress an explicit -L on 64-bit arches, too. - ---- libgcrypt-1.2.2/src/libgcrypt-config.in 2006-05-16 18:50:43.000000000 -0400 -+++ libgcrypt-1.2.2/src/libgcrypt-config.in 2006-05-16 18:50:50.000000000 -0400 -@@ -138,7 +138,8 @@ - libs_final="$libs" - - # Set up `libdirs'. -- if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib"; then -+ if test "x$libdir" != "x/usr/lib" -a "x$libdir" != "x/lib" -a \ -+ "x$libdir" != "x/usr/lib64" -a "x$libdir" != "x/lib64"; then - libdirs="-L$libdir" - fi - diff --git a/libgcrypt-1.4.4-fips-no-access.patch b/libgcrypt-1.4.4-fips-no-access.patch new file mode 100644 index 0000000..f2972e9 --- /dev/null +++ b/libgcrypt-1.4.4-fips-no-access.patch @@ -0,0 +1,13 @@ +Do not abort when the fips mode flag is simply inaccessible because of +insufficient permissions. +diff -up libgcrypt-1.4.4/src/fips.c.no-access libgcrypt-1.4.4/src/fips.c +--- libgcrypt-1.4.4/src/fips.c.no-access 2009-01-29 17:37:12.000000000 +0100 ++++ libgcrypt-1.4.4/src/fips.c 2009-01-29 17:37:15.000000000 +0100 +@@ -155,6 +155,7 @@ _gcry_initialize_fips_mode (int force) + fclose (fp); + } + else if ((saved_errno = errno) != ENOENT ++ && saved_errno != EACCES + && !access ("/proc/version", F_OK) ) + { + /* Problem reading the fips file despite that we have the proc diff --git a/libgcrypt.spec b/libgcrypt.spec index 3431ea9..ddf91d1 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,9 +1,16 @@ Name: libgcrypt -Version: 1.4.3 -Release: 2%{?dist} -Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 -Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig +Version: 1.4.4 +Release: 1%{?dist} +Source0: libgcrypt-%{version}-hobbled.tar.bz2 +# The original libgcrypt sources now contain potentially patented ECC +# cipher support. We have to remove it in the tarball we ship with +# the hobble-libgcrypt script. +#Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 +#Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com +Source3: hobble-libgcrypt +Patch1: libgcrypt-1.4.4-fips-no-access.patch + # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. License: LGPLv2+ Summary: A general-purpose cryptography library @@ -29,13 +36,16 @@ applications using libgcrypt. %prep %setup -q +%{SOURCE3} +%patch1 -p1 -b .no-access %build %configure --disable-static \ %ifarch sparc64 --disable-asm \ %endif - --enable-noexecstack + --enable-noexecstack \ + --enable-pubkey-ciphers='dsa elgamal rsa' make %{?_smp_mflags} %check @@ -123,6 +133,12 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Fri Jan 30 2009 Tomas Mraz 1.4.4-1 +- update to 1.4.4 +- do not abort when the fips mode kernel flag is inaccessible + due to permissions (#470219) +- hobble the library to drop the ECC support + * Mon Oct 20 2008 Dennis Gilmore 1.4.3-2 - disable asm on sparc64 diff --git a/sources b/sources index 030af1e..04b5ae2 100644 --- a/sources +++ b/sources @@ -1,2 +1 @@ -46e50e811ed51f1e0e8dd677dded967d libgcrypt-1.4.3.tar.bz2 -b6c8495eaeb912aa612196a849039e74 libgcrypt-1.4.3.tar.bz2.sig +12d3fec91c663b541d63e34eabddacc5 libgcrypt-1.4.4-hobbled.tar.bz2 From 7de50499323062178089bab4ac3c62389956ebec Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Wed, 25 Feb 2009 15:00:17 +0000 Subject: [PATCH 019/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index ddf91d1..e78f5c8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.4 -Release: 1%{?dist} +Release: 2%{?dist} Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -133,6 +133,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Wed Feb 25 2009 Fedora Release Engineering - 1.4.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild + * Fri Jan 30 2009 Tomas Mraz 1.4.4-1 - update to 1.4.4 - do not abort when the fips mode kernel flag is inaccessible From 4b8542ad6da7aeb2b5aef7795438aaae1d344ff7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Tue, 3 Mar 2009 20:32:37 +0000 Subject: [PATCH 020/214] - add hmac FIPS integrity verification check --- libgcrypt-1.4.4-use-fipscheck.patch | 74 +++++++++++++++++++++++++++++ libgcrypt.spec | 23 +++++++-- 2 files changed, 93 insertions(+), 4 deletions(-) create mode 100644 libgcrypt-1.4.4-use-fipscheck.patch diff --git a/libgcrypt-1.4.4-use-fipscheck.patch b/libgcrypt-1.4.4-use-fipscheck.patch new file mode 100644 index 0000000..aa7d7d1 --- /dev/null +++ b/libgcrypt-1.4.4-use-fipscheck.patch @@ -0,0 +1,74 @@ +diff -up libgcrypt-1.4.4/src/fips.c.use-fipscheck libgcrypt-1.4.4/src/fips.c +--- libgcrypt-1.4.4/src/fips.c.use-fipscheck 2009-03-03 18:10:49.000000000 +0100 ++++ libgcrypt-1.4.4/src/fips.c 2009-03-03 18:51:31.000000000 +0100 +@@ -570,23 +570,48 @@ run_random_selftests (void) + return !!err; + } + ++static int ++get_library_path(const char *libname, const char *symbolname, char *path, size_t pathlen) ++{ ++ Dl_info info; ++ void *dl, *sym; ++ int rv = -1; ++ ++ dl = dlopen(libname, RTLD_LAZY); ++ if (dl == NULL) { ++ return -1; ++ } ++ ++ sym = dlsym(dl, symbolname); ++ ++ if (sym != NULL && dladdr(sym, &info)) { ++ strncpy(path, info.dli_fname, pathlen-1); ++ path[pathlen-1] = '\0'; ++ rv = 0; ++ } ++ ++ dlclose(dl); ++ ++ return rv; ++} ++ + /* Run an integrity check on the binary. Returns 0 on success. */ + static int + check_binary_integrity (void) + { + #ifdef ENABLE_HMAC_BINARY_CHECK + gpg_error_t err; +- Dl_info info; ++ char libpath[4096]; + unsigned char digest[32]; + int dlen; + char *fname = NULL; +- const char key[] = "What am I, a doctor or a moonshuttle conductor?"; ++ const char key[] = "orboDeJITITejsirpADONivirpUkvarP"; + +- if (!dladdr ("gcry_check_version", &info)) ++ if (get_library_path ("libgcrypt.so.11", "gcry_check_version", libpath, sizeof(libpath))) + err = gpg_error_from_syserror (); + else + { +- dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname, ++ dlen = _gcry_hmac256_file (digest, sizeof digest, libpath, + key, strlen (key)); + if (dlen < 0) + err = gpg_error_from_syserror (); +@@ -594,7 +619,7 @@ check_binary_integrity (void) + err = gpg_error (GPG_ERR_INTERNAL); + else + { +- fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 ); ++ fname = gcry_malloc (strlen (libpath) + 1 + 5 + 1 ); + if (!fname) + err = gpg_error_from_syserror (); + else +@@ -603,7 +628,7 @@ check_binary_integrity (void) + char *p; + + /* Prefix the basename with a dot. */ +- strcpy (fname, info.dli_fname); ++ strcpy (fname, libpath); + p = strrchr (fname, '/'); + if (p) + p++; diff --git a/libgcrypt.spec b/libgcrypt.spec index e78f5c8..0242a85 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.4 -Release: 2%{?dist} +Release: 3%{?dist} Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -10,12 +10,14 @@ Source0: libgcrypt-%{version}-hobbled.tar.bz2 Source2: wk@g10code.com Source3: hobble-libgcrypt Patch1: libgcrypt-1.4.4-fips-no-access.patch +Patch2: libgcrypt-1.4.4-use-fipscheck.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. License: LGPLv2+ Summary: A general-purpose cryptography library BuildRoot: %{_tmppath}/%{name}-%{version}-root BuildRequires: gawk, libgpg-error-devel >= 1.4, pkgconfig +BuildRequires: fipscheck Group: System Environment/Libraries %package devel @@ -38,6 +40,7 @@ applications using libgcrypt. %setup -q %{SOURCE3} %patch1 -p1 -b .no-access +%patch2 -p1 -b .use-fipscheck %build %configure --disable-static \ @@ -45,12 +48,22 @@ applications using libgcrypt. --disable-asm \ %endif --enable-noexecstack \ + --enable-hmac-binary-check \ --enable-pubkey-ciphers='dsa elgamal rsa' make %{?_smp_mflags} %check +fipshmac src/.libs/libgcrypt.so.?? make check +# Add generation of HMAC checksums of the final stripped binaries +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ + fipshmac $RPM_BUILD_ROOT/%{_lib}/*.so.?? \ +%{nil} + %install rm -fr $RPM_BUILD_ROOT %makeinstall @@ -117,8 +130,8 @@ exit 0 %files %defattr(-,root,root) %dir /etc/gcrypt -/%{_lib}/*.so.* -#%{_libdir}/%{name} +/%{_lib}/libgcrypt.so.* +/%{_lib}/.libgcrypt.so.*.hmac %files devel %defattr(-,root,root) @@ -128,11 +141,13 @@ exit 0 %{_includedir}/* %{_libdir}/*.so %{_datadir}/aclocal/* -#%{_datadir}/%{name} %{_infodir}/gcrypt.info* %changelog +* Tue Mar 3 2009 Tomas Mraz 1.4.4-3 +- add hmac FIPS integrity verification check + * Wed Feb 25 2009 Fedora Release Engineering - 1.4.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_11_Mass_Rebuild From e569e4374458beabedd4f80c51806169615fb7e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Thu, 5 Mar 2009 10:25:19 +0000 Subject: [PATCH 021/214] - with the integrity verification check the library needs to link to libdl (#488702) --- libgcrypt-1.4.4-use-fipscheck.patch | 16 ++++++++++++++-- libgcrypt.spec | 6 +++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/libgcrypt-1.4.4-use-fipscheck.patch b/libgcrypt-1.4.4-use-fipscheck.patch index aa7d7d1..5708534 100644 --- a/libgcrypt-1.4.4-use-fipscheck.patch +++ b/libgcrypt-1.4.4-use-fipscheck.patch @@ -1,6 +1,6 @@ diff -up libgcrypt-1.4.4/src/fips.c.use-fipscheck libgcrypt-1.4.4/src/fips.c ---- libgcrypt-1.4.4/src/fips.c.use-fipscheck 2009-03-03 18:10:49.000000000 +0100 -+++ libgcrypt-1.4.4/src/fips.c 2009-03-03 18:51:31.000000000 +0100 +--- libgcrypt-1.4.4/src/fips.c.use-fipscheck 2009-03-03 21:09:27.000000000 +0100 ++++ libgcrypt-1.4.4/src/fips.c 2009-03-05 11:20:48.000000000 +0100 @@ -570,23 +570,48 @@ run_random_selftests (void) return !!err; } @@ -72,3 +72,15 @@ diff -up libgcrypt-1.4.4/src/fips.c.use-fipscheck libgcrypt-1.4.4/src/fips.c p = strrchr (fname, '/'); if (p) p++; +diff -up libgcrypt-1.4.4/src/Makefile.use-fipscheck libgcrypt-1.4.4/src/Makefile +--- libgcrypt-1.4.4/src/Makefile.use-fipscheck 2009-03-03 21:09:41.000000000 +0100 ++++ libgcrypt-1.4.4/src/Makefile 2009-03-05 11:20:40.000000000 +0100 +@@ -337,7 +337,7 @@ libgcrypt_la_LIBADD = \ + ../cipher/libcipher.la \ + ../random/librandom.la \ + ../mpi/libmpi.la \ +- -lgpg-error ++ -lgpg-error -ldl + + dumpsexp_SOURCES = dumpsexp.c + dumpsexp_LDADD = diff --git a/libgcrypt.spec b/libgcrypt.spec index 0242a85..df1fcad 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.4 -Release: 3%{?dist} +Release: 4%{?dist} Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -145,6 +145,10 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Thu Mar 5 2009 Tomas Mraz 1.4.4-4 +- with the integrity verification check the library needs to link to libdl + (#488702) + * Tue Mar 3 2009 Tomas Mraz 1.4.4-3 - add hmac FIPS integrity verification check From fd11f879aed0f87fd2999b7c6c3c406512011757 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Thu, 5 Mar 2009 10:32:46 +0000 Subject: [PATCH 022/214] - we need to patch Makefile.in of course --- libgcrypt-1.4.4-use-fipscheck.patch | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libgcrypt-1.4.4-use-fipscheck.patch b/libgcrypt-1.4.4-use-fipscheck.patch index 5708534..d6f45b2 100644 --- a/libgcrypt-1.4.4-use-fipscheck.patch +++ b/libgcrypt-1.4.4-use-fipscheck.patch @@ -72,15 +72,15 @@ diff -up libgcrypt-1.4.4/src/fips.c.use-fipscheck libgcrypt-1.4.4/src/fips.c p = strrchr (fname, '/'); if (p) p++; -diff -up libgcrypt-1.4.4/src/Makefile.use-fipscheck libgcrypt-1.4.4/src/Makefile ---- libgcrypt-1.4.4/src/Makefile.use-fipscheck 2009-03-03 21:09:41.000000000 +0100 -+++ libgcrypt-1.4.4/src/Makefile 2009-03-05 11:20:40.000000000 +0100 +diff -up libgcrypt-1.4.4/src/Makefile.in.use-fipscheck libgcrypt-1.4.4/src/Makefile.in +--- libgcrypt-1.4.4/src/Makefile.in.use-fipscheck 2009-01-22 19:16:51.000000000 +0100 ++++ libgcrypt-1.4.4/src/Makefile.in 2009-03-05 11:31:57.000000000 +0100 @@ -337,7 +337,7 @@ libgcrypt_la_LIBADD = \ ../cipher/libcipher.la \ ../random/librandom.la \ ../mpi/libmpi.la \ -- -lgpg-error -+ -lgpg-error -ldl +- @LTLIBOBJS@ @GPG_ERROR_LIBS@ ++ @LTLIBOBJS@ @GPG_ERROR_LIBS@ -ldl dumpsexp_SOURCES = dumpsexp.c dumpsexp_LDADD = From 0d713cca5e55ba71a04ea04ce959e4b414d4eaf4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Wed, 17 Jun 2009 18:17:06 +0000 Subject: [PATCH 023/214] - fix VIA padlock RNG inline assembly call (#505724) --- libgcrypt-1.4.4-padlock.patch | 28 ++++++++++++++++++++++++++++ libgcrypt.spec | 6 +++++- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.4.4-padlock.patch diff --git a/libgcrypt-1.4.4-padlock.patch b/libgcrypt-1.4.4-padlock.patch new file mode 100644 index 0000000..e9501de --- /dev/null +++ b/libgcrypt-1.4.4-padlock.patch @@ -0,0 +1,28 @@ +diff -up libgcrypt-1.4.4/random/rndhw.c.padlock libgcrypt-1.4.4/random/rndhw.c +--- libgcrypt-1.4.4/random/rndhw.c.padlock 2008-09-03 12:04:43.000000000 +0200 ++++ libgcrypt-1.4.4/random/rndhw.c 2009-06-17 20:11:42.000000000 +0200 +@@ -41,7 +41,7 @@ static size_t + poll_padlock (void (*add)(const void*, size_t, enum random_origins), + enum random_origins origin, int fast) + { +- char buffer[64+8] __attribute__ ((aligned (8))); ++ volatile char buffer[64+8] __attribute__ ((aligned (8))); + char *p; + unsigned int nbytes, status; + +@@ -55,12 +55,11 @@ poll_padlock (void (*add)(const void*, s + nbytes = 0; + while (nbytes < 64) + { +- asm volatile ++ asm volatile + ("movl %1, %%edi\n\t" /* Set buffer. */ + "xorl %%edx, %%edx\n\t" /* Request up to 8 bytes. */ +- ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */ +- "movl %%eax, %0\n" /* Return the status. */ +- : "=g" (status) ++ ".byte 0x0f, 0xa7, 0xc0\n" /* XSTORE RNG. */ ++ : "=a" (status) + : "g" (p) + : "%edx", "%edi", "cc" + ); diff --git a/libgcrypt.spec b/libgcrypt.spec index df1fcad..431ca4f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.4 -Release: 4%{?dist} +Release: 5%{?dist} Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -11,6 +11,7 @@ Source2: wk@g10code.com Source3: hobble-libgcrypt Patch1: libgcrypt-1.4.4-fips-no-access.patch Patch2: libgcrypt-1.4.4-use-fipscheck.patch +Patch3: libgcrypt-1.4.4-padlock.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. License: LGPLv2+ @@ -145,6 +146,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Wed Jun 17 2009 Tomas Mraz 1.4.4-5 +- fix VIA padlock RNG inline assembly call (#505724) + * Thu Mar 5 2009 Tomas Mraz 1.4.4-4 - with the integrity verification check the library needs to link to libdl (#488702) From 06cc870937f04c82fff10f1b21ae3b672ceca718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Thu, 18 Jun 2009 21:30:12 +0000 Subject: [PATCH 024/214] - and now really apply the padlock patch --- libgcrypt.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 431ca4f..3e9c9fd 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.4 -Release: 5%{?dist} +Release: 6%{?dist} Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -42,6 +42,7 @@ applications using libgcrypt. %{SOURCE3} %patch1 -p1 -b .no-access %patch2 -p1 -b .use-fipscheck +%patch3 -p1 -b .padlock %build %configure --disable-static \ @@ -146,6 +147,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Thu Jun 18 2009 Tomas Mraz 1.4.4-6 +- and now really apply the padlock patch + * Wed Jun 17 2009 Tomas Mraz 1.4.4-5 - fix VIA padlock RNG inline assembly call (#505724) From 2a6e183e10b328125e674b057ec78b88d7192941 Mon Sep 17 00:00:00 2001 From: Jesse Keating Date: Sat, 25 Jul 2009 05:40:56 +0000 Subject: [PATCH 025/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3e9c9fd..cba46d8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.4 -Release: 6%{?dist} +Release: 7%{?dist} Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -147,6 +147,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Fri Jul 24 2009 Fedora Release Engineering - 1.4.4-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild + * Thu Jun 18 2009 Tomas Mraz 1.4.4-6 - and now really apply the padlock patch From f235e635adadcf0999a9481035168363c19d7d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Tue, 11 Aug 2009 12:41:05 +0000 Subject: [PATCH 026/214] - fix warning when installed with --excludedocs (#515961) --- libgcrypt.spec | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index cba46d8..b89e4d6 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.4 -Release: 7%{?dist} +Release: 8%{?dist} Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -120,11 +120,12 @@ rm -fr $RPM_BUILD_ROOT %postun -p /sbin/ldconfig %post devel -/sbin/install-info %{_infodir}/gcrypt.info.gz %{_infodir}/dir +[ -f %{_infodir}/gcrypt.info.gz ] && \ + /sbin/install-info %{_infodir}/gcrypt.info.gz %{_infodir}/dir exit 0 %preun devel -if [ $1 = 0 ]; then +if [ $1 = 0 -a -f %{_infodir}/gcrypt.info.gz ]; then /sbin/install-info --delete %{_infodir}/gcrypt.info.gz %{_infodir}/dir fi exit 0 @@ -147,6 +148,9 @@ exit 0 %{_infodir}/gcrypt.info* %changelog +* Tue Aug 11 2009 Tomas Mraz 1.4.4-8 +- fix warning when installed with --excludedocs (#515961) + * Fri Jul 24 2009 Fedora Release Engineering - 1.4.4-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild From c9de6acdaccedda3f1b283ec34c04d61396443ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Tue, 27 Oct 2009 14:36:08 +0000 Subject: [PATCH 027/214] Drop dot from summary --- libgcrypt.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index b89e4d6..1e6ad47 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -22,7 +22,7 @@ BuildRequires: fipscheck Group: System Environment/Libraries %package devel -Summary: Development files for the %{name} package. +Summary: Development files for the %{name} package Group: Development/Libraries PreReq: /sbin/install-info Requires: libgpg-error-devel From b46cd3c25b5fb0ab17091ea931614dc354c95ac1 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Wed, 25 Nov 2009 23:50:57 +0000 Subject: [PATCH 028/214] Fix typo that causes a failure to update the common directory. (releng #2781) --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 4de825d..58eb767 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ # Makefile for source rpm: libgcrypt -# $Id: Makefile,v 1.1 2004/09/09 07:25:33 cvsdist Exp $ +# $Id: Makefile,v 1.2 2007/10/15 19:00:34 notting Exp $ NAME := libgcrypt SPECFILE = $(firstword $(wildcard *.spec)) define find-makefile-common -for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done +for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done endef MAKEFILE_COMMON := $(shell $(find-makefile-common)) From e56dfebe1c1853857afecaea39976e568d085509 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Mon, 21 Dec 2009 08:26:28 +0000 Subject: [PATCH 029/214] *** empty log message *** --- libgcrypt.spec | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 1e6ad47..0abc16e 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,7 @@ Name: libgcrypt Version: 1.4.4 -Release: 8%{?dist} +Release: 9%{?dist} +URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -24,7 +25,8 @@ Group: System Environment/Libraries %package devel Summary: Development files for the %{name} package Group: Development/Libraries -PreReq: /sbin/install-info +Requires(pre): /sbin/install-info +Requires(post): /sbin/install-info Requires: libgpg-error-devel Requires: %{name} = %{version}-%{release} @@ -45,6 +47,9 @@ applications using libgcrypt. %patch3 -p1 -b .padlock %build +%ifarch s390 +%global optflags %optflags -fno-schedule-insns +%endif %configure --disable-static \ %ifarch sparc64 --disable-asm \ @@ -148,6 +153,11 @@ exit 0 %{_infodir}/gcrypt.info* %changelog + +* Mon Dec 21 2009 Tomas Mraz 1.4.4-9 +- Workaround for build on S390 (#548825) +- Spec file cleanups + * Tue Aug 11 2009 Tomas Mraz 1.4.4-8 - fix warning when installed with --excludedocs (#515961) @@ -223,7 +233,7 @@ exit 0 - disable static libraries (part of #249815) * Fri Jul 27 2007 Nalin Dahyabhai - 1.2.4-2 -- move libgcrypt shared library to /%{_lib} (#249815) +- move libgcrypt shared library to /%%{_lib} (#249815) * Tue Feb 6 2007 Nalin Dahyabhai - 1.2.4-1 - update to 1.2.4 From 9b6823253d1e7840568abed8a48772f348efcf9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Mon, 21 Dec 2009 08:46:43 +0000 Subject: [PATCH 030/214] - workaround for build on S390 (#548825) - spec file cleanups - upgrade to new minor upstream release --- .cvsignore | 2 +- libgcrypt-1.4.4-fips-no-access.patch | 13 ------------- libgcrypt-1.4.4-padlock.patch | 28 ---------------------------- libgcrypt.spec | 19 ++++++++----------- sources | 2 +- 5 files changed, 10 insertions(+), 54 deletions(-) delete mode 100644 libgcrypt-1.4.4-fips-no-access.patch delete mode 100644 libgcrypt-1.4.4-padlock.patch diff --git a/.cvsignore b/.cvsignore index b8edc03..1e51c05 100644 --- a/.cvsignore +++ b/.cvsignore @@ -1 +1 @@ -libgcrypt-1.4.4-hobbled.tar.bz2 +libgcrypt-1.4.5-hobbled.tar.bz2 diff --git a/libgcrypt-1.4.4-fips-no-access.patch b/libgcrypt-1.4.4-fips-no-access.patch deleted file mode 100644 index f2972e9..0000000 --- a/libgcrypt-1.4.4-fips-no-access.patch +++ /dev/null @@ -1,13 +0,0 @@ -Do not abort when the fips mode flag is simply inaccessible because of -insufficient permissions. -diff -up libgcrypt-1.4.4/src/fips.c.no-access libgcrypt-1.4.4/src/fips.c ---- libgcrypt-1.4.4/src/fips.c.no-access 2009-01-29 17:37:12.000000000 +0100 -+++ libgcrypt-1.4.4/src/fips.c 2009-01-29 17:37:15.000000000 +0100 -@@ -155,6 +155,7 @@ _gcry_initialize_fips_mode (int force) - fclose (fp); - } - else if ((saved_errno = errno) != ENOENT -+ && saved_errno != EACCES - && !access ("/proc/version", F_OK) ) - { - /* Problem reading the fips file despite that we have the proc diff --git a/libgcrypt-1.4.4-padlock.patch b/libgcrypt-1.4.4-padlock.patch deleted file mode 100644 index e9501de..0000000 --- a/libgcrypt-1.4.4-padlock.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff -up libgcrypt-1.4.4/random/rndhw.c.padlock libgcrypt-1.4.4/random/rndhw.c ---- libgcrypt-1.4.4/random/rndhw.c.padlock 2008-09-03 12:04:43.000000000 +0200 -+++ libgcrypt-1.4.4/random/rndhw.c 2009-06-17 20:11:42.000000000 +0200 -@@ -41,7 +41,7 @@ static size_t - poll_padlock (void (*add)(const void*, size_t, enum random_origins), - enum random_origins origin, int fast) - { -- char buffer[64+8] __attribute__ ((aligned (8))); -+ volatile char buffer[64+8] __attribute__ ((aligned (8))); - char *p; - unsigned int nbytes, status; - -@@ -55,12 +55,11 @@ poll_padlock (void (*add)(const void*, s - nbytes = 0; - while (nbytes < 64) - { -- asm volatile -+ asm volatile - ("movl %1, %%edi\n\t" /* Set buffer. */ - "xorl %%edx, %%edx\n\t" /* Request up to 8 bytes. */ -- ".byte 0x0f, 0xa7, 0xc0\n\t" /* XSTORE RNG. */ -- "movl %%eax, %0\n" /* Return the status. */ -- : "=g" (status) -+ ".byte 0x0f, 0xa7, 0xc0\n" /* XSTORE RNG. */ -+ : "=a" (status) - : "g" (p) - : "%edx", "%edi", "cc" - ); diff --git a/libgcrypt.spec b/libgcrypt.spec index 0abc16e..78f13a9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.4.4 -Release: 9%{?dist} +Version: 1.4.5 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -10,9 +10,7 @@ Source0: libgcrypt-%{version}-hobbled.tar.bz2 #Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com Source3: hobble-libgcrypt -Patch1: libgcrypt-1.4.4-fips-no-access.patch Patch2: libgcrypt-1.4.4-use-fipscheck.patch -Patch3: libgcrypt-1.4.4-padlock.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. License: LGPLv2+ @@ -42,9 +40,7 @@ applications using libgcrypt. %prep %setup -q %{SOURCE3} -%patch1 -p1 -b .no-access %patch2 -p1 -b .use-fipscheck -%patch3 -p1 -b .padlock %build %ifarch s390 @@ -56,7 +52,8 @@ applications using libgcrypt. %endif --enable-noexecstack \ --enable-hmac-binary-check \ - --enable-pubkey-ciphers='dsa elgamal rsa' + --enable-pubkey-ciphers='dsa elgamal rsa' \ + --disable-O-flag-munging make %{?_smp_mflags} %check @@ -153,10 +150,10 @@ exit 0 %{_infodir}/gcrypt.info* %changelog - -* Mon Dec 21 2009 Tomas Mraz 1.4.4-9 -- Workaround for build on S390 (#548825) -- Spec file cleanups +* Mon Dec 21 2009 Tomas Mraz 1.4.5-1 +- workaround for build on S390 (#548825) +- spec file cleanups +- upgrade to new minor upstream release * Tue Aug 11 2009 Tomas Mraz 1.4.4-8 - fix warning when installed with --excludedocs (#515961) diff --git a/sources b/sources index 04b5ae2..6851e28 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -12d3fec91c663b541d63e34eabddacc5 libgcrypt-1.4.4-hobbled.tar.bz2 +56a36e06fff2ed0a3b07c901a907db5f libgcrypt-1.4.5-hobbled.tar.bz2 From c9eae9797f38c5771ea099264f004942e7c9330e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Mr=C3=A1z?= Date: Wed, 3 Feb 2010 08:23:55 +0000 Subject: [PATCH 031/214] - drop the S390 build workaround as it is no longer needed - additional spec file cleanups for merge review (#226008) --- libgcrypt.spec | 26 ++++++++++++++++++-------- 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 78f13a9..f9b6c40 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.5 -Release: 1%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -10,18 +10,22 @@ Source0: libgcrypt-%{version}-hobbled.tar.bz2 #Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com Source3: hobble-libgcrypt +# make FIPS hmac compatible with fipscheck - non upstreamable Patch2: libgcrypt-1.4.4-use-fipscheck.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. +# Documentation and some utilities are GPLv2+ licensed. These files +# are in the devel subpackage. License: LGPLv2+ Summary: A general-purpose cryptography library -BuildRoot: %{_tmppath}/%{name}-%{version}-root +BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRequires: gawk, libgpg-error-devel >= 1.4, pkgconfig BuildRequires: fipscheck Group: System Environment/Libraries %package devel Summary: Development files for the %{name} package +License: LGPLv2+ and GPLv2+ Group: Development/Libraries Requires(pre): /sbin/install-info Requires(post): /sbin/install-info @@ -42,10 +46,10 @@ applications using libgcrypt. %{SOURCE3} %patch2 -p1 -b .use-fipscheck +mv AUTHORS AUTHORS.iso88591 +iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS + %build -%ifarch s390 -%global optflags %optflags -fno-schedule-insns -%endif %configure --disable-static \ %ifarch sparc64 --disable-asm \ @@ -70,7 +74,7 @@ make check %install rm -fr $RPM_BUILD_ROOT -%makeinstall +make install DESTDIR=$RPM_BUILD_ROOT # Change /usr/lib64 back to /usr/lib. This saves us from having to patch the # script to "know" that -L/usr/lib64 should be suppressed, and also removes @@ -133,13 +137,14 @@ fi exit 0 %files -%defattr(-,root,root) +%defattr(-,root,root,-) %dir /etc/gcrypt /%{_lib}/libgcrypt.so.* /%{_lib}/.libgcrypt.so.*.hmac +%doc COPYING.LIB AUTHORS NEWS THANKS %files devel -%defattr(-,root,root) +%defattr(-,root,root,-) %{_bindir}/%{name}-config %{_bindir}/dumpsexp %{_bindir}/hmac256 @@ -148,8 +153,13 @@ exit 0 %{_datadir}/aclocal/* %{_infodir}/gcrypt.info* +%doc COPYING %changelog +* Wed Feb 3 2010 Tomas Mraz 1.4.5-3 +- drop the S390 build workaround as it is no longer needed +- additional spec file cleanups for merge review (#226008) + * Mon Dec 21 2009 Tomas Mraz 1.4.5-1 - workaround for build on S390 (#548825) - spec file cleanups From 6d243f390f4f7c4893d989146e76cdcb77cc1486 Mon Sep 17 00:00:00 2001 From: Rex Dieter Date: Sun, 14 Feb 2010 20:32:09 +0000 Subject: [PATCH 032/214] - FTBFS libgcrypt-1.4.5-3.fc13: ImplicitDSOLinking (#564973) --- libgcrypt-1.4.5-ImplicitDSOLinking.patch | 24 ++++++++++++++++++++++++ libgcrypt.spec | 8 +++++++- 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.4.5-ImplicitDSOLinking.patch diff --git a/libgcrypt-1.4.5-ImplicitDSOLinking.patch b/libgcrypt-1.4.5-ImplicitDSOLinking.patch new file mode 100644 index 0000000..7b4671f --- /dev/null +++ b/libgcrypt-1.4.5-ImplicitDSOLinking.patch @@ -0,0 +1,24 @@ +diff -up libgcrypt-1.4.5/tests/Makefile.am.ImplicitDSOLinking libgcrypt-1.4.5/tests/Makefile.am +--- libgcrypt-1.4.5/tests/Makefile.am.ImplicitDSOLinking 2009-04-02 04:25:34.000000000 -0500 ++++ libgcrypt-1.4.5/tests/Makefile.am 2010-02-14 14:28:49.792383613 -0600 +@@ -36,7 +36,7 @@ TESTS += benchmark + AM_CPPFLAGS = -I../src -I$(top_srcdir)/src + AM_CFLAGS = $(GPG_ERROR_CFLAGS) + +-LDADD = ../src/libgcrypt.la $(DL_LIBS) ++LDADD = ../src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) + + EXTRA_PROGRAMS = testapi pkbench + noinst_PROGRAMS = $(TESTS) fipsdrv +diff -up libgcrypt-1.4.5/tests/Makefile.in.ImplicitDSOLinking libgcrypt-1.4.5/tests/Makefile.in +--- libgcrypt-1.4.5/tests/Makefile.in.ImplicitDSOLinking 2009-12-11 09:43:30.000000000 -0600 ++++ libgcrypt-1.4.5/tests/Makefile.in 2010-02-14 14:29:30.232368780 -0600 +@@ -334,7 +334,7 @@ top_srcdir = @top_srcdir@ + # a built header. + AM_CPPFLAGS = -I../src -I$(top_srcdir)/src + AM_CFLAGS = $(GPG_ERROR_CFLAGS) +-LDADD = ../src/libgcrypt.la $(DL_LIBS) ++LDADD = ../src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) + EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl + all: all-am + diff --git a/libgcrypt.spec b/libgcrypt.spec index f9b6c40..e81f80e 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.5 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -12,6 +12,8 @@ Source2: wk@g10code.com Source3: hobble-libgcrypt # make FIPS hmac compatible with fipscheck - non upstreamable Patch2: libgcrypt-1.4.4-use-fipscheck.patch +# fix ImplicitDSOLinking (missing -lgpg-error linkage in tests/), upstreamable +Patch3: libgcrypt-1.4.5-ImplicitDSOLinking.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -45,6 +47,7 @@ applications using libgcrypt. %setup -q %{SOURCE3} %patch2 -p1 -b .use-fipscheck +%patch3 -p1 -b .ImplicitDSOLinking mv AUTHORS AUTHORS.iso88591 iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS @@ -156,6 +159,9 @@ exit 0 %doc COPYING %changelog +* Sun Feb 14 2010 Rex Dieter 1.4.5-4 +- FTBFS libgcrypt-1.4.5-3.fc13: ImplicitDSOLinking (#564973) + * Wed Feb 3 2010 Tomas Mraz 1.4.5-3 - drop the S390 build workaround as it is no longer needed - additional spec file cleanups for merge review (#226008) From 76ce03ce828dffd46dd65eb4c540545c5f298d34 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 28 Jul 2010 20:58:58 +0000 Subject: [PATCH 033/214] dist-git conversion --- .cvsignore => .gitignore | 0 Makefile | 21 --------------------- 2 files changed, 21 deletions(-) rename .cvsignore => .gitignore (100%) delete mode 100644 Makefile diff --git a/.cvsignore b/.gitignore similarity index 100% rename from .cvsignore rename to .gitignore diff --git a/Makefile b/Makefile deleted file mode 100644 index 58eb767..0000000 --- a/Makefile +++ /dev/null @@ -1,21 +0,0 @@ -# Makefile for source rpm: libgcrypt -# $Id: Makefile,v 1.2 2007/10/15 19:00:34 notting Exp $ -NAME := libgcrypt -SPECFILE = $(firstword $(wildcard *.spec)) - -define find-makefile-common -for d in common ../common ../../common ; do if [ -f $$d/Makefile.common ] ; then if [ -f $$d/CVS/Root -a -w $$d/Makefile.common ] ; then cd $$d ; cvs -Q update ; fi ; echo "$$d/Makefile.common" ; break ; fi ; done -endef - -MAKEFILE_COMMON := $(shell $(find-makefile-common)) - -ifeq ($(MAKEFILE_COMMON),) -# attempt a checkout -define checkout-makefile-common -test -f CVS/Root && { cvs -Q -d $$(cat CVS/Root) checkout common && echo "common/Makefile.common" ; } || { echo "ERROR: I can't figure out how to checkout the 'common' module." ; exit -1 ; } >&2 -endef - -MAKEFILE_COMMON := $(shell $(checkout-makefile-common)) -endif - -include $(MAKEFILE_COMMON) From 16991a5be46cb1617acec215a4e83d0268501b11 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 1 Feb 2011 18:54:42 +0100 Subject: [PATCH 034/214] - use /dev/urandom for seeding in the FIPS mode - make the tests to pass in the FIPS mode also fixing the FIPS-186-3 DSA keygen --- libgcrypt-1.4.5-tests.patch | 206 ++++++++++++++++++++++++++++++++++ libgcrypt-1.4.5-urandom.patch | 33 ++++++ libgcrypt.spec | 13 ++- 3 files changed, 251 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.4.5-tests.patch create mode 100644 libgcrypt-1.4.5-urandom.patch diff --git a/libgcrypt-1.4.5-tests.patch b/libgcrypt-1.4.5-tests.patch new file mode 100644 index 0000000..c71f3a8 --- /dev/null +++ b/libgcrypt-1.4.5-tests.patch @@ -0,0 +1,206 @@ +diff -up libgcrypt-1.4.5/cipher/dsa.c.tests libgcrypt-1.4.5/cipher/dsa.c +--- libgcrypt-1.4.5/cipher/dsa.c.tests 2009-08-21 10:18:30.000000000 +0200 ++++ libgcrypt-1.4.5/cipher/dsa.c 2011-02-01 18:04:56.000000000 +0100 +@@ -468,21 +468,20 @@ generate_fips186 (DSA_secret_key *sk, un + &initial_seed.seedlen); + } + +- /* Fixme: Enable 186-3 after it has been approved and after fixing +- the generation function. */ +- /* if (use_fips186_2) */ +- (void)use_fips186_2; +- ec = _gcry_generate_fips186_2_prime (nbits, qbits, ++ if (use_fips186_2) ++ ec = _gcry_generate_fips186_2_prime (nbits, qbits, + initial_seed.seed, + initial_seed.seedlen, + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen); +- /* else */ +- /* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */ +- /* &prime_q, &prime_p, */ +- /* r_counter, */ +- /* r_seed, r_seedlen, NULL); */ ++ else ++ ec = _gcry_generate_fips186_3_prime (nbits, qbits, ++ initial_seed.seed, ++ initial_seed.seedlen, ++ &prime_q, &prime_p, ++ r_counter, ++ r_seed, r_seedlen, NULL); + gcry_sexp_release (initial_seed.sexp); + if (ec) + goto leave; +diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen.c +--- libgcrypt-1.4.5/cipher/primegen.c.tests 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.5/cipher/primegen.c 2011-02-01 18:00:53.000000000 +0100 +@@ -1647,7 +1647,7 @@ _gcry_generate_fips186_3_prime (unsigned + gpg_err_code_t ec; + unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */ + unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */ +- unsigned char digest[256/8]; /* Helper buffer for SHA-1 digest. */ ++ unsigned char digest[256/8]; /* Helper buffer for SHA-x digest. */ + gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */ + gcry_mpi_t tmpval = NULL; /* Helper variable. */ + int hashalgo; /* The id of the Approved Hash Function. */ +@@ -1737,7 +1737,7 @@ _gcry_generate_fips186_3_prime (unsigned + } + gcry_mpi_release (prime_q); prime_q = NULL; + ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, +- value_u, sizeof value_u, NULL)); ++ value_u, qbits/8, NULL)); + if (ec) + goto leave; + mpi_set_highbit (prime_q, qbits-1 ); +@@ -1782,7 +1782,7 @@ _gcry_generate_fips186_3_prime (unsigned + if (seed_plus[i]) + break; + } +- gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen); ++ gcry_md_hash_buffer (hashalgo, digest, seed_plus, seedlen); + + gcry_mpi_release (tmpval); tmpval = NULL; + ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG, +@@ -1822,11 +1822,11 @@ _gcry_generate_fips186_3_prime (unsigned + } + + /* Step 12: Save p, q, counter and seed. */ +- log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", ++/* log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", + mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); + log_printhex("fips186-3 seed:", seed, seedlen); + log_mpidump ("fips186-3 prime p", prime_p); +- log_mpidump ("fips186-3 prime q", prime_q); ++ log_mpidump ("fips186-3 prime q", prime_q); */ + if (r_q) + { + *r_q = prime_q; +diff -up libgcrypt-1.4.5/cipher/rsa.c.tests libgcrypt-1.4.5/cipher/rsa.c +--- libgcrypt-1.4.5/cipher/rsa.c.tests 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.5/cipher/rsa.c 2011-02-01 18:40:26.000000000 +0100 +@@ -388,7 +388,7 @@ generate_x931 (RSA_secret_key *sk, unsig + + *swapped = 0; + +- if (e_value == 1) /* Alias for a secure value. */ ++ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ + e_value = 65537; + + /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ +diff -up libgcrypt-1.4.5/random/random-fips.c.tests libgcrypt-1.4.5/random/random-fips.c +--- libgcrypt-1.4.5/random/random-fips.c.tests 2011-02-01 12:31:00.000000000 +0100 ++++ libgcrypt-1.4.5/random/random-fips.c 2011-02-01 12:31:00.000000000 +0100 +@@ -691,6 +691,7 @@ get_random (void *buffer, size_t length, + + check_guards (rng_ctx); + ++ reinitialize: + /* Initialize the cipher handle and thus setup the key if needed. */ + if (!rng_ctx->cipher_hd) + { +@@ -710,13 +711,11 @@ get_random (void *buffer, size_t length, + if (rng_ctx->key_init_pid != getpid () + || rng_ctx->seed_init_pid != getpid ()) + { +- /* We are in a child of us. Because we have no way yet to do +- proper re-initialization (including self-checks etc), the +- only chance we have is to bail out. Obviusly a fork/exec +- won't harm because the exec overwrites the old image. */ +- fips_signal_error ("fork without proper re-initialization " +- "detected in RNG"); +- goto bailout; ++ /* Just reinitialize the key & seed. */ ++ gcry_cipher_close(rng_ctx->cipher_hd); ++ rng_ctx->cipher_hd = NULL; ++ rng_ctx->is_seeded = 0; ++ goto reinitialize; + } + + if (x931_aes_driver (buffer, length, rng_ctx)) +diff -up libgcrypt-1.4.5/tests/ac.c.tests libgcrypt-1.4.5/tests/ac.c +--- libgcrypt-1.4.5/tests/ac.c.tests 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.5/tests/ac.c 2011-02-01 12:49:14.000000000 +0100 +@@ -150,6 +150,9 @@ main (int argc, char **argv) + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); ++ if (gcry_fips_mode_active()) ++ /* ac not functional in the fips mode, skip it */ ++ return 77; + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + /* No valuable keys are create, so we can speed up our RNG. */ +diff -up libgcrypt-1.4.5/tests/ac-data.c.tests libgcrypt-1.4.5/tests/ac-data.c +--- libgcrypt-1.4.5/tests/ac-data.c.tests 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.5/tests/ac-data.c 2011-02-01 12:49:54.000000000 +0100 +@@ -198,6 +198,9 @@ main (int argc, char **argv) + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); ++ if (gcry_fips_mode_active()) ++ /* ac not functional in the fips mode, skip it */ ++ return 77; + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + +diff -up libgcrypt-1.4.5/tests/ac-schemes.c.tests libgcrypt-1.4.5/tests/ac-schemes.c +--- libgcrypt-1.4.5/tests/ac-schemes.c.tests 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.5/tests/ac-schemes.c 2011-02-01 12:49:41.000000000 +0100 +@@ -338,6 +338,9 @@ main (int argc, char **argv) + if (! gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); ++ if (gcry_fips_mode_active()) ++ /* ac not functional in the fips mode, skip it */ ++ return 77; + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + +diff -up libgcrypt-1.4.5/tests/keygen.c.tests libgcrypt-1.4.5/tests/keygen.c +--- libgcrypt-1.4.5/tests/keygen.c.tests 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.5/tests/keygen.c 2011-02-01 18:19:56.000000000 +0100 +@@ -148,12 +148,12 @@ check_rsa_keys (void) + } + + if (verbose) +- fprintf (stderr, "creating 1536 bit DSA key\n"); ++ fprintf (stderr, "creating 2048 bit DSA key\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (dsa\n" +- " (nbits 4:1536)\n" +- " (qbits 3:224)\n" ++ " (nbits 4:2048)\n" ++ " (qbits 3:256)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); +@@ -190,11 +190,11 @@ check_rsa_keys (void) + + + if (verbose) +- fprintf (stderr, "creating 512 bit RSA key with e=257\n"); ++ fprintf (stderr, "creating 1024 bit RSA key with e=257\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" +- " (nbits 3:512)\n" ++ " (nbits 4:1024)\n" + " (rsa-use-e 3:257)\n" + " ))", 0, 1); + if (rc) +@@ -208,11 +208,11 @@ check_rsa_keys (void) + gcry_sexp_release (key); + + if (verbose) +- fprintf (stderr, "creating 512 bit RSA key with default e\n"); ++ fprintf (stderr, "creating 1024 bit RSA key with default secure e\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" +- " (nbits 3:512)\n" ++ " (nbits 4:1024)\n" + " (rsa-use-e 1:0)\n" + " ))", 0, 1); + if (rc) diff --git a/libgcrypt-1.4.5-urandom.patch b/libgcrypt-1.4.5-urandom.patch new file mode 100644 index 0000000..0bccbfc --- /dev/null +++ b/libgcrypt-1.4.5-urandom.patch @@ -0,0 +1,33 @@ +diff -up libgcrypt-1.4.5/random/random-fips.c.urandom libgcrypt-1.4.5/random/random-fips.c +--- libgcrypt-1.4.5/random/random-fips.c.urandom 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.5/random/random-fips.c 2011-02-01 11:33:59.000000000 +0100 +@@ -29,8 +29,8 @@ + + Generator Seed and Key Kernel entropy (init/reseed) + ------------------------------------------------------------ +- GCRY_VERY_STRONG_RANDOM /dev/random 256/128 bits +- GCRY_STRONG_RANDOM /dev/random 256/128 bits ++ GCRY_VERY_STRONG_RANDOM /dev/urandom 256/128 bits ++ GCRY_STRONG_RANDOM /dev/urandom 256/128 bits + gcry_create_nonce GCRY_STRONG_RANDOM n/a + + All random generators return their data in 128 bit blocks. If the +@@ -40,8 +40,7 @@ + (SEED_TTL) output blocks; the re-seeding is disabled in test mode. + + The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are +- keyed and seeded from the /dev/random device. Thus these +- generators may block until the kernel has collected enough entropy. ++ keyed and seeded from the /dev/urandom device. + + The gcry_create_nonce generator is keyed and seeded from the + GCRY_STRONG_RANDOM generator. It may also block if the +@@ -562,7 +561,7 @@ get_entropy (size_t nbytes) + #if USE_RNDLINUX + rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, + X931_AES_KEYLEN, +- GCRY_VERY_STRONG_RANDOM); ++ GCRY_STRONG_RANDOM); + #elif USE_RNDW32 + do + { diff --git a/libgcrypt.spec b/libgcrypt.spec index e81f80e..a6ca1f6 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.5 -Release: 4%{?dist} +Release: 5%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -14,6 +14,10 @@ Source3: hobble-libgcrypt Patch2: libgcrypt-1.4.4-use-fipscheck.patch # fix ImplicitDSOLinking (missing -lgpg-error linkage in tests/), upstreamable Patch3: libgcrypt-1.4.5-ImplicitDSOLinking.patch +# use /dev/urandom in the FIPS mode +Patch4: libgcrypt-1.4.5-urandom.patch +# fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen +Patch5: libgcrypt-1.4.5-tests.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -48,6 +52,8 @@ applications using libgcrypt. %{SOURCE3} %patch2 -p1 -b .use-fipscheck %patch3 -p1 -b .ImplicitDSOLinking +%patch4 -p1 -b .urandom +%patch5 -p1 -b .tests mv AUTHORS AUTHORS.iso88591 iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS @@ -159,6 +165,11 @@ exit 0 %doc COPYING %changelog +* Tue Feb 1 2011 Tomas Mraz 1.4.5-5 +- use /dev/urandom for seeding in the FIPS mode +- make the tests to pass in the FIPS mode also fixing + the FIPS-186-3 DSA keygen + * Sun Feb 14 2010 Rex Dieter 1.4.5-4 - FTBFS libgcrypt-1.4.5-3.fc13: ImplicitDSOLinking (#564973) From 474b273f7d3c94b799a3dfe09f2723ded6b18cd4 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 4 Feb 2011 10:04:08 +0100 Subject: [PATCH 035/214] - fix a bug in the fips-186-3 dsa parameter generation code --- libgcrypt-1.4.5-tests.patch | 25 +++++++++++++++---------- libgcrypt.spec | 5 ++++- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/libgcrypt-1.4.5-tests.patch b/libgcrypt-1.4.5-tests.patch index c71f3a8..d2f0256 100644 --- a/libgcrypt-1.4.5-tests.patch +++ b/libgcrypt-1.4.5-tests.patch @@ -1,6 +1,6 @@ diff -up libgcrypt-1.4.5/cipher/dsa.c.tests libgcrypt-1.4.5/cipher/dsa.c --- libgcrypt-1.4.5/cipher/dsa.c.tests 2009-08-21 10:18:30.000000000 +0200 -+++ libgcrypt-1.4.5/cipher/dsa.c 2011-02-01 18:04:56.000000000 +0100 ++++ libgcrypt-1.4.5/cipher/dsa.c 2011-02-04 09:06:02.000000000 +0100 @@ -468,21 +468,20 @@ generate_fips186 (DSA_secret_key *sk, un &initial_seed.seedlen); } @@ -34,7 +34,7 @@ diff -up libgcrypt-1.4.5/cipher/dsa.c.tests libgcrypt-1.4.5/cipher/dsa.c goto leave; diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen.c --- libgcrypt-1.4.5/cipher/primegen.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/cipher/primegen.c 2011-02-01 18:00:53.000000000 +0100 ++++ libgcrypt-1.4.5/cipher/primegen.c 2011-02-04 09:06:34.000000000 +0100 @@ -1647,7 +1647,7 @@ _gcry_generate_fips186_3_prime (unsigned gpg_err_code_t ec; unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */ @@ -53,7 +53,7 @@ diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen if (ec) goto leave; mpi_set_highbit (prime_q, qbits-1 ); -@@ -1782,7 +1782,7 @@ _gcry_generate_fips186_3_prime (unsigned +@@ -1782,11 +1782,11 @@ _gcry_generate_fips186_3_prime (unsigned if (seed_plus[i]) break; } @@ -62,6 +62,11 @@ diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen gcry_mpi_release (tmpval); tmpval = NULL; ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG, +- digest, sizeof digest, NULL)); ++ digest, qbits/8, NULL)); + if (ec) + goto leave; + if (value_j == value_n) @@ -1822,11 +1822,11 @@ _gcry_generate_fips186_3_prime (unsigned } @@ -78,7 +83,7 @@ diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen *r_q = prime_q; diff -up libgcrypt-1.4.5/cipher/rsa.c.tests libgcrypt-1.4.5/cipher/rsa.c --- libgcrypt-1.4.5/cipher/rsa.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/cipher/rsa.c 2011-02-01 18:40:26.000000000 +0100 ++++ libgcrypt-1.4.5/cipher/rsa.c 2011-02-04 09:06:02.000000000 +0100 @@ -388,7 +388,7 @@ generate_x931 (RSA_secret_key *sk, unsig *swapped = 0; @@ -89,8 +94,8 @@ diff -up libgcrypt-1.4.5/cipher/rsa.c.tests libgcrypt-1.4.5/cipher/rsa.c /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ diff -up libgcrypt-1.4.5/random/random-fips.c.tests libgcrypt-1.4.5/random/random-fips.c ---- libgcrypt-1.4.5/random/random-fips.c.tests 2011-02-01 12:31:00.000000000 +0100 -+++ libgcrypt-1.4.5/random/random-fips.c 2011-02-01 12:31:00.000000000 +0100 +--- libgcrypt-1.4.5/random/random-fips.c.tests 2011-02-04 09:06:02.000000000 +0100 ++++ libgcrypt-1.4.5/random/random-fips.c 2011-02-04 09:06:02.000000000 +0100 @@ -691,6 +691,7 @@ get_random (void *buffer, size_t length, check_guards (rng_ctx); @@ -120,7 +125,7 @@ diff -up libgcrypt-1.4.5/random/random-fips.c.tests libgcrypt-1.4.5/random/rando if (x931_aes_driver (buffer, length, rng_ctx)) diff -up libgcrypt-1.4.5/tests/ac.c.tests libgcrypt-1.4.5/tests/ac.c --- libgcrypt-1.4.5/tests/ac.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/tests/ac.c 2011-02-01 12:49:14.000000000 +0100 ++++ libgcrypt-1.4.5/tests/ac.c 2011-02-04 09:06:02.000000000 +0100 @@ -150,6 +150,9 @@ main (int argc, char **argv) if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); @@ -133,7 +138,7 @@ diff -up libgcrypt-1.4.5/tests/ac.c.tests libgcrypt-1.4.5/tests/ac.c /* No valuable keys are create, so we can speed up our RNG. */ diff -up libgcrypt-1.4.5/tests/ac-data.c.tests libgcrypt-1.4.5/tests/ac-data.c --- libgcrypt-1.4.5/tests/ac-data.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/tests/ac-data.c 2011-02-01 12:49:54.000000000 +0100 ++++ libgcrypt-1.4.5/tests/ac-data.c 2011-02-04 09:06:02.000000000 +0100 @@ -198,6 +198,9 @@ main (int argc, char **argv) if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); @@ -146,7 +151,7 @@ diff -up libgcrypt-1.4.5/tests/ac-data.c.tests libgcrypt-1.4.5/tests/ac-data.c diff -up libgcrypt-1.4.5/tests/ac-schemes.c.tests libgcrypt-1.4.5/tests/ac-schemes.c --- libgcrypt-1.4.5/tests/ac-schemes.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/tests/ac-schemes.c 2011-02-01 12:49:41.000000000 +0100 ++++ libgcrypt-1.4.5/tests/ac-schemes.c 2011-02-04 09:06:02.000000000 +0100 @@ -338,6 +338,9 @@ main (int argc, char **argv) if (! gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); @@ -159,7 +164,7 @@ diff -up libgcrypt-1.4.5/tests/ac-schemes.c.tests libgcrypt-1.4.5/tests/ac-schem diff -up libgcrypt-1.4.5/tests/keygen.c.tests libgcrypt-1.4.5/tests/keygen.c --- libgcrypt-1.4.5/tests/keygen.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/tests/keygen.c 2011-02-01 18:19:56.000000000 +0100 ++++ libgcrypt-1.4.5/tests/keygen.c 2011-02-04 09:06:02.000000000 +0100 @@ -148,12 +148,12 @@ check_rsa_keys (void) } diff --git a/libgcrypt.spec b/libgcrypt.spec index a6ca1f6..88332bf 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.5 -Release: 5%{?dist} +Release: 6%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -165,6 +165,9 @@ exit 0 %doc COPYING %changelog +* Thu Feb 4 2011 Tomas Mraz 1.4.5-6 +- fix a bug in the fips-186-3 dsa parameter generation code + * Tue Feb 1 2011 Tomas Mraz 1.4.5-5 - use /dev/urandom for seeding in the FIPS mode - make the tests to pass in the FIPS mode also fixing From 1a76790722967c451eb0306a8989f8f57c41663c Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Mon, 7 Feb 2011 23:55:13 -0600 Subject: [PATCH 036/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 88332bf..ebfe2e8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.5 -Release: 6%{?dist} +Release: 7%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -165,6 +165,9 @@ exit 0 %doc COPYING %changelog +* Mon Feb 07 2011 Fedora Release Engineering - 1.4.5-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild + * Thu Feb 4 2011 Tomas Mraz 1.4.5-6 - fix a bug in the fips-186-3 dsa parameter generation code From d1e5e2486acdcab43f88ae6ac3c4253dcc87cf1e Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 11 Feb 2011 19:53:59 +0100 Subject: [PATCH 037/214] - new upstream version with minor changes --- .gitignore | 1 + libgcrypt.spec | 7 +++++-- sources | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 1e51c05..3259611 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ libgcrypt-1.4.5-hobbled.tar.bz2 +/libgcrypt-1.4.6-hobbled.tar.bz2 diff --git a/libgcrypt.spec b/libgcrypt.spec index ebfe2e8..8a4cd73 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.4.5 -Release: 7%{?dist} +Version: 1.4.6 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -165,6 +165,9 @@ exit 0 %doc COPYING %changelog +* Fri Feb 11 2011 Tomas Mraz 1.4.6-1 +- new upstream version with minor changes + * Mon Feb 07 2011 Fedora Release Engineering - 1.4.5-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild diff --git a/sources b/sources index 6851e28..be4fd16 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -56a36e06fff2ed0a3b07c901a907db5f libgcrypt-1.4.5-hobbled.tar.bz2 +f89395ced1cec0107d49524f5bf432f9 libgcrypt-1.4.6-hobbled.tar.bz2 From db9fb5d2e7ad8b1850deba0a0c36b711deaf1f10 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 30 May 2011 14:23:11 +0200 Subject: [PATCH 038/214] Make the FIPS-186-3 DSA implementation CAVS testable --- libgcrypt-1.4.6-cavs.patch | 1160 ++++++++++++++++++++++++++++++++++++ libgcrypt.spec | 7 +- 2 files changed, 1166 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.4.6-cavs.patch diff --git a/libgcrypt-1.4.6-cavs.patch b/libgcrypt-1.4.6-cavs.patch new file mode 100644 index 0000000..c41e900 --- /dev/null +++ b/libgcrypt-1.4.6-cavs.patch @@ -0,0 +1,1160 @@ +diff -up libgcrypt-1.4.6/cipher/dsa.c.cavs libgcrypt-1.4.6/cipher/dsa.c +--- libgcrypt-1.4.6/cipher/dsa.c.cavs 2011-05-26 22:03:17.000000000 +0200 ++++ libgcrypt-1.4.6/cipher/dsa.c 2011-05-26 22:03:18.000000000 +0200 +@@ -467,7 +467,6 @@ generate_fips186 (DSA_secret_key *sk, un + initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1, + &initial_seed.seedlen); + } +- + if (use_fips186_2) + ec = _gcry_generate_fips186_2_prime (nbits, qbits, + initial_seed.seed, +@@ -475,13 +474,22 @@ generate_fips186 (DSA_secret_key *sk, un + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen); +- else ++ else if (!domain->p || !domain->q) + ec = _gcry_generate_fips186_3_prime (nbits, qbits, + initial_seed.seed, + initial_seed.seedlen, + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen, NULL); ++ else ++ { ++ /* Domain parameters p and q are given; use them. */ ++ prime_p = mpi_copy (domain->p); ++ prime_q = mpi_copy (domain->q); ++ gcry_assert (mpi_get_nbits (prime_p) == nbits); ++ gcry_assert (mpi_get_nbits (prime_q) == qbits); ++ ec = 0; ++ } + gcry_sexp_release (initial_seed.sexp); + if (ec) + goto leave; +@@ -772,13 +780,12 @@ dsa_generate_ext (int algo, unsigned int + gcry_sexp_release (l1); + gcry_sexp_release (domainsexp); + +- /* Check that all domain parameters are available. */ +- if (!domain.p || !domain.q || !domain.g) ++ /* Check that p and q domain parameters are available. */ ++ if (!domain.p || !domain.q || (!domain.g && !use_fips186)) + { + gcry_mpi_release (domain.p); + gcry_mpi_release (domain.q); + gcry_mpi_release (domain.g); +- gcry_sexp_release (deriveparms); + return GPG_ERR_MISSING_VALUE; + } + +diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_driver.pl +--- libgcrypt-1.4.6/tests/cavs_driver.pl.cavs 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.6/tests/cavs_driver.pl 2011-05-27 21:32:14.000000000 +0200 +@@ -1,9 +1,11 @@ + #!/usr/bin/env perl + # +-# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ ++# $Id: cavs_driver.pl 2124 2010-12-20 07:56:30Z smueller $ + # + # CAVS test driver (based on the OpenSSL driver) + # Written by: Stephan Müller ++# Werner Koch (libgcrypt interface) ++# Tomas Mraz (addition of DSA2) + # Copyright (c) atsec information security corporation + # + # Permission is hereby granted, free of charge, to any person obtaining a copy +@@ -85,13 +87,16 @@ + # T[CBC|CFB??|ECB|OFB]varkey + # T[CBC|CFB??|ECB|OFB]invperm + # T[CBC|CFB??|ECB|OFB]vartext ++# WARNING: TDES in CFB and OFB mode problems see below + # + # ANSI X9.31 RNG + # ANSI931_AES128MCT + # ANSI931_AES128VST + # +-# DSA ++# DSA2 + # PQGGen ++# PQGVer ++# KeyPair + # SigGen + # SigVer + # +@@ -101,6 +106,36 @@ + # RC4PltBD + # RC4REGT + # ++# ++# TDES MCT for CFB and OFB: ++# ------------------------- ++# The inner loop cannot be handled by this script. If you want to have tests ++# for these cipher types, implement your own inner loop and add it to ++# crypto_mct. ++# ++# the value $next_source in crypto_mct is NOT set by the standard implementation ++# of this script. It would need to be set as follows for these two (code take ++# from fipsdrv.c from libgcrypt - the value input at the end will contain the ++# the value for $next_source: ++# ++# ... inner loop ... ++# ... ++# get_current_iv (hd, last_iv, blocklen); ++# ... encrypt / decrypt (input is the data to be en/decrypted and output is the ++# result of operation) ... ++# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) ++# memcpy (input, last_iv, blocklen); ++# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) ++# memcpy (input, last_iv, blocklen); ++# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) ++# { ++# /* Reconstruct the output vector. */ ++# int i; ++# for (i=0; i < blocklen; i++) ++# input[i] ^= output[i]; ++# } ++# ... inner loop ends ... ++# ==> now, the value of input is to be put into $next_source + + use strict; + use warnings; +@@ -226,6 +261,8 @@ my $hmac; + # Generate the P, Q, G, Seed, counter, h (value used to generate g) values + # for DSA + # $1: modulus size ++# $2: q size ++# $3: seed (might be empty string) + # return: string with the calculated values in hex format, where each value + # is separated from the previous with a \n in the following order: + # P\n +@@ -236,6 +273,19 @@ my $hmac; + # h + my $dsa_pqggen; + ++# Generate the G value from P and Q ++# for DSA ++# $1: modulus size ++# $2: q size ++# $3: P in hex form ++# $4: Q in hex form ++# return: string with the calculated values in hex format, where each value ++# is separated from the previous with a \n in the following order: ++# P\n ++# Q\n ++# G\n ++my $dsa_ggen; ++ + # + # Generate an DSA public key from the provided parameters: + # $1: Name of file to create +@@ -255,10 +305,20 @@ my $dsa_verify; + + # generate a new DSA key with the following properties: + # PEM format +-# $1 keyfile name +-# return: file created, hash with keys of P, Q, G in hex format ++# $1: modulus size ++# $2: q size ++# $3 keyfile name ++# return: file created with key, string with values of P, Q, G in hex format + my $gen_dsakey; + ++# generate a new DSA private key XY parameters in domain: ++# PEM format ++# $1: P in hex form ++# $2: Q in hex form ++# $3: G in hex form ++# return: string with values of X, Y in hex format ++my $gen_dsakey_domain; ++ + # Sign a message with DSA + # $1: data to be signed in hex form + # $2: Key file in PEM format with the private key +@@ -500,17 +560,32 @@ sub libgcrypt_hmac($$$$) { + return pipe_through_program($msg, $program); + } + +-sub libgcrypt_dsa_pqggen($) { ++sub libgcrypt_dsa_pqggen($$$) { + my $mod = shift; ++ my $qsize = shift; ++ my $seed = shift; ++ ++ my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; ++ return pipe_through_program($seed, $program); ++} + +- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; ++sub libgcrypt_dsa_ggen($$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $domain = "(domain (p #$p#)(q #$q#))"; ++ ++ my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; + return pipe_through_program("", $program); + } + +-sub libgcrypt_gen_dsakey($) { ++sub libgcrypt_gen_dsakey($$$) { ++ my $mod = shift; ++ my $qsize = shift; + my $file = shift; + +- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; ++ my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; + my $tmp; + my %ret; + +@@ -519,10 +594,21 @@ sub libgcrypt_gen_dsakey($) { + $tmp = pipe_through_program("", $program); + die "dsa key gen failed: file $file not created" if (! -f $file); + +- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); ++ @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); + return %ret; + } + ++sub libgcrypt_gen_dsakey_domain($$$) { ++ my $p = shift; ++ my $q = shift; ++ my $g = shift; ++ my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; ++ ++ my $program = "fipsdrv --key '$domain' dsa-gen-key"; ++ ++ return pipe_through_program("", $program); ++} ++ + sub libgcrypt_dsa_genpubkey($$$$$) { + my $filename = shift; + my $p = shift; +@@ -1139,7 +1225,7 @@ sub hmac_kat($$$$) { + $out .= "Tlen = $tlen\n"; + $out .= "Key = $key\n"; + $out .= "Msg = $msg\n"; +- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; ++ $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; + + return $out; + } +@@ -1205,7 +1291,7 @@ sub crypto_mct($$$$$$$$) { + } + my ($CO, $CI); + my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); +- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); ++ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); + my $pid = open2($CO, $CI, $cipher_imp); + + my $calc_data = $iv; # CT[j] +@@ -1213,8 +1299,8 @@ sub crypto_mct($$$$$$$$) { + my $old_old_calc_data; # CT[j-2] + my $next_source; + +- # TDES inner loop implements logic within driver +- if ($cipher =~ /des/) { ++ # TDES inner loop implements logic within driver of libgcrypt ++ if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { + # Need to provide a dummy IV in case of ECB mode. + my $iv_arg = (defined($iv) && $iv ne "") + ? bin2hex($iv) +@@ -1238,6 +1324,10 @@ sub crypto_mct($$$$$$$$) { + $line = <$CO>; + } else { + for (my $j = 0; $j < $iloop; ++$j) { ++ if ($cipher =~ /des-ede3-ofb/ || ++ (!$enc && $cipher =~ /des-ede3-cfb/)) { ++ die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; ++ } + $old_old_calc_data = $old_calc_data; + $old_calc_data = $calc_data; + +@@ -1503,21 +1593,23 @@ sub rngx931($$$$) { + return $out; + } + +-# DSA PQGGen test ++# DSA PQGen test + # $1 modulus size +-# $2 number of rounds to perform the test ++# $2 q size ++# $3 number of rounds to perform the test + # return: string formatted as expected by CAVS +-sub dsa_pqggen_driver($$) { ++sub dsa_pqgen_driver($$$) { + my $mod = shift; ++ my $qsize = shift; + my $rounds = shift; + + my $out = ""; + for(my $i=0; $i<$rounds; $i++) { +- my $ret = &$dsa_pqggen($mod); ++ my $ret = &$dsa_pqggen($mod, $qsize, ""); + my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); +- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" +- if (!defined($P) || !defined($Q) || !defined($G) || +- !defined($Seed) || !defined($c) || !defined($H)); ++ die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || ++ !defined($Seed) || !defined($c)); + + # now change the counter to decimal as CAVS wants decimal + # counter value although all other is HEX +@@ -1525,15 +1617,149 @@ sub dsa_pqggen_driver($$) { + + $out .= "P = $P\n"; + $out .= "Q = $Q\n"; +- $out .= "G = $G\n"; +- $out .= "Seed = $Seed\n"; +- $out .= "c = $c\n"; +- $out .= "H = $H\n\n"; ++ $out .= "domain_parameter_seed = $Seed\n"; ++ $out .= "counter = $c\n\n"; ++ } ++ ++ return $out; ++} ++ ++# DSA GGen test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# return: string formatted as expected by CAVS ++sub dsa_ggen_driver($$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_ggen($mod, $qsize, $p, $q); ++ my ($P, $Q, $G) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G for dsa_ggen" ++ if (!defined($P) || !defined($Q) || !defined($G)); ++ ++ $out .= "G = $G\n\n"; ++ ++ return $out; ++} ++ ++# DSA PQVer test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# $5 seed in hex form ++# $6 c decimal counter ++# return: string formatted as expected by CAVS ++sub dsa_pqver_driver($$$$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $seed = shift; ++ my $c = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_pqggen($mod, $qsize, $seed); ++ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || !defined($G) || ++ !defined($seed2) || !defined($c2)); ++ ++ $c2 = hex($c2); ++ ++ $out .= "Seed = $seed\n"; ++ $out .= "c = $c\n"; ++ ++ if ($P eq $p && $Q eq $q && $seed eq lc $seed2 && $c eq $c2) { ++ $out .= "Result = P\n\n"; ++ } ++ else { ++ $out .= "Result = F\n\n"; ++ } ++ return $out; ++} ++ ++# DSA PQGVer test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# $5 g in hex form ++# $6 seed in hex form ++# $7 c decimal counter ++# $8 h in hex form ++# return: string formatted as expected by CAVS ++sub dsa_pqgver_driver($$$$$$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $g = shift; ++ my $seed = shift; ++ my $c = shift; ++ my $h = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_pqggen($mod, $qsize, $seed); ++ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || !defined($G) || ++ !defined($seed2) || !defined($c2) || !defined($h2)); ++ ++ ++ ++ $out .= "Seed = $seed\n"; ++ $out .= "c = $c\n"; ++ $out .= "H = $h\n"; ++ ++ $c2 = hex($c2); ++ ++ if ($P eq $p && $Q eq $q && $G eq $g && $seed eq lc $seed2 && ++ $c eq $c2 && hex($h) == hex($h2)) { ++ $out .= "Result = P\n\n"; ++ } ++ else { ++ $out .= "Result = F\n\n"; + } + + return $out; + } + ++# DSA Keypair test ++# $1 modulus size ++# $2 q size ++# $3 number of rounds to perform the test ++# return: string formatted as expected by CAVS ++sub dsa_keypair_driver($$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $rounds = shift; ++ ++ my $out = ""; ++ my $tmpkeyfile = "dsa_siggen.tmp.$$"; ++ my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); ++ $out .= "P = " . $pqg{'P'} . "\n"; ++ $out .= "Q = " . $pqg{'Q'} . "\n"; ++ $out .= "G = " . $pqg{'G'} . "\n\n"; ++ unlink($tmpkeyfile); ++ ++ for(my $i=0; $i<$rounds; $i++) { ++ my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); ++ my ($X, $Y) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" ++ if (!defined($X) || !defined($Y)); ++ ++ $out .= "X = $X\n"; ++ $out .= "Y = $Y\n\n"; ++ } ++ ++ return $out; ++} + + # DSA SigGen test + # $1: Message to be signed in hex form +@@ -1658,12 +1884,16 @@ sub parse($$) { + my $klen = ""; + my $tlen = ""; + my $modulus = ""; ++ my $qsize = ""; + my $capital_n = 0; ++ my $num = 0; + my $capital_p = ""; + my $capital_q = ""; + my $capital_g = ""; + my $capital_y = ""; + my $capital_r = ""; ++ my $capital_h = ""; ++ my $c = ""; + my $xp1 = ""; + my $xp2 = ""; + my $Xp = ""; +@@ -1700,7 +1930,7 @@ sub parse($$) { + + ##### Extract cipher + # XXX there may be more - to be added +- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { ++ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyPair|PQGVer)/) { + if ($tmpline =~ /CBC/) { $mode="cbc"; } + elsif ($tmpline =~ /ECB/) { $mode="ecb"; } + elsif ($tmpline =~ /OFB/) { $mode="ofb"; } +@@ -1749,7 +1979,15 @@ sub parse($$) { + + if ($tt == 0) { + ##### Identify the test type +- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { ++ if ($tmpline =~ /PQGVer/) { ++ $tt = 16; ++ die "Interface function for DSA PQGVer testing not defined for tested library" ++ if (!defined($dsa_pqggen)); ++ } elsif ($tmpline =~ /KeyPair/) { ++ $tt = 14; ++ die "Interface function dsa_keygen for DSA key generation not defined for tested library" ++ if (!defined($gen_dsakey_domain)); ++ } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { + $tt = 13; + die "Interface function rsa_derive for RSA key generation not defined for tested library" + if (!defined($rsa_derive)); +@@ -1760,11 +1998,11 @@ sub parse($$) { + } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { + $tt = 11; + die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" +- if (!defined($dsa_sign) || !defined($gen_rsakey)); ++ if (!defined($dsa_sign) || !defined($gen_dsakey)); + } elsif ($tmpline =~ /PQGGen/) { + $tt = 10; + die "Interface function for DSA PQGGen testing not defined for tested library" +- if (!defined($dsa_pqggen)); ++ if (!defined($dsa_pqggen) || !defined($dsa_ggen)); + } elsif ($tmpline =~ /Hash sizes tested/) { + $tt = 9; + die "Interface function hmac for HMAC testing not defined for tested library" +@@ -1792,7 +2030,7 @@ sub parse($$) { + } elsif ($tmpline =~ /Monte|MCT|Carlo/) { + $tt = 2; + die "Interface function state_cipher for Stateful Cipher operation defined for tested library" +- if (!defined($state_cipher) || !defined($state_cipher_des)); ++ if (!defined($state_cipher) && !defined($state_cipher_des)); + } elsif ($cipher =~ /^sha/) { + $tt = 3; + die "Interface function hash for Hashing not defined for tested library" +@@ -1875,18 +2113,44 @@ sub parse($$) { + die "Msg/Seed seen twice - input file crap" if ($pt ne ""); + $pt=$2; + } +- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests ++ elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request ++ $out .= $line . "\n"; # print it ++ if ($tt == 10) { ++ # now generate G from PQ ++ $tt = 15; ++ } ++ } ++ elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request ++ $out .= $line . "\n"; # print it ++ if ($tt == 16) { ++ # now verify PQG ++ $tt = 17; ++ } ++ } ++ elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests + $modulus = $1; ++ $qsize = $2; + $out .= $line . "\n\n"; # print it ++ # clear eventual PQG ++ $capital_p = ""; ++ $capital_q = ""; ++ $capital_g = ""; + # generate the private key with given bit length now + # as we have the required key length in bit + if ($tt == 11) { + $dsa_keyfile = "dsa_siggen.tmp.$$"; +- my %pqg = &$gen_dsakey($dsa_keyfile); ++ my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); + $out .= "P = " . $pqg{'P'} . "\n"; + $out .= "Q = " . $pqg{'Q'} . "\n"; +- $out .= "G = " . $pqg{'G'} . "\n"; +- } elsif ( $tt == 5 ) { ++ $out .= "G = " . $pqg{'G'} . "\n\n"; ++ } ++ } ++ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests ++ $modulus = $1; ++ $out .= $line . "\n\n"; # print it ++ # generate the private key with given bit length now ++ # as we have the required key length in bit ++ if ( $tt == 5 ) { + # XXX maybe a secure temp file name is better here + # but since it is not run on a security sensitive + # system, I hope that this is fine +@@ -1932,11 +2196,16 @@ sub parse($$) { + if ($tlen ne ""); + $tlen=$1; + } +- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen ++ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair + die "N seen twice - check input file" + if ($capital_n); + $capital_n = $1; + } ++ elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen ++ die "Num seen twice - check input file" ++ if ($num); ++ $num = $1; ++ } + elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer + die "P seen twice - check input file" + if ($capital_p); +@@ -1965,6 +2234,16 @@ sub parse($$) { + if ($capital_r); + $capital_r = $1; + } ++ elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer ++ die "H seen twice - check input file" ++ if ($capital_h); ++ $capital_h = $1; ++ } ++ elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer ++ die "c seen twice - check input file" ++ if ($c); ++ $c = $1; ++ } + elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen + die "xp1 seen twice - check input file" + if ($xp1); +@@ -2074,11 +2353,10 @@ sub parse($$) { + } + } + elsif ($tt == 10) { +- if ($modulus ne "" && $capital_n > 0) { +- $out .= dsa_pqggen_driver($modulus, $capital_n); +- #$mod is not resetted +- $capital_n = 0; +- } ++ if ($modulus ne "" && $qsize ne "" && $num > 0) { ++ $out .= dsa_pqgen_driver($modulus, $qsize, $num); ++ $num = 0; ++ } + } + elsif ($tt == 11) { + if ($pt ne "" && $dsa_keyfile ne "") { +@@ -2141,6 +2419,74 @@ sub parse($$) { + $Xq = ""; + } + } ++ elsif ($tt == 14) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_n > 0) { ++ $out .= dsa_keypair_driver($modulus, ++ $qsize, ++ $capital_n); ++ $capital_n = 0; ++ } ++ } ++ elsif ($tt == 15) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "") { ++ $out .= dsa_ggen_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q); ++ $capital_p = ""; ++ $capital_q = ""; ++ $num--; ++ } ++ } ++ elsif ($tt == 16) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "" && ++ $pt ne "" && ++ $c ne "") { ++ $out .= dsa_pqver_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q, ++ $pt, ++ $c); ++ $capital_p = ""; ++ $capital_q = ""; ++ $pt = ""; ++ $c = ""; ++ } ++ } ++ elsif ($tt == 17) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "" && ++ $capital_g ne "" && ++ $pt ne "" && ++ $c ne "" && ++ $capital_h ne "") { ++ $out .= dsa_pqgver_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q, ++ $capital_g, ++ $pt, ++ $c, ++ $capital_h); ++ $capital_p = ""; ++ $capital_q = ""; ++ $capital_g = ""; ++ $pt = ""; ++ $c = ""; ++ $capital_h = ""; ++ } ++ } + elsif ($tt > 0) { + die "Test case $tt not defined"; + } +@@ -2199,7 +2545,9 @@ sub main() { + $state_rng = \&libgcrypt_state_rng; + $hmac = \&libgcrypt_hmac; + $dsa_pqggen = \&libgcrypt_dsa_pqggen; ++ $dsa_ggen = \&libgcrypt_dsa_ggen; + $gen_dsakey = \&libgcrypt_gen_dsakey; ++ $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; + $dsa_sign = \&libgcrypt_dsa_sign; + $dsa_verify = \&libgcrypt_dsa_verify; + $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; +diff -up libgcrypt-1.4.6/tests/cavs_tests.sh.cavs libgcrypt-1.4.6/tests/cavs_tests.sh +--- libgcrypt-1.4.6/tests/cavs_tests.sh.cavs 2011-05-26 21:02:02.000000000 +0200 ++++ libgcrypt-1.4.6/tests/cavs_tests.sh 2011-05-26 22:20:20.000000000 +0200 +@@ -55,7 +55,7 @@ function run_one_test () { + [ -d "$respdir" ] || mkdir "$respdir" + [ -f "$rspfile" ] && rm "$rspfile" + +- if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then ++ if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then + dflag="-D" + fi + +diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c +--- libgcrypt-1.4.6/tests/fipsdrv.c.cavs 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.6/tests/fipsdrv.c 2011-05-27 18:03:11.000000000 +0200 +@@ -893,9 +893,12 @@ print_mpi_line (gcry_mpi_t a, int no_lz) + die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); + + p = buf; ++ while (*p) ++ *p++ = tolower(*p); ++ p = buf; + if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) + p += 2; +- ++ + printf ("%s\n", p); + if (ferror (stdout)) + writerr++; +@@ -1675,14 +1678,14 @@ run_rsa_verify (const void *data, size_t + /* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ + static gcry_sexp_t +-dsa_gen (int keysize) ++dsa_gen (int keysize, int qsize) + { + gpg_error_t err; + gcry_sexp_t keyspec, key; + + err = gcry_sexp_build (&keyspec, NULL, +- "(genkey (dsa (nbits %d)(use-fips186-2)))", +- keysize); ++ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", ++ keysize, qsize); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); +@@ -1700,7 +1703,7 @@ dsa_gen (int keysize) + /* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ + static gcry_sexp_t +-dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) ++dsa_gen_with_seed (int keysize, int qsize, const void *seed, size_t seedlen) + { + gpg_error_t err; + gcry_sexp_t keyspec, key; +@@ -1709,10 +1712,11 @@ dsa_gen_with_seed (int keysize, const vo + "(genkey" + " (dsa" + " (nbits %d)" +- " (use-fips186-2)" ++ " (qbits %d)" ++ " (use-fips186)" + " (derive-parms" + " (seed %b))))", +- keysize, (int)seedlen, seed); ++ keysize, qsize, (int)seedlen, seed); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); +@@ -1726,13 +1730,44 @@ dsa_gen_with_seed (int keysize, const vo + return key; + } + ++/* Generate a DSA key with specified domain parameters and return the complete ++ S-expression. */ ++static gcry_sexp_t ++dsa_gen_key (const char *domain) ++{ ++ gpg_error_t err; ++ gcry_sexp_t keyspec, key, domspec; ++ ++ err = gcry_sexp_new (&domspec, domain, strlen(domain), 0); ++ if (err) ++ die ("gcry_sexp_build failed for domain spec: %s\n", ++ gpg_strerror (err)); ++ ++ err = gcry_sexp_build (&keyspec, NULL, ++ "(genkey" ++ " (dsa" ++ " (use-fips186)" ++ " %S))", ++ domspec); ++ if (err) ++ die ("gcry_sexp_build failed for DSA key generation: %s\n", ++ gpg_strerror (err)); ++ err = gcry_pk_genkey (&key, keyspec); ++ if (err) ++ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); ++ ++ gcry_sexp_release (keyspec); ++ ++ return key; ++} ++ + + /* Print the domain parameter as well as the derive information. KEY + is the complete key as returned by dsa_gen. We print to stdout + with one parameter per line in hex format using this order: p, q, + g, seed, counter, h. */ + static void +-print_dsa_domain_parameters (gcry_sexp_t key) ++print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) + { + gcry_sexp_t l1, l2; + gcry_mpi_t mpi; +@@ -1768,6 +1803,9 @@ print_dsa_domain_parameters (gcry_sexp_t + } + gcry_sexp_release (l1); + ++ if (!print_misc) ++ return; ++ + /* Extract the seed values. */ + l1 = gcry_sexp_find_token (key, "misc-key-info", 0); + if (!l1) +@@ -1819,38 +1857,106 @@ print_dsa_domain_parameters (gcry_sexp_t + } + + +-/* Generate DSA domain parameters for a modulus size of KEYSIZE. The ++/* Print just the XY private key parameters. KEY ++ is the complete key as returned by dsa_gen. We print to stdout ++ with one parameter per line in hex format using this order: x, y. */ ++static void ++print_dsa_xy (gcry_sexp_t key) ++{ ++ gcry_sexp_t l1, l2; ++ gcry_mpi_t mpi; ++ int idx; ++ ++ l1 = gcry_sexp_find_token (key, "private-key", 0); ++ if (!l1) ++ die ("private key not found in genkey result\n"); ++ ++ l2 = gcry_sexp_find_token (l1, "dsa", 0); ++ if (!l2) ++ die ("returned private key not formed as expected\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ /* Extract the parameters from the S-expression and print them to stdout. */ ++ for (idx=0; "xy"[idx]; idx++) ++ { ++ l2 = gcry_sexp_find_token (l1, "xy"+idx, 1); ++ if (!l2) ++ die ("no %c parameter in returned public key\n", "xy"[idx]); ++ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); ++ if (!mpi) ++ die ("no value for %c parameter in returned private key\n","xy"[idx]); ++ gcry_sexp_release (l2); ++ if (standalone_mode) ++ printf ("%c = ", "XY"[idx]); ++ print_mpi_line (mpi, 1); ++ gcry_mpi_release (mpi); ++ } ++ ++ gcry_sexp_release (l1); ++} ++ ++ ++/* Generate DSA pq domain parameters for a modulus size of KEYSIZE. The + result is printed to stdout with one parameter per line in hex +- format and in this order: p, q, g, seed, counter, h. If SEED is ++ format and in this order: p, q, seed, counter. If SEED is + not NULL this seed value will be used for the generation. */ + static void +-run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) ++run_dsa_pqg_gen (int keysize, int qsize, const void *seed, size_t seedlen) + { + gcry_sexp_t key; + + if (seed) +- key = dsa_gen_with_seed (keysize, seed, seedlen); ++ key = dsa_gen_with_seed (keysize, qsize, seed, seedlen); + else +- key = dsa_gen (keysize); +- print_dsa_domain_parameters (key); ++ key = dsa_gen (keysize, qsize); ++ print_dsa_domain_parameters (key, 1); ++ gcry_sexp_release (key); ++} ++ ++ ++/* Generate DSA domain parameters for a modulus size of KEYSIZE. The ++ result is printed to stdout with one parameter per line in hex ++ format and in this order: p, q, g, seed, counter, h. If SEED is ++ not NULL this seed value will be used for the generation. */ ++static void ++run_dsa_g_gen (int keysize, int qsize, const char *domain) ++{ ++ gcry_sexp_t key; ++ ++ key = dsa_gen_key (domain); ++ print_dsa_domain_parameters (key, 0); ++ gcry_sexp_release (key); ++} ++ ++/* Generate a DSA key with specified domain parameters ++ and print the XY values. */ ++static void ++run_dsa_gen_key (const char *domain) ++{ ++ gcry_sexp_t key; ++ ++ key = dsa_gen_key (domain); ++ print_dsa_xy (key); ++ + gcry_sexp_release (key); + } + + + /* Generate a DSA key of size of KEYSIZE and write the private key to + FILENAME. Also write the parameters to stdout in the same way as +- run_dsa_pqg_gen. */ ++ run_dsa_g_gen. */ + static void +-run_dsa_gen (int keysize, const char *filename) ++run_dsa_gen (int keysize, int qsize, const char *filename) + { + gcry_sexp_t key, private_key; + FILE *fp; + +- key = dsa_gen (keysize); ++ key = dsa_gen (keysize, qsize); + private_key = gcry_sexp_find_token (key, "private-key", 0); + if (!private_key) + die ("private key not found in genkey result\n"); +- print_dsa_domain_parameters (key); ++ print_dsa_domain_parameters (key, 1); + + fp = fopen (filename, "wb"); + if (!fp) +@@ -1863,6 +1969,53 @@ run_dsa_gen (int keysize, const char *fi + } + + ++static int ++dsa_hash_from_key(gcry_sexp_t s_key) ++{ ++ gcry_sexp_t l1, l2; ++ gcry_mpi_t q; ++ unsigned int qbits; ++ ++ l1 = gcry_sexp_find_token (s_key, "public-key", 0); ++ if (!l1) ++ { ++ l1 = gcry_sexp_find_token (s_key, "private-key", 0); ++ if (!l1) ++ die ("neither private nor public key found in the loaded key\n"); ++ } ++ ++ l2 = gcry_sexp_find_token (l1, "dsa", 0); ++ if (!l2) ++ die ("public key not formed as expected - no dsa\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ l2 = gcry_sexp_find_token (l1, "q", 0); ++ if (!l2) ++ die ("public key not formed as expected - no q\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); ++ if (!q) ++ die ("public key not formed as expected - no mpi in q\n"); ++ qbits = gcry_mpi_get_nbits(q); ++ gcry_sexp_release(l1); ++ gcry_mpi_release(q); ++ switch(qbits) ++ { ++ case 160: ++ return GCRY_MD_SHA1; ++ case 224: ++ return GCRY_MD_SHA224; ++ case 256: ++ return GCRY_MD_SHA256; ++ default: ++ die("bad number bits (%d) of q in key\n", qbits); ++ } ++ return GCRY_MD_NONE; ++} ++ + + /* Sign DATA of length DATALEN using the key taken from the S-expression + encoded KEYFILE. */ +@@ -1872,11 +2025,16 @@ run_dsa_sign (const void *data, size_t d + { + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; +- char hash[20]; ++ char hash[128]; + gcry_mpi_t tmpmpi; ++ int algo; ++ ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); + +- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); +- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); ++ gcry_md_hash_buffer (algo, hash, data, datalen); ++ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, ++ gcry_md_get_algo_dlen(algo), NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, +@@ -1887,8 +2045,6 @@ run_dsa_sign (const void *data, size_t d + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + +- s_key = read_sexp_from_file (keyfile); +- + err = gcry_pk_sign (&s_sig, s_data, s_key); + if (err) + { +@@ -1964,13 +2120,18 @@ run_dsa_verify (const void *data, size_t + { + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig; +- char hash[20]; ++ char hash[128]; + gcry_mpi_t tmpmpi; ++ int algo; ++ ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); + +- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); ++ gcry_md_hash_buffer (algo, hash, data, datalen); + /* Note that we can't simply use %b with HASH to build the + S-expression, because that might yield a negative value. */ +- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); ++ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, ++ gcry_md_get_algo_dlen(algo), NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, +@@ -1981,7 +2142,6 @@ run_dsa_verify (const void *data, size_t + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + +- s_key = read_sexp_from_file (keyfile); + s_sig = read_sexp_from_file (sigfile); + + err = gcry_pk_verify (s_sig, s_data, s_key); +@@ -2014,7 +2174,7 @@ usage (int show_help) + "Run a crypto operation using hex encoded input and output.\n" + "MODE:\n" + " encrypt, decrypt, digest, random, hmac-sha,\n" +- " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" ++ " rsa-{derive,gen,sign,verify}, dsa-{pq-gen,g-gen,gen,sign,verify}\n" + "OPTIONS:\n" + " --verbose Print additional information\n" + " --binary Input and output is in binary form\n" +@@ -2024,6 +2184,7 @@ usage (int show_help) + " --dt DT Use the hex encoded DT for the RNG\n" + " --algo NAME Use algorithm NAME\n" + " --keysize N Use a keysize of N bits\n" ++ " --qize N Use a DSA q parameter size of N bits\n" + " --signature NAME Take signature from file NAME\n" + " --chunk N Read in chunks of N bytes (implies --binary)\n" + " --pkcs1 Use PKCS#1 encoding\n" +@@ -2050,6 +2211,7 @@ main (int argc, char **argv) + const char *dt_string = NULL; + const char *algo_string = NULL; + const char *keysize_string = NULL; ++ const char *qsize_string = NULL; + const char *signature_string = NULL; + FILE *input; + void *data; +@@ -2143,6 +2305,14 @@ main (int argc, char **argv) + keysize_string = *argv; + argc--; argv++; + } ++ else if (!strcmp (*argv, "--qsize")) ++ { ++ argc--; argv++; ++ if (!argc) ++ usage (0); ++ qsize_string = *argv; ++ argc--; argv++; ++ } + else if (!strcmp (*argv, "--signature")) + { + argc--; argv++; +@@ -2463,23 +2633,49 @@ main (int argc, char **argv) + } + else if (!strcmp (mode_string, "dsa-pqg-gen")) + { +- int keysize; ++ int keysize, qsize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); +- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); ++ run_dsa_pqg_gen (keysize, qsize, datalen? data:NULL, datalen); ++ } ++ else if (!strcmp (mode_string, "dsa-g-gen")) ++ { ++ int keysize, qsize; ++ ++ keysize = keysize_string? atoi (keysize_string) : 0; ++ if (keysize < 1024 || keysize > 3072) ++ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); ++ if (!key_string) ++ die ("option --key containing pq domain parameters is required in this mode\n"); ++ run_dsa_g_gen (keysize, qsize, key_string); ++ } ++ else if (!strcmp (mode_string, "dsa-gen-key")) ++ { ++ if (!key_string) ++ die ("option --key containing pqg domain parameters is required in this mode\n"); ++ run_dsa_gen_key (key_string); + } + else if (!strcmp (mode_string, "dsa-gen")) + { +- int keysize; ++ int keysize, qsize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); + if (!key_string) + die ("option --key is required in this mode\n"); +- run_dsa_gen (keysize, key_string); ++ run_dsa_gen (keysize, qsize, key_string); + } + else if (!strcmp (mode_string, "dsa-sign")) + { diff --git a/libgcrypt.spec b/libgcrypt.spec index 8a4cd73..59ef62a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.6 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -18,6 +18,8 @@ Patch3: libgcrypt-1.4.5-ImplicitDSOLinking.patch Patch4: libgcrypt-1.4.5-urandom.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen Patch5: libgcrypt-1.4.5-tests.patch +# make the FIPS-186-3 DSA CAVS testable +Patch6: libgcrypt-1.4.6-cavs.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -165,6 +167,9 @@ exit 0 %doc COPYING %changelog +* Mon May 30 2011 Tomas Mraz 1.4.6-2 +- Make the FIPS-186-3 DSA implementation CAVS testable + * Fri Feb 11 2011 Tomas Mraz 1.4.6-1 - new upstream version with minor changes From 7082be2ecdd4c61f24c209f8a135324f23b1a2ee Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 30 May 2011 15:25:11 +0200 Subject: [PATCH 039/214] Make the FIPS-186-3 DSA implementation CAVS testable add configurable source of RNG seed /etc/gcrypt/rngseed in the FIPS mode (#700388) --- libgcrypt.spec | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 59ef62a..9f1a62a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.6 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -18,8 +18,10 @@ Patch3: libgcrypt-1.4.5-ImplicitDSOLinking.patch Patch4: libgcrypt-1.4.5-urandom.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen Patch5: libgcrypt-1.4.5-tests.patch +# add configurable source of RNG seed in the FIPS mode +Patch6: libgcrypt-1.4.5-fips-cfgrandom.patch # make the FIPS-186-3 DSA CAVS testable -Patch6: libgcrypt-1.4.6-cavs.patch +Patch7: libgcrypt-1.4.6-cavs.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -56,6 +58,8 @@ applications using libgcrypt. %patch3 -p1 -b .ImplicitDSOLinking %patch4 -p1 -b .urandom %patch5 -p1 -b .tests +%patch6 -p1 -b .cfgrandom +%patch7 -p1 -b .cavs mv AUTHORS AUTHORS.iso88591 iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS @@ -167,8 +171,10 @@ exit 0 %doc COPYING %changelog -* Mon May 30 2011 Tomas Mraz 1.4.6-2 +* Mon May 30 2011 Tomas Mraz 1.4.6-3 - Make the FIPS-186-3 DSA implementation CAVS testable +- add configurable source of RNG seed /etc/gcrypt/rngseed + in the FIPS mode (#700388) * Fri Feb 11 2011 Tomas Mraz 1.4.6-1 - new upstream version with minor changes From b0d0a7fac3f3216888c55ef6b9fe4aeff1b88b92 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 30 May 2011 15:30:14 +0200 Subject: [PATCH 040/214] Make the FIPS-186-3 DSA implementation CAVS testable add configurable source of RNG seed /etc/gcrypt/rngseed in the FIPS mode (#700388) --- libgcrypt-1.4.5-fips-cfgrandom.patch | 126 +++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 libgcrypt-1.4.5-fips-cfgrandom.patch diff --git a/libgcrypt-1.4.5-fips-cfgrandom.patch b/libgcrypt-1.4.5-fips-cfgrandom.patch new file mode 100644 index 0000000..4fa689d --- /dev/null +++ b/libgcrypt-1.4.5-fips-cfgrandom.patch @@ -0,0 +1,126 @@ +diff -up libgcrypt-1.4.5/random/random-fips.c.cfgrandom libgcrypt-1.4.5/random/random-fips.c +--- libgcrypt-1.4.5/random/random-fips.c.cfgrandom 2011-05-06 10:58:55.000000000 +0200 ++++ libgcrypt-1.4.5/random/random-fips.c 2011-05-06 10:58:55.000000000 +0200 +@@ -27,10 +27,10 @@ + There are 3 random context which map to the different levels of + random quality: + +- Generator Seed and Key Kernel entropy (init/reseed) +- ------------------------------------------------------------ +- GCRY_VERY_STRONG_RANDOM /dev/urandom 256/128 bits +- GCRY_STRONG_RANDOM /dev/urandom 256/128 bits ++ Generator Seed and Key Kernel entropy (init/reseed) ++ --------------------------------------------------------------------------------------- ++ GCRY_VERY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits ++ GCRY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits + gcry_create_nonce GCRY_STRONG_RANDOM n/a + + All random generators return their data in 128 bit blocks. If the +@@ -40,7 +40,10 @@ + (SEED_TTL) output blocks; the re-seeding is disabled in test mode. + + The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are +- keyed and seeded from the /dev/urandom device. ++ keyed and seeded with data that is loaded from the /etc/gcrypt/rngseed ++ if the device or symlink to device exists xored with the data ++ from the /dev/urandom device. This allows the system administrator ++ to always seed the RNGs from /dev/random if it is required. + + The gcry_create_nonce generator is keyed and seeded from the + GCRY_STRONG_RANDOM generator. It may also block if the +@@ -561,7 +564,7 @@ get_entropy (size_t nbytes) + #if USE_RNDLINUX + rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, + X931_AES_KEYLEN, +- GCRY_STRONG_RANDOM); ++ -1); + #elif USE_RNDW32 + do + { +diff -up libgcrypt-1.4.5/random/rndlinux.c.cfgrandom libgcrypt-1.4.5/random/rndlinux.c +--- libgcrypt-1.4.5/random/rndlinux.c.cfgrandom 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.5/random/rndlinux.c 2011-05-06 11:35:39.000000000 +0200 +@@ -35,7 +35,9 @@ + #include "g10lib.h" + #include "rand-internal.h" + +-static int open_device ( const char *name ); ++#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed" ++ ++static int open_device ( const char *name, int fatal ); + + + static int +@@ -56,13 +58,17 @@ set_cloexec_flag (int fd) + * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it exists)). + */ + static int +-open_device ( const char *name ) ++open_device ( const char *name, int fatal ) + { + int fd; + + fd = open ( name, O_RDONLY ); + if ( fd == -1 ) +- log_fatal ("can't open %s: %s\n", name, strerror(errno) ); ++ { ++ if (! fatal) ++ return fd; ++ log_fatal ("can't open %s: %s\n", name, strerror(errno) ); ++ } + + if (set_cloexec_flag (fd)) + log_error ("error setting FD_CLOEXEC on fd %d: %s\n", +@@ -91,11 +97,13 @@ _gcry_rndlinux_gather_random (void (*add + { + static int fd_urandom = -1; + static int fd_random = -1; ++ static int fd_configured = -1; + int fd; + int n; + int warn=0; + byte buffer[768]; + size_t n_hw; ++ size_t orig_length = length; + + /* First read from a hardware source. However let it account only + for up to 50% of the requested bytes. */ +@@ -106,16 +114,26 @@ _gcry_rndlinux_gather_random (void (*add + length -= n_hw; + + /* Open the requested device. */ ++ ++ if (level == -1) ++ { ++ if (fd_configured == -1) ++ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0 ); ++ fd = fd_configured; ++ if (fd == -1) ++ level = 1; ++ } ++ + if (level >= 2) + { + if( fd_random == -1 ) +- fd_random = open_device ( NAME_OF_DEV_RANDOM ); ++ fd_random = open_device ( NAME_OF_DEV_RANDOM, 1 ); + fd = fd_random; + } +- else ++ else if (level != -1) + { + if( fd_urandom == -1 ) +- fd_urandom = open_device ( NAME_OF_DEV_URANDOM ); ++ fd_urandom = open_device ( NAME_OF_DEV_URANDOM, 1 ); + fd = fd_urandom; + } + +@@ -163,5 +181,8 @@ _gcry_rndlinux_gather_random (void (*add + } + memset(buffer, 0, sizeof(buffer) ); + ++ if (level == -1) ++ _gcry_rndlinux_gather_random(add, origin, orig_length, 1); ++ + return 0; /* success */ + } From 9371d8c5fab21915f8c1b29c2d4ce54a30167c24 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 20 Jun 2011 21:40:03 +0200 Subject: [PATCH 041/214] Always xor seed from /dev/urandom over /etc/gcrypt/rngseed --- libgcrypt-1.4.6-cavs.patch | 59 ++++++++++++------- ...ch => libgcrypt-1.4.6-fips-cfgrandom.patch | 37 +++++------- libgcrypt.spec | 7 ++- 3 files changed, 58 insertions(+), 45 deletions(-) rename libgcrypt-1.4.5-fips-cfgrandom.patch => libgcrypt-1.4.6-fips-cfgrandom.patch (81%) diff --git a/libgcrypt-1.4.6-cavs.patch b/libgcrypt-1.4.6-cavs.patch index c41e900..b23129b 100644 --- a/libgcrypt-1.4.6-cavs.patch +++ b/libgcrypt-1.4.6-cavs.patch @@ -51,7 +51,7 @@ diff -up libgcrypt-1.4.6/cipher/dsa.c.cavs libgcrypt-1.4.6/cipher/dsa.c diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_driver.pl --- libgcrypt-1.4.6/tests/cavs_driver.pl.cavs 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.6/tests/cavs_driver.pl 2011-05-27 21:32:14.000000000 +0200 ++++ libgcrypt-1.4.6/tests/cavs_driver.pl 2011-06-20 20:00:13.000000000 +0200 @@ -1,9 +1,11 @@ #!/usr/bin/env perl # @@ -178,22 +178,22 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr -sub libgcrypt_dsa_pqggen($) { +sub libgcrypt_dsa_pqggen($$$) { - my $mod = shift; ++ my $mod = shift; + my $qsize = shift; + my $seed = shift; + + my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; + return pipe_through_program($seed, $program); +} - -- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; ++ +sub libgcrypt_dsa_ggen($$$$) { -+ my $mod = shift; + my $mod = shift; + my $qsize = shift; + my $p = shift; + my $q = shift; + my $domain = "(domain (p #$p#)(q #$q#))"; -+ + +- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; + my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; return pipe_through_program("", $program); } @@ -303,7 +303,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr # now change the counter to decimal as CAVS wants decimal # counter value although all other is HEX -@@ -1525,15 +1617,149 @@ sub dsa_pqggen_driver($$) { +@@ -1525,15 +1617,166 @@ sub dsa_pqggen_driver($$) { $out .= "P = $P\n"; $out .= "Q = $Q\n"; @@ -341,6 +341,23 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr + return $out; +} + ++sub hexcomp($$) { ++ my $a = lc shift; ++ my $b = lc shift; ++ ++ if (length $a < length $b) { ++ my $c = $a; ++ $a = $b; ++ $b = $a; ++ } ++ ++ while (length $b < length $a) { ++ $b = "00$b"; ++ } ++ ++ return $a eq $b; ++} ++ +# DSA PQVer test +# $1 modulus size +# $2 q size @@ -369,7 +386,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr + $out .= "Seed = $seed\n"; + $out .= "c = $c\n"; + -+ if ($P eq $p && $Q eq $q && $seed eq lc $seed2 && $c eq $c2) { ++ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($seed, $seed2) && $c == $c2) { + $out .= "Result = P\n\n"; + } + else { @@ -413,8 +430,8 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr + + $c2 = hex($c2); + -+ if ($P eq $p && $Q eq $q && $G eq $g && $seed eq lc $seed2 && -+ $c eq $c2 && hex($h) == hex($h2)) { ++ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && ++ $c == $c2 && hex($h) == hex($h2)) { + $out .= "Result = P\n\n"; + } + else { @@ -457,7 +474,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr # DSA SigGen test # $1: Message to be signed in hex form -@@ -1658,12 +1884,16 @@ sub parse($$) { +@@ -1658,12 +1901,16 @@ sub parse($$) { my $klen = ""; my $tlen = ""; my $modulus = ""; @@ -474,7 +491,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr my $xp1 = ""; my $xp2 = ""; my $Xp = ""; -@@ -1700,7 +1930,7 @@ sub parse($$) { +@@ -1700,7 +1947,7 @@ sub parse($$) { ##### Extract cipher # XXX there may be more - to be added @@ -483,7 +500,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr if ($tmpline =~ /CBC/) { $mode="cbc"; } elsif ($tmpline =~ /ECB/) { $mode="ecb"; } elsif ($tmpline =~ /OFB/) { $mode="ofb"; } -@@ -1749,7 +1979,15 @@ sub parse($$) { +@@ -1749,7 +1996,15 @@ sub parse($$) { if ($tt == 0) { ##### Identify the test type @@ -500,7 +517,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr $tt = 13; die "Interface function rsa_derive for RSA key generation not defined for tested library" if (!defined($rsa_derive)); -@@ -1760,11 +1998,11 @@ sub parse($$) { +@@ -1760,11 +2015,11 @@ sub parse($$) { } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { $tt = 11; die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" @@ -514,7 +531,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr } elsif ($tmpline =~ /Hash sizes tested/) { $tt = 9; die "Interface function hmac for HMAC testing not defined for tested library" -@@ -1792,7 +2030,7 @@ sub parse($$) { +@@ -1792,7 +2047,7 @@ sub parse($$) { } elsif ($tmpline =~ /Monte|MCT|Carlo/) { $tt = 2; die "Interface function state_cipher for Stateful Cipher operation defined for tested library" @@ -523,7 +540,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr } elsif ($cipher =~ /^sha/) { $tt = 3; die "Interface function hash for Hashing not defined for tested library" -@@ -1875,18 +2113,44 @@ sub parse($$) { +@@ -1875,18 +2130,44 @@ sub parse($$) { die "Msg/Seed seen twice - input file crap" if ($pt ne ""); $pt=$2; } @@ -572,7 +589,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr # XXX maybe a secure temp file name is better here # but since it is not run on a security sensitive # system, I hope that this is fine -@@ -1932,11 +2196,16 @@ sub parse($$) { +@@ -1932,11 +2213,16 @@ sub parse($$) { if ($tlen ne ""); $tlen=$1; } @@ -590,7 +607,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer die "P seen twice - check input file" if ($capital_p); -@@ -1965,6 +2234,16 @@ sub parse($$) { +@@ -1965,6 +2251,16 @@ sub parse($$) { if ($capital_r); $capital_r = $1; } @@ -607,7 +624,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen die "xp1 seen twice - check input file" if ($xp1); -@@ -2074,11 +2353,10 @@ sub parse($$) { +@@ -2074,11 +2370,10 @@ sub parse($$) { } } elsif ($tt == 10) { @@ -623,7 +640,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr } elsif ($tt == 11) { if ($pt ne "" && $dsa_keyfile ne "") { -@@ -2141,6 +2419,74 @@ sub parse($$) { +@@ -2141,6 +2436,74 @@ sub parse($$) { $Xq = ""; } } @@ -698,7 +715,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr elsif ($tt > 0) { die "Test case $tt not defined"; } -@@ -2199,7 +2545,9 @@ sub main() { +@@ -2199,7 +2562,9 @@ sub main() { $state_rng = \&libgcrypt_state_rng; $hmac = \&libgcrypt_hmac; $dsa_pqggen = \&libgcrypt_dsa_pqggen; diff --git a/libgcrypt-1.4.5-fips-cfgrandom.patch b/libgcrypt-1.4.6-fips-cfgrandom.patch similarity index 81% rename from libgcrypt-1.4.5-fips-cfgrandom.patch rename to libgcrypt-1.4.6-fips-cfgrandom.patch index 4fa689d..574d6a0 100644 --- a/libgcrypt-1.4.5-fips-cfgrandom.patch +++ b/libgcrypt-1.4.6-fips-cfgrandom.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.4.5/random/random-fips.c.cfgrandom libgcrypt-1.4.5/random/random-fips.c ---- libgcrypt-1.4.5/random/random-fips.c.cfgrandom 2011-05-06 10:58:55.000000000 +0200 -+++ libgcrypt-1.4.5/random/random-fips.c 2011-05-06 10:58:55.000000000 +0200 +diff -up libgcrypt-1.4.6/random/random-fips.c.cfgrandom libgcrypt-1.4.6/random/random-fips.c +--- libgcrypt-1.4.6/random/random-fips.c.cfgrandom 2011-06-20 21:13:38.000000000 +0200 ++++ libgcrypt-1.4.6/random/random-fips.c 2011-06-20 21:32:47.000000000 +0200 @@ -27,10 +27,10 @@ There are 3 random context which map to the different levels of random quality: @@ -28,18 +28,20 @@ diff -up libgcrypt-1.4.5/random/random-fips.c.cfgrandom libgcrypt-1.4.5/random/r The gcry_create_nonce generator is keyed and seeded from the GCRY_STRONG_RANDOM generator. It may also block if the -@@ -561,7 +564,7 @@ get_entropy (size_t nbytes) +@@ -559,6 +562,10 @@ get_entropy (size_t nbytes) + entropy_collect_buffer_len = 0; + #if USE_RNDLINUX ++ _gcry_rndlinux_gather_random (entropy_collect_cb, 0, ++ X931_AES_KEYLEN, ++ -1); ++ entropy_collect_buffer_len = 0; rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, X931_AES_KEYLEN, -- GCRY_STRONG_RANDOM); -+ -1); - #elif USE_RNDW32 - do - { -diff -up libgcrypt-1.4.5/random/rndlinux.c.cfgrandom libgcrypt-1.4.5/random/rndlinux.c ---- libgcrypt-1.4.5/random/rndlinux.c.cfgrandom 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/random/rndlinux.c 2011-05-06 11:35:39.000000000 +0200 + GCRY_STRONG_RANDOM); +diff -up libgcrypt-1.4.6/random/rndlinux.c.cfgrandom libgcrypt-1.4.6/random/rndlinux.c +--- libgcrypt-1.4.6/random/rndlinux.c.cfgrandom 2009-04-02 11:25:34.000000000 +0200 ++++ libgcrypt-1.4.6/random/rndlinux.c 2011-06-20 21:34:09.000000000 +0200 @@ -35,7 +35,9 @@ #include "g10lib.h" #include "rand-internal.h" @@ -96,7 +98,7 @@ diff -up libgcrypt-1.4.5/random/rndlinux.c.cfgrandom libgcrypt-1.4.5/random/rndl + fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0 ); + fd = fd_configured; + if (fd == -1) -+ level = 1; ++ return -1; + } + if (level >= 2) @@ -115,12 +117,3 @@ diff -up libgcrypt-1.4.5/random/rndlinux.c.cfgrandom libgcrypt-1.4.5/random/rndl fd = fd_urandom; } -@@ -163,5 +181,8 @@ _gcry_rndlinux_gather_random (void (*add - } - memset(buffer, 0, sizeof(buffer) ); - -+ if (level == -1) -+ _gcry_rndlinux_gather_random(add, origin, orig_length, 1); -+ - return 0; /* success */ - } diff --git a/libgcrypt.spec b/libgcrypt.spec index 9f1a62a..b430412 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.4.6 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -19,7 +19,7 @@ Patch4: libgcrypt-1.4.5-urandom.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen Patch5: libgcrypt-1.4.5-tests.patch # add configurable source of RNG seed in the FIPS mode -Patch6: libgcrypt-1.4.5-fips-cfgrandom.patch +Patch6: libgcrypt-1.4.6-fips-cfgrandom.patch # make the FIPS-186-3 DSA CAVS testable Patch7: libgcrypt-1.4.6-cavs.patch @@ -171,6 +171,9 @@ exit 0 %doc COPYING %changelog +* Mon Jun 20 2011 Tomas Mraz 1.4.6-4 +- Always xor seed from /dev/urandom over /etc/gcrypt/rngseed + * Mon May 30 2011 Tomas Mraz 1.4.6-3 - Make the FIPS-186-3 DSA implementation CAVS testable - add configurable source of RNG seed /etc/gcrypt/rngseed From b5054585fee31a6c0a42cd6e42fca02e747d53f7 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 21 Jul 2011 15:57:57 +0200 Subject: [PATCH 042/214] new upstream version --- .gitignore | 1 + libgcrypt-1.4.5-ImplicitDSOLinking.patch | 24 ---- libgcrypt-1.4.5-urandom.patch | 33 ------ ...s.patch => libgcrypt-1.5.0-fips-cavs.patch | 109 +++++++++--------- ...ch => libgcrypt-1.5.0-fips-cfgrandom.patch | 43 ++++--- libgcrypt-1.5.0-noecc.patch | 12 ++ ...tests.patch => libgcrypt-1.5.0-tests.patch | 73 ++++++------ ...tch => libgcrypt-1.5.0-use-fipscheck.patch | 25 ++-- libgcrypt.spec | 27 ++--- sources | 2 +- 10 files changed, 157 insertions(+), 192 deletions(-) delete mode 100644 libgcrypt-1.4.5-ImplicitDSOLinking.patch delete mode 100644 libgcrypt-1.4.5-urandom.patch rename libgcrypt-1.4.6-cavs.patch => libgcrypt-1.5.0-fips-cavs.patch (95%) rename libgcrypt-1.4.6-fips-cfgrandom.patch => libgcrypt-1.5.0-fips-cfgrandom.patch (72%) create mode 100644 libgcrypt-1.5.0-noecc.patch rename libgcrypt-1.4.5-tests.patch => libgcrypt-1.5.0-tests.patch (77%) rename libgcrypt-1.4.4-use-fipscheck.patch => libgcrypt-1.5.0-use-fipscheck.patch (77%) diff --git a/.gitignore b/.gitignore index 3259611..2daa2a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.4.6-hobbled.tar.bz2 +/libgcrypt-1.5.0-hobbled.tar.bz2 diff --git a/libgcrypt-1.4.5-ImplicitDSOLinking.patch b/libgcrypt-1.4.5-ImplicitDSOLinking.patch deleted file mode 100644 index 7b4671f..0000000 --- a/libgcrypt-1.4.5-ImplicitDSOLinking.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up libgcrypt-1.4.5/tests/Makefile.am.ImplicitDSOLinking libgcrypt-1.4.5/tests/Makefile.am ---- libgcrypt-1.4.5/tests/Makefile.am.ImplicitDSOLinking 2009-04-02 04:25:34.000000000 -0500 -+++ libgcrypt-1.4.5/tests/Makefile.am 2010-02-14 14:28:49.792383613 -0600 -@@ -36,7 +36,7 @@ TESTS += benchmark - AM_CPPFLAGS = -I../src -I$(top_srcdir)/src - AM_CFLAGS = $(GPG_ERROR_CFLAGS) - --LDADD = ../src/libgcrypt.la $(DL_LIBS) -+LDADD = ../src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) - - EXTRA_PROGRAMS = testapi pkbench - noinst_PROGRAMS = $(TESTS) fipsdrv -diff -up libgcrypt-1.4.5/tests/Makefile.in.ImplicitDSOLinking libgcrypt-1.4.5/tests/Makefile.in ---- libgcrypt-1.4.5/tests/Makefile.in.ImplicitDSOLinking 2009-12-11 09:43:30.000000000 -0600 -+++ libgcrypt-1.4.5/tests/Makefile.in 2010-02-14 14:29:30.232368780 -0600 -@@ -334,7 +334,7 @@ top_srcdir = @top_srcdir@ - # a built header. - AM_CPPFLAGS = -I../src -I$(top_srcdir)/src - AM_CFLAGS = $(GPG_ERROR_CFLAGS) --LDADD = ../src/libgcrypt.la $(DL_LIBS) -+LDADD = ../src/libgcrypt.la $(DL_LIBS) $(GPG_ERROR_LIBS) - EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl - all: all-am - diff --git a/libgcrypt-1.4.5-urandom.patch b/libgcrypt-1.4.5-urandom.patch deleted file mode 100644 index 0bccbfc..0000000 --- a/libgcrypt-1.4.5-urandom.patch +++ /dev/null @@ -1,33 +0,0 @@ -diff -up libgcrypt-1.4.5/random/random-fips.c.urandom libgcrypt-1.4.5/random/random-fips.c ---- libgcrypt-1.4.5/random/random-fips.c.urandom 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/random/random-fips.c 2011-02-01 11:33:59.000000000 +0100 -@@ -29,8 +29,8 @@ - - Generator Seed and Key Kernel entropy (init/reseed) - ------------------------------------------------------------ -- GCRY_VERY_STRONG_RANDOM /dev/random 256/128 bits -- GCRY_STRONG_RANDOM /dev/random 256/128 bits -+ GCRY_VERY_STRONG_RANDOM /dev/urandom 256/128 bits -+ GCRY_STRONG_RANDOM /dev/urandom 256/128 bits - gcry_create_nonce GCRY_STRONG_RANDOM n/a - - All random generators return their data in 128 bit blocks. If the -@@ -40,8 +40,7 @@ - (SEED_TTL) output blocks; the re-seeding is disabled in test mode. - - The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are -- keyed and seeded from the /dev/random device. Thus these -- generators may block until the kernel has collected enough entropy. -+ keyed and seeded from the /dev/urandom device. - - The gcry_create_nonce generator is keyed and seeded from the - GCRY_STRONG_RANDOM generator. It may also block if the -@@ -562,7 +561,7 @@ get_entropy (size_t nbytes) - #if USE_RNDLINUX - rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, - X931_AES_KEYLEN, -- GCRY_VERY_STRONG_RANDOM); -+ GCRY_STRONG_RANDOM); - #elif USE_RNDW32 - do - { diff --git a/libgcrypt-1.4.6-cavs.patch b/libgcrypt-1.5.0-fips-cavs.patch similarity index 95% rename from libgcrypt-1.4.6-cavs.patch rename to libgcrypt-1.5.0-fips-cavs.patch index b23129b..ac999f9 100644 --- a/libgcrypt-1.4.6-cavs.patch +++ b/libgcrypt-1.5.0-fips-cavs.patch @@ -1,7 +1,7 @@ -diff -up libgcrypt-1.4.6/cipher/dsa.c.cavs libgcrypt-1.4.6/cipher/dsa.c ---- libgcrypt-1.4.6/cipher/dsa.c.cavs 2011-05-26 22:03:17.000000000 +0200 -+++ libgcrypt-1.4.6/cipher/dsa.c 2011-05-26 22:03:18.000000000 +0200 -@@ -467,7 +467,6 @@ generate_fips186 (DSA_secret_key *sk, un +diff -up libgcrypt-1.5.0/cipher/dsa.c.cavs libgcrypt-1.5.0/cipher/dsa.c +--- libgcrypt-1.5.0/cipher/dsa.c.cavs 2011-07-21 14:56:35.000000000 +0200 ++++ libgcrypt-1.5.0/cipher/dsa.c 2011-07-21 14:58:06.000000000 +0200 +@@ -479,7 +479,6 @@ generate_fips186 (DSA_secret_key *sk, un initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1, &initial_seed.seedlen); } @@ -9,8 +9,8 @@ diff -up libgcrypt-1.4.6/cipher/dsa.c.cavs libgcrypt-1.4.6/cipher/dsa.c if (use_fips186_2) ec = _gcry_generate_fips186_2_prime (nbits, qbits, initial_seed.seed, -@@ -475,13 +474,22 @@ generate_fips186 (DSA_secret_key *sk, un - &prime_q, &prime_p, +@@ -487,13 +486,22 @@ generate_fips186 (DSA_secret_key *sk, un + &prime_q, &prime_p, r_counter, r_seed, r_seedlen); - else @@ -33,7 +33,7 @@ diff -up libgcrypt-1.4.6/cipher/dsa.c.cavs libgcrypt-1.4.6/cipher/dsa.c gcry_sexp_release (initial_seed.sexp); if (ec) goto leave; -@@ -772,13 +780,12 @@ dsa_generate_ext (int algo, unsigned int +@@ -784,13 +792,12 @@ dsa_generate_ext (int algo, unsigned int gcry_sexp_release (l1); gcry_sexp_release (domainsexp); @@ -49,9 +49,9 @@ diff -up libgcrypt-1.4.6/cipher/dsa.c.cavs libgcrypt-1.4.6/cipher/dsa.c return GPG_ERR_MISSING_VALUE; } -diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_driver.pl ---- libgcrypt-1.4.6/tests/cavs_driver.pl.cavs 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.6/tests/cavs_driver.pl 2011-06-20 20:00:13.000000000 +0200 +diff -up libgcrypt-1.5.0/tests/cavs_driver.pl.cavs libgcrypt-1.5.0/tests/cavs_driver.pl +--- libgcrypt-1.5.0/tests/cavs_driver.pl.cavs 2011-02-04 20:18:20.000000000 +0100 ++++ libgcrypt-1.5.0/tests/cavs_driver.pl 2011-07-21 15:01:47.000000000 +0200 @@ -1,9 +1,11 @@ #!/usr/bin/env perl # @@ -153,11 +153,11 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr # generate a new DSA key with the following properties: # PEM format --# $1 keyfile name +-# $1 keyfile name -# return: file created, hash with keys of P, Q, G in hex format +# $1: modulus size +# $2: q size -+# $3 keyfile name ++# $3 keyfile name +# return: file created with key, string with values of P, Q, G in hex format my $gen_dsakey; @@ -165,7 +165,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr +# PEM format +# $1: P in hex form +# $2: Q in hex form -+# $3: G in hex form ++# $3: G in hex form +# return: string with values of X, Y in hex format +my $gen_dsakey_domain; + @@ -173,7 +173,7 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr # $1: data to be signed in hex form # $2: Key file in PEM format with the private key @@ -500,17 +560,32 @@ sub libgcrypt_hmac($$$$) { - return pipe_through_program($msg, $program); + return pipe_through_program($msg, $program); } -sub libgcrypt_dsa_pqggen($) { @@ -313,11 +313,11 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr - $out .= "H = $H\n\n"; + $out .= "domain_parameter_seed = $Seed\n"; + $out .= "counter = $c\n\n"; -+ } -+ -+ return $out; -+} -+ + } + + return $out; + } + +# DSA GGen test +# $1 modulus size +# $2 q size @@ -436,11 +436,11 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr + } + else { + $out .= "Result = F\n\n"; - } - - return $out; - } - ++ } ++ ++ return $out; ++} ++ +# DSA Keypair test +# $1 modulus size +# $2 q size @@ -725,9 +725,9 @@ diff -up libgcrypt-1.4.6/tests/cavs_driver.pl.cavs libgcrypt-1.4.6/tests/cavs_dr $dsa_sign = \&libgcrypt_dsa_sign; $dsa_verify = \&libgcrypt_dsa_verify; $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; -diff -up libgcrypt-1.4.6/tests/cavs_tests.sh.cavs libgcrypt-1.4.6/tests/cavs_tests.sh ---- libgcrypt-1.4.6/tests/cavs_tests.sh.cavs 2011-05-26 21:02:02.000000000 +0200 -+++ libgcrypt-1.4.6/tests/cavs_tests.sh 2011-05-26 22:20:20.000000000 +0200 +diff -up libgcrypt-1.5.0/tests/cavs_tests.sh.cavs libgcrypt-1.5.0/tests/cavs_tests.sh +--- libgcrypt-1.5.0/tests/cavs_tests.sh.cavs 2011-02-04 20:18:20.000000000 +0100 ++++ libgcrypt-1.5.0/tests/cavs_tests.sh 2011-07-21 15:02:16.000000000 +0200 @@ -55,7 +55,7 @@ function run_one_test () { [ -d "$respdir" ] || mkdir "$respdir" [ -f "$rspfile" ] && rm "$rspfile" @@ -735,12 +735,12 @@ diff -up libgcrypt-1.4.6/tests/cavs_tests.sh.cavs libgcrypt-1.4.6/tests/cavs_tes - if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then + if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then dflag="-D" - fi - -diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c ---- libgcrypt-1.4.6/tests/fipsdrv.c.cavs 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.6/tests/fipsdrv.c 2011-05-27 18:03:11.000000000 +0200 -@@ -893,9 +893,12 @@ print_mpi_line (gcry_mpi_t a, int no_lz) + fi + +diff -up libgcrypt-1.5.0/tests/fipsdrv.c.cavs libgcrypt-1.5.0/tests/fipsdrv.c +--- libgcrypt-1.5.0/tests/fipsdrv.c.cavs 2011-02-04 20:18:20.000000000 +0100 ++++ libgcrypt-1.5.0/tests/fipsdrv.c 2011-07-21 15:06:44.000000000 +0200 +@@ -893,6 +893,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); p = buf; @@ -749,11 +749,7 @@ diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c + p = buf; if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) p += 2; -- -+ - printf ("%s\n", p); - if (ferror (stdout)) - writerr++; + @@ -1675,14 +1678,14 @@ run_rsa_verify (const void *data, size_t /* Generate a DSA key of size KEYSIZE and return the complete S-expression. */ @@ -764,7 +760,7 @@ diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c gpg_error_t err; gcry_sexp_t keyspec, key; - err = gcry_sexp_build (&keyspec, NULL, + err = gcry_sexp_build (&keyspec, NULL, - "(genkey (dsa (nbits %d)(use-fips186-2)))", - keysize); + "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", @@ -795,10 +791,16 @@ diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c if (err) die ("gcry_sexp_build failed for DSA key generation: %s\n", gpg_strerror (err)); -@@ -1726,13 +1730,44 @@ dsa_gen_with_seed (int keysize, const vo - return key; - } - +@@ -1720,6 +1724,37 @@ dsa_gen_with_seed (int keysize, const vo + err = gcry_pk_genkey (&key, keyspec); + if (err) + die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); ++ ++ gcry_sexp_release (keyspec); ++ ++ return key; ++} ++ +/* Generate a DSA key with specified domain parameters and return the complete + S-expression. */ +static gcry_sexp_t @@ -812,7 +814,7 @@ diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c + die ("gcry_sexp_build failed for domain spec: %s\n", + gpg_strerror (err)); + -+ err = gcry_sexp_build (&keyspec, NULL, ++ err = gcry_sexp_build (&keyspec, NULL, + "(genkey" + " (dsa" + " (use-fips186)" @@ -824,18 +826,13 @@ diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c + err = gcry_pk_genkey (&key, keyspec); + if (err) + die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); -+ -+ gcry_sexp_release (keyspec); -+ -+ return key; -+} -+ - /* Print the domain parameter as well as the derive information. KEY - is the complete key as returned by dsa_gen. We print to stdout + gcry_sexp_release (keyspec); + +@@ -1732,7 +1767,7 @@ dsa_gen_with_seed (int keysize, const vo with one parameter per line in hex format using this order: p, q, g, seed, counter, h. */ - static void + static void -print_dsa_domain_parameters (gcry_sexp_t key) +print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) { @@ -1127,7 +1124,7 @@ diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c { - int keysize; + int keysize, qsize; - + keysize = keysize_string? atoi (keysize_string) : 0; if (keysize < 1024 || keysize > 3072) die ("invalid keysize specified; needs to be 1024 .. 3072\n"); @@ -1140,7 +1137,7 @@ diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c + else if (!strcmp (mode_string, "dsa-g-gen")) + { + int keysize, qsize; -+ ++ + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); @@ -1161,7 +1158,7 @@ diff -up libgcrypt-1.4.6/tests/fipsdrv.c.cavs libgcrypt-1.4.6/tests/fipsdrv.c { - int keysize; + int keysize, qsize; - + keysize = keysize_string? atoi (keysize_string) : 0; if (keysize < 1024 || keysize > 3072) die ("invalid keysize specified; needs to be 1024 .. 3072\n"); diff --git a/libgcrypt-1.4.6-fips-cfgrandom.patch b/libgcrypt-1.5.0-fips-cfgrandom.patch similarity index 72% rename from libgcrypt-1.4.6-fips-cfgrandom.patch rename to libgcrypt-1.5.0-fips-cfgrandom.patch index 574d6a0..1384c25 100644 --- a/libgcrypt-1.4.6-fips-cfgrandom.patch +++ b/libgcrypt-1.5.0-fips-cfgrandom.patch @@ -1,14 +1,14 @@ -diff -up libgcrypt-1.4.6/random/random-fips.c.cfgrandom libgcrypt-1.4.6/random/random-fips.c ---- libgcrypt-1.4.6/random/random-fips.c.cfgrandom 2011-06-20 21:13:38.000000000 +0200 -+++ libgcrypt-1.4.6/random/random-fips.c 2011-06-20 21:32:47.000000000 +0200 +diff -up libgcrypt-1.5.0/random/random-fips.c.cfgrandom libgcrypt-1.5.0/random/random-fips.c +--- libgcrypt-1.5.0/random/random-fips.c.cfgrandom 2011-07-21 14:50:34.000000000 +0200 ++++ libgcrypt-1.5.0/random/random-fips.c 2011-07-21 14:50:34.000000000 +0200 @@ -27,10 +27,10 @@ There are 3 random context which map to the different levels of random quality: - Generator Seed and Key Kernel entropy (init/reseed) - ------------------------------------------------------------ -- GCRY_VERY_STRONG_RANDOM /dev/urandom 256/128 bits -- GCRY_STRONG_RANDOM /dev/urandom 256/128 bits +- GCRY_VERY_STRONG_RANDOM /dev/random 256/128 bits +- GCRY_STRONG_RANDOM /dev/random 256/128 bits + Generator Seed and Key Kernel entropy (init/reseed) + --------------------------------------------------------------------------------------- + GCRY_VERY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits @@ -16,11 +16,12 @@ diff -up libgcrypt-1.4.6/random/random-fips.c.cfgrandom libgcrypt-1.4.6/random/r gcry_create_nonce GCRY_STRONG_RANDOM n/a All random generators return their data in 128 bit blocks. If the -@@ -40,7 +40,10 @@ +@@ -40,8 +40,10 @@ (SEED_TTL) output blocks; the re-seeding is disabled in test mode. The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are -- keyed and seeded from the /dev/urandom device. +- keyed and seeded from the /dev/random device. Thus these +- generators may block until the kernel has collected enough entropy. + keyed and seeded with data that is loaded from the /etc/gcrypt/rngseed + if the device or symlink to device exists xored with the data + from the /dev/urandom device. This allows the system administrator @@ -28,7 +29,7 @@ diff -up libgcrypt-1.4.6/random/random-fips.c.cfgrandom libgcrypt-1.4.6/random/r The gcry_create_nonce generator is keyed and seeded from the GCRY_STRONG_RANDOM generator. It may also block if the -@@ -559,6 +562,10 @@ get_entropy (size_t nbytes) +@@ -560,9 +562,13 @@ get_entropy (size_t nbytes) entropy_collect_buffer_len = 0; #if USE_RNDLINUX @@ -38,11 +39,15 @@ diff -up libgcrypt-1.4.6/random/random-fips.c.cfgrandom libgcrypt-1.4.6/random/r + entropy_collect_buffer_len = 0; rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, X931_AES_KEYLEN, - GCRY_STRONG_RANDOM); -diff -up libgcrypt-1.4.6/random/rndlinux.c.cfgrandom libgcrypt-1.4.6/random/rndlinux.c ---- libgcrypt-1.4.6/random/rndlinux.c.cfgrandom 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.6/random/rndlinux.c 2011-06-20 21:34:09.000000000 +0200 -@@ -35,7 +35,9 @@ +- GCRY_VERY_STRONG_RANDOM); ++ GCRY_STRONG_RANDOM); + #elif USE_RNDW32 + do + { +diff -up libgcrypt-1.5.0/random/rndlinux.c.cfgrandom libgcrypt-1.5.0/random/rndlinux.c +--- libgcrypt-1.5.0/random/rndlinux.c.cfgrandom 2011-02-04 20:16:03.000000000 +0100 ++++ libgcrypt-1.5.0/random/rndlinux.c 2011-07-21 14:50:34.000000000 +0200 +@@ -36,7 +36,9 @@ #include "g10lib.h" #include "rand-internal.h" @@ -53,7 +58,7 @@ diff -up libgcrypt-1.4.6/random/rndlinux.c.cfgrandom libgcrypt-1.4.6/random/rndl static int -@@ -56,13 +58,17 @@ set_cloexec_flag (int fd) +@@ -57,13 +59,17 @@ set_cloexec_flag (int fd) * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it exists)). */ static int @@ -73,21 +78,23 @@ diff -up libgcrypt-1.4.6/random/rndlinux.c.cfgrandom libgcrypt-1.4.6/random/rndl if (set_cloexec_flag (fd)) log_error ("error setting FD_CLOEXEC on fd %d: %s\n", -@@ -91,11 +97,13 @@ _gcry_rndlinux_gather_random (void (*add +@@ -92,6 +98,7 @@ _gcry_rndlinux_gather_random (void (*add { static int fd_urandom = -1; static int fd_random = -1; + static int fd_configured = -1; int fd; int n; - int warn=0; byte buffer[768]; - size_t n_hw; +@@ -100,6 +107,7 @@ _gcry_rndlinux_gather_random (void (*add + size_t last_so_far = 0; + int any_need_entropy = 0; + int delay; + size_t orig_length = length; /* First read from a hardware source. However let it account only for up to 50% of the requested bytes. */ -@@ -106,16 +114,26 @@ _gcry_rndlinux_gather_random (void (*add +@@ -110,16 +118,26 @@ _gcry_rndlinux_gather_random (void (*add length -= n_hw; /* Open the requested device. */ diff --git a/libgcrypt-1.5.0-noecc.patch b/libgcrypt-1.5.0-noecc.patch new file mode 100644 index 0000000..7905c71 --- /dev/null +++ b/libgcrypt-1.5.0-noecc.patch @@ -0,0 +1,12 @@ +diff -up libgcrypt-1.5.0/tests/Makefile.noecc libgcrypt-1.5.0/tests/Makefile +--- libgcrypt-1.5.0/tests/Makefile.in.noecc 2011-07-21 15:34:33.000000000 +0200 ++++ libgcrypt-1.5.0/tests/Makefile.in 2011-07-21 15:39:35.000000000 +0200 +@@ -57,7 +57,7 @@ TESTS = version$(EXEEXT) t-mpi-bit$(EXEE + ac-data$(EXEEXT) basic$(EXEEXT) mpitests$(EXEEXT) \ + tsexp$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \ + keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \ +- curves$(EXEEXT) t-kdf$(EXEEXT) pkcs1v2$(EXEEXT) \ ++ t-kdf$(EXEEXT) pkcs1v2$(EXEEXT) \ + $(am__EXEEXT_1) benchmark$(EXEEXT) + + # random.c uses fork() thus a test for W32 does not make any sense. diff --git a/libgcrypt-1.4.5-tests.patch b/libgcrypt-1.5.0-tests.patch similarity index 77% rename from libgcrypt-1.4.5-tests.patch rename to libgcrypt-1.5.0-tests.patch index d2f0256..277438f 100644 --- a/libgcrypt-1.4.5-tests.patch +++ b/libgcrypt-1.5.0-tests.patch @@ -1,20 +1,23 @@ -diff -up libgcrypt-1.4.5/cipher/dsa.c.tests libgcrypt-1.4.5/cipher/dsa.c ---- libgcrypt-1.4.5/cipher/dsa.c.tests 2009-08-21 10:18:30.000000000 +0200 -+++ libgcrypt-1.4.5/cipher/dsa.c 2011-02-04 09:06:02.000000000 +0100 -@@ -468,21 +468,20 @@ generate_fips186 (DSA_secret_key *sk, un +diff -up libgcrypt-1.5.0/cipher/dsa.c.tests libgcrypt-1.5.0/cipher/dsa.c +--- libgcrypt-1.5.0/cipher/dsa.c.tests 2011-06-13 12:24:46.000000000 +0200 ++++ libgcrypt-1.5.0/cipher/dsa.c 2011-07-20 16:44:51.000000000 +0200 +@@ -479,22 +479,21 @@ generate_fips186 (DSA_secret_key *sk, un + initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1, &initial_seed.seedlen); } - +- - /* Fixme: Enable 186-3 after it has been approved and after fixing - the generation function. */ - /* if (use_fips186_2) */ - (void)use_fips186_2; -- ec = _gcry_generate_fips186_2_prime (nbits, qbits, +- ec = _gcry_generate_fips186_2_prime (nbits, qbits, +- initial_seed.seed, ++ + if (use_fips186_2) + ec = _gcry_generate_fips186_2_prime (nbits, qbits, - initial_seed.seed, ++ initial_seed.seed, initial_seed.seedlen, - &prime_q, &prime_p, + &prime_q, &prime_p, r_counter, r_seed, r_seedlen); - /* else */ @@ -32,9 +35,9 @@ diff -up libgcrypt-1.4.5/cipher/dsa.c.tests libgcrypt-1.4.5/cipher/dsa.c gcry_sexp_release (initial_seed.sexp); if (ec) goto leave; -diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen.c ---- libgcrypt-1.4.5/cipher/primegen.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/cipher/primegen.c 2011-02-04 09:06:34.000000000 +0100 +diff -up libgcrypt-1.5.0/cipher/primegen.c.tests libgcrypt-1.5.0/cipher/primegen.c +--- libgcrypt-1.5.0/cipher/primegen.c.tests 2011-03-28 14:19:52.000000000 +0200 ++++ libgcrypt-1.5.0/cipher/primegen.c 2011-07-21 14:36:03.000000000 +0200 @@ -1647,7 +1647,7 @@ _gcry_generate_fips186_3_prime (unsigned gpg_err_code_t ec; unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */ @@ -47,7 +50,7 @@ diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen @@ -1737,7 +1737,7 @@ _gcry_generate_fips186_3_prime (unsigned } gcry_mpi_release (prime_q); prime_q = NULL; - ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, + ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, - value_u, sizeof value_u, NULL)); + value_u, qbits/8, NULL)); if (ec) @@ -59,7 +62,7 @@ diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen } - gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen); + gcry_md_hash_buffer (hashalgo, digest, seed_plus, seedlen); - + gcry_mpi_release (tmpval); tmpval = NULL; ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG, - digest, sizeof digest, NULL)); @@ -81,21 +84,21 @@ diff -up libgcrypt-1.4.5/cipher/primegen.c.tests libgcrypt-1.4.5/cipher/primegen if (r_q) { *r_q = prime_q; -diff -up libgcrypt-1.4.5/cipher/rsa.c.tests libgcrypt-1.4.5/cipher/rsa.c ---- libgcrypt-1.4.5/cipher/rsa.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/cipher/rsa.c 2011-02-04 09:06:02.000000000 +0100 +diff -up libgcrypt-1.5.0/cipher/rsa.c.tests libgcrypt-1.5.0/cipher/rsa.c +--- libgcrypt-1.5.0/cipher/rsa.c.tests 2011-06-10 10:53:41.000000000 +0200 ++++ libgcrypt-1.5.0/cipher/rsa.c 2011-07-21 14:36:59.000000000 +0200 @@ -388,7 +388,7 @@ generate_x931 (RSA_secret_key *sk, unsig *swapped = 0; - if (e_value == 1) /* Alias for a secure value. */ + if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ - e_value = 65537; + e_value = 65537; /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ -diff -up libgcrypt-1.4.5/random/random-fips.c.tests libgcrypt-1.4.5/random/random-fips.c ---- libgcrypt-1.4.5/random/random-fips.c.tests 2011-02-04 09:06:02.000000000 +0100 -+++ libgcrypt-1.4.5/random/random-fips.c 2011-02-04 09:06:02.000000000 +0100 +diff -up libgcrypt-1.5.0/random/random-fips.c.tests libgcrypt-1.5.0/random/random-fips.c +--- libgcrypt-1.5.0/random/random-fips.c.tests 2011-07-20 16:40:59.000000000 +0200 ++++ libgcrypt-1.5.0/random/random-fips.c 2011-07-20 16:40:59.000000000 +0200 @@ -691,6 +691,7 @@ get_random (void *buffer, size_t length, check_guards (rng_ctx); @@ -123,9 +126,9 @@ diff -up libgcrypt-1.4.5/random/random-fips.c.tests libgcrypt-1.4.5/random/rando } if (x931_aes_driver (buffer, length, rng_ctx)) -diff -up libgcrypt-1.4.5/tests/ac.c.tests libgcrypt-1.4.5/tests/ac.c ---- libgcrypt-1.4.5/tests/ac.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/tests/ac.c 2011-02-04 09:06:02.000000000 +0100 +diff -up libgcrypt-1.5.0/tests/ac.c.tests libgcrypt-1.5.0/tests/ac.c +--- libgcrypt-1.5.0/tests/ac.c.tests 2011-02-04 20:18:20.000000000 +0100 ++++ libgcrypt-1.5.0/tests/ac.c 2011-07-20 16:40:59.000000000 +0200 @@ -150,6 +150,9 @@ main (int argc, char **argv) if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); @@ -136,9 +139,9 @@ diff -up libgcrypt-1.4.5/tests/ac.c.tests libgcrypt-1.4.5/tests/ac.c if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); /* No valuable keys are create, so we can speed up our RNG. */ -diff -up libgcrypt-1.4.5/tests/ac-data.c.tests libgcrypt-1.4.5/tests/ac-data.c ---- libgcrypt-1.4.5/tests/ac-data.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/tests/ac-data.c 2011-02-04 09:06:02.000000000 +0100 +diff -up libgcrypt-1.5.0/tests/ac-data.c.tests libgcrypt-1.5.0/tests/ac-data.c +--- libgcrypt-1.5.0/tests/ac-data.c.tests 2011-02-04 20:18:20.000000000 +0100 ++++ libgcrypt-1.5.0/tests/ac-data.c 2011-07-20 16:40:59.000000000 +0200 @@ -198,6 +198,9 @@ main (int argc, char **argv) if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); @@ -149,9 +152,9 @@ diff -up libgcrypt-1.4.5/tests/ac-data.c.tests libgcrypt-1.4.5/tests/ac-data.c if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); -diff -up libgcrypt-1.4.5/tests/ac-schemes.c.tests libgcrypt-1.4.5/tests/ac-schemes.c ---- libgcrypt-1.4.5/tests/ac-schemes.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/tests/ac-schemes.c 2011-02-04 09:06:02.000000000 +0100 +diff -up libgcrypt-1.5.0/tests/ac-schemes.c.tests libgcrypt-1.5.0/tests/ac-schemes.c +--- libgcrypt-1.5.0/tests/ac-schemes.c.tests 2011-02-04 20:18:20.000000000 +0100 ++++ libgcrypt-1.5.0/tests/ac-schemes.c 2011-07-20 16:40:59.000000000 +0200 @@ -338,6 +338,9 @@ main (int argc, char **argv) if (! gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); @@ -162,16 +165,16 @@ diff -up libgcrypt-1.4.5/tests/ac-schemes.c.tests libgcrypt-1.4.5/tests/ac-schem if (debug) gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); -diff -up libgcrypt-1.4.5/tests/keygen.c.tests libgcrypt-1.4.5/tests/keygen.c ---- libgcrypt-1.4.5/tests/keygen.c.tests 2009-04-02 11:25:34.000000000 +0200 -+++ libgcrypt-1.4.5/tests/keygen.c 2011-02-04 09:06:02.000000000 +0100 +diff -up libgcrypt-1.5.0/tests/keygen.c.tests libgcrypt-1.5.0/tests/keygen.c +--- libgcrypt-1.5.0/tests/keygen.c.tests 2011-02-04 20:18:20.000000000 +0100 ++++ libgcrypt-1.5.0/tests/keygen.c 2011-07-21 14:39:03.000000000 +0200 @@ -148,12 +148,12 @@ check_rsa_keys (void) } if (verbose) - fprintf (stderr, "creating 1536 bit DSA key\n"); + fprintf (stderr, "creating 2048 bit DSA key\n"); - rc = gcry_sexp_new (&keyparm, + rc = gcry_sexp_new (&keyparm, "(genkey\n" " (dsa\n" - " (nbits 4:1536)\n" @@ -187,7 +190,7 @@ diff -up libgcrypt-1.4.5/tests/keygen.c.tests libgcrypt-1.4.5/tests/keygen.c if (verbose) - fprintf (stderr, "creating 512 bit RSA key with e=257\n"); + fprintf (stderr, "creating 1024 bit RSA key with e=257\n"); - rc = gcry_sexp_new (&keyparm, + rc = gcry_sexp_new (&keyparm, "(genkey\n" " (rsa\n" - " (nbits 3:512)\n" @@ -201,7 +204,7 @@ diff -up libgcrypt-1.4.5/tests/keygen.c.tests libgcrypt-1.4.5/tests/keygen.c if (verbose) - fprintf (stderr, "creating 512 bit RSA key with default e\n"); + fprintf (stderr, "creating 1024 bit RSA key with default secure e\n"); - rc = gcry_sexp_new (&keyparm, + rc = gcry_sexp_new (&keyparm, "(genkey\n" " (rsa\n" - " (nbits 3:512)\n" diff --git a/libgcrypt-1.4.4-use-fipscheck.patch b/libgcrypt-1.5.0-use-fipscheck.patch similarity index 77% rename from libgcrypt-1.4.4-use-fipscheck.patch rename to libgcrypt-1.5.0-use-fipscheck.patch index d6f45b2..1cef010 100644 --- a/libgcrypt-1.4.4-use-fipscheck.patch +++ b/libgcrypt-1.5.0-use-fipscheck.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.4.4/src/fips.c.use-fipscheck libgcrypt-1.4.4/src/fips.c ---- libgcrypt-1.4.4/src/fips.c.use-fipscheck 2009-03-03 21:09:27.000000000 +0100 -+++ libgcrypt-1.4.4/src/fips.c 2009-03-05 11:20:48.000000000 +0100 +diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c +--- libgcrypt-1.5.0/src/fips.c.use-fipscheck 2011-02-04 20:17:33.000000000 +0100 ++++ libgcrypt-1.5.0/src/fips.c 2011-07-20 16:17:21.000000000 +0200 @@ -570,23 +570,48 @@ run_random_selftests (void) return !!err; } @@ -42,9 +42,10 @@ diff -up libgcrypt-1.4.4/src/fips.c.use-fipscheck libgcrypt-1.4.4/src/fips.c int dlen; char *fname = NULL; - const char key[] = "What am I, a doctor or a moonshuttle conductor?"; -+ const char key[] = "orboDeJITITejsirpADONivirpUkvarP"; - +- - if (!dladdr ("gcry_check_version", &info)) ++ const char key[] = "orboDeJITITejsirpADONivirpUkvarP"; ++ + if (get_library_path ("libgcrypt.so.11", "gcry_check_version", libpath, sizeof(libpath))) err = gpg_error_from_syserror (); else @@ -72,15 +73,15 @@ diff -up libgcrypt-1.4.4/src/fips.c.use-fipscheck libgcrypt-1.4.4/src/fips.c p = strrchr (fname, '/'); if (p) p++; -diff -up libgcrypt-1.4.4/src/Makefile.in.use-fipscheck libgcrypt-1.4.4/src/Makefile.in ---- libgcrypt-1.4.4/src/Makefile.in.use-fipscheck 2009-01-22 19:16:51.000000000 +0100 -+++ libgcrypt-1.4.4/src/Makefile.in 2009-03-05 11:31:57.000000000 +0100 -@@ -337,7 +337,7 @@ libgcrypt_la_LIBADD = \ +diff -up libgcrypt-1.5.0/src/Makefile.in.use-fipscheck libgcrypt-1.5.0/src/Makefile.in +--- libgcrypt-1.5.0/src/Makefile.in.use-fipscheck 2011-06-29 10:58:01.000000000 +0200 ++++ libgcrypt-1.5.0/src/Makefile.in 2011-07-20 16:19:33.000000000 +0200 +@@ -375,7 +375,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \ ../cipher/libcipher.la \ ../random/librandom.la \ ../mpi/libmpi.la \ -- @LTLIBOBJS@ @GPG_ERROR_LIBS@ -+ @LTLIBOBJS@ @GPG_ERROR_LIBS@ -ldl +- ../compat/libcompat.la $(GPG_ERROR_LIBS) ++ ../compat/libcompat.la $(GPG_ERROR_LIBS) -ldl dumpsexp_SOURCES = dumpsexp.c - dumpsexp_LDADD = + dumpsexp_CFLAGS = $(arch_gpg_error_cflags) diff --git a/libgcrypt.spec b/libgcrypt.spec index b430412..5fdee9d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.4.6 -Release: 4%{?dist} +Version: 1.5.0 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -10,18 +10,17 @@ Source0: libgcrypt-%{version}-hobbled.tar.bz2 #Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com Source3: hobble-libgcrypt +# do not run the ecc curves test +Patch1: libgcrypt-1.5.0-noecc.patch # make FIPS hmac compatible with fipscheck - non upstreamable -Patch2: libgcrypt-1.4.4-use-fipscheck.patch -# fix ImplicitDSOLinking (missing -lgpg-error linkage in tests/), upstreamable -Patch3: libgcrypt-1.4.5-ImplicitDSOLinking.patch -# use /dev/urandom in the FIPS mode -Patch4: libgcrypt-1.4.5-urandom.patch +Patch2: libgcrypt-1.5.0-use-fipscheck.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen -Patch5: libgcrypt-1.4.5-tests.patch -# add configurable source of RNG seed in the FIPS mode -Patch6: libgcrypt-1.4.6-fips-cfgrandom.patch +Patch5: libgcrypt-1.5.0-tests.patch +# add configurable source of RNG seed and seed by default +# from /dev/urandom in the FIPS mode +Patch6: libgcrypt-1.5.0-fips-cfgrandom.patch # make the FIPS-186-3 DSA CAVS testable -Patch7: libgcrypt-1.4.6-cavs.patch +Patch7: libgcrypt-1.5.0-fips-cavs.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -54,9 +53,8 @@ applications using libgcrypt. %prep %setup -q %{SOURCE3} +%patch1 -p1 -b .noecc %patch2 -p1 -b .use-fipscheck -%patch3 -p1 -b .ImplicitDSOLinking -%patch4 -p1 -b .urandom %patch5 -p1 -b .tests %patch6 -p1 -b .cfgrandom %patch7 -p1 -b .cavs @@ -171,6 +169,9 @@ exit 0 %doc COPYING %changelog +* Thu Jul 21 2011 Tomas Mraz 1.5.0-1 +- new upstream version + * Mon Jun 20 2011 Tomas Mraz 1.4.6-4 - Always xor seed from /dev/urandom over /etc/gcrypt/rngseed diff --git a/sources b/sources index be4fd16..28984ca 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -f89395ced1cec0107d49524f5bf432f9 libgcrypt-1.4.6-hobbled.tar.bz2 +35a73c1f2616ad904108ed8645c82f4c libgcrypt-1.5.0-hobbled.tar.bz2 From 4c532c09041f9997faf132445adae486280af224 Mon Sep 17 00:00:00 2001 From: Kalev Lember Date: Mon, 15 Aug 2011 08:03:34 +0300 Subject: [PATCH 043/214] Rebuilt for rpm bug #728707 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 5fdee9d..3b97384 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -169,6 +169,9 @@ exit 0 %doc COPYING %changelog +* Mon Aug 15 2011 Kalev Lember 1.5.0-2 +- Rebuilt for rpm bug #728707 + * Thu Jul 21 2011 Tomas Mraz 1.5.0-1 - new upstream version From 01a0c8d733517a06aa3bfc2e5995e826b6b16f31 Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Fri, 13 Jan 2012 01:42:32 -0600 Subject: [PATCH 044/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3b97384..927807f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -169,6 +169,9 @@ exit 0 %doc COPYING %changelog +* Fri Jan 13 2012 Fedora Release Engineering - 1.5.0-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild + * Mon Aug 15 2011 Kalev Lember 1.5.0-2 - Rebuilt for rpm bug #728707 From 92db45d69375b4990a658c187d00537702382831 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 4 Apr 2012 15:28:35 +0200 Subject: [PATCH 045/214] Add GCRYCTL_SET_ENFORCED_FIPS_FLAG command --- libgcrypt-1.5.0-set-enforced-mode.patch | 127 ++++++++++++++++++++++++ libgcrypt.spec | 8 +- 2 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.5.0-set-enforced-mode.patch diff --git a/libgcrypt-1.5.0-set-enforced-mode.patch b/libgcrypt-1.5.0-set-enforced-mode.patch new file mode 100644 index 0000000..05ee548 --- /dev/null +++ b/libgcrypt-1.5.0-set-enforced-mode.patch @@ -0,0 +1,127 @@ +diff -up libgcrypt-1.5.0/doc/gcrypt.texi.enforce libgcrypt-1.5.0/doc/gcrypt.texi +--- libgcrypt-1.5.0/doc/gcrypt.texi.enforce 2011-06-29 10:36:37.000000000 +0200 ++++ libgcrypt-1.5.0/doc/gcrypt.texi 2012-04-04 11:05:41.527430118 +0200 +@@ -577,8 +577,10 @@ initialization (i.e. before @code{gcry_c + + In addition to the standard FIPS mode, Libgcrypt may also be put into + an Enforced FIPS mode by writing a non-zero value into the file +-@file{/etc/gcrypt/fips_enabled}. The Enforced FIPS mode helps to +-detect applications which don't fulfill all requirements for using ++@file{/etc/gcrypt/fips_enabled} or by using the control command ++@code{GCRYCTL_SET_ENFORCED_FIPS_FLAG} before any other calls to ++libgcrypt. The Enforced FIPS mode helps to detect applications ++which don't fulfill all requirements for using + Libgcrypt in FIPS mode (@pxref{FIPS Mode}). + + Once Libgcrypt has been put into FIPS mode, it is not possible to +@@ -787,20 +789,20 @@ proper random device. + This command dumps information pertaining to the configuration of the + library to the given stream. If NULL is given for @var{stream}, the log + system is used. This command may be used before the intialization has +-been finished but not before a gcry_version_check. ++been finished but not before a @code{gcry_check_version}. + + @item GCRYCTL_OPERATIONAL_P; Arguments: none + This command returns true if the library is in an operational state. + This information makes only sense in FIPS mode. In contrast to other + functions, this is a pure test function and won't put the library into + FIPS mode or change the internal state. This command may be used before +-the intialization has been finished but not before a gcry_version_check. ++the intialization has been finished but not before a @code{gcry_check_version}. + + @item GCRYCTL_FIPS_MODE_P; Arguments: none + This command returns true if the library is in FIPS mode. Note, that + this is no indication about the current state of the library. This + command may be used before the intialization has been finished but not +-before a gcry_version_check. An application may use this command or ++before a @code{gcry_check_version}. An application may use this command or + the convenience macro below to check whether FIPS mode is actually + active. + +@@ -816,10 +818,19 @@ implemented as a macro. + Running this command puts the library into FIPS mode. If the library is + already in FIPS mode, a self-test is triggered and thus the library will + be put into operational state. This command may be used before a call +-to gcry_check_version and that is actually the recommended way to let an ++to @code{gcry_check_version} and that is actually the recommended way to let an + application switch the library into FIPS mode. Note that Libgcrypt will + reject an attempt to switch to fips mode during or after the intialization. + ++@item GCRYCTL_SET_ENFORCED_FIPS_FLAG; Arguments: none ++Running this command sets the internal flag that puts the library into ++the enforced FIPS mode during the FIPS mode initialization. This command ++does not affect the library if the library is not put into the FIPS mode and ++it must be used before any other libgcrypt library calls that initialize ++the library such as @code{gcry_check_version}. Note that Libgcrypt will ++reject an attempt to switch to the enforced fips mode during or after ++the intialization. ++ + @item GCRYCTL_SELFTEST; Arguments: none + This may be used at anytime to have the library run all implemented + self-tests. It works in standard and in FIPS mode. Returns 0 on +diff -up libgcrypt-1.5.0/src/fips.c.enforce libgcrypt-1.5.0/src/fips.c +--- libgcrypt-1.5.0/src/fips.c.enforce 2011-07-21 15:41:25.000000000 +0200 ++++ libgcrypt-1.5.0/src/fips.c 2012-04-04 10:26:24.311525789 +0200 +@@ -274,9 +274,17 @@ _gcry_fips_mode (void) + int + _gcry_enforced_fips_mode (void) + { ++ if (!_gcry_fips_mode ()) ++ return 0; + return enforced_fips_mode; + } + ++/* Set a flag telling whether we are in the enforced fips mode. */ ++void ++_gcry_set_enforced_fips_mode (void) ++{ ++ enforced_fips_mode = 1; ++} + + /* If we do not want to enforce the fips mode, we can set a flag so + that the application may check whether it is still in fips mode. +diff -up libgcrypt-1.5.0/src/g10lib.h.enforce libgcrypt-1.5.0/src/g10lib.h +--- libgcrypt-1.5.0/src/g10lib.h.enforce 2011-02-16 18:27:28.000000000 +0100 ++++ libgcrypt-1.5.0/src/g10lib.h 2012-04-04 10:25:03.280777602 +0200 +@@ -326,6 +326,8 @@ int _gcry_fips_mode (void); + + int _gcry_enforced_fips_mode (void); + ++void _gcry_set_enforced_fips_mode (void); ++ + void _gcry_inactivate_fips_mode (const char *text); + int _gcry_is_fips_mode_inactive (void); + +diff -up libgcrypt-1.5.0/src/gcrypt.h.in.enforce libgcrypt-1.5.0/src/gcrypt.h.in +--- libgcrypt-1.5.0/src/gcrypt.h.in.enforce 2011-03-11 09:47:39.000000000 +0100 ++++ libgcrypt-1.5.0/src/gcrypt.h.in 2012-04-04 10:25:53.806867670 +0200 +@@ -415,7 +415,8 @@ enum gcry_ctl_cmds + GCRYCTL_FORCE_FIPS_MODE = 56, + GCRYCTL_SELFTEST = 57, + /* Note: 58 .. 62 are used internally. */ +- GCRYCTL_DISABLE_HWF = 63 ++ GCRYCTL_DISABLE_HWF = 63, ++ GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64 + }; + + /* Perform various operations defined by CMD. */ +diff -up libgcrypt-1.5.0/src/global.c.enforce libgcrypt-1.5.0/src/global.c +--- libgcrypt-1.5.0/src/global.c.enforce 2011-04-01 10:15:40.000000000 +0200 ++++ libgcrypt-1.5.0/src/global.c 2012-04-04 10:24:12.647685222 +0200 +@@ -596,6 +596,16 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, + } + break; + ++ case GCRYCTL_SET_ENFORCED_FIPS_FLAG: ++ if (!any_init_done) ++ { ++ /* Not yet intialized at all. Set the enforced fips mode flag */ ++ _gcry_set_enforced_fips_mode (); ++ } ++ else ++ err = GPG_ERR_GENERAL; ++ break; ++ + default: + /* A call to make sure that the dummy code is linked in. */ + _gcry_compat_identification (); diff --git a/libgcrypt.spec b/libgcrypt.spec index 927807f..b4fc11c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -21,6 +21,8 @@ Patch5: libgcrypt-1.5.0-tests.patch Patch6: libgcrypt-1.5.0-fips-cfgrandom.patch # make the FIPS-186-3 DSA CAVS testable Patch7: libgcrypt-1.5.0-fips-cavs.patch +# add GCRYCTL_SET_ENFORCED_FIPS_FLAG +Patch8: libgcrypt-1.5.0-set-enforced-mode.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -58,6 +60,7 @@ applications using libgcrypt. %patch5 -p1 -b .tests %patch6 -p1 -b .cfgrandom %patch7 -p1 -b .cavs +%patch8 -p1 -b .enforce mv AUTHORS AUTHORS.iso88591 iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS @@ -169,6 +172,9 @@ exit 0 %doc COPYING %changelog +* Wed Apr 4 2012 Tomas Mraz 1.5.0-4 +- Add GCRYCTL_SET_ENFORCED_FIPS_FLAG command + * Fri Jan 13 2012 Fedora Release Engineering - 1.5.0-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_17_Mass_Rebuild From 4e2e7e93679be7c407043fa19e76d4897dc1647d Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 5 Apr 2012 23:35:22 +0200 Subject: [PATCH 046/214] Correctly rebuild the info documentation --- libgcrypt.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index b4fc11c..e71cfc1 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 4%{?dist} +Release: 5%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -32,6 +32,8 @@ Summary: A general-purpose cryptography library BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRequires: gawk, libgpg-error-devel >= 1.4, pkgconfig BuildRequires: fipscheck +# This is needed only when patching the .texi doc. +BuildRequires: texinfo Group: System Environment/Libraries %package devel @@ -172,6 +174,9 @@ exit 0 %doc COPYING %changelog +* Thu Apr 5 2012 Tomas Mraz 1.5.0-5 +- Correctly rebuild the info documentation + * Wed Apr 4 2012 Tomas Mraz 1.5.0-4 - Add GCRYCTL_SET_ENFORCED_FIPS_FLAG command From f98619e8586096d93bcd439b020f3ec4fffe5a81 Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Thu, 19 Jul 2012 14:49:18 -0500 Subject: [PATCH 047/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index e71cfc1..5026410 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 5%{?dist} +Release: 6%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -174,6 +174,9 @@ exit 0 %doc COPYING %changelog +* Thu Jul 19 2012 Fedora Release Engineering - 1.5.0-6 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild + * Thu Apr 5 2012 Tomas Mraz 1.5.0-5 - Correctly rebuild the info documentation From d630de2f618e14064b88a7c739905d6ecc968b34 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 3 Dec 2012 13:44:00 +0100 Subject: [PATCH 048/214] fix multilib conflict in libgcrypt-config --- libgcrypt.spec | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 5026410..7f0a015 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 6%{?dist} +Release: 7%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -97,7 +97,9 @@ make install DESTDIR=$RPM_BUILD_ROOT # Change /usr/lib64 back to /usr/lib. This saves us from having to patch the # script to "know" that -L/usr/lib64 should be suppressed, and also removes # a file conflict between 32- and 64-bit versions of this package. +# Also replace my_host with none. sed -i -e 's,^libdir="/usr/lib.*"$,libdir="/usr/lib",g' $RPM_BUILD_ROOT/%{_bindir}/libgcrypt-config +sed -i -e 's,^my_host=".*"$,my_host="none",g' $RPM_BUILD_ROOT/%{_bindir}/libgcrypt-config rm -f ${RPM_BUILD_ROOT}/%{_infodir}/dir ${RPM_BUILD_ROOT}/%{_libdir}/*.la /sbin/ldconfig -n $RPM_BUILD_ROOT/%{_libdir} @@ -174,6 +176,9 @@ exit 0 %doc COPYING %changelog +* Mon Dec 3 2012 Tomas Mraz 1.5.0-7 +- fix multilib conflict in libgcrypt-config + * Thu Jul 19 2012 Fedora Release Engineering - 1.5.0-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild From da4e639781df2add830699ecfad0f78cfab5a238 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 3 Dec 2012 15:42:53 +0100 Subject: [PATCH 049/214] fix minor memory leaks and other bugs found by Coverity scan --- libgcrypt-1.5.0-leak.patch | 73 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 libgcrypt-1.5.0-leak.patch diff --git a/libgcrypt-1.5.0-leak.patch b/libgcrypt-1.5.0-leak.patch new file mode 100644 index 0000000..5f0d191 --- /dev/null +++ b/libgcrypt-1.5.0-leak.patch @@ -0,0 +1,73 @@ +diff -up libgcrypt-1.5.0/cipher/elgamal.c.leak libgcrypt-1.5.0/cipher/elgamal.c +--- libgcrypt-1.5.0/cipher/elgamal.c.leak 2011-02-04 20:09:38.000000000 +0100 ++++ libgcrypt-1.5.0/cipher/elgamal.c 2012-12-03 14:51:10.743067964 +0100 +@@ -641,7 +641,10 @@ elg_generate_ext (int algo, unsigned int + } + + if (xvalue) +- ec = generate_using_x (&sk, nbits, xvalue, retfactors); ++ { ++ ec = generate_using_x (&sk, nbits, xvalue, retfactors); ++ gcry_mpi_release(xvalue); ++ } + else + { + generate (&sk, nbits, retfactors); +diff -up libgcrypt-1.5.0/cipher/primegen.c.leak libgcrypt-1.5.0/cipher/primegen.c +--- libgcrypt-1.5.0/cipher/primegen.c.leak 2012-04-05 15:37:52.000000000 +0200 ++++ libgcrypt-1.5.0/cipher/primegen.c 2012-12-03 14:44:14.610010867 +0100 +@@ -1198,10 +1198,7 @@ gcry_prime_group_generator (gcry_mpi_t * + gcry_mpi_t prime, gcry_mpi_t *factors, + gcry_mpi_t start_g) + { +- gcry_mpi_t tmp = gcry_mpi_new (0); +- gcry_mpi_t b = gcry_mpi_new (0); +- gcry_mpi_t pmin1 = gcry_mpi_new (0); +- gcry_mpi_t g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3); ++ gcry_mpi_t tmp, b, pmin1, g; + int first = 1; + int i, n; + +@@ -1214,6 +1211,11 @@ gcry_prime_group_generator (gcry_mpi_t * + if (n < 2) + return gpg_error (GPG_ERR_INV_ARG); + ++ tmp = gcry_mpi_new (0); ++ b = gcry_mpi_new (0); ++ pmin1 = gcry_mpi_new (0); ++ g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3); ++ + /* Extra sanity check - usually disabled. */ + /* mpi_set (tmp, factors[0]); */ + /* for(i = 1; i < n; i++) */ +diff -up libgcrypt-1.5.0/cipher/pubkey.c.leak libgcrypt-1.5.0/cipher/pubkey.c +--- libgcrypt-1.5.0/cipher/pubkey.c.leak 2011-06-13 12:23:50.000000000 +0200 ++++ libgcrypt-1.5.0/cipher/pubkey.c 2012-12-03 15:23:42.377183489 +0100 +@@ -2853,6 +2853,8 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gc + + REGISTER_DEFAULT_PUBKEYS; + ++ init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey)); ++ + /* Get the key. */ + rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module); + if (rc) +@@ -2873,7 +2875,6 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gc + algo_elems = pubkey->elements_enc; + + /* Get the stuff we want to encrypt. */ +- init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey)); + rc = sexp_data_to_mpi (s_data, &data, &ctx); + if (rc) + goto leave; +diff -up libgcrypt-1.5.0/src/hmac256.c.leak libgcrypt-1.5.0/src/hmac256.c +--- libgcrypt-1.5.0/src/hmac256.c.leak 2011-02-04 20:17:33.000000000 +0100 ++++ libgcrypt-1.5.0/src/hmac256.c 2012-12-03 15:37:36.504955809 +0100 +@@ -435,7 +435,6 @@ _gcry_hmac256_finalize (hmac256_context_ + tmphd = _gcry_hmac256_new (NULL, 0); + if (!tmphd) + { +- free (hd); + return NULL; + } + _gcry_hmac256_update (tmphd, hd->opad, 64); From c907a55cb5d9d41cad1052d59bc228b87276a0c0 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 3 Dec 2012 15:43:32 +0100 Subject: [PATCH 050/214] fix minor memory leaks and other bugs found by Coverity scan --- libgcrypt.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index 7f0a015..6da4af5 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -23,6 +23,8 @@ Patch6: libgcrypt-1.5.0-fips-cfgrandom.patch Patch7: libgcrypt-1.5.0-fips-cavs.patch # add GCRYCTL_SET_ENFORCED_FIPS_FLAG Patch8: libgcrypt-1.5.0-set-enforced-mode.patch +# fix for memory leaks an other errors found by Coverity scan +Patch9: libgcrypt-1.5.0-leak.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -178,6 +180,7 @@ exit 0 %changelog * Mon Dec 3 2012 Tomas Mraz 1.5.0-7 - fix multilib conflict in libgcrypt-config +- fix minor memory leaks and other bugs found by Coverity scan * Thu Jul 19 2012 Fedora Release Engineering - 1.5.0-6 - Rebuilt for https://fedoraproject.org/wiki/Fedora_18_Mass_Rebuild From 07b385d5db63c0de849151e2aa4b96e143860e61 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 3 Dec 2012 16:45:37 +0100 Subject: [PATCH 051/214] And also apply the patch. --- libgcrypt.spec | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6da4af5..3a9ffb9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 7%{?dist} +Release: 8%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -65,6 +65,7 @@ applications using libgcrypt. %patch6 -p1 -b .cfgrandom %patch7 -p1 -b .cavs %patch8 -p1 -b .enforce +%patch9 -p1 -b .leak mv AUTHORS AUTHORS.iso88591 iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS @@ -178,7 +179,7 @@ exit 0 %doc COPYING %changelog -* Mon Dec 3 2012 Tomas Mraz 1.5.0-7 +* Mon Dec 3 2012 Tomas Mraz 1.5.0-8 - fix multilib conflict in libgcrypt-config - fix minor memory leaks and other bugs found by Coverity scan From 02a80de4724dbc971f1b85534b249c69b69815d1 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 3 Jan 2013 14:54:02 +0100 Subject: [PATCH 052/214] allow empty passphrase in PBKDF2 needed for cryptsetup (=891266) --- libgcrypt-1.5.0-empty-passphrase.patch | 54 ++++++++++++++++++++++++++ libgcrypt.spec | 8 +++- 2 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.5.0-empty-passphrase.patch diff --git a/libgcrypt-1.5.0-empty-passphrase.patch b/libgcrypt-1.5.0-empty-passphrase.patch new file mode 100644 index 0000000..c989420 --- /dev/null +++ b/libgcrypt-1.5.0-empty-passphrase.patch @@ -0,0 +1,54 @@ +commit 8528f1ba40e587dc17e02822e529fbd7ac69a189 +Author: Milan Broz +Date: Mon Oct 29 17:18:09 2012 +0100 + + PBKDF2: Allow empty passphrase. + + * cipher/kdf.c (gcry_kdf_derive): Allow empty passphrase for PBKDF2. + * tests/t-kdf.c (check_pbkdf2): Add test case for above. + -- + + While it is insecure, the PBKDF2 implementations usually + allows to derive key only from salt. + + This particular case is used e.g. in cryptsetup when + you use empty file as keyfile for LUKS keyslot. + + Test vector is compared with two independent implementations. + + Signed-off-by: Milan Broz + +diff --git a/cipher/kdf.c b/cipher/kdf.c +index d981022..46e8550 100644 +--- a/cipher/kdf.c ++++ b/cipher/kdf.c +@@ -238,7 +238,7 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen, + { + gpg_err_code_t ec; + +- if (!passphrase || !passphraselen) ++ if (!passphrase || (!passphraselen && algo != GCRY_KDF_PBKDF2)) + { + ec = GPG_ERR_INV_DATA; + goto leave; +diff --git a/tests/t-kdf.c b/tests/t-kdf.c +index 7209525..06c0026 100644 +--- a/tests/t-kdf.c ++++ b/tests/t-kdf.c +@@ -917,7 +917,15 @@ check_pbkdf2 (void) + 16, + "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37" + "\xd7\xf0\x34\x25\xe0\xc3" +- } ++ }, ++ { /* empty password test, not in RFC-6070 */ ++ "", 0, ++ "salt", 4, ++ 2, ++ 20, ++ "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2" ++ "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97" ++ }, + }; + int tvidx; + gpg_error_t err; diff --git a/libgcrypt.spec b/libgcrypt.spec index 3a9ffb9..cc91552 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 8%{?dist} +Release: 9%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -25,6 +25,8 @@ Patch7: libgcrypt-1.5.0-fips-cavs.patch Patch8: libgcrypt-1.5.0-set-enforced-mode.patch # fix for memory leaks an other errors found by Coverity scan Patch9: libgcrypt-1.5.0-leak.patch +# allow empty passphrase (upstreamed) +Patch10: libgcrypt-1.5.0-empty-passphrase.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -66,6 +68,7 @@ applications using libgcrypt. %patch7 -p1 -b .cavs %patch8 -p1 -b .enforce %patch9 -p1 -b .leak +%patch10 -p1 -b .emptypass mv AUTHORS AUTHORS.iso88591 iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS @@ -179,6 +182,9 @@ exit 0 %doc COPYING %changelog +* Thu Jan 3 2013 Tomas Mraz 1.5.0-9 +- allow empty passphrase in PBKDF2 needed for cryptsetup (=891266) + * Mon Dec 3 2012 Tomas Mraz 1.5.0-8 - fix multilib conflict in libgcrypt-config - fix minor memory leaks and other bugs found by Coverity scan From 8df0581f5a157e0398e8e6f2610af844ff2a9e5a Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Wed, 13 Feb 2013 22:22:29 -0600 Subject: [PATCH 053/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index cc91552..918f7f4 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 9%{?dist} +Release: 10%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -182,6 +182,9 @@ exit 0 %doc COPYING %changelog +* Thu Feb 14 2013 Fedora Release Engineering - 1.5.0-10 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild + * Thu Jan 3 2013 Tomas Mraz 1.5.0-9 - allow empty passphrase in PBKDF2 needed for cryptsetup (=891266) From 6fb8d4d1e60528419afb1fafb5e52b044fa06fc7 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 5 Mar 2013 14:27:20 +0100 Subject: [PATCH 054/214] use poll() instead of select() when gathering randomness (#913773) --- libgcrypt-1.5.0-use-poll.patch | 57 ++++++++++++++++++++++++++++++++++ libgcrypt.spec | 8 ++++- 2 files changed, 64 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.5.0-use-poll.patch diff --git a/libgcrypt-1.5.0-use-poll.patch b/libgcrypt-1.5.0-use-poll.patch new file mode 100644 index 0000000..b0ca158 --- /dev/null +++ b/libgcrypt-1.5.0-use-poll.patch @@ -0,0 +1,57 @@ +diff -up libgcrypt-1.5.0/random/rndlinux.c.use-poll libgcrypt-1.5.0/random/rndlinux.c +--- libgcrypt-1.5.0/random/rndlinux.c.use-poll 2012-04-05 15:37:52.000000000 +0200 ++++ libgcrypt-1.5.0/random/rndlinux.c 2013-03-05 14:15:29.735709032 +0100 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include "types.h" + #include "g10lib.h" + #include "rand-internal.h" +@@ -142,21 +143,19 @@ _gcry_rndlinux_gather_random (void (*add + } + + /* Enter the read loop. */ +- delay = 0; /* Start with 0 seconds so that we do no block on the ++ delay = 100; /* Start with 0 seconds so that we do no block on the + first iteration and in turn call the progress function + before blocking. To give the OS a better chance to + return with something we will actually use 100ms. */ + while (length) + { +- fd_set rfds; +- struct timeval tv; + int rc; ++ struct pollfd pfd; + +- FD_ZERO(&rfds); +- FD_SET(fd, &rfds); +- tv.tv_sec = delay; +- tv.tv_usec = delay? 0 : 100000; +- if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) ++ pfd.fd = fd; ++ pfd.events = POLLIN; ++ ++ if ( !(rc=poll(&pfd, 1, delay)) ) + { + if (!any_need_entropy || last_so_far != (want - length) ) + { +@@ -165,14 +164,14 @@ _gcry_rndlinux_gather_random (void (*add + (int)last_so_far, (int)want); + any_need_entropy = 1; + } +- delay = 3; /* Use 3 seconds henceforth. */ ++ delay = 3000; /* Use 3 seconds henceforth. */ + continue; + } + else if( rc == -1 ) + { +- log_error ("select() error: %s\n", strerror(errno)); ++ log_error ("poll() error: %s\n", strerror(errno)); + if (!delay) +- delay = 1; /* Use 1 second if we encounter an error before ++ delay = 1000; /* Use 1 second if we encounter an error before + we have ever blocked. */ + continue; + } diff --git a/libgcrypt.spec b/libgcrypt.spec index 918f7f4..12b34ca 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.0 -Release: 10%{?dist} +Release: 11%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.bz2 # The original libgcrypt sources now contain potentially patented ECC @@ -27,6 +27,8 @@ Patch8: libgcrypt-1.5.0-set-enforced-mode.patch Patch9: libgcrypt-1.5.0-leak.patch # allow empty passphrase (upstreamed) Patch10: libgcrypt-1.5.0-empty-passphrase.patch +# use poll instead of select when gathering randomness +Patch11: libgcrypt-1.5.0-use-poll.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -69,6 +71,7 @@ applications using libgcrypt. %patch8 -p1 -b .enforce %patch9 -p1 -b .leak %patch10 -p1 -b .emptypass +%patch11 -p1 -b .use-poll mv AUTHORS AUTHORS.iso88591 iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS @@ -182,6 +185,9 @@ exit 0 %doc COPYING %changelog +* Tue Mar 5 2013 Tomas Mraz 1.5.0-11 +- use poll() instead of select() when gathering randomness (#913773) + * Thu Feb 14 2013 Fedora Release Engineering - 1.5.0-10 - Rebuilt for https://fedoraproject.org/wiki/Fedora_19_Mass_Rebuild From 1aafe14181fc567907ad0f43384f9ba84c7d655b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 20 Mar 2013 16:38:05 +0100 Subject: [PATCH 055/214] new upstream version --- .gitignore | 1 + libgcrypt-1.5.0-empty-passphrase.patch | 54 ---------- libgcrypt-1.5.0-set-enforced-mode.patch | 127 ------------------------ libgcrypt-1.5.0-use-poll.patch | 57 ----------- libgcrypt-1.5.1-use-poll.patch | 82 +++++++++++++++ libgcrypt.spec | 17 ++-- sources | 2 +- 7 files changed, 91 insertions(+), 249 deletions(-) delete mode 100644 libgcrypt-1.5.0-empty-passphrase.patch delete mode 100644 libgcrypt-1.5.0-set-enforced-mode.patch delete mode 100644 libgcrypt-1.5.0-use-poll.patch create mode 100644 libgcrypt-1.5.1-use-poll.patch diff --git a/.gitignore b/.gitignore index 2daa2a1..2474d69 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.4.6-hobbled.tar.bz2 /libgcrypt-1.5.0-hobbled.tar.bz2 +/libgcrypt-1.5.1-hobbled.tar.xz diff --git a/libgcrypt-1.5.0-empty-passphrase.patch b/libgcrypt-1.5.0-empty-passphrase.patch deleted file mode 100644 index c989420..0000000 --- a/libgcrypt-1.5.0-empty-passphrase.patch +++ /dev/null @@ -1,54 +0,0 @@ -commit 8528f1ba40e587dc17e02822e529fbd7ac69a189 -Author: Milan Broz -Date: Mon Oct 29 17:18:09 2012 +0100 - - PBKDF2: Allow empty passphrase. - - * cipher/kdf.c (gcry_kdf_derive): Allow empty passphrase for PBKDF2. - * tests/t-kdf.c (check_pbkdf2): Add test case for above. - -- - - While it is insecure, the PBKDF2 implementations usually - allows to derive key only from salt. - - This particular case is used e.g. in cryptsetup when - you use empty file as keyfile for LUKS keyslot. - - Test vector is compared with two independent implementations. - - Signed-off-by: Milan Broz - -diff --git a/cipher/kdf.c b/cipher/kdf.c -index d981022..46e8550 100644 ---- a/cipher/kdf.c -+++ b/cipher/kdf.c -@@ -238,7 +238,7 @@ gcry_kdf_derive (const void *passphrase, size_t passphraselen, - { - gpg_err_code_t ec; - -- if (!passphrase || !passphraselen) -+ if (!passphrase || (!passphraselen && algo != GCRY_KDF_PBKDF2)) - { - ec = GPG_ERR_INV_DATA; - goto leave; -diff --git a/tests/t-kdf.c b/tests/t-kdf.c -index 7209525..06c0026 100644 ---- a/tests/t-kdf.c -+++ b/tests/t-kdf.c -@@ -917,7 +917,15 @@ check_pbkdf2 (void) - 16, - "\x56\xfa\x6a\xa7\x55\x48\x09\x9d\xcc\x37" - "\xd7\xf0\x34\x25\xe0\xc3" -- } -+ }, -+ { /* empty password test, not in RFC-6070 */ -+ "", 0, -+ "salt", 4, -+ 2, -+ 20, -+ "\x13\x3a\x4c\xe8\x37\xb4\xd2\x52\x1e\xe2" -+ "\xbf\x03\xe1\x1c\x71\xca\x79\x4e\x07\x97" -+ }, - }; - int tvidx; - gpg_error_t err; diff --git a/libgcrypt-1.5.0-set-enforced-mode.patch b/libgcrypt-1.5.0-set-enforced-mode.patch deleted file mode 100644 index 05ee548..0000000 --- a/libgcrypt-1.5.0-set-enforced-mode.patch +++ /dev/null @@ -1,127 +0,0 @@ -diff -up libgcrypt-1.5.0/doc/gcrypt.texi.enforce libgcrypt-1.5.0/doc/gcrypt.texi ---- libgcrypt-1.5.0/doc/gcrypt.texi.enforce 2011-06-29 10:36:37.000000000 +0200 -+++ libgcrypt-1.5.0/doc/gcrypt.texi 2012-04-04 11:05:41.527430118 +0200 -@@ -577,8 +577,10 @@ initialization (i.e. before @code{gcry_c - - In addition to the standard FIPS mode, Libgcrypt may also be put into - an Enforced FIPS mode by writing a non-zero value into the file --@file{/etc/gcrypt/fips_enabled}. The Enforced FIPS mode helps to --detect applications which don't fulfill all requirements for using -+@file{/etc/gcrypt/fips_enabled} or by using the control command -+@code{GCRYCTL_SET_ENFORCED_FIPS_FLAG} before any other calls to -+libgcrypt. The Enforced FIPS mode helps to detect applications -+which don't fulfill all requirements for using - Libgcrypt in FIPS mode (@pxref{FIPS Mode}). - - Once Libgcrypt has been put into FIPS mode, it is not possible to -@@ -787,20 +789,20 @@ proper random device. - This command dumps information pertaining to the configuration of the - library to the given stream. If NULL is given for @var{stream}, the log - system is used. This command may be used before the intialization has --been finished but not before a gcry_version_check. -+been finished but not before a @code{gcry_check_version}. - - @item GCRYCTL_OPERATIONAL_P; Arguments: none - This command returns true if the library is in an operational state. - This information makes only sense in FIPS mode. In contrast to other - functions, this is a pure test function and won't put the library into - FIPS mode or change the internal state. This command may be used before --the intialization has been finished but not before a gcry_version_check. -+the intialization has been finished but not before a @code{gcry_check_version}. - - @item GCRYCTL_FIPS_MODE_P; Arguments: none - This command returns true if the library is in FIPS mode. Note, that - this is no indication about the current state of the library. This - command may be used before the intialization has been finished but not --before a gcry_version_check. An application may use this command or -+before a @code{gcry_check_version}. An application may use this command or - the convenience macro below to check whether FIPS mode is actually - active. - -@@ -816,10 +818,19 @@ implemented as a macro. - Running this command puts the library into FIPS mode. If the library is - already in FIPS mode, a self-test is triggered and thus the library will - be put into operational state. This command may be used before a call --to gcry_check_version and that is actually the recommended way to let an -+to @code{gcry_check_version} and that is actually the recommended way to let an - application switch the library into FIPS mode. Note that Libgcrypt will - reject an attempt to switch to fips mode during or after the intialization. - -+@item GCRYCTL_SET_ENFORCED_FIPS_FLAG; Arguments: none -+Running this command sets the internal flag that puts the library into -+the enforced FIPS mode during the FIPS mode initialization. This command -+does not affect the library if the library is not put into the FIPS mode and -+it must be used before any other libgcrypt library calls that initialize -+the library such as @code{gcry_check_version}. Note that Libgcrypt will -+reject an attempt to switch to the enforced fips mode during or after -+the intialization. -+ - @item GCRYCTL_SELFTEST; Arguments: none - This may be used at anytime to have the library run all implemented - self-tests. It works in standard and in FIPS mode. Returns 0 on -diff -up libgcrypt-1.5.0/src/fips.c.enforce libgcrypt-1.5.0/src/fips.c ---- libgcrypt-1.5.0/src/fips.c.enforce 2011-07-21 15:41:25.000000000 +0200 -+++ libgcrypt-1.5.0/src/fips.c 2012-04-04 10:26:24.311525789 +0200 -@@ -274,9 +274,17 @@ _gcry_fips_mode (void) - int - _gcry_enforced_fips_mode (void) - { -+ if (!_gcry_fips_mode ()) -+ return 0; - return enforced_fips_mode; - } - -+/* Set a flag telling whether we are in the enforced fips mode. */ -+void -+_gcry_set_enforced_fips_mode (void) -+{ -+ enforced_fips_mode = 1; -+} - - /* If we do not want to enforce the fips mode, we can set a flag so - that the application may check whether it is still in fips mode. -diff -up libgcrypt-1.5.0/src/g10lib.h.enforce libgcrypt-1.5.0/src/g10lib.h ---- libgcrypt-1.5.0/src/g10lib.h.enforce 2011-02-16 18:27:28.000000000 +0100 -+++ libgcrypt-1.5.0/src/g10lib.h 2012-04-04 10:25:03.280777602 +0200 -@@ -326,6 +326,8 @@ int _gcry_fips_mode (void); - - int _gcry_enforced_fips_mode (void); - -+void _gcry_set_enforced_fips_mode (void); -+ - void _gcry_inactivate_fips_mode (const char *text); - int _gcry_is_fips_mode_inactive (void); - -diff -up libgcrypt-1.5.0/src/gcrypt.h.in.enforce libgcrypt-1.5.0/src/gcrypt.h.in ---- libgcrypt-1.5.0/src/gcrypt.h.in.enforce 2011-03-11 09:47:39.000000000 +0100 -+++ libgcrypt-1.5.0/src/gcrypt.h.in 2012-04-04 10:25:53.806867670 +0200 -@@ -415,7 +415,8 @@ enum gcry_ctl_cmds - GCRYCTL_FORCE_FIPS_MODE = 56, - GCRYCTL_SELFTEST = 57, - /* Note: 58 .. 62 are used internally. */ -- GCRYCTL_DISABLE_HWF = 63 -+ GCRYCTL_DISABLE_HWF = 63, -+ GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64 - }; - - /* Perform various operations defined by CMD. */ -diff -up libgcrypt-1.5.0/src/global.c.enforce libgcrypt-1.5.0/src/global.c ---- libgcrypt-1.5.0/src/global.c.enforce 2011-04-01 10:15:40.000000000 +0200 -+++ libgcrypt-1.5.0/src/global.c 2012-04-04 10:24:12.647685222 +0200 -@@ -596,6 +596,16 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - } - break; - -+ case GCRYCTL_SET_ENFORCED_FIPS_FLAG: -+ if (!any_init_done) -+ { -+ /* Not yet intialized at all. Set the enforced fips mode flag */ -+ _gcry_set_enforced_fips_mode (); -+ } -+ else -+ err = GPG_ERR_GENERAL; -+ break; -+ - default: - /* A call to make sure that the dummy code is linked in. */ - _gcry_compat_identification (); diff --git a/libgcrypt-1.5.0-use-poll.patch b/libgcrypt-1.5.0-use-poll.patch deleted file mode 100644 index b0ca158..0000000 --- a/libgcrypt-1.5.0-use-poll.patch +++ /dev/null @@ -1,57 +0,0 @@ -diff -up libgcrypt-1.5.0/random/rndlinux.c.use-poll libgcrypt-1.5.0/random/rndlinux.c ---- libgcrypt-1.5.0/random/rndlinux.c.use-poll 2012-04-05 15:37:52.000000000 +0200 -+++ libgcrypt-1.5.0/random/rndlinux.c 2013-03-05 14:15:29.735709032 +0100 -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #include "types.h" - #include "g10lib.h" - #include "rand-internal.h" -@@ -142,21 +143,19 @@ _gcry_rndlinux_gather_random (void (*add - } - - /* Enter the read loop. */ -- delay = 0; /* Start with 0 seconds so that we do no block on the -+ delay = 100; /* Start with 0 seconds so that we do no block on the - first iteration and in turn call the progress function - before blocking. To give the OS a better chance to - return with something we will actually use 100ms. */ - while (length) - { -- fd_set rfds; -- struct timeval tv; - int rc; -+ struct pollfd pfd; - -- FD_ZERO(&rfds); -- FD_SET(fd, &rfds); -- tv.tv_sec = delay; -- tv.tv_usec = delay? 0 : 100000; -- if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) -+ pfd.fd = fd; -+ pfd.events = POLLIN; -+ -+ if ( !(rc=poll(&pfd, 1, delay)) ) - { - if (!any_need_entropy || last_so_far != (want - length) ) - { -@@ -165,14 +164,14 @@ _gcry_rndlinux_gather_random (void (*add - (int)last_so_far, (int)want); - any_need_entropy = 1; - } -- delay = 3; /* Use 3 seconds henceforth. */ -+ delay = 3000; /* Use 3 seconds henceforth. */ - continue; - } - else if( rc == -1 ) - { -- log_error ("select() error: %s\n", strerror(errno)); -+ log_error ("poll() error: %s\n", strerror(errno)); - if (!delay) -- delay = 1; /* Use 1 second if we encounter an error before -+ delay = 1000; /* Use 1 second if we encounter an error before - we have ever blocked. */ - continue; - } diff --git a/libgcrypt-1.5.1-use-poll.patch b/libgcrypt-1.5.1-use-poll.patch new file mode 100644 index 0000000..f6ed0b7 --- /dev/null +++ b/libgcrypt-1.5.1-use-poll.patch @@ -0,0 +1,82 @@ +diff -up libgcrypt-1.5.1/random/rndlinux.c.use-poll libgcrypt-1.5.1/random/rndlinux.c +--- libgcrypt-1.5.1/random/rndlinux.c.use-poll 2013-03-20 15:33:26.504867356 +0100 ++++ libgcrypt-1.5.1/random/rndlinux.c 2013-03-20 15:37:24.999944048 +0100 +@@ -32,6 +32,7 @@ + #include + #include + #include ++#include + #include "types.h" + #include "g10lib.h" + #include "rand-internal.h" +@@ -142,49 +143,37 @@ _gcry_rndlinux_gather_random (void (*add + } + + /* Enter the read loop. */ +- delay = 0; /* Start with 0 seconds so that we do no block on the ++ delay = 100; /* Start with 0 seconds so that we do no block on the + first iteration and in turn call the progress function + before blocking. To give the OS a better chance to + return with something we will actually use 100ms. */ + while (length) + { +- fd_set rfds; +- struct timeval tv; + int rc; ++ struct pollfd pfd; + +- /* If the system has no limit on the number of file descriptors +- and we encounter an fd which is larger than the fd_set size, +- we don't use the select at all. The select code is only used +- to emit progress messages. A better solution would be to +- fall back to poll() if available. */ +-#ifdef FD_SETSIZE +- if (fd < FD_SETSIZE) +-#endif ++ pfd.fd = fd; ++ pfd.events = POLLIN; ++ ++ if ( !(rc=poll(&pfd, 1, delay)) ) + { +- FD_ZERO(&rfds); +- FD_SET(fd, &rfds); +- tv.tv_sec = delay; +- tv.tv_usec = delay? 0 : 100000; +- if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) +- { +- if (!any_need_entropy || last_so_far != (want - length) ) +- { +- last_so_far = want - length; +- _gcry_random_progress ("need_entropy", 'X', +- (int)last_so_far, (int)want); +- any_need_entropy = 1; +- } +- delay = 3; /* Use 3 seconds henceforth. */ +- continue; +- } +- else if( rc == -1 ) ++ if (!any_need_entropy || last_so_far != (want - length) ) + { +- log_error ("select() error: %s\n", strerror(errno)); +- if (!delay) +- delay = 1; /* Use 1 second if we encounter an error before ++ last_so_far = want - length; ++ _gcry_random_progress ("need_entropy", 'X', ++ (int)last_so_far, (int)want); ++ any_need_entropy = 1; ++ } ++ delay = 3000; /* Use 3 seconds henceforth. */ ++ continue; ++ } ++ else if( rc == -1 ) ++ { ++ log_error ("poll() error: %s\n", strerror(errno)); ++ if (!delay) ++ delay = 1000; /* Use 1 second if we encounter an error before + we have ever blocked. */ +- continue; +- } ++ continue; + } + + do diff --git a/libgcrypt.spec b/libgcrypt.spec index 12b34ca..bf35271 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,8 +1,8 @@ Name: libgcrypt -Version: 1.5.0 -Release: 11%{?dist} +Version: 1.5.1 +Release: 1%{?dist} URL: http://www.gnupg.org/ -Source0: libgcrypt-%{version}-hobbled.tar.bz2 +Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with # the hobble-libgcrypt script. @@ -21,14 +21,10 @@ Patch5: libgcrypt-1.5.0-tests.patch Patch6: libgcrypt-1.5.0-fips-cfgrandom.patch # make the FIPS-186-3 DSA CAVS testable Patch7: libgcrypt-1.5.0-fips-cavs.patch -# add GCRYCTL_SET_ENFORCED_FIPS_FLAG -Patch8: libgcrypt-1.5.0-set-enforced-mode.patch # fix for memory leaks an other errors found by Coverity scan Patch9: libgcrypt-1.5.0-leak.patch -# allow empty passphrase (upstreamed) -Patch10: libgcrypt-1.5.0-empty-passphrase.patch # use poll instead of select when gathering randomness -Patch11: libgcrypt-1.5.0-use-poll.patch +Patch11: libgcrypt-1.5.1-use-poll.patch # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -68,9 +64,7 @@ applications using libgcrypt. %patch5 -p1 -b .tests %patch6 -p1 -b .cfgrandom %patch7 -p1 -b .cavs -%patch8 -p1 -b .enforce %patch9 -p1 -b .leak -%patch10 -p1 -b .emptypass %patch11 -p1 -b .use-poll mv AUTHORS AUTHORS.iso88591 @@ -185,6 +179,9 @@ exit 0 %doc COPYING %changelog +* Wed Mar 20 2013 Tomas Mraz 1.5.1-1 +- new upstream version + * Tue Mar 5 2013 Tomas Mraz 1.5.0-11 - use poll() instead of select() when gathering randomness (#913773) diff --git a/sources b/sources index 28984ca..e3421d3 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -35a73c1f2616ad904108ed8645c82f4c libgcrypt-1.5.0-hobbled.tar.bz2 +ec6ed0e0c3ad51a4a3d15e730cab0f6a libgcrypt-1.5.1-hobbled.tar.xz From d7bb823f8544209ffaa94cf2a531944e6c72384e Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 20 Mar 2013 19:34:46 +0100 Subject: [PATCH 056/214] AUTHORS file is now UTF-8 upstream. --- libgcrypt.spec | 3 --- 1 file changed, 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index bf35271..d3d0cc0 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -67,9 +67,6 @@ applications using libgcrypt. %patch9 -p1 -b .leak %patch11 -p1 -b .use-poll -mv AUTHORS AUTHORS.iso88591 -iconv -f ISO-8859-1 -t UTF-8 AUTHORS.iso88591 >AUTHORS - %build %configure --disable-static \ %ifarch sparc64 From 771f7f2ed7a70436abfe80077bdd9eca551d6b9b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 19 Apr 2013 10:34:04 +0200 Subject: [PATCH 057/214] new upstream version --- .gitignore | 1 + libgcrypt.spec | 5 ++++- sources | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 2474d69..3907163 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.4.6-hobbled.tar.bz2 /libgcrypt-1.5.0-hobbled.tar.bz2 /libgcrypt-1.5.1-hobbled.tar.xz +/libgcrypt-1.5.2-hobbled.tar.xz diff --git a/libgcrypt.spec b/libgcrypt.spec index d3d0cc0..e60bcd3 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.5.1 +Version: 1.5.2 Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -176,6 +176,9 @@ exit 0 %doc COPYING %changelog +* Fri Apr 19 2013 Tomáš Mráz 1.5.2-1 +- new upstream version + * Wed Mar 20 2013 Tomas Mraz 1.5.1-1 - new upstream version diff --git a/sources b/sources index e3421d3..ea4f3a4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -ec6ed0e0c3ad51a4a3d15e730cab0f6a libgcrypt-1.5.1-hobbled.tar.xz +2a60d011ddc880cfd0d1da8eaec228a5 libgcrypt-1.5.2-hobbled.tar.xz From b5413f756abe49172d2c042a3b3898bf5fe51ef1 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 25 Apr 2013 21:59:33 +0200 Subject: [PATCH 058/214] silence strict aliasing warning in Rijndael - apply UsrMove - spec file cleanups --- libgcrypt-1.5.2-aliasing.patch | 30 +++++++++++++++++++++++ libgcrypt.spec | 44 +++++++++++++++++----------------- 2 files changed, 52 insertions(+), 22 deletions(-) create mode 100644 libgcrypt-1.5.2-aliasing.patch diff --git a/libgcrypt-1.5.2-aliasing.patch b/libgcrypt-1.5.2-aliasing.patch new file mode 100644 index 0000000..db0e0e0 --- /dev/null +++ b/libgcrypt-1.5.2-aliasing.patch @@ -0,0 +1,30 @@ +diff -up libgcrypt-1.5.2/cipher/Makefile.am.aliasing libgcrypt-1.5.2/cipher/Makefile.am +--- libgcrypt-1.5.2/cipher/Makefile.am.aliasing 2013-04-18 16:49:13.000000000 +0200 ++++ libgcrypt-1.5.2/cipher/Makefile.am 2013-04-25 21:48:57.867465215 +0200 +@@ -81,3 +81,9 @@ tiger.o: $(srcdir)/tiger.c + + tiger.lo: $(srcdir)/tiger.c + `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` ++ ++rijndael.o: $(srcdir)/rijndael.c ++ `echo $(COMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` ++ ++rijndael.lo: $(srcdir)/rijndael.c ++ `echo $(LTCOMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` +diff -up libgcrypt-1.5.2/cipher/Makefile.in.aliasing libgcrypt-1.5.2/cipher/Makefile.in +--- libgcrypt-1.5.2/cipher/Makefile.in.aliasing 2013-04-18 17:06:03.000000000 +0200 ++++ libgcrypt-1.5.2/cipher/Makefile.in 2013-04-25 21:48:59.164493610 +0200 +@@ -638,6 +638,12 @@ tiger.o: $(srcdir)/tiger.c + tiger.lo: $(srcdir)/tiger.c + `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` + ++rijndael.o: $(srcdir)/rijndael.c ++ `echo $(COMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` ++ ++rijndael.lo: $(srcdir)/rijndael.c ++ `echo $(LTCOMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` ++ + # Tell versions [3.59,3.63) of GNU make to not export all variables. + # Otherwise a system limit (for SysV at least) may be exceeded. + .NOEXPORT: +diff -up libgcrypt-1.5.2/cipher/rijndael.c.aliasing libgcrypt-1.5.2/cipher/rijndael.c diff --git a/libgcrypt.spec b/libgcrypt.spec index e60bcd3..1083633 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.2 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -25,13 +25,16 @@ Patch7: libgcrypt-1.5.0-fips-cavs.patch Patch9: libgcrypt-1.5.0-leak.patch # use poll instead of select when gathering randomness Patch11: libgcrypt-1.5.1-use-poll.patch +# compile rijndael with -fno-strict-aliasing +Patch12: libgcrypt-1.5.2-aliasing.patch + +%define gcrylibdir %{_libdir} # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files # are in the devel subpackage. License: LGPLv2+ Summary: A general-purpose cryptography library -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root BuildRequires: gawk, libgpg-error-devel >= 1.4, pkgconfig BuildRequires: fipscheck # This is needed only when patching the .texi doc. @@ -66,6 +69,7 @@ applications using libgcrypt. %patch7 -p1 -b .cavs %patch9 -p1 -b .leak %patch11 -p1 -b .use-poll +%patch12 -p1 -b .aliasing %build %configure --disable-static \ @@ -87,11 +91,10 @@ make check %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ %{__os_install_post} \ - fipshmac $RPM_BUILD_ROOT/%{_lib}/*.so.?? \ + fipshmac $RPM_BUILD_ROOT%{gcrylibdir}/*.so.?? \ %{nil} %install -rm -fr $RPM_BUILD_ROOT make install DESTDIR=$RPM_BUILD_ROOT # Change /usr/lib64 back to /usr/lib. This saves us from having to patch the @@ -104,26 +107,20 @@ sed -i -e 's,^my_host=".*"$,my_host="none",g' $RPM_BUILD_ROOT/%{_bindir}/libgcry rm -f ${RPM_BUILD_ROOT}/%{_infodir}/dir ${RPM_BUILD_ROOT}/%{_libdir}/*.la /sbin/ldconfig -n $RPM_BUILD_ROOT/%{_libdir} -# Relocate the shared libraries to /%{_lib}. -mkdir -p $RPM_BUILD_ROOT/%{_lib} -for shlib in $RPM_BUILD_ROOT/%{_libdir}/*.so* ; do +%if "%{gcrylibdir}" != "%{_libdir}" +# Relocate the shared libraries to %{gcrylibdir}. +mkdir -p $RPM_BUILD_ROOT%{gcrylibdir} +for shlib in $RPM_BUILD_ROOT%{_libdir}/*.so* ; do if test -L "$shlib" ; then rm "$shlib" else - mv "$shlib" $RPM_BUILD_ROOT/%{_lib}/ + mv "$shlib" $RPM_BUILD_ROOT%{gcrylibdir}/ fi done -# Figure out where /%{_lib} is relative to %{_libdir}. -touch $RPM_BUILD_ROOT/root_marker -relroot=.. -while ! test -f $RPM_BUILD_ROOT/%{_libdir}/$relroot/root_marker ; do - relroot=$relroot/.. -done - # Overwrite development symlinks. pushd $RPM_BUILD_ROOT/%{_libdir} -for shlib in $relroot/%{_lib}/lib*.so.* ; do +for shlib in %{gcrylibdir}/lib*.so.* ; do shlib=`echo "$shlib" | sed -e 's,//,/,g'` target=`basename "$shlib" | sed -e 's,\.so.*,,g'`.so ln -sf $shlib $target @@ -132,15 +129,13 @@ popd # Add soname symlink. /sbin/ldconfig -n $RPM_BUILD_ROOT/%{_lib}/ -rm -f $RPM_BUILD_ROOT/root_marker +%endif + # Create /etc/gcrypt (hardwired, not dependent on the configure invocation) so # that _someone_ owns it. mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt -%clean -rm -fr $RPM_BUILD_ROOT - %post -p /sbin/ldconfig %postun -p /sbin/ldconfig @@ -159,8 +154,8 @@ exit 0 %files %defattr(-,root,root,-) %dir /etc/gcrypt -/%{_lib}/libgcrypt.so.* -/%{_lib}/.libgcrypt.so.*.hmac +%{gcrylibdir}/libgcrypt.so.* +%{gcrylibdir}/.libgcrypt.so.*.hmac %doc COPYING.LIB AUTHORS NEWS THANKS %files devel @@ -176,6 +171,11 @@ exit 0 %doc COPYING %changelog +* Thu Apr 25 2013 Tomáš Mráz 1.5.2-2 +- silence strict aliasing warning in Rijndael +- apply UsrMove +- spec file cleanups + * Fri Apr 19 2013 Tomáš Mráz 1.5.2-1 - new upstream version From 03c131f7fa370397cbfc0676597fefebe8322e46 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 20 Jun 2013 11:51:19 +0200 Subject: [PATCH 059/214] silence false error detected by valgrind (#968288) --- libgcrypt-1.5.2-mpicoder-gccopt.patch | 102 ++++++++++++++++++++++++++ libgcrypt.spec | 8 +- 2 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.5.2-mpicoder-gccopt.patch diff --git a/libgcrypt-1.5.2-mpicoder-gccopt.patch b/libgcrypt-1.5.2-mpicoder-gccopt.patch new file mode 100644 index 0000000..c374709 --- /dev/null +++ b/libgcrypt-1.5.2-mpicoder-gccopt.patch @@ -0,0 +1,102 @@ +diff -up libgcrypt-1.5.2/mpi/mpicoder.c.gccopt libgcrypt-1.5.2/mpi/mpicoder.c +--- libgcrypt-1.5.2/mpi/mpicoder.c.gccopt 2013-04-18 16:48:42.000000000 +0200 ++++ libgcrypt-1.5.2/mpi/mpicoder.c 2013-06-20 10:24:57.241510589 +0200 +@@ -555,16 +555,16 @@ gcry_mpi_print (enum gcry_mpi_format for + extra=1; + } + +- if (buffer && n > len) +- { +- /* The provided buffer is too short. */ +- gcry_free (tmp); +- return gcry_error (GPG_ERR_TOO_SHORT); +- } + if (buffer) + { + unsigned char *s = buffer; + ++ if (n > len) ++ { ++ /* The provided buffer is too short. */ ++ gcry_free (tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } + if (extra) + *s++ = 0; + memcpy (s, tmp, n-extra); +@@ -580,12 +580,12 @@ gcry_mpi_print (enum gcry_mpi_format for + /* Note: We ignore the sign for this format. */ + /* FIXME: for performance reasons we should put this into + mpi_aprint because we can then use the buffer directly. */ +- if (buffer && n > len) +- return gcry_error (GPG_ERR_TOO_SHORT); + if (buffer) + { + unsigned char *tmp; + ++ if (n > len) ++ return gcry_error (GPG_ERR_TOO_SHORT); + tmp = _gcry_mpi_get_buffer (a, &n, NULL); + if (!tmp) + return gpg_error_from_syserror (); +@@ -603,14 +603,13 @@ gcry_mpi_print (enum gcry_mpi_format for + if( a->sign ) + return gcry_error (GPG_ERR_INV_ARG); + +- if (buffer && n+2 > len) +- return gcry_error (GPG_ERR_TOO_SHORT); +- + if (buffer) + { + unsigned char *tmp; + unsigned char *s = buffer; + ++ if (n+2 > len) ++ return gcry_error (GPG_ERR_TOO_SHORT); + s[0] = nbits >> 8; + s[1] = nbits; + +@@ -641,16 +640,16 @@ gcry_mpi_print (enum gcry_mpi_format for + extra=1; + } + +- if (buffer && n+4 > len) +- { +- gcry_free(tmp); +- return gcry_error (GPG_ERR_TOO_SHORT); +- } +- + if (buffer) + { + unsigned char *s = buffer; + ++ if (n+4 > len) ++ { ++ gcry_free(tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } ++ + *s++ = n >> 24; + *s++ = n >> 16; + *s++ = n >> 8; +@@ -677,15 +676,15 @@ gcry_mpi_print (enum gcry_mpi_format for + if (!n || (*tmp & 0x80)) + extra = 2; + +- if (buffer && 2*n + extra + !!a->sign + 1 > len) +- { +- gcry_free(tmp); +- return gcry_error (GPG_ERR_TOO_SHORT); +- } + if (buffer) + { + unsigned char *s = buffer; + ++ if (2*n + extra + !!a->sign + 1 > len) ++ { ++ gcry_free(tmp); ++ return gcry_error (GPG_ERR_TOO_SHORT); ++ } + if (a->sign) + *s++ = '-'; + if (extra) diff --git a/libgcrypt.spec b/libgcrypt.spec index 1083633..4efb4d4 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.2 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -27,6 +27,8 @@ Patch9: libgcrypt-1.5.0-leak.patch Patch11: libgcrypt-1.5.1-use-poll.patch # compile rijndael with -fno-strict-aliasing Patch12: libgcrypt-1.5.2-aliasing.patch +# slight optimalization of mpicoder.c to silence Valgrind (#968288) +Patch13: libgcrypt-1.5.2-mpicoder-gccopt.patch %define gcrylibdir %{_libdir} @@ -70,6 +72,7 @@ applications using libgcrypt. %patch9 -p1 -b .leak %patch11 -p1 -b .use-poll %patch12 -p1 -b .aliasing +%patch13 -p1 -b .gccopt %build %configure --disable-static \ @@ -171,6 +174,9 @@ exit 0 %doc COPYING %changelog +* Thu Jun 20 2013 Tomáš Mráz 1.5.2-3 +- silence false error detected by valgrind (#968288) + * Thu Apr 25 2013 Tomáš Mráz 1.5.2-2 - silence strict aliasing warning in Rijndael - apply UsrMove From 0551bce38177a2bfa754edceac7057e84b9e7442 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 26 Jul 2013 14:27:50 +0200 Subject: [PATCH 060/214] new upstream version fixing cache side-channel attack on RSA private keys --- .gitignore | 1 + libgcrypt.spec | 7 +++++-- sources | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 3907163..d77b0c1 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.5.0-hobbled.tar.bz2 /libgcrypt-1.5.1-hobbled.tar.xz /libgcrypt-1.5.2-hobbled.tar.xz +/libgcrypt-1.5.3-hobbled.tar.xz diff --git a/libgcrypt.spec b/libgcrypt.spec index 4efb4d4..6aca195 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.5.2 -Release: 3%{?dist} +Version: 1.5.3 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -174,6 +174,9 @@ exit 0 %doc COPYING %changelog +* Fri Jul 26 2013 Tomáš Mráz 1.5.3-1 +- new upstream version fixing cache side-channel attack on RSA private keys + * Thu Jun 20 2013 Tomáš Mráz 1.5.2-3 - silence false error detected by valgrind (#968288) diff --git a/sources b/sources index ea4f3a4..4838fbc 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -2a60d011ddc880cfd0d1da8eaec228a5 libgcrypt-1.5.2-hobbled.tar.xz +99e0f2dc94dac6eceab709d03d613328 libgcrypt-1.5.3-hobbled.tar.xz From 5eab7fdca51b8ae459d49ef2bd401861de0ae2d7 Mon Sep 17 00:00:00 2001 From: Tom Callaway Date: Mon, 21 Oct 2013 17:50:29 +0100 Subject: [PATCH 061/214] add cleared ECC support --- curves.c | 166 +++ ecc.c | 1658 ++++++++++++++++++++++++++++ libgcrypt-1.5.3-ecc-test-fix.patch | 12 + libgcrypt.spec | 22 +- 4 files changed, 1852 insertions(+), 6 deletions(-) create mode 100644 curves.c create mode 100644 ecc.c create mode 100644 libgcrypt-1.5.3-ecc-test-fix.patch diff --git a/curves.c b/curves.c new file mode 100644 index 0000000..caead00 --- /dev/null +++ b/curves.c @@ -0,0 +1,166 @@ +/* curves.c - ECC curves regression tests + * Copyright (C) 2011 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif +#include +#include +#include +#include + +#include "../src/gcrypt.h" + +/* Number of curves defined in ../cipger/ecc.c */ +#define N_CURVES 2 + +/* A real world sample public key. */ +static char const sample_key_1[] = +"(public-key\n" +" (ecdsa\n" +" (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)\n" +" (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)\n" +" (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)\n" +" (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" + "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n" +" (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n" +" (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE" + "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n" +" ))"; +static char const sample_key_1_curve[] = "NIST P-256"; +static unsigned int sample_key_1_nbits = 256; + +/* Program option flags. */ +static int verbose; +static int error_count; + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + +static void +list_curves (void) +{ + int idx; + const char *name; + unsigned int nbits; + + for (idx=0; (name = gcry_pk_get_curve (NULL, idx, &nbits)); idx++) + { + if (verbose) + printf ("%s - %u bits\n", name, nbits); + } + if (idx != N_CURVES) + fail ("expected %d curves but got %d\n", N_CURVES, idx); + if (gcry_pk_get_curve (NULL, -1, NULL)) + fail ("curve iteration failed\n"); +} + + +static void +check_matching (void) +{ + gpg_error_t err; + gcry_sexp_t key; + const char *name; + unsigned int nbits; + + err = gcry_sexp_new (&key, sample_key_1, 0, 1); + if (err) + die ("parsing s-expression string failed: %s\n", gpg_strerror (err)); + name = gcry_pk_get_curve (key, 0, &nbits); + if (!name) + fail ("curve name not found for sample_key_1\n"); + else if (strcmp (name, sample_key_1_curve)) + fail ("expected curve name %s but got %s for sample_key_1\n", + sample_key_1_curve, name); + else if (nbits != sample_key_1_nbits) + fail ("expected curve size %u but got %u for sample_key_1\n", + sample_key_1_nbits, nbits); + + gcry_sexp_release (key); + +} + + +static void +check_get_params (void) +{ + gcry_sexp_t param; + const char *name; + + param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_1_curve); + if (!param) + fail ("error gerring parameters for `%s'\n", sample_key_1_curve); + + name = gcry_pk_get_curve (param, 0, NULL); + if (!name) + fail ("get_param: curve name not found for sample_key_1\n"); + else if (strcmp (name, sample_key_1_curve)) + fail ("get_param: expected curve name %s but got %s for sample_key_1\n", + sample_key_1_curve, name); + + gcry_sexp_release (param); + +} + + +int +main (int argc, char **argv) +{ + int debug = 0; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + list_curves (); + check_matching (); + check_get_params (); + + return error_count ? 1 : 0; +} diff --git a/ecc.c b/ecc.c new file mode 100644 index 0000000..bf63f4b --- /dev/null +++ b/ecc.c @@ -0,0 +1,1658 @@ +/* ecc.c - Elliptic Curve Cryptography + Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. + + This file is part of Libgcrypt. + + Libgcrypt 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. + + Libgcrypt 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 program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +/* This code is originally based on the Patch 0.1.6 for the gnupg + 1.4.x branch as retrieved on 2007-03-21 from + http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2 + The original authors are: + Written by + Sergi Blanch i Torne , + Ramiro Moreno Chiral + Maintainers + Sergi Blanch i Torne + Ramiro Moreno Chiral + Mikael Mylnikov (mmr) + For use in Libgcrypt the code has been heavily modified and cleaned + up. In fact there is not much left of the orginally code except for + some variable names and the text book implementaion of the sign and + verification algorithms. The arithmetic functions have entirely + been rewritten and moved to mpi/ec.c. + + ECDH encrypt and decrypt code written by Andrey Jivsov, +*/ + + +/* TODO: + + - If we support point compression we need to uncompress before + computing the keygrip + + - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a + special case in mpi_powm or check whether mpi_mulm is faster. + + - Decide whether we should hide the mpi_point_t definition. +*/ + + +#include +#include +#include +#include + +#include "g10lib.h" +#include "mpi.h" +#include "cipher.h" + +/* Definition of a curve. */ +typedef struct +{ + gcry_mpi_t p; /* Prime specifying the field GF(p). */ + gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */ + gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */ + mpi_point_t G; /* Base point (generator). */ + gcry_mpi_t n; /* Order of G. */ + const char *name; /* Name of curve or NULL. */ +} elliptic_curve_t; + + +typedef struct +{ + elliptic_curve_t E; + mpi_point_t Q; /* Q = [d]G */ +} ECC_public_key; + +typedef struct +{ + elliptic_curve_t E; + mpi_point_t Q; + gcry_mpi_t d; +} ECC_secret_key; + + +/* This tables defines aliases for curve names. */ +static const struct +{ + const char *name; /* Our name. */ + const char *other; /* Other name. */ +} curve_aliases[] = + { + { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */ + { "NIST P-256", "prime256v1" }, + { "NIST P-256", "secp256r1" }, + + { "NIST P-384", "secp384r1" }, + { "NIST P-384", "1.3.132.0.34" }, + + { NULL, NULL} + }; + +typedef struct { + const char *desc; /* Description of the curve. */ + unsigned int nbits; /* Number of bits. */ + unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */ + const char *p; /* Order of the prime field. */ + const char *a, *b; /* The coefficients. */ + const char *n; /* The order of the base point. */ + const char *g_x, *g_y; /* Base point. */ +} ecc_domain_parms_t; + +/* This static table defines all available curves. */ +static const ecc_domain_parms_t domain_parms[] = + { + { + "NIST P-256", 256, 1, + "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", + "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", + "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + + "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + }, + { + "NIST P-384", 384, 1, + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + "ffffffff0000000000000000ffffffff", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + "ffffffff0000000000000000fffffffc", + "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" + "c656398d8a2ed19d2a85c8edd3ec2aef", + "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" + "581a0db248b0a77aecec196accc52973", + + "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" + "5502f25dbf55296c3a545e3872760ab7", + "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" + "0a60b1ce1d7e819d7a431d7c90ea0e5f" + }, + + { NULL, 0, 0, NULL, NULL, NULL, NULL } + }; + + +/* Registered progress function and its callback value. */ +static void (*progress_cb) (void *, const char*, int, int, int); +static void *progress_cb_data; + + +#define point_init(a) _gcry_mpi_ec_point_init ((a)) +#define point_free(a) _gcry_mpi_ec_point_free ((a)) + + + +/* Local prototypes. */ +static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level); +static void test_keys (ECC_secret_key * sk, unsigned int nbits); +static int check_secret_key (ECC_secret_key * sk); +static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey, + gcry_mpi_t r, gcry_mpi_t s); +static gpg_err_code_t verify (gcry_mpi_t input, ECC_public_key *pkey, + gcry_mpi_t r, gcry_mpi_t s); + + +static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base); + + + + +void +_gcry_register_pk_ecc_progress (void (*cb) (void *, const char *, + int, int, int), + void *cb_data) +{ + progress_cb = cb; + progress_cb_data = cb_data; +} + +/* static void */ +/* progress (int c) */ +/* { */ +/* if (progress_cb) */ +/* progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */ +/* } */ + + + + +/* Set the value from S into D. */ +static void +point_set (mpi_point_t *d, mpi_point_t *s) +{ + mpi_set (d->x, s->x); + mpi_set (d->y, s->y); + mpi_set (d->z, s->z); +} + + +/* + * Release a curve object. + */ +static void +curve_free (elliptic_curve_t *E) +{ + mpi_free (E->p); E->p = NULL; + mpi_free (E->a); E->a = NULL; + mpi_free (E->b); E->b = NULL; + point_free (&E->G); + mpi_free (E->n); E->n = NULL; +} + + +/* + * Return a copy of a curve object. + */ +static elliptic_curve_t +curve_copy (elliptic_curve_t E) +{ + elliptic_curve_t R; + + R.p = mpi_copy (E.p); + R.a = mpi_copy (E.a); + R.b = mpi_copy (E.b); + point_init (&R.G); + point_set (&R.G, &E.G); + R.n = mpi_copy (E.n); + + return R; +} + + +/* Helper to scan a hex string. */ +static gcry_mpi_t +scanval (const char *string) +{ + gpg_error_t err; + gcry_mpi_t val; + + err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); + if (err) + log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err)); + return val; +} + + + + + +/**************** + * Solve the right side of the equation that defines a curve. + */ +static gcry_mpi_t +gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base) +{ + gcry_mpi_t three, x_3, axb, y; + + three = mpi_alloc_set_ui (3); + x_3 = mpi_new (0); + axb = mpi_new (0); + y = mpi_new (0); + + mpi_powm (x_3, x, three, base->p); + mpi_mulm (axb, base->a, x, base->p); + mpi_addm (axb, axb, base->b, base->p); + mpi_addm (y, x_3, axb, base->p); + + mpi_free (x_3); + mpi_free (axb); + mpi_free (three); + return y; /* The quadratic value of the coordinate if it exist. */ +} + + +/* Generate a random secret scalar k with an order of p + + At the beginning this was identical to the code is in elgamal.c. + Later imporved by mmr. Further simplified by wk. */ +static gcry_mpi_t +gen_k (gcry_mpi_t p, int security_level) +{ + gcry_mpi_t k; + unsigned int nbits; + + nbits = mpi_get_nbits (p); + k = mpi_snew (nbits); + if (DBG_CIPHER) + log_debug ("choosing a random k of %u bits at seclevel %d\n", + nbits, security_level); + + gcry_mpi_randomize (k, nbits, security_level); + + mpi_mod (k, k, p); /* k = k mod p */ + + return k; +} + + +/* Generate the crypto system setup. This function takes the NAME of + a curve or the desired number of bits and stores at R_CURVE the + parameters of the named curve or those of a suitable curve. The + chosen number of bits is stored on R_NBITS. */ +static gpg_err_code_t +fill_in_curve (unsigned int nbits, const char *name, + elliptic_curve_t *curve, unsigned int *r_nbits) +{ + int idx, aliasno; + const char *resname = NULL; /* Set to a found curve name. */ + + if (name) + { + /* First check our native curves. */ + for (idx = 0; domain_parms[idx].desc; idx++) + if (!strcmp (name, domain_parms[idx].desc)) + { + resname = domain_parms[idx].desc; + break; + } + /* If not found consult the alias table. */ + if (!domain_parms[idx].desc) + { + for (aliasno = 0; curve_aliases[aliasno].name; aliasno++) + if (!strcmp (name, curve_aliases[aliasno].other)) + break; + if (curve_aliases[aliasno].name) + { + for (idx = 0; domain_parms[idx].desc; idx++) + if (!strcmp (curve_aliases[aliasno].name, + domain_parms[idx].desc)) + { + resname = domain_parms[idx].desc; + break; + } + } + } + } + else + { + for (idx = 0; domain_parms[idx].desc; idx++) + if (nbits == domain_parms[idx].nbits) + break; + } + if (!domain_parms[idx].desc) + return GPG_ERR_INV_VALUE; + + /* In fips mode we only support NIST curves. Note that it is + possible to bypass this check by specifying the curve parameters + directly. */ + if (fips_mode () && !domain_parms[idx].fips ) + return GPG_ERR_NOT_SUPPORTED; + + *r_nbits = domain_parms[idx].nbits; + curve->p = scanval (domain_parms[idx].p); + curve->a = scanval (domain_parms[idx].a); + curve->b = scanval (domain_parms[idx].b); + curve->n = scanval (domain_parms[idx].n); + curve->G.x = scanval (domain_parms[idx].g_x); + curve->G.y = scanval (domain_parms[idx].g_y); + curve->G.z = mpi_alloc_set_ui (1); + curve->name = resname; + + return 0; +} + + +/* + * First obtain the setup. Over the finite field randomize an scalar + * secret value, and calculate the public point. + */ +static gpg_err_code_t +generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, + int transient_key, + gcry_mpi_t g_x, gcry_mpi_t g_y, + gcry_mpi_t q_x, gcry_mpi_t q_y, + const char **r_usedcurve) +{ + gpg_err_code_t err; + elliptic_curve_t E; + gcry_mpi_t d; + mpi_point_t Q; + mpi_ec_t ctx; + gcry_random_level_t random_level; + + *r_usedcurve = NULL; + + err = fill_in_curve (nbits, name, &E, &nbits); + if (err) + return err; + + if (DBG_CIPHER) + { + log_mpidump ("ecgen curve p", E.p); + log_mpidump ("ecgen curve a", E.a); + log_mpidump ("ecgen curve b", E.b); + log_mpidump ("ecgen curve n", E.n); + log_mpidump ("ecgen curve Gx", E.G.x); + log_mpidump ("ecgen curve Gy", E.G.y); + log_mpidump ("ecgen curve Gz", E.G.z); + if (E.name) + log_debug ("ecgen curve used: %s\n", E.name); + } + + random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; + d = gen_k (E.n, random_level); + + /* Compute Q. */ + point_init (&Q); + ctx = _gcry_mpi_ec_init (E.p, E.a); + _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx); + + /* Copy the stuff to the key structures. */ + sk->E.p = mpi_copy (E.p); + sk->E.a = mpi_copy (E.a); + sk->E.b = mpi_copy (E.b); + point_init (&sk->E.G); + point_set (&sk->E.G, &E.G); + sk->E.n = mpi_copy (E.n); + point_init (&sk->Q); + point_set (&sk->Q, &Q); + sk->d = mpi_copy (d); + /* We also return copies of G and Q in affine coordinates if + requested. */ + if (g_x && g_y) + { + if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx)) + log_fatal ("ecgen: Failed to get affine coordinates\n"); + } + if (q_x && q_y) + { + if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx)) + log_fatal ("ecgen: Failed to get affine coordinates\n"); + } + _gcry_mpi_ec_free (ctx); + + point_free (&Q); + mpi_free (d); + + *r_usedcurve = E.name; + curve_free (&E); + + /* Now we can test our keys (this should never fail!). */ + test_keys (sk, nbits - 64); + + return 0; +} + + +/* + * To verify correct skey it use a random information. + * First, encrypt and decrypt this dummy value, + * test if the information is recuperated. + * Second, test with the sign and verify functions. + */ +static void +test_keys (ECC_secret_key *sk, unsigned int nbits) +{ + ECC_public_key pk; + gcry_mpi_t test = mpi_new (nbits); + mpi_point_t R_; + gcry_mpi_t c = mpi_new (nbits); + gcry_mpi_t out = mpi_new (nbits); + gcry_mpi_t r = mpi_new (nbits); + gcry_mpi_t s = mpi_new (nbits); + + if (DBG_CIPHER) + log_debug ("Testing key.\n"); + + point_init (&R_); + + pk.E = curve_copy (sk->E); + point_init (&pk.Q); + point_set (&pk.Q, &sk->Q); + + gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM); + + if (sign (test, sk, r, s) ) + log_fatal ("ECDSA operation: sign failed\n"); + + if (verify (test, &pk, r, s)) + { + log_fatal ("ECDSA operation: sign, verify failed\n"); + } + + if (DBG_CIPHER) + log_debug ("ECDSA operation: sign, verify ok.\n"); + + point_free (&pk.Q); + curve_free (&pk.E); + + point_free (&R_); + mpi_free (s); + mpi_free (r); + mpi_free (out); + mpi_free (c); + mpi_free (test); +} + + +/* + * To check the validity of the value, recalculate the correspondence + * between the public value and the secret one. + */ +static int +check_secret_key (ECC_secret_key * sk) +{ + int rc = 1; + mpi_point_t Q; + gcry_mpi_t y_2, y2; + mpi_ec_t ctx = NULL; + + point_init (&Q); + + /* ?primarity test of 'p' */ + /* (...) //!! */ + /* G in E(F_p) */ + y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */ + y2 = mpi_alloc (0); + mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */ + if (mpi_cmp (y_2, y2)) + { + if (DBG_CIPHER) + log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n"); + goto leave; + } + /* G != PaI */ + if (!mpi_cmp_ui (sk->E.G.z, 0)) + { + if (DBG_CIPHER) + log_debug ("Bad check: 'G' cannot be Point at Infinity!\n"); + goto leave; + } + + ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a); + + _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx); + if (mpi_cmp_ui (Q.z, 0)) + { + if (DBG_CIPHER) + log_debug ("check_secret_key: E is not a curve of order n\n"); + goto leave; + } + /* pubkey cannot be PaI */ + if (!mpi_cmp_ui (sk->Q.z, 0)) + { + if (DBG_CIPHER) + log_debug ("Bad check: Q can not be a Point at Infinity!\n"); + goto leave; + } + /* pubkey = [d]G over E */ + _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx); + if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z)) + { + if (DBG_CIPHER) + log_debug + ("Bad check: There is NO correspondence between 'd' and 'Q'!\n"); + goto leave; + } + rc = 0; /* Okay. */ + + leave: + _gcry_mpi_ec_free (ctx); + mpi_free (y2); + mpi_free (y_2); + point_free (&Q); + return rc; +} + + +/* + * Return the signature struct (r,s) from the message hash. The caller + * must have allocated R and S. + */ +static gpg_err_code_t +sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s) +{ + gpg_err_code_t err = 0; + gcry_mpi_t k, dr, sum, k_1, x; + mpi_point_t I; + mpi_ec_t ctx; + + if (DBG_CIPHER) + log_mpidump ("ecdsa sign hash ", input ); + + k = NULL; + dr = mpi_alloc (0); + sum = mpi_alloc (0); + k_1 = mpi_alloc (0); + x = mpi_alloc (0); + point_init (&I); + + mpi_set_ui (s, 0); + mpi_set_ui (r, 0); + + ctx = _gcry_mpi_ec_init (skey->E.p, skey->E.a); + + while (!mpi_cmp_ui (s, 0)) /* s == 0 */ + { + while (!mpi_cmp_ui (r, 0)) /* r == 0 */ + { + /* Note, that we are guaranteed to enter this loop at least + once because r has been intialized to 0. We can't use a + do_while because we want to keep the value of R even if S + has to be recomputed. */ + mpi_free (k); + k = gen_k (skey->E.n, GCRY_STRONG_RANDOM); + _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx); + if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx)) + { + if (DBG_CIPHER) + log_debug ("ecc sign: Failed to get affine coordinates\n"); + err = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + mpi_mod (r, x, skey->E.n); /* r = x mod n */ + } + mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */ + mpi_addm (sum, input, dr, skey->E.n); /* sum = hash + (d*r) mod n */ + mpi_invm (k_1, k, skey->E.n); /* k_1 = k^(-1) mod n */ + mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */ + } + + if (DBG_CIPHER) + { + log_mpidump ("ecdsa sign result r ", r); + log_mpidump ("ecdsa sign result s ", s); + } + + leave: + _gcry_mpi_ec_free (ctx); + point_free (&I); + mpi_free (x); + mpi_free (k_1); + mpi_free (sum); + mpi_free (dr); + mpi_free (k); + + return err; +} + + +/* + * Check if R and S verifies INPUT. + */ +static gpg_err_code_t +verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s) +{ + gpg_err_code_t err = 0; + gcry_mpi_t h, h1, h2, x, y; + mpi_point_t Q, Q1, Q2; + mpi_ec_t ctx; + + if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) ) + return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */ + if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) ) + return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */ + + h = mpi_alloc (0); + h1 = mpi_alloc (0); + h2 = mpi_alloc (0); + x = mpi_alloc (0); + y = mpi_alloc (0); + point_init (&Q); + point_init (&Q1); + point_init (&Q2); + + ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a); + + /* h = s^(-1) (mod n) */ + mpi_invm (h, s, pkey->E.n); +/* log_mpidump (" h", h); */ + /* h1 = hash * s^(-1) (mod n) */ + mpi_mulm (h1, input, h, pkey->E.n); +/* log_mpidump (" h1", h1); */ + /* Q1 = [ hash * s^(-1) ]G */ + _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx); +/* log_mpidump ("Q1.x", Q1.x); */ +/* log_mpidump ("Q1.y", Q1.y); */ +/* log_mpidump ("Q1.z", Q1.z); */ + /* h2 = r * s^(-1) (mod n) */ + mpi_mulm (h2, r, h, pkey->E.n); +/* log_mpidump (" h2", h2); */ + /* Q2 = [ r * s^(-1) ]Q */ + _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx); +/* log_mpidump ("Q2.x", Q2.x); */ +/* log_mpidump ("Q2.y", Q2.y); */ +/* log_mpidump ("Q2.z", Q2.z); */ + /* Q = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */ + _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx); +/* log_mpidump (" Q.x", Q.x); */ +/* log_mpidump (" Q.y", Q.y); */ +/* log_mpidump (" Q.z", Q.z); */ + + if (!mpi_cmp_ui (Q.z, 0)) + { + if (DBG_CIPHER) + log_debug ("ecc verify: Rejected\n"); + err = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx)) + { + if (DBG_CIPHER) + log_debug ("ecc verify: Failed to get affine coordinates\n"); + err = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */ + if (mpi_cmp (x, r)) /* x != r */ + { + if (DBG_CIPHER) + { + log_mpidump (" x", x); + log_mpidump (" y", y); + log_mpidump (" r", r); + log_mpidump (" s", s); + log_debug ("ecc verify: Not verified\n"); + } + err = GPG_ERR_BAD_SIGNATURE; + goto leave; + } + if (DBG_CIPHER) + log_debug ("ecc verify: Accepted\n"); + + leave: + _gcry_mpi_ec_free (ctx); + point_free (&Q2); + point_free (&Q1); + point_free (&Q); + mpi_free (y); + mpi_free (x); + mpi_free (h2); + mpi_free (h1); + mpi_free (h); + return err; +} + + + +/********************************************* + ************** interface ****************** + *********************************************/ +static gcry_mpi_t +ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p) +{ + gpg_error_t err; + int pbytes = (mpi_get_nbits (p)+7)/8; + size_t n; + unsigned char *buf, *ptr; + gcry_mpi_t result; + + buf = gcry_xmalloc ( 1 + 2*pbytes ); + *buf = 04; /* Uncompressed point. */ + ptr = buf+1; + err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x); + if (err) + log_fatal ("mpi_print failed: %s\n", gpg_strerror (err)); + if (n < pbytes) + { + memmove (ptr+(pbytes-n), ptr, n); + memset (ptr, 0, (pbytes-n)); + } + ptr += pbytes; + err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y); + if (err) + log_fatal ("mpi_print failed: %s\n", gpg_strerror (err)); + if (n < pbytes) + { + memmove (ptr+(pbytes-n), ptr, n); + memset (ptr, 0, (pbytes-n)); + } + + err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL); + if (err) + log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); + gcry_free (buf); + + return result; +} + + +/* RESULT must have been initialized and is set on success to the + point given by VALUE. */ +static gcry_error_t +os2ec (mpi_point_t *result, gcry_mpi_t value) +{ + gcry_error_t err; + size_t n; + unsigned char *buf; + gcry_mpi_t x, y; + + n = (mpi_get_nbits (value)+7)/8; + buf = gcry_xmalloc (n); + err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value); + if (err) + { + gcry_free (buf); + return err; + } + if (n < 1) + { + gcry_free (buf); + return GPG_ERR_INV_OBJ; + } + if (*buf != 4) + { + gcry_free (buf); + return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression. */ + } + if ( ((n-1)%2) ) + { + gcry_free (buf); + return GPG_ERR_INV_OBJ; + } + n = (n-1)/2; + err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL); + if (err) + { + gcry_free (buf); + return err; + } + err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL); + gcry_free (buf); + if (err) + { + mpi_free (x); + return err; + } + + mpi_set (result->x, x); + mpi_set (result->y, y); + mpi_set_ui (result->z, 1); + + mpi_free (x); + mpi_free (y); + + return 0; +} + + +/* Extended version of ecc_generate. */ +static gcry_err_code_t +ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue, + const gcry_sexp_t genparms, + gcry_mpi_t *skey, gcry_mpi_t **retfactors, + gcry_sexp_t *r_extrainfo) +{ + gpg_err_code_t ec; + ECC_secret_key sk; + gcry_mpi_t g_x, g_y, q_x, q_y; + char *curve_name = NULL; + gcry_sexp_t l1; + int transient_key = 0; + const char *usedcurve = NULL; + + (void)algo; + (void)evalue; + + if (genparms) + { + /* Parse the optional "curve" parameter. */ + l1 = gcry_sexp_find_token (genparms, "curve", 0); + if (l1) + { + curve_name = _gcry_sexp_nth_string (l1, 1); + gcry_sexp_release (l1); + if (!curve_name) + return GPG_ERR_INV_OBJ; /* No curve name or value too large. */ + } + + /* Parse the optional transient-key flag. */ + l1 = gcry_sexp_find_token (genparms, "transient-key", 0); + if (l1) + { + transient_key = 1; + gcry_sexp_release (l1); + } + } + + /* NBITS is required if no curve name has been given. */ + if (!nbits && !curve_name) + return GPG_ERR_NO_OBJ; /* No NBITS parameter. */ + + g_x = mpi_new (0); + g_y = mpi_new (0); + q_x = mpi_new (0); + q_y = mpi_new (0); + ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y, + &usedcurve); + gcry_free (curve_name); + if (ec) + return ec; + if (usedcurve) /* Fixme: No error return checking. */ + gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve); + + skey[0] = sk.E.p; + skey[1] = sk.E.a; + skey[2] = sk.E.b; + skey[3] = ec2os (g_x, g_y, sk.E.p); + skey[4] = sk.E.n; + skey[5] = ec2os (q_x, q_y, sk.E.p); + skey[6] = sk.d; + + mpi_free (g_x); + mpi_free (g_y); + mpi_free (q_x); + mpi_free (q_y); + + point_free (&sk.E.G); + point_free (&sk.Q); + + /* Make an empty list of factors. */ + *retfactors = gcry_calloc ( 1, sizeof **retfactors ); + if (!*retfactors) + return gpg_err_code_from_syserror (); /* Fixme: relase mem? */ + + if (DBG_CIPHER) + { + log_mpidump ("ecgen result p", skey[0]); + log_mpidump ("ecgen result a", skey[1]); + log_mpidump ("ecgen result b", skey[2]); + log_mpidump ("ecgen result G", skey[3]); + log_mpidump ("ecgen result n", skey[4]); + log_mpidump ("ecgen result Q", skey[5]); + log_mpidump ("ecgen result d", skey[6]); + } + + return 0; +} + + +static gcry_err_code_t +ecc_generate (int algo, unsigned int nbits, unsigned long evalue, + gcry_mpi_t *skey, gcry_mpi_t **retfactors) +{ + (void)evalue; + return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL); +} + + +/* Return the parameters of the curve NAME in an MPI array. */ +static gcry_err_code_t +ecc_get_param (const char *name, gcry_mpi_t *pkey) +{ + gpg_err_code_t err; + unsigned int nbits; + elliptic_curve_t E; + mpi_ec_t ctx; + gcry_mpi_t g_x, g_y; + + err = fill_in_curve (0, name, &E, &nbits); + if (err) + return err; + + g_x = mpi_new (0); + g_y = mpi_new (0); + ctx = _gcry_mpi_ec_init (E.p, E.a); + if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx)) + log_fatal ("ecc get param: Failed to get affine coordinates\n"); + _gcry_mpi_ec_free (ctx); + point_free (&E.G); + + pkey[0] = E.p; + pkey[1] = E.a; + pkey[2] = E.b; + pkey[3] = ec2os (g_x, g_y, E.p); + pkey[4] = E.n; + pkey[5] = NULL; + + mpi_free (g_x); + mpi_free (g_y); + + return 0; +} + + +/* Return the parameters of the curve NAME as an S-expression. */ +static gcry_sexp_t +ecc_get_param_sexp (const char *name) +{ + gcry_mpi_t pkey[6]; + gcry_sexp_t result; + int i; + + if (ecc_get_param (name, pkey)) + return NULL; + + if (gcry_sexp_build (&result, NULL, + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", + pkey[0], pkey[1], pkey[2], pkey[3], pkey[4])) + result = NULL; + + for (i=0; pkey[i]; i++) + gcry_mpi_release (pkey[i]); + + return result; +} + + +/* Return the name matching the parameters in PKEY. */ +static const char * +ecc_get_curve (gcry_mpi_t *pkey, int iterator, unsigned int *r_nbits) +{ + gpg_err_code_t err; + elliptic_curve_t E; + int idx; + gcry_mpi_t tmp; + const char *result = NULL; + + if (r_nbits) + *r_nbits = 0; + + if (!pkey) + { + idx = iterator; + if (idx >= 0 && idx < DIM (domain_parms)) + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + } + return result; + } + + if (!pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4]) + return NULL; + + E.p = pkey[0]; + E.a = pkey[1]; + E.b = pkey[2]; + point_init (&E.G); + err = os2ec (&E.G, pkey[3]); + if (err) + { + point_free (&E.G); + return NULL; + } + E.n = pkey[4]; + + for (idx = 0; domain_parms[idx].desc; idx++) + { + tmp = scanval (domain_parms[idx].p); + if (!mpi_cmp (tmp, E.p)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].a); + if (!mpi_cmp (tmp, E.a)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].b); + if (!mpi_cmp (tmp, E.b)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].n); + if (!mpi_cmp (tmp, E.n)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_x); + if (!mpi_cmp (tmp, E.G.x)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_y); + if (!mpi_cmp (tmp, E.G.y)) + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + break; + } + } + } + } + } + } + mpi_free (tmp); + } + + point_free (&E.G); + + return result; +} + + +static gcry_err_code_t +ecc_check_secret_key (int algo, gcry_mpi_t *skey) +{ + gpg_err_code_t err; + ECC_secret_key sk; + + (void)algo; + + /* FIXME: This check looks a bit fishy: Now long is the array? */ + if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5] + || !skey[6]) + return GPG_ERR_BAD_MPI; + + sk.E.p = skey[0]; + sk.E.a = skey[1]; + sk.E.b = skey[2]; + point_init (&sk.E.G); + err = os2ec (&sk.E.G, skey[3]); + if (err) + { + point_free (&sk.E.G); + return err; + } + sk.E.n = skey[4]; + point_init (&sk.Q); + err = os2ec (&sk.Q, skey[5]); + if (err) + { + point_free (&sk.E.G); + point_free (&sk.Q); + return err; + } + + sk.d = skey[6]; + + if (check_secret_key (&sk)) + { + point_free (&sk.E.G); + point_free (&sk.Q); + return GPG_ERR_BAD_SECKEY; + } + point_free (&sk.E.G); + point_free (&sk.Q); + return 0; +} + + +static gcry_err_code_t +ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey) +{ + gpg_err_code_t err; + ECC_secret_key sk; + + (void)algo; + + if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] + || !skey[5] || !skey[6] ) + return GPG_ERR_BAD_MPI; + + sk.E.p = skey[0]; + sk.E.a = skey[1]; + sk.E.b = skey[2]; + point_init (&sk.E.G); + err = os2ec (&sk.E.G, skey[3]); + if (err) + { + point_free (&sk.E.G); + return err; + } + sk.E.n = skey[4]; + point_init (&sk.Q); + err = os2ec (&sk.Q, skey[5]); + if (err) + { + point_free (&sk.E.G); + point_free (&sk.Q); + return err; + } + sk.d = skey[6]; + + resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p)); + resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p)); + err = sign (data, &sk, resarr[0], resarr[1]); + if (err) + { + mpi_free (resarr[0]); + mpi_free (resarr[1]); + resarr[0] = NULL; /* Mark array as released. */ + } + point_free (&sk.E.G); + point_free (&sk.Q); + return err; +} + + +static gcry_err_code_t +ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, + int (*cmp)(void *, gcry_mpi_t), void *opaquev) +{ + gpg_err_code_t err; + ECC_public_key pk; + + (void)algo; + (void)cmp; + (void)opaquev; + + if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2] + || !pkey[3] || !pkey[4] || !pkey[5] ) + return GPG_ERR_BAD_MPI; + + pk.E.p = pkey[0]; + pk.E.a = pkey[1]; + pk.E.b = pkey[2]; + point_init (&pk.E.G); + err = os2ec (&pk.E.G, pkey[3]); + if (err) + { + point_free (&pk.E.G); + return err; + } + pk.E.n = pkey[4]; + point_init (&pk.Q); + err = os2ec (&pk.Q, pkey[5]); + if (err) + { + point_free (&pk.E.G); + point_free (&pk.Q); + return err; + } + + err = verify (hash, &pk, data[0], data[1]); + + point_free (&pk.E.G); + point_free (&pk.Q); + return err; +} + + +/* ecdh raw is classic 2-round DH protocol published in 1976. + * + * Overview of ecc_encrypt_raw and ecc_decrypt_raw. + * + * As with any PK operation, encrypt version uses a public key and + * decrypt -- private. + * + * Symbols used below: + * G - field generator point + * d - private long-term scalar + * dG - public long-term key + * k - ephemeral scalar + * kG - ephemeral public key + * dkG - shared secret + * + * ecc_encrypt_raw description: + * input: + * data[0] : private scalar (k) + * output: + * result[0] : shared point (kdG) + * result[1] : generated ephemeral public key (kG) + * + * ecc_decrypt_raw description: + * input: + * data[0] : a point kG (ephemeral public key) + * output: + * result[0] : shared point (kdG) + */ +static gcry_err_code_t +ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k, + gcry_mpi_t *pkey, int flags) +{ + ECC_public_key pk; + mpi_ec_t ctx; + gcry_mpi_t result[2]; + int err; + + (void)algo; + (void)flags; + + if (!k + || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5]) + return GPG_ERR_BAD_MPI; + + pk.E.p = pkey[0]; + pk.E.a = pkey[1]; + pk.E.b = pkey[2]; + point_init (&pk.E.G); + err = os2ec (&pk.E.G, pkey[3]); + if (err) + { + point_free (&pk.E.G); + return err; + } + pk.E.n = pkey[4]; + point_init (&pk.Q); + err = os2ec (&pk.Q, pkey[5]); + if (err) + { + point_free (&pk.E.G); + point_free (&pk.Q); + return err; + } + + ctx = _gcry_mpi_ec_init (pk.E.p, pk.E.a); + + /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */ + { + mpi_point_t R; /* Result that we return. */ + gcry_mpi_t x, y; + + x = mpi_new (0); + y = mpi_new (0); + + point_init (&R); + + /* R = kQ <=> R = kdG */ + _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx); + + if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) + log_fatal ("ecdh: Failed to get affine coordinates for kdG\n"); + + result[0] = ec2os (x, y, pk.E.p); + + /* R = kG */ + _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx); + + if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) + log_fatal ("ecdh: Failed to get affine coordinates for kG\n"); + + result[1] = ec2os (x, y, pk.E.p); + + mpi_free (x); + mpi_free (y); + + point_free (&R); + } + + _gcry_mpi_ec_free (ctx); + point_free (&pk.E.G); + point_free (&pk.Q); + + if (!result[0] || !result[1]) + { + mpi_free (result[0]); + mpi_free (result[1]); + return GPG_ERR_ENOMEM; + } + + /* Success. */ + resarr[0] = result[0]; + resarr[1] = result[1]; + + return 0; +} + +/* input: + * data[0] : a point kG (ephemeral public key) + * output: + * resaddr[0] : shared point kdG + * + * see ecc_encrypt_raw for details. + */ +static gcry_err_code_t +ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data, + gcry_mpi_t *skey, int flags) +{ + ECC_secret_key sk; + mpi_point_t R; /* Result that we return. */ + mpi_point_t kG; + mpi_ec_t ctx; + gcry_mpi_t r; + int err; + + (void)algo; + (void)flags; + + *result = NULL; + + if (!data || !data[0] + || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] + || !skey[5] || !skey[6] ) + return GPG_ERR_BAD_MPI; + + point_init (&kG); + err = os2ec (&kG, data[0]); + if (err) + { + point_free (&kG); + return err; + } + + + sk.E.p = skey[0]; + sk.E.a = skey[1]; + sk.E.b = skey[2]; + point_init (&sk.E.G); + err = os2ec (&sk.E.G, skey[3]); + if (err) + { + point_free (&kG); + point_free (&sk.E.G); + return err; + } + sk.E.n = skey[4]; + point_init (&sk.Q); + err = os2ec (&sk.Q, skey[5]); + if (err) + { + point_free (&kG); + point_free (&sk.E.G); + point_free (&sk.Q); + return err; + } + sk.d = skey[6]; + + ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a); + + /* R = dkG */ + point_init (&R); + _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx); + + point_free (&kG); + + /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */ + { + gcry_mpi_t x, y; + + x = mpi_new (0); + y = mpi_new (0); + + if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) + log_fatal ("ecdh: Failed to get affine coordinates\n"); + + r = ec2os (x, y, sk.E.p); + mpi_free (x); + mpi_free (y); + } + + point_free (&R); + _gcry_mpi_ec_free (ctx); + point_free (&kG); + point_free (&sk.E.G); + point_free (&sk.Q); + + if (!r) + return GPG_ERR_ENOMEM; + + /* Success. */ + + *result = r; + + return 0; +} + + +static unsigned int +ecc_get_nbits (int algo, gcry_mpi_t *pkey) +{ + (void)algo; + + return mpi_get_nbits (pkey[0]); +} + + +/* See rsa.c for a description of this function. */ +static gpg_err_code_t +compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) +{ +#define N_COMPONENTS 6 + static const char names[N_COMPONENTS+1] = "pabgnq"; + gpg_err_code_t ec = 0; + gcry_sexp_t l1; + gcry_mpi_t values[N_COMPONENTS]; + int idx; + + /* Clear the values for easier error cleanup. */ + for (idx=0; idx < N_COMPONENTS; idx++) + values[idx] = NULL; + + /* Fill values with all provided parameters. */ + for (idx=0; idx < N_COMPONENTS; idx++) + { + l1 = gcry_sexp_find_token (keyparam, names+idx, 1); + if (l1) + { + values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l1); + if (!values[idx]) + { + ec = GPG_ERR_INV_OBJ; + goto leave; + } + } + } + + /* Check whether a curve parameter is available and use that to fill + in missing values. */ + l1 = gcry_sexp_find_token (keyparam, "curve", 5); + if (l1) + { + char *curve; + gcry_mpi_t tmpvalues[N_COMPONENTS]; + + for (idx = 0; idx < N_COMPONENTS; idx++) + tmpvalues[idx] = NULL; + + curve = _gcry_sexp_nth_string (l1, 1); + gcry_sexp_release (l1); + if (!curve) + { + ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */ + goto leave; + } + ec = ecc_get_param (curve, tmpvalues); + gcry_free (curve); + if (ec) + goto leave; + + for (idx = 0; idx < N_COMPONENTS; idx++) + { + if (!values[idx]) + values[idx] = tmpvalues[idx]; + else + mpi_free (tmpvalues[idx]); + } + } + + /* Check that all parameters are known and normalize all MPIs (that + should not be required but we use an internal function later and + thus we better make 100% sure that they are normalized). */ + for (idx = 0; idx < N_COMPONENTS; idx++) + if (!values[idx]) + { + ec = GPG_ERR_NO_OBJ; + goto leave; + } + else + _gcry_mpi_normalize (values[idx]); + + /* Hash them all. */ + for (idx = 0; idx < N_COMPONENTS; idx++) + { + char buf[30]; + unsigned char *rawmpi; + unsigned int rawmpilen; + + rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL); + if (!rawmpi) + { + ec = gpg_err_code_from_syserror (); + goto leave; + } + snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen); + gcry_md_write (md, buf, strlen (buf)); + gcry_md_write (md, rawmpi, rawmpilen); + gcry_md_write (md, ")", 1); + gcry_free (rawmpi); + } + + leave: + for (idx = 0; idx < N_COMPONENTS; idx++) + _gcry_mpi_release (values[idx]); + + return ec; +#undef N_COMPONENTS +} + + + + + +/* + Self-test section. + */ + + +static gpg_err_code_t +selftests_ecdsa (selftest_report_func_t report) +{ + const char *what; + const char *errtxt; + + what = "low-level"; + errtxt = NULL; /*selftest ();*/ + if (errtxt) + goto failed; + + /* FIXME: need more tests. */ + + return 0; /* Succeeded. */ + + failed: + if (report) + report ("pubkey", GCRY_PK_ECDSA, what, errtxt); + return GPG_ERR_SELFTEST_FAILED; +} + + +/* Run a full self-test for ALGO and return 0 on success. */ +static gpg_err_code_t +run_selftests (int algo, int extended, selftest_report_func_t report) +{ + gpg_err_code_t ec; + + (void)extended; + + switch (algo) + { + case GCRY_PK_ECDSA: + ec = selftests_ecdsa (report); + break; + default: + ec = GPG_ERR_PUBKEY_ALGO; + break; + + } + return ec; +} + + + + +static const char *ecdsa_names[] = + { + "ecdsa", + "ecc", + NULL, + }; +static const char *ecdh_names[] = + { + "ecdh", + "ecc", + NULL, + }; + +gcry_pk_spec_t _gcry_pubkey_spec_ecdsa = + { + "ECDSA", ecdsa_names, + "pabgnq", "pabgnqd", "", "rs", "pabgnq", + GCRY_PK_USAGE_SIGN, + ecc_generate, + ecc_check_secret_key, + NULL, + NULL, + ecc_sign, + ecc_verify, + ecc_get_nbits + }; + +gcry_pk_spec_t _gcry_pubkey_spec_ecdh = + { + "ECDH", ecdh_names, + "pabgnq", "pabgnqd", "se", "", "pabgnq", + GCRY_PK_USAGE_ENCR, + ecc_generate, + ecc_check_secret_key, + ecc_encrypt_raw, + ecc_decrypt_raw, + NULL, + NULL, + ecc_get_nbits + }; + + +pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa = + { + run_selftests, + ecc_generate_ext, + compute_keygrip, + ecc_get_param, + ecc_get_curve, + ecc_get_param_sexp + }; diff --git a/libgcrypt-1.5.3-ecc-test-fix.patch b/libgcrypt-1.5.3-ecc-test-fix.patch new file mode 100644 index 0000000..a5cca64 --- /dev/null +++ b/libgcrypt-1.5.3-ecc-test-fix.patch @@ -0,0 +1,12 @@ +diff -up libgcrypt-1.5.3/tests/benchmark.c.eccfix libgcrypt-1.5.3/tests/benchmark.c +--- libgcrypt-1.5.3/tests/benchmark.c.eccfix 2013-10-20 23:45:32.157297611 +0100 ++++ libgcrypt-1.5.3/tests/benchmark.c 2013-10-20 23:45:42.683275072 +0100 +@@ -962,7 +962,7 @@ ecc_bench (int iterations, int print_hea + { + #if USE_ECC + gpg_error_t err; +- int p_sizes[] = { 192, 224, 256, 384, 521 }; ++ int p_sizes[] = { 256, 384 }; + int testno; + + if (print_header) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6aca195..833e92a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,17 +1,19 @@ Name: libgcrypt Version: 1.5.3 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with -# the hobble-libgcrypt script. +# the hobble-libgcrypt script. +# (We replace it with RH approved ECC in Source4-5) #Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 #Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com Source3: hobble-libgcrypt -# do not run the ecc curves test -Patch1: libgcrypt-1.5.0-noecc.patch +# Approved ECC support (from 1.5.3) +Source4: ecc.c +Source5: curves.c # make FIPS hmac compatible with fipscheck - non upstreamable Patch2: libgcrypt-1.5.0-use-fipscheck.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen @@ -29,6 +31,8 @@ Patch11: libgcrypt-1.5.1-use-poll.patch Patch12: libgcrypt-1.5.2-aliasing.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.5.2-mpicoder-gccopt.patch +# fix tests to work with approved ECC +Patch14: libgcrypt-1.5.3-ecc-test-fix.patch %define gcrylibdir %{_libdir} @@ -64,7 +68,6 @@ applications using libgcrypt. %prep %setup -q %{SOURCE3} -%patch1 -p1 -b .noecc %patch2 -p1 -b .use-fipscheck %patch5 -p1 -b .tests %patch6 -p1 -b .cfgrandom @@ -73,6 +76,10 @@ applications using libgcrypt. %patch11 -p1 -b .use-poll %patch12 -p1 -b .aliasing %patch13 -p1 -b .gccopt +%patch14 -p1 -b .eccfix +cp %{SOURCE4} cipher/ +rm -rf tests/curves.c +cp %{SOURCE5} tests/curves.c %build %configure --disable-static \ @@ -81,7 +88,7 @@ applications using libgcrypt. %endif --enable-noexecstack \ --enable-hmac-binary-check \ - --enable-pubkey-ciphers='dsa elgamal rsa' \ + --enable-pubkey-ciphers='dsa elgamal rsa ecc' \ --disable-O-flag-munging make %{?_smp_mflags} @@ -174,6 +181,9 @@ exit 0 %doc COPYING %changelog +* Sun Oct 20 2013 Tom Callaway - 1.5.3-2 +- add cleared ECC support + * Fri Jul 26 2013 Tomáš Mráz 1.5.3-1 - new upstream version fixing cache side-channel attack on RSA private keys From 1725d42356fd2fc5aa09437a0dbcf7dbcafc129f Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 21 Jan 2014 16:05:07 +0100 Subject: [PATCH 062/214] add back the nistp521r1 EC curve - fix a bug in the Whirlpool hash implementation - speed up the PBKDF2 computation --- ecc.c | 19 +++++++++++++++++ libgcrypt-1.5.3-pbkdf-speedup.patch | 32 +++++++++++++++++++++++++++++ libgcrypt-1.5.3-whirlpool-bug.patch | 28 +++++++++++++++++++++++++ libgcrypt.spec | 15 +++++++++++++- 4 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.5.3-pbkdf-speedup.patch create mode 100644 libgcrypt-1.5.3-whirlpool-bug.patch diff --git a/ecc.c b/ecc.c index bf63f4b..5e4717e 100644 --- a/ecc.c +++ b/ecc.c @@ -100,6 +100,9 @@ static const struct { "NIST P-384", "secp384r1" }, { "NIST P-384", "1.3.132.0.34" }, + { "NIST P-521", "secp521r1" }, + { "NIST P-521", "1.3.132.0.35" }, + { NULL, NULL} }; @@ -142,6 +145,22 @@ static const ecc_domain_parms_t domain_parms[] = "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" "0a60b1ce1d7e819d7a431d7c90ea0e5f" }, + { + "NIST P-521", 521, 1, + "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", + "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" + "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", + "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", + + "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" + "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", + "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" + "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + }, { NULL, 0, 0, NULL, NULL, NULL, NULL } }; diff --git a/libgcrypt-1.5.3-pbkdf-speedup.patch b/libgcrypt-1.5.3-pbkdf-speedup.patch new file mode 100644 index 0000000..7017367 --- /dev/null +++ b/libgcrypt-1.5.3-pbkdf-speedup.patch @@ -0,0 +1,32 @@ +diff -up libgcrypt-1.5.3/cipher/kdf.c.pbkdf-speedup libgcrypt-1.5.3/cipher/kdf.c +--- libgcrypt-1.5.3/cipher/kdf.c.pbkdf-speedup 2014-01-21 15:49:22.676638703 +0100 ++++ libgcrypt-1.5.3/cipher/kdf.c 2014-01-21 15:52:40.115047218 +0100 +@@ -172,19 +172,21 @@ pkdf2 (const void *passphrase, size_t pa + return ec; + } + ++ ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen)); ++ if (ec) ++ { ++ gcry_md_close (md); ++ gcry_free (sbuf); ++ return ec; ++ } ++ + /* Step 3 and 4. */ + memcpy (sbuf, salt, saltlen); + for (lidx = 1; lidx <= l; lidx++) + { + for (iter = 0; iter < iterations; iter++) + { +- ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen)); +- if (ec) +- { +- gcry_md_close (md); +- gcry_free (sbuf); +- return ec; +- } ++ gcry_md_reset (md); + if (!iter) /* Compute U_1: */ + { + sbuf[saltlen] = (lidx >> 24); diff --git a/libgcrypt-1.5.3-whirlpool-bug.patch b/libgcrypt-1.5.3-whirlpool-bug.patch new file mode 100644 index 0000000..f64c94f --- /dev/null +++ b/libgcrypt-1.5.3-whirlpool-bug.patch @@ -0,0 +1,28 @@ +diff -up libgcrypt-1.5.3/cipher/whirlpool.c.whirlpool-bug libgcrypt-1.5.3/cipher/whirlpool.c +--- libgcrypt-1.5.3/cipher/whirlpool.c.whirlpool-bug 2013-05-22 18:02:54.000000000 +0200 ++++ libgcrypt-1.5.3/cipher/whirlpool.c 2014-01-21 15:45:51.308919415 +0100 +@@ -56,6 +56,7 @@ typedef struct { + unsigned char buffer[BLOCK_SIZE]; + size_t count; + unsigned char length[32]; ++ int bug; + } whirlpool_context_t; + + +@@ -1185,6 +1186,7 @@ whirlpool_init (void *ctx) + whirlpool_context_t *context = ctx; + + memset (context, 0, sizeof (*context)); ++ context->bug = secure_getenv("GCRYPT_WHIRLPOOL_BUG") != NULL; + } + + +@@ -1316,7 +1318,7 @@ whirlpool_add (whirlpool_context_t *cont + buffer_n--; + } + whirlpool_add (context, NULL, 0); +- if (!buffer_n) ++ if (context->bug && !buffer_n) + /* Done. */ + return; + } diff --git a/libgcrypt.spec b/libgcrypt.spec index 833e92a..e6aec0f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.5.3 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -33,6 +33,12 @@ Patch12: libgcrypt-1.5.2-aliasing.patch Patch13: libgcrypt-1.5.2-mpicoder-gccopt.patch # fix tests to work with approved ECC Patch14: libgcrypt-1.5.3-ecc-test-fix.patch +# pbkdf2 speedup - upstream +Patch15: libgcrypt-1.5.3-pbkdf-speedup.patch +# fix bug in whirlpool implementation (for backwards compatibility +# with files generated with buggy version set environment +# varible GCRYPT_WHIRLPOOL_BUG +Patch16: libgcrypt-1.5.3-whirlpool-bug.patch %define gcrylibdir %{_libdir} @@ -77,6 +83,8 @@ applications using libgcrypt. %patch12 -p1 -b .aliasing %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix +%patch15 -p1 -b .pbkdf-speedup +%patch16 -p1 -b .whirlpool-bug cp %{SOURCE4} cipher/ rm -rf tests/curves.c cp %{SOURCE5} tests/curves.c @@ -181,6 +189,11 @@ exit 0 %doc COPYING %changelog +* Tue Jan 21 2014 Tomáš Mráz 1.5.3-3 +- add back the nistp521r1 EC curve +- fix a bug in the Whirlpool hash implementation +- speed up the PBKDF2 computation + * Sun Oct 20 2013 Tom Callaway - 1.5.3-2 - add cleared ECC support From 1e4987983ae9cd13d649335f3d95077d20737baa Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 21 Jan 2014 16:11:17 +0100 Subject: [PATCH 063/214] Fix bogus dates in changelog --- libgcrypt.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index e6aec0f..cd41803 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -259,7 +259,7 @@ exit 0 * Mon Feb 07 2011 Fedora Release Engineering - 1.4.5-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_15_Mass_Rebuild -* Thu Feb 4 2011 Tomas Mraz 1.4.5-6 +* Fri Feb 4 2011 Tomas Mraz 1.4.5-6 - fix a bug in the fips-186-3 dsa parameter generation code * Tue Feb 1 2011 Tomas Mraz 1.4.5-5 @@ -436,5 +436,5 @@ exit 0 * Thu Jan 10 2002 Nalin Dahyabhai 1.1.5-1 - fix the Source tag so that it's a real URL -* Wed Dec 20 2001 Nalin Dahyabhai +* Thu Dec 20 2001 Nalin Dahyabhai - initial package From a2cb9937d8badd0a0b47fc378611a6477d08f0df Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 21 Jan 2014 16:26:32 +0100 Subject: [PATCH 064/214] We now support 3 EC curves. --- curves.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curves.c b/curves.c index caead00..aa51a3a 100644 --- a/curves.c +++ b/curves.c @@ -29,7 +29,7 @@ #include "../src/gcrypt.h" /* Number of curves defined in ../cipger/ecc.c */ -#define N_CURVES 2 +#define N_CURVES 3 /* A real world sample public key. */ static char const sample_key_1[] = From 247b2115d1358ccc7022ddefa593eb2e35aadce5 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 28 Feb 2014 16:32:41 +0100 Subject: [PATCH 065/214] new upstream version breaking ABI compatibility - this release temporarily includes old compatibility .so --- curves.c | 4 +- ecc-curves.c | 1007 ++++++++++ ecc.c | 1677 ----------------- hobble-libgcrypt | 4 +- libgcrypt-1.5.0-leak.patch | 73 - libgcrypt-1.5.0-noecc.patch | 12 - libgcrypt-1.5.0-tests.patch | 214 --- libgcrypt-1.5.0-use-fipscheck.patch | 2 +- libgcrypt-1.5.2-mpicoder-gccopt.patch | 102 - libgcrypt-1.5.3-ecc-test-fix.patch | 12 - libgcrypt-1.5.3-pbkdf-speedup.patch | 32 - libgcrypt-1.5.3-whirlpool-bug.patch | 28 - libgcrypt-1.6.1-ecc-test-fix.patch | 214 +++ ...s.patch => libgcrypt-1.6.1-fips-cavs.patch | 69 +- ...ch => libgcrypt-1.6.1-fips-cfgrandom.patch | 105 +- libgcrypt-1.6.1-leak.patch | 38 + libgcrypt-1.6.1-mpicoder-gccopt.patch | 104 + libgcrypt-1.6.1-tests.patch | 198 ++ ...ll.patch => libgcrypt-1.6.1-use-poll.patch | 61 +- libgcrypt.spec | 46 +- t-mpi-point.c | 970 ++++++++++ 21 files changed, 2655 insertions(+), 2317 deletions(-) create mode 100644 ecc-curves.c delete mode 100644 ecc.c delete mode 100644 libgcrypt-1.5.0-leak.patch delete mode 100644 libgcrypt-1.5.0-noecc.patch delete mode 100644 libgcrypt-1.5.0-tests.patch delete mode 100644 libgcrypt-1.5.2-mpicoder-gccopt.patch delete mode 100644 libgcrypt-1.5.3-ecc-test-fix.patch delete mode 100644 libgcrypt-1.5.3-pbkdf-speedup.patch delete mode 100644 libgcrypt-1.5.3-whirlpool-bug.patch create mode 100644 libgcrypt-1.6.1-ecc-test-fix.patch rename libgcrypt-1.5.0-fips-cavs.patch => libgcrypt-1.6.1-fips-cavs.patch (91%) rename libgcrypt-1.5.0-fips-cfgrandom.patch => libgcrypt-1.6.1-fips-cfgrandom.patch (50%) create mode 100644 libgcrypt-1.6.1-leak.patch create mode 100644 libgcrypt-1.6.1-mpicoder-gccopt.patch create mode 100644 libgcrypt-1.6.1-tests.patch rename libgcrypt-1.5.1-use-poll.patch => libgcrypt-1.6.1-use-poll.patch (54%) create mode 100644 t-mpi-point.c diff --git a/curves.c b/curves.c index aa51a3a..fccd1d4 100644 --- a/curves.c +++ b/curves.c @@ -26,10 +26,10 @@ #include #include -#include "../src/gcrypt.h" +#include "../src/gcrypt-int.h" /* Number of curves defined in ../cipger/ecc.c */ -#define N_CURVES 3 +#define N_CURVES 4 /* A real world sample public key. */ static char const sample_key_1[] = diff --git a/ecc-curves.c b/ecc-curves.c new file mode 100644 index 0000000..b8679da --- /dev/null +++ b/ecc-curves.c @@ -0,0 +1,1007 @@ +/* ecc-curves.c - Elliptic Curve parameter mangement + * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. + * Copyright (C) 2013 g10 Code GmbH + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt 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 program; if not, see . + */ + +#include +#include +#include +#include +#include + +#include "g10lib.h" +#include "mpi.h" +#include "cipher.h" +#include "context.h" +#include "ec-context.h" +#include "pubkey-internal.h" +#include "ecc-common.h" + + +/* This tables defines aliases for curve names. */ +static const struct +{ + const char *name; /* Our name. */ + const char *other; /* Other name. */ +} curve_aliases[] = + { + /*{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1" },*/ + { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, + + { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */ + { "NIST P-256", "prime256v1" }, + { "NIST P-256", "secp256r1" }, + { "NIST P-256", "nistp256" }, /* rfc5656. */ + + { "NIST P-384", "secp384r1" }, + { "NIST P-384", "1.3.132.0.34" }, + { "NIST P-384", "nistp384" }, /* rfc5656. */ + + { "NIST P-521", "secp521r1" }, + { "NIST P-521", "1.3.132.0.35" }, + { "NIST P-521", "nistp521" }, /* rfc5656. */ + + { NULL, NULL} + }; + + +typedef struct +{ + const char *desc; /* Description of the curve. */ + unsigned int nbits; /* Number of bits. */ + unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */ + + /* The model describing this curve. This is mainly used to select + the group equation. */ + enum gcry_mpi_ec_models model; + + /* The actual ECC dialect used. This is used for curve specific + optimizations and to select encodings etc. */ + enum ecc_dialects dialect; + + const char *p; /* The prime defining the field. */ + const char *a, *b; /* The coefficients. For Twisted Edwards + Curves b is used for d. */ + const char *n; /* The order of the base point. */ + const char *g_x, *g_y; /* Base point. */ +} ecc_domain_parms_t; + + +/* This static table defines all available curves. */ +static const ecc_domain_parms_t domain_parms[] = + { + { + /* (-x^2 + y^2 = 1 + dx^2y^2) */ + "Ed25519", 256, 0, + MPI_EC_TWISTEDEDWARDS, ECC_DIALECT_ED25519, + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", + "-0x01", + "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", + "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", + "0x6666666666666666666666666666666666666666666666666666666666666658" + }, + { + "NIST P-256", 256, 1, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", + "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", + "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + + "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + }, + { + "NIST P-384", 384, 1, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + "ffffffff0000000000000000ffffffff", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + "ffffffff0000000000000000fffffffc", + "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" + "c656398d8a2ed19d2a85c8edd3ec2aef", + "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" + "581a0db248b0a77aecec196accc52973", + + "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" + "5502f25dbf55296c3a545e3872760ab7", + "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" + "0a60b1ce1d7e819d7a431d7c90ea0e5f" + }, + { + "NIST P-521", 521, 1, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", + "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" + "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", + "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", + + "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" + "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", + "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" + "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + }, + + { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL } + }; + + + + +/* Return a copy of POINT. */ +static gcry_mpi_point_t +point_copy (gcry_mpi_point_t point) +{ + gcry_mpi_point_t newpoint; + + if (point) + { + newpoint = mpi_point_new (0); + point_set (newpoint, point); + } + else + newpoint = NULL; + return newpoint; +} + + +/* Helper to scan a hex string. */ +static gcry_mpi_t +scanval (const char *string) +{ + gpg_err_code_t rc; + gcry_mpi_t val; + + rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); + if (rc) + log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc)); + return val; +} + + +/* Return the index of the domain_parms table for a curve with NAME. + Return -1 if not found. */ +static int +find_domain_parms_idx (const char *name) +{ + int idx, aliasno; + + /* First check our native curves. */ + for (idx = 0; domain_parms[idx].desc; idx++) + if (!strcmp (name, domain_parms[idx].desc)) + return idx; + + /* If not found consult the alias table. */ + if (!domain_parms[idx].desc) + { + for (aliasno = 0; curve_aliases[aliasno].name; aliasno++) + if (!strcmp (name, curve_aliases[aliasno].other)) + break; + if (curve_aliases[aliasno].name) + { + for (idx = 0; domain_parms[idx].desc; idx++) + if (!strcmp (curve_aliases[aliasno].name, domain_parms[idx].desc)) + return idx; + } + } + + return -1; +} + + +/* Generate the crypto system setup. This function takes the NAME of + a curve or the desired number of bits and stores at R_CURVE the + parameters of the named curve or those of a suitable curve. If + R_NBITS is not NULL, the chosen number of bits is stored there. + NULL may be given for R_CURVE, if the value is not required and for + example only a quick test for availability is desired. Note that + the curve fields should be initialized to zero because fields which + are not NULL are skipped. */ +gpg_err_code_t +_gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, + elliptic_curve_t *curve, unsigned int *r_nbits) +{ + int idx; + const char *resname = NULL; /* Set to a found curve name. */ + + if (name) + idx = find_domain_parms_idx (name); + else + { + for (idx = 0; domain_parms[idx].desc; idx++) + if (nbits == domain_parms[idx].nbits + && domain_parms[idx].model == MPI_EC_WEIERSTRASS) + break; + if (!domain_parms[idx].desc) + idx = -1; + } + if (idx < 0) + return GPG_ERR_UNKNOWN_CURVE; + + resname = domain_parms[idx].desc; + + /* In fips mode we only support NIST curves. Note that it is + possible to bypass this check by specifying the curve parameters + directly. */ + if (fips_mode () && !domain_parms[idx].fips ) + return GPG_ERR_NOT_SUPPORTED; + + switch (domain_parms[idx].model) + { + case MPI_EC_WEIERSTRASS: + case MPI_EC_TWISTEDEDWARDS: + break; + case MPI_EC_MONTGOMERY: + return GPG_ERR_NOT_SUPPORTED; + default: + return GPG_ERR_BUG; + } + + + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + + if (curve) + { + curve->model = domain_parms[idx].model; + curve->dialect = domain_parms[idx].dialect; + if (!curve->p) + curve->p = scanval (domain_parms[idx].p); + if (!curve->a) + curve->a = scanval (domain_parms[idx].a); + if (!curve->b) + curve->b = scanval (domain_parms[idx].b); + if (!curve->n) + curve->n = scanval (domain_parms[idx].n); + if (!curve->G.x) + curve->G.x = scanval (domain_parms[idx].g_x); + if (!curve->G.y) + curve->G.y = scanval (domain_parms[idx].g_y); + if (!curve->G.z) + curve->G.z = mpi_alloc_set_ui (1); + if (!curve->name) + curve->name = resname; + } + + return 0; +} + + +/* Give the name of the curve NAME, store the curve parameters into P, + A, B, G, and N if they point to NULL value. Note that G is returned + in standard uncompressed format. Also update MODEL and DIALECT if + they are not NULL. */ +gpg_err_code_t +_gcry_ecc_update_curve_param (const char *name, + enum gcry_mpi_ec_models *model, + enum ecc_dialects *dialect, + gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, + gcry_mpi_t *g, gcry_mpi_t *n) +{ + int idx; + + idx = find_domain_parms_idx (name); + if (idx < 0) + return GPG_ERR_UNKNOWN_CURVE; + + if (g) + { + char *buf; + size_t len; + + len = 4; + len += strlen (domain_parms[idx].g_x+2); + len += strlen (domain_parms[idx].g_y+2); + len++; + buf = xtrymalloc (len); + if (!buf) + return gpg_err_code_from_syserror (); + strcpy (stpcpy (stpcpy (buf, "0x04"), domain_parms[idx].g_x+2), + domain_parms[idx].g_y+2); + _gcry_mpi_release (*g); + *g = scanval (buf); + xfree (buf); + } + if (model) + *model = domain_parms[idx].model; + if (dialect) + *dialect = domain_parms[idx].dialect; + if (p) + { + _gcry_mpi_release (*p); + *p = scanval (domain_parms[idx].p); + } + if (a) + { + _gcry_mpi_release (*a); + *a = scanval (domain_parms[idx].a); + } + if (b) + { + _gcry_mpi_release (*b); + *b = scanval (domain_parms[idx].b); + } + if (n) + { + _gcry_mpi_release (*n); + *n = scanval (domain_parms[idx].n); + } + return 0; +} + + +/* Return the name matching the parameters in PKEY. This works only + with curves described by the Weierstrass equation. */ +const char * +_gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) +{ + gpg_err_code_t rc; + const char *result = NULL; + elliptic_curve_t E; + gcry_mpi_t mpi_g = NULL; + gcry_mpi_t tmp = NULL; + int idx; + + memset (&E, 0, sizeof E); + + if (r_nbits) + *r_nbits = 0; + + if (!keyparms) + { + idx = iterator; + if (idx >= 0 && idx < DIM (domain_parms)) + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + } + return result; + } + + + /* + * Extract the curve parameters.. + */ + rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgn", + &E.p, &E.a, &E.b, &mpi_g, &E.n, + NULL)); + if (rc == GPG_ERR_NO_OBJ) + { + /* This might be the second use case of checking whether a + specific curve given by name is supported. */ + gcry_sexp_t l1; + char *name; + + l1 = sexp_find_token (keyparms, "curve", 5); + if (!l1) + goto leave; /* No curve name parameter. */ + + name = sexp_nth_string (l1, 1); + sexp_release (l1); + if (!name) + goto leave; /* Name missing or out of core. */ + + idx = find_domain_parms_idx (name); + xfree (name); + if (idx >= 0) /* Curve found. */ + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + } + return result; + } + + if (rc) + goto leave; + + if (mpi_g) + { + _gcry_mpi_point_init (&E.G); + if (_gcry_ecc_os2ec (&E.G, mpi_g)) + goto leave; + } + + for (idx = 0; domain_parms[idx].desc; idx++) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].p); + if (!mpi_cmp (tmp, E.p)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].a); + if (!mpi_cmp (tmp, E.a)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].b); + if (!mpi_cmp (tmp, E.b)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].n); + if (!mpi_cmp (tmp, E.n)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_x); + if (!mpi_cmp (tmp, E.G.x)) + { + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_y); + if (!mpi_cmp (tmp, E.G.y)) + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + goto leave; + } + } + } + } + } + } + } + + leave: + _gcry_mpi_release (tmp); + _gcry_mpi_release (E.p); + _gcry_mpi_release (E.a); + _gcry_mpi_release (E.b); + _gcry_mpi_release (mpi_g); + _gcry_mpi_point_free_parts (&E.G); + _gcry_mpi_release (E.n); + return result; +} + + +/* Helper to extract an MPI from key parameters. */ +static gpg_err_code_t +mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name) +{ + gcry_err_code_t ec = 0; + gcry_sexp_t l1; + + l1 = sexp_find_token (keyparam, name, 0); + if (l1) + { + *r_a = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + sexp_release (l1); + if (!*r_a) + ec = GPG_ERR_INV_OBJ; + } + return ec; +} + +/* Helper to extract a point from key parameters. If no parameter + with NAME is found, the functions tries to find a non-encoded point + by appending ".x", ".y" and ".z" to NAME. ".z" is in this case + optional and defaults to 1. EC is the context which at this point + may not be fully initialized. */ +static gpg_err_code_t +point_from_keyparam (gcry_mpi_point_t *r_a, + gcry_sexp_t keyparam, const char *name, mpi_ec_t ec) +{ + gcry_err_code_t rc; + gcry_sexp_t l1; + gcry_mpi_point_t point; + + l1 = sexp_find_token (keyparam, name, 0); + if (l1) + { + gcry_mpi_t a; + + a = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE); + sexp_release (l1); + if (!a) + return GPG_ERR_INV_OBJ; + + point = mpi_point_new (0); + if (ec && ec->dialect == ECC_DIALECT_ED25519) + rc = _gcry_ecc_eddsa_decodepoint (a, ec, point, NULL, NULL); + else + rc = _gcry_ecc_os2ec (point, a); + mpi_free (a); + if (rc) + { + mpi_point_release (point); + return rc; + } + } + else + { + char *tmpname; + gcry_mpi_t x = NULL; + gcry_mpi_t y = NULL; + gcry_mpi_t z = NULL; + + tmpname = xtrymalloc (strlen (name) + 2 + 1); + if (!tmpname) + return gpg_err_code_from_syserror (); + strcpy (stpcpy (tmpname, name), ".x"); + rc = mpi_from_keyparam (&x, keyparam, tmpname); + if (rc) + { + xfree (tmpname); + return rc; + } + strcpy (stpcpy (tmpname, name), ".y"); + rc = mpi_from_keyparam (&y, keyparam, tmpname); + if (rc) + { + mpi_free (x); + xfree (tmpname); + return rc; + } + strcpy (stpcpy (tmpname, name), ".z"); + rc = mpi_from_keyparam (&z, keyparam, tmpname); + if (rc) + { + mpi_free (y); + mpi_free (x); + xfree (tmpname); + return rc; + } + if (!z) + z = mpi_set_ui (NULL, 1); + if (x && y) + point = mpi_point_snatch_set (NULL, x, y, z); + else + { + mpi_free (x); + mpi_free (y); + mpi_free (z); + point = NULL; + } + xfree (tmpname); + } + + if (point) + *r_a = point; + return 0; +} + + +/* This function creates a new context for elliptic curve operations. + Either KEYPARAM or CURVENAME must be given. If both are given and + KEYPARAM has no curve parameter, CURVENAME is used to add missing + parameters. On success 0 is returned and the new context stored at + R_CTX. On error NULL is stored at R_CTX and an error code is + returned. The context needs to be released using + gcry_ctx_release. */ +gpg_err_code_t +_gcry_mpi_ec_new (gcry_ctx_t *r_ctx, + gcry_sexp_t keyparam, const char *curvename) +{ + gpg_err_code_t errc; + gcry_ctx_t ctx = NULL; + enum gcry_mpi_ec_models model = MPI_EC_WEIERSTRASS; + enum ecc_dialects dialect = ECC_DIALECT_STANDARD; + gcry_mpi_t p = NULL; + gcry_mpi_t a = NULL; + gcry_mpi_t b = NULL; + gcry_mpi_point_t G = NULL; + gcry_mpi_t n = NULL; + gcry_mpi_point_t Q = NULL; + gcry_mpi_t d = NULL; + int flags = 0; + gcry_sexp_t l1; + + *r_ctx = NULL; + + if (keyparam) + { + /* Parse an optional flags list. */ + l1 = sexp_find_token (keyparam, "flags", 0); + if (l1) + { + errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL); + sexp_release (l1); + l1 = NULL; + if (errc) + goto leave; + } + + /* Check whether a curve name was given. */ + l1 = sexp_find_token (keyparam, "curve", 5); + + /* If we don't have a curve name or if override parameters have + explicitly been requested, parse them. */ + if (!l1 || (flags & PUBKEY_FLAG_PARAM)) + { + errc = mpi_from_keyparam (&p, keyparam, "p"); + if (errc) + goto leave; + errc = mpi_from_keyparam (&a, keyparam, "a"); + if (errc) + goto leave; + errc = mpi_from_keyparam (&b, keyparam, "b"); + if (errc) + goto leave; + errc = point_from_keyparam (&G, keyparam, "g", NULL); + if (errc) + goto leave; + errc = mpi_from_keyparam (&n, keyparam, "n"); + if (errc) + goto leave; + } + } + else + l1 = NULL; /* No curvename. */ + + /* Check whether a curve parameter is available and use that to fill + in missing values. If no curve parameter is available try an + optional provided curvename. If only the curvename has been + given use that one. */ + if (l1 || curvename) + { + char *name; + elliptic_curve_t *E; + + if (l1) + { + name = sexp_nth_string (l1, 1); + sexp_release (l1); + if (!name) + { + errc = GPG_ERR_INV_OBJ; /* Name missing or out of core. */ + goto leave; + } + } + else + name = NULL; + + E = xtrycalloc (1, sizeof *E); + if (!E) + { + errc = gpg_err_code_from_syserror (); + xfree (name); + goto leave; + } + + errc = _gcry_ecc_fill_in_curve (0, name? name : curvename, E, NULL); + xfree (name); + if (errc) + { + xfree (E); + goto leave; + } + + model = E->model; + dialect = E->dialect; + + if (!p) + { + p = E->p; + E->p = NULL; + } + if (!a) + { + a = E->a; + E->a = NULL; + } + if (!b) + { + b = E->b; + E->b = NULL; + } + if (!G) + { + G = mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z); + E->G.x = NULL; + E->G.y = NULL; + E->G.z = NULL; + } + if (!n) + { + n = E->n; + E->n = NULL; + } + _gcry_ecc_curve_free (E); + xfree (E); + } + + + errc = _gcry_mpi_ec_p_new (&ctx, model, dialect, flags, p, a, b); + if (!errc) + { + mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); + + if (b) + { + mpi_free (ec->b); + ec->b = b; + b = NULL; + } + if (G) + { + ec->G = G; + G = NULL; + } + if (n) + { + ec->n = n; + n = NULL; + } + + /* Now that we know the curve name we can look for the public key + Q. point_from_keyparam needs to know the curve parameters so + that it is able to use the correct decompression. Parsing + the private key D could have been done earlier but it is less + surprising if we do it here as well. */ + if (keyparam) + { + errc = point_from_keyparam (&Q, keyparam, "q", ec); + if (errc) + goto leave; + errc = mpi_from_keyparam (&d, keyparam, "d"); + if (errc) + goto leave; + } + + if (Q) + { + ec->Q = Q; + Q = NULL; + } + if (d) + { + ec->d = d; + d = NULL; + } + + *r_ctx = ctx; + ctx = NULL; + } + + leave: + _gcry_ctx_release (ctx); + mpi_free (p); + mpi_free (a); + mpi_free (b); + _gcry_mpi_point_release (G); + mpi_free (n); + _gcry_mpi_point_release (Q); + mpi_free (d); + return errc; +} + + +/* Return the parameters of the curve NAME as an S-expression. */ +gcry_sexp_t +_gcry_ecc_get_param_sexp (const char *name) +{ + unsigned int nbits; + elliptic_curve_t E; + mpi_ec_t ctx; + gcry_mpi_t g_x, g_y; + gcry_mpi_t pkey[6]; + gcry_sexp_t result; + int i; + + memset (&E, 0, sizeof E); + if (_gcry_ecc_fill_in_curve (0, name, &E, &nbits)) + return NULL; + + g_x = mpi_new (0); + g_y = mpi_new (0); + ctx = _gcry_mpi_ec_p_internal_new (MPI_EC_WEIERSTRASS, + ECC_DIALECT_STANDARD, + 0, + E.p, E.a, NULL); + if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx)) + log_fatal ("ecc get param: Failed to get affine coordinates\n"); + _gcry_mpi_ec_free (ctx); + _gcry_mpi_point_free_parts (&E.G); + + pkey[0] = E.p; + pkey[1] = E.a; + pkey[2] = E.b; + pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p); + pkey[4] = E.n; + pkey[5] = NULL; + + mpi_free (g_x); + mpi_free (g_y); + + if (sexp_build (&result, NULL, + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", + pkey[0], pkey[1], pkey[2], pkey[3], pkey[4])) + result = NULL; + + for (i=0; pkey[i]; i++) + _gcry_mpi_release (pkey[i]); + + return result; +} + + +/* Return an MPI (or opaque MPI) described by NAME and the context EC. + If COPY is true a copy is returned, if not a const MPI may be + returned. In any case mpi_free must be used. */ +gcry_mpi_t +_gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) +{ + if (!*name) + return NULL; + + if (!strcmp (name, "p") && ec->p) + return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p); + if (!strcmp (name, "a") && ec->a) + return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a); + if (!strcmp (name, "b") && ec->b) + return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); + if (!strcmp (name, "n") && ec->n) + return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); + if (!strcmp (name, "d") && ec->d) + return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); + + /* Return a requested point coordinate. */ + if (!strcmp (name, "g.x") && ec->G && ec->G->x) + return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x); + if (!strcmp (name, "g.y") && ec->G && ec->G->y) + return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y); + if (!strcmp (name, "q.x") && ec->Q && ec->Q->x) + return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x); + if (!strcmp (name, "q.y") && ec->Q && ec->Q->y) + return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y); + + /* If the base point has been requested, return it in standard + encoding. */ + if (!strcmp (name, "g") && ec->G) + return _gcry_mpi_ec_ec2os (ec->G, ec); + + /* If the public key has been requested, return it by default in + standard uncompressed encoding or if requested in other + encodings. */ + if (*name == 'q' && (!name[1] || name[1] == '@')) + { + /* If only the private key is given, compute the public key. */ + if (!ec->Q) + ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL); + + if (!ec->Q) + return NULL; + + if (name[1] != '@') + return _gcry_mpi_ec_ec2os (ec->Q, ec); + + if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_TWISTEDEDWARDS) + { + unsigned char *encpk; + unsigned int encpklen; + + if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, + &encpk, &encpklen)) + return mpi_set_opaque (NULL, encpk, encpklen*8); + } + } + + return NULL; +} + + +/* Return a point described by NAME and the context EC. */ +gcry_mpi_point_t +_gcry_ecc_get_point (const char *name, mpi_ec_t ec) +{ + if (!strcmp (name, "g") && ec->G) + return point_copy (ec->G); + if (!strcmp (name, "q")) + { + /* If only the private key is given, compute the public key. */ + if (!ec->Q) + ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL); + + if (ec->Q) + return point_copy (ec->Q); + } + + return NULL; +} + + +/* Store the MPI NEWVALUE into the context EC under NAME. */ +gpg_err_code_t +_gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) +{ + gpg_err_code_t rc = 0; + + if (!*name) + ; + else if (!strcmp (name, "p")) + { + mpi_free (ec->p); + ec->p = mpi_copy (newvalue); + _gcry_mpi_ec_get_reset (ec); + } + else if (!strcmp (name, "a")) + { + mpi_free (ec->a); + ec->a = mpi_copy (newvalue); + _gcry_mpi_ec_get_reset (ec); + } + else if (!strcmp (name, "b")) + { + mpi_free (ec->b); + ec->b = mpi_copy (newvalue); + } + else if (!strcmp (name, "n")) + { + mpi_free (ec->n); + ec->n = mpi_copy (newvalue); + } + else if (*name == 'q' && (!name[1] || name[1] == '@')) + { + if (newvalue) + { + if (!ec->Q) + ec->Q = mpi_point_new (0); + if (ec->dialect == ECC_DIALECT_ED25519) + rc = _gcry_ecc_eddsa_decodepoint (newvalue, ec, ec->Q, NULL, NULL); + else + rc = _gcry_ecc_os2ec (ec->Q, newvalue); + } + if (rc || !newvalue) + { + _gcry_mpi_point_release (ec->Q); + ec->Q = NULL; + } + /* Note: We assume that Q matches d and thus do not reset d. */ + } + else if (!strcmp (name, "d")) + { + mpi_free (ec->d); + ec->d = mpi_copy (newvalue); + if (ec->d) + { + /* We need to reset the public key because it may not + anymore match. */ + _gcry_mpi_point_release (ec->Q); + ec->Q = NULL; + } + } + else + rc = GPG_ERR_UNKNOWN_NAME; + + return rc; +} + + +/* Store the point NEWVALUE into the context EC under NAME. */ +gpg_err_code_t +_gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec) +{ + if (!strcmp (name, "g")) + { + _gcry_mpi_point_release (ec->G); + ec->G = point_copy (newvalue); + } + else if (!strcmp (name, "q")) + { + _gcry_mpi_point_release (ec->Q); + ec->Q = point_copy (newvalue); + } + else + return GPG_ERR_UNKNOWN_NAME; + + return 0; +} diff --git a/ecc.c b/ecc.c deleted file mode 100644 index 5e4717e..0000000 --- a/ecc.c +++ /dev/null @@ -1,1677 +0,0 @@ -/* ecc.c - Elliptic Curve Cryptography - Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. - - This file is part of Libgcrypt. - - Libgcrypt 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. - - Libgcrypt 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 program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, - USA. */ - -/* This code is originally based on the Patch 0.1.6 for the gnupg - 1.4.x branch as retrieved on 2007-03-21 from - http://www.calcurco.cat/eccGnuPG/src/gnupg-1.4.6-ecc0.2.0beta1.diff.bz2 - The original authors are: - Written by - Sergi Blanch i Torne , - Ramiro Moreno Chiral - Maintainers - Sergi Blanch i Torne - Ramiro Moreno Chiral - Mikael Mylnikov (mmr) - For use in Libgcrypt the code has been heavily modified and cleaned - up. In fact there is not much left of the orginally code except for - some variable names and the text book implementaion of the sign and - verification algorithms. The arithmetic functions have entirely - been rewritten and moved to mpi/ec.c. - - ECDH encrypt and decrypt code written by Andrey Jivsov, -*/ - - -/* TODO: - - - If we support point compression we need to uncompress before - computing the keygrip - - - In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a - special case in mpi_powm or check whether mpi_mulm is faster. - - - Decide whether we should hide the mpi_point_t definition. -*/ - - -#include -#include -#include -#include - -#include "g10lib.h" -#include "mpi.h" -#include "cipher.h" - -/* Definition of a curve. */ -typedef struct -{ - gcry_mpi_t p; /* Prime specifying the field GF(p). */ - gcry_mpi_t a; /* First coefficient of the Weierstrass equation. */ - gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */ - mpi_point_t G; /* Base point (generator). */ - gcry_mpi_t n; /* Order of G. */ - const char *name; /* Name of curve or NULL. */ -} elliptic_curve_t; - - -typedef struct -{ - elliptic_curve_t E; - mpi_point_t Q; /* Q = [d]G */ -} ECC_public_key; - -typedef struct -{ - elliptic_curve_t E; - mpi_point_t Q; - gcry_mpi_t d; -} ECC_secret_key; - - -/* This tables defines aliases for curve names. */ -static const struct -{ - const char *name; /* Our name. */ - const char *other; /* Other name. */ -} curve_aliases[] = - { - { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */ - { "NIST P-256", "prime256v1" }, - { "NIST P-256", "secp256r1" }, - - { "NIST P-384", "secp384r1" }, - { "NIST P-384", "1.3.132.0.34" }, - - { "NIST P-521", "secp521r1" }, - { "NIST P-521", "1.3.132.0.35" }, - - { NULL, NULL} - }; - -typedef struct { - const char *desc; /* Description of the curve. */ - unsigned int nbits; /* Number of bits. */ - unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */ - const char *p; /* Order of the prime field. */ - const char *a, *b; /* The coefficients. */ - const char *n; /* The order of the base point. */ - const char *g_x, *g_y; /* Base point. */ -} ecc_domain_parms_t; - -/* This static table defines all available curves. */ -static const ecc_domain_parms_t domain_parms[] = - { - { - "NIST P-256", 256, 1, - "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", - "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", - "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - - "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" - }, - { - "NIST P-384", 384, 1, - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000ffffffff", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000fffffffc", - "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" - "c656398d8a2ed19d2a85c8edd3ec2aef", - "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" - "581a0db248b0a77aecec196accc52973", - - "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" - "5502f25dbf55296c3a545e3872760ab7", - "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" - }, - { - "NIST P-521", 521, 1, - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", - "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" - "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", - "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - - "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" - "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", - "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" - }, - - { NULL, 0, 0, NULL, NULL, NULL, NULL } - }; - - -/* Registered progress function and its callback value. */ -static void (*progress_cb) (void *, const char*, int, int, int); -static void *progress_cb_data; - - -#define point_init(a) _gcry_mpi_ec_point_init ((a)) -#define point_free(a) _gcry_mpi_ec_point_free ((a)) - - - -/* Local prototypes. */ -static gcry_mpi_t gen_k (gcry_mpi_t p, int security_level); -static void test_keys (ECC_secret_key * sk, unsigned int nbits); -static int check_secret_key (ECC_secret_key * sk); -static gpg_err_code_t sign (gcry_mpi_t input, ECC_secret_key *skey, - gcry_mpi_t r, gcry_mpi_t s); -static gpg_err_code_t verify (gcry_mpi_t input, ECC_public_key *pkey, - gcry_mpi_t r, gcry_mpi_t s); - - -static gcry_mpi_t gen_y_2 (gcry_mpi_t x, elliptic_curve_t * base); - - - - -void -_gcry_register_pk_ecc_progress (void (*cb) (void *, const char *, - int, int, int), - void *cb_data) -{ - progress_cb = cb; - progress_cb_data = cb_data; -} - -/* static void */ -/* progress (int c) */ -/* { */ -/* if (progress_cb) */ -/* progress_cb (progress_cb_data, "pk_ecc", c, 0, 0); */ -/* } */ - - - - -/* Set the value from S into D. */ -static void -point_set (mpi_point_t *d, mpi_point_t *s) -{ - mpi_set (d->x, s->x); - mpi_set (d->y, s->y); - mpi_set (d->z, s->z); -} - - -/* - * Release a curve object. - */ -static void -curve_free (elliptic_curve_t *E) -{ - mpi_free (E->p); E->p = NULL; - mpi_free (E->a); E->a = NULL; - mpi_free (E->b); E->b = NULL; - point_free (&E->G); - mpi_free (E->n); E->n = NULL; -} - - -/* - * Return a copy of a curve object. - */ -static elliptic_curve_t -curve_copy (elliptic_curve_t E) -{ - elliptic_curve_t R; - - R.p = mpi_copy (E.p); - R.a = mpi_copy (E.a); - R.b = mpi_copy (E.b); - point_init (&R.G); - point_set (&R.G, &E.G); - R.n = mpi_copy (E.n); - - return R; -} - - -/* Helper to scan a hex string. */ -static gcry_mpi_t -scanval (const char *string) -{ - gpg_error_t err; - gcry_mpi_t val; - - err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); - if (err) - log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (err)); - return val; -} - - - - - -/**************** - * Solve the right side of the equation that defines a curve. - */ -static gcry_mpi_t -gen_y_2 (gcry_mpi_t x, elliptic_curve_t *base) -{ - gcry_mpi_t three, x_3, axb, y; - - three = mpi_alloc_set_ui (3); - x_3 = mpi_new (0); - axb = mpi_new (0); - y = mpi_new (0); - - mpi_powm (x_3, x, three, base->p); - mpi_mulm (axb, base->a, x, base->p); - mpi_addm (axb, axb, base->b, base->p); - mpi_addm (y, x_3, axb, base->p); - - mpi_free (x_3); - mpi_free (axb); - mpi_free (three); - return y; /* The quadratic value of the coordinate if it exist. */ -} - - -/* Generate a random secret scalar k with an order of p - - At the beginning this was identical to the code is in elgamal.c. - Later imporved by mmr. Further simplified by wk. */ -static gcry_mpi_t -gen_k (gcry_mpi_t p, int security_level) -{ - gcry_mpi_t k; - unsigned int nbits; - - nbits = mpi_get_nbits (p); - k = mpi_snew (nbits); - if (DBG_CIPHER) - log_debug ("choosing a random k of %u bits at seclevel %d\n", - nbits, security_level); - - gcry_mpi_randomize (k, nbits, security_level); - - mpi_mod (k, k, p); /* k = k mod p */ - - return k; -} - - -/* Generate the crypto system setup. This function takes the NAME of - a curve or the desired number of bits and stores at R_CURVE the - parameters of the named curve or those of a suitable curve. The - chosen number of bits is stored on R_NBITS. */ -static gpg_err_code_t -fill_in_curve (unsigned int nbits, const char *name, - elliptic_curve_t *curve, unsigned int *r_nbits) -{ - int idx, aliasno; - const char *resname = NULL; /* Set to a found curve name. */ - - if (name) - { - /* First check our native curves. */ - for (idx = 0; domain_parms[idx].desc; idx++) - if (!strcmp (name, domain_parms[idx].desc)) - { - resname = domain_parms[idx].desc; - break; - } - /* If not found consult the alias table. */ - if (!domain_parms[idx].desc) - { - for (aliasno = 0; curve_aliases[aliasno].name; aliasno++) - if (!strcmp (name, curve_aliases[aliasno].other)) - break; - if (curve_aliases[aliasno].name) - { - for (idx = 0; domain_parms[idx].desc; idx++) - if (!strcmp (curve_aliases[aliasno].name, - domain_parms[idx].desc)) - { - resname = domain_parms[idx].desc; - break; - } - } - } - } - else - { - for (idx = 0; domain_parms[idx].desc; idx++) - if (nbits == domain_parms[idx].nbits) - break; - } - if (!domain_parms[idx].desc) - return GPG_ERR_INV_VALUE; - - /* In fips mode we only support NIST curves. Note that it is - possible to bypass this check by specifying the curve parameters - directly. */ - if (fips_mode () && !domain_parms[idx].fips ) - return GPG_ERR_NOT_SUPPORTED; - - *r_nbits = domain_parms[idx].nbits; - curve->p = scanval (domain_parms[idx].p); - curve->a = scanval (domain_parms[idx].a); - curve->b = scanval (domain_parms[idx].b); - curve->n = scanval (domain_parms[idx].n); - curve->G.x = scanval (domain_parms[idx].g_x); - curve->G.y = scanval (domain_parms[idx].g_y); - curve->G.z = mpi_alloc_set_ui (1); - curve->name = resname; - - return 0; -} - - -/* - * First obtain the setup. Over the finite field randomize an scalar - * secret value, and calculate the public point. - */ -static gpg_err_code_t -generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name, - int transient_key, - gcry_mpi_t g_x, gcry_mpi_t g_y, - gcry_mpi_t q_x, gcry_mpi_t q_y, - const char **r_usedcurve) -{ - gpg_err_code_t err; - elliptic_curve_t E; - gcry_mpi_t d; - mpi_point_t Q; - mpi_ec_t ctx; - gcry_random_level_t random_level; - - *r_usedcurve = NULL; - - err = fill_in_curve (nbits, name, &E, &nbits); - if (err) - return err; - - if (DBG_CIPHER) - { - log_mpidump ("ecgen curve p", E.p); - log_mpidump ("ecgen curve a", E.a); - log_mpidump ("ecgen curve b", E.b); - log_mpidump ("ecgen curve n", E.n); - log_mpidump ("ecgen curve Gx", E.G.x); - log_mpidump ("ecgen curve Gy", E.G.y); - log_mpidump ("ecgen curve Gz", E.G.z); - if (E.name) - log_debug ("ecgen curve used: %s\n", E.name); - } - - random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; - d = gen_k (E.n, random_level); - - /* Compute Q. */ - point_init (&Q); - ctx = _gcry_mpi_ec_init (E.p, E.a); - _gcry_mpi_ec_mul_point (&Q, d, &E.G, ctx); - - /* Copy the stuff to the key structures. */ - sk->E.p = mpi_copy (E.p); - sk->E.a = mpi_copy (E.a); - sk->E.b = mpi_copy (E.b); - point_init (&sk->E.G); - point_set (&sk->E.G, &E.G); - sk->E.n = mpi_copy (E.n); - point_init (&sk->Q); - point_set (&sk->Q, &Q); - sk->d = mpi_copy (d); - /* We also return copies of G and Q in affine coordinates if - requested. */ - if (g_x && g_y) - { - if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx)) - log_fatal ("ecgen: Failed to get affine coordinates\n"); - } - if (q_x && q_y) - { - if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx)) - log_fatal ("ecgen: Failed to get affine coordinates\n"); - } - _gcry_mpi_ec_free (ctx); - - point_free (&Q); - mpi_free (d); - - *r_usedcurve = E.name; - curve_free (&E); - - /* Now we can test our keys (this should never fail!). */ - test_keys (sk, nbits - 64); - - return 0; -} - - -/* - * To verify correct skey it use a random information. - * First, encrypt and decrypt this dummy value, - * test if the information is recuperated. - * Second, test with the sign and verify functions. - */ -static void -test_keys (ECC_secret_key *sk, unsigned int nbits) -{ - ECC_public_key pk; - gcry_mpi_t test = mpi_new (nbits); - mpi_point_t R_; - gcry_mpi_t c = mpi_new (nbits); - gcry_mpi_t out = mpi_new (nbits); - gcry_mpi_t r = mpi_new (nbits); - gcry_mpi_t s = mpi_new (nbits); - - if (DBG_CIPHER) - log_debug ("Testing key.\n"); - - point_init (&R_); - - pk.E = curve_copy (sk->E); - point_init (&pk.Q); - point_set (&pk.Q, &sk->Q); - - gcry_mpi_randomize (test, nbits, GCRY_WEAK_RANDOM); - - if (sign (test, sk, r, s) ) - log_fatal ("ECDSA operation: sign failed\n"); - - if (verify (test, &pk, r, s)) - { - log_fatal ("ECDSA operation: sign, verify failed\n"); - } - - if (DBG_CIPHER) - log_debug ("ECDSA operation: sign, verify ok.\n"); - - point_free (&pk.Q); - curve_free (&pk.E); - - point_free (&R_); - mpi_free (s); - mpi_free (r); - mpi_free (out); - mpi_free (c); - mpi_free (test); -} - - -/* - * To check the validity of the value, recalculate the correspondence - * between the public value and the secret one. - */ -static int -check_secret_key (ECC_secret_key * sk) -{ - int rc = 1; - mpi_point_t Q; - gcry_mpi_t y_2, y2; - mpi_ec_t ctx = NULL; - - point_init (&Q); - - /* ?primarity test of 'p' */ - /* (...) //!! */ - /* G in E(F_p) */ - y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */ - y2 = mpi_alloc (0); - mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */ - if (mpi_cmp (y_2, y2)) - { - if (DBG_CIPHER) - log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n"); - goto leave; - } - /* G != PaI */ - if (!mpi_cmp_ui (sk->E.G.z, 0)) - { - if (DBG_CIPHER) - log_debug ("Bad check: 'G' cannot be Point at Infinity!\n"); - goto leave; - } - - ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a); - - _gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx); - if (mpi_cmp_ui (Q.z, 0)) - { - if (DBG_CIPHER) - log_debug ("check_secret_key: E is not a curve of order n\n"); - goto leave; - } - /* pubkey cannot be PaI */ - if (!mpi_cmp_ui (sk->Q.z, 0)) - { - if (DBG_CIPHER) - log_debug ("Bad check: Q can not be a Point at Infinity!\n"); - goto leave; - } - /* pubkey = [d]G over E */ - _gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx); - if ((Q.x == sk->Q.x) && (Q.y == sk->Q.y) && (Q.z == sk->Q.z)) - { - if (DBG_CIPHER) - log_debug - ("Bad check: There is NO correspondence between 'd' and 'Q'!\n"); - goto leave; - } - rc = 0; /* Okay. */ - - leave: - _gcry_mpi_ec_free (ctx); - mpi_free (y2); - mpi_free (y_2); - point_free (&Q); - return rc; -} - - -/* - * Return the signature struct (r,s) from the message hash. The caller - * must have allocated R and S. - */ -static gpg_err_code_t -sign (gcry_mpi_t input, ECC_secret_key *skey, gcry_mpi_t r, gcry_mpi_t s) -{ - gpg_err_code_t err = 0; - gcry_mpi_t k, dr, sum, k_1, x; - mpi_point_t I; - mpi_ec_t ctx; - - if (DBG_CIPHER) - log_mpidump ("ecdsa sign hash ", input ); - - k = NULL; - dr = mpi_alloc (0); - sum = mpi_alloc (0); - k_1 = mpi_alloc (0); - x = mpi_alloc (0); - point_init (&I); - - mpi_set_ui (s, 0); - mpi_set_ui (r, 0); - - ctx = _gcry_mpi_ec_init (skey->E.p, skey->E.a); - - while (!mpi_cmp_ui (s, 0)) /* s == 0 */ - { - while (!mpi_cmp_ui (r, 0)) /* r == 0 */ - { - /* Note, that we are guaranteed to enter this loop at least - once because r has been intialized to 0. We can't use a - do_while because we want to keep the value of R even if S - has to be recomputed. */ - mpi_free (k); - k = gen_k (skey->E.n, GCRY_STRONG_RANDOM); - _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx); - if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx)) - { - if (DBG_CIPHER) - log_debug ("ecc sign: Failed to get affine coordinates\n"); - err = GPG_ERR_BAD_SIGNATURE; - goto leave; - } - mpi_mod (r, x, skey->E.n); /* r = x mod n */ - } - mpi_mulm (dr, skey->d, r, skey->E.n); /* dr = d*r mod n */ - mpi_addm (sum, input, dr, skey->E.n); /* sum = hash + (d*r) mod n */ - mpi_invm (k_1, k, skey->E.n); /* k_1 = k^(-1) mod n */ - mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */ - } - - if (DBG_CIPHER) - { - log_mpidump ("ecdsa sign result r ", r); - log_mpidump ("ecdsa sign result s ", s); - } - - leave: - _gcry_mpi_ec_free (ctx); - point_free (&I); - mpi_free (x); - mpi_free (k_1); - mpi_free (sum); - mpi_free (dr); - mpi_free (k); - - return err; -} - - -/* - * Check if R and S verifies INPUT. - */ -static gpg_err_code_t -verify (gcry_mpi_t input, ECC_public_key *pkey, gcry_mpi_t r, gcry_mpi_t s) -{ - gpg_err_code_t err = 0; - gcry_mpi_t h, h1, h2, x, y; - mpi_point_t Q, Q1, Q2; - mpi_ec_t ctx; - - if( !(mpi_cmp_ui (r, 0) > 0 && mpi_cmp (r, pkey->E.n) < 0) ) - return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < r < n failed. */ - if( !(mpi_cmp_ui (s, 0) > 0 && mpi_cmp (s, pkey->E.n) < 0) ) - return GPG_ERR_BAD_SIGNATURE; /* Assertion 0 < s < n failed. */ - - h = mpi_alloc (0); - h1 = mpi_alloc (0); - h2 = mpi_alloc (0); - x = mpi_alloc (0); - y = mpi_alloc (0); - point_init (&Q); - point_init (&Q1); - point_init (&Q2); - - ctx = _gcry_mpi_ec_init (pkey->E.p, pkey->E.a); - - /* h = s^(-1) (mod n) */ - mpi_invm (h, s, pkey->E.n); -/* log_mpidump (" h", h); */ - /* h1 = hash * s^(-1) (mod n) */ - mpi_mulm (h1, input, h, pkey->E.n); -/* log_mpidump (" h1", h1); */ - /* Q1 = [ hash * s^(-1) ]G */ - _gcry_mpi_ec_mul_point (&Q1, h1, &pkey->E.G, ctx); -/* log_mpidump ("Q1.x", Q1.x); */ -/* log_mpidump ("Q1.y", Q1.y); */ -/* log_mpidump ("Q1.z", Q1.z); */ - /* h2 = r * s^(-1) (mod n) */ - mpi_mulm (h2, r, h, pkey->E.n); -/* log_mpidump (" h2", h2); */ - /* Q2 = [ r * s^(-1) ]Q */ - _gcry_mpi_ec_mul_point (&Q2, h2, &pkey->Q, ctx); -/* log_mpidump ("Q2.x", Q2.x); */ -/* log_mpidump ("Q2.y", Q2.y); */ -/* log_mpidump ("Q2.z", Q2.z); */ - /* Q = ([hash * s^(-1)]G) + ([r * s^(-1)]Q) */ - _gcry_mpi_ec_add_points (&Q, &Q1, &Q2, ctx); -/* log_mpidump (" Q.x", Q.x); */ -/* log_mpidump (" Q.y", Q.y); */ -/* log_mpidump (" Q.z", Q.z); */ - - if (!mpi_cmp_ui (Q.z, 0)) - { - if (DBG_CIPHER) - log_debug ("ecc verify: Rejected\n"); - err = GPG_ERR_BAD_SIGNATURE; - goto leave; - } - if (_gcry_mpi_ec_get_affine (x, y, &Q, ctx)) - { - if (DBG_CIPHER) - log_debug ("ecc verify: Failed to get affine coordinates\n"); - err = GPG_ERR_BAD_SIGNATURE; - goto leave; - } - mpi_mod (x, x, pkey->E.n); /* x = x mod E_n */ - if (mpi_cmp (x, r)) /* x != r */ - { - if (DBG_CIPHER) - { - log_mpidump (" x", x); - log_mpidump (" y", y); - log_mpidump (" r", r); - log_mpidump (" s", s); - log_debug ("ecc verify: Not verified\n"); - } - err = GPG_ERR_BAD_SIGNATURE; - goto leave; - } - if (DBG_CIPHER) - log_debug ("ecc verify: Accepted\n"); - - leave: - _gcry_mpi_ec_free (ctx); - point_free (&Q2); - point_free (&Q1); - point_free (&Q); - mpi_free (y); - mpi_free (x); - mpi_free (h2); - mpi_free (h1); - mpi_free (h); - return err; -} - - - -/********************************************* - ************** interface ****************** - *********************************************/ -static gcry_mpi_t -ec2os (gcry_mpi_t x, gcry_mpi_t y, gcry_mpi_t p) -{ - gpg_error_t err; - int pbytes = (mpi_get_nbits (p)+7)/8; - size_t n; - unsigned char *buf, *ptr; - gcry_mpi_t result; - - buf = gcry_xmalloc ( 1 + 2*pbytes ); - *buf = 04; /* Uncompressed point. */ - ptr = buf+1; - err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, x); - if (err) - log_fatal ("mpi_print failed: %s\n", gpg_strerror (err)); - if (n < pbytes) - { - memmove (ptr+(pbytes-n), ptr, n); - memset (ptr, 0, (pbytes-n)); - } - ptr += pbytes; - err = gcry_mpi_print (GCRYMPI_FMT_USG, ptr, pbytes, &n, y); - if (err) - log_fatal ("mpi_print failed: %s\n", gpg_strerror (err)); - if (n < pbytes) - { - memmove (ptr+(pbytes-n), ptr, n); - memset (ptr, 0, (pbytes-n)); - } - - err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL); - if (err) - log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err)); - gcry_free (buf); - - return result; -} - - -/* RESULT must have been initialized and is set on success to the - point given by VALUE. */ -static gcry_error_t -os2ec (mpi_point_t *result, gcry_mpi_t value) -{ - gcry_error_t err; - size_t n; - unsigned char *buf; - gcry_mpi_t x, y; - - n = (mpi_get_nbits (value)+7)/8; - buf = gcry_xmalloc (n); - err = gcry_mpi_print (GCRYMPI_FMT_USG, buf, n, &n, value); - if (err) - { - gcry_free (buf); - return err; - } - if (n < 1) - { - gcry_free (buf); - return GPG_ERR_INV_OBJ; - } - if (*buf != 4) - { - gcry_free (buf); - return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression. */ - } - if ( ((n-1)%2) ) - { - gcry_free (buf); - return GPG_ERR_INV_OBJ; - } - n = (n-1)/2; - err = gcry_mpi_scan (&x, GCRYMPI_FMT_USG, buf+1, n, NULL); - if (err) - { - gcry_free (buf); - return err; - } - err = gcry_mpi_scan (&y, GCRYMPI_FMT_USG, buf+1+n, n, NULL); - gcry_free (buf); - if (err) - { - mpi_free (x); - return err; - } - - mpi_set (result->x, x); - mpi_set (result->y, y); - mpi_set_ui (result->z, 1); - - mpi_free (x); - mpi_free (y); - - return 0; -} - - -/* Extended version of ecc_generate. */ -static gcry_err_code_t -ecc_generate_ext (int algo, unsigned int nbits, unsigned long evalue, - const gcry_sexp_t genparms, - gcry_mpi_t *skey, gcry_mpi_t **retfactors, - gcry_sexp_t *r_extrainfo) -{ - gpg_err_code_t ec; - ECC_secret_key sk; - gcry_mpi_t g_x, g_y, q_x, q_y; - char *curve_name = NULL; - gcry_sexp_t l1; - int transient_key = 0; - const char *usedcurve = NULL; - - (void)algo; - (void)evalue; - - if (genparms) - { - /* Parse the optional "curve" parameter. */ - l1 = gcry_sexp_find_token (genparms, "curve", 0); - if (l1) - { - curve_name = _gcry_sexp_nth_string (l1, 1); - gcry_sexp_release (l1); - if (!curve_name) - return GPG_ERR_INV_OBJ; /* No curve name or value too large. */ - } - - /* Parse the optional transient-key flag. */ - l1 = gcry_sexp_find_token (genparms, "transient-key", 0); - if (l1) - { - transient_key = 1; - gcry_sexp_release (l1); - } - } - - /* NBITS is required if no curve name has been given. */ - if (!nbits && !curve_name) - return GPG_ERR_NO_OBJ; /* No NBITS parameter. */ - - g_x = mpi_new (0); - g_y = mpi_new (0); - q_x = mpi_new (0); - q_y = mpi_new (0); - ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y, - &usedcurve); - gcry_free (curve_name); - if (ec) - return ec; - if (usedcurve) /* Fixme: No error return checking. */ - gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve); - - skey[0] = sk.E.p; - skey[1] = sk.E.a; - skey[2] = sk.E.b; - skey[3] = ec2os (g_x, g_y, sk.E.p); - skey[4] = sk.E.n; - skey[5] = ec2os (q_x, q_y, sk.E.p); - skey[6] = sk.d; - - mpi_free (g_x); - mpi_free (g_y); - mpi_free (q_x); - mpi_free (q_y); - - point_free (&sk.E.G); - point_free (&sk.Q); - - /* Make an empty list of factors. */ - *retfactors = gcry_calloc ( 1, sizeof **retfactors ); - if (!*retfactors) - return gpg_err_code_from_syserror (); /* Fixme: relase mem? */ - - if (DBG_CIPHER) - { - log_mpidump ("ecgen result p", skey[0]); - log_mpidump ("ecgen result a", skey[1]); - log_mpidump ("ecgen result b", skey[2]); - log_mpidump ("ecgen result G", skey[3]); - log_mpidump ("ecgen result n", skey[4]); - log_mpidump ("ecgen result Q", skey[5]); - log_mpidump ("ecgen result d", skey[6]); - } - - return 0; -} - - -static gcry_err_code_t -ecc_generate (int algo, unsigned int nbits, unsigned long evalue, - gcry_mpi_t *skey, gcry_mpi_t **retfactors) -{ - (void)evalue; - return ecc_generate_ext (algo, nbits, 0, NULL, skey, retfactors, NULL); -} - - -/* Return the parameters of the curve NAME in an MPI array. */ -static gcry_err_code_t -ecc_get_param (const char *name, gcry_mpi_t *pkey) -{ - gpg_err_code_t err; - unsigned int nbits; - elliptic_curve_t E; - mpi_ec_t ctx; - gcry_mpi_t g_x, g_y; - - err = fill_in_curve (0, name, &E, &nbits); - if (err) - return err; - - g_x = mpi_new (0); - g_y = mpi_new (0); - ctx = _gcry_mpi_ec_init (E.p, E.a); - if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx)) - log_fatal ("ecc get param: Failed to get affine coordinates\n"); - _gcry_mpi_ec_free (ctx); - point_free (&E.G); - - pkey[0] = E.p; - pkey[1] = E.a; - pkey[2] = E.b; - pkey[3] = ec2os (g_x, g_y, E.p); - pkey[4] = E.n; - pkey[5] = NULL; - - mpi_free (g_x); - mpi_free (g_y); - - return 0; -} - - -/* Return the parameters of the curve NAME as an S-expression. */ -static gcry_sexp_t -ecc_get_param_sexp (const char *name) -{ - gcry_mpi_t pkey[6]; - gcry_sexp_t result; - int i; - - if (ecc_get_param (name, pkey)) - return NULL; - - if (gcry_sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4])) - result = NULL; - - for (i=0; pkey[i]; i++) - gcry_mpi_release (pkey[i]); - - return result; -} - - -/* Return the name matching the parameters in PKEY. */ -static const char * -ecc_get_curve (gcry_mpi_t *pkey, int iterator, unsigned int *r_nbits) -{ - gpg_err_code_t err; - elliptic_curve_t E; - int idx; - gcry_mpi_t tmp; - const char *result = NULL; - - if (r_nbits) - *r_nbits = 0; - - if (!pkey) - { - idx = iterator; - if (idx >= 0 && idx < DIM (domain_parms)) - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - } - return result; - } - - if (!pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4]) - return NULL; - - E.p = pkey[0]; - E.a = pkey[1]; - E.b = pkey[2]; - point_init (&E.G); - err = os2ec (&E.G, pkey[3]); - if (err) - { - point_free (&E.G); - return NULL; - } - E.n = pkey[4]; - - for (idx = 0; domain_parms[idx].desc; idx++) - { - tmp = scanval (domain_parms[idx].p); - if (!mpi_cmp (tmp, E.p)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].a); - if (!mpi_cmp (tmp, E.a)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].b); - if (!mpi_cmp (tmp, E.b)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].n); - if (!mpi_cmp (tmp, E.n)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (!mpi_cmp (tmp, E.G.x)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (!mpi_cmp (tmp, E.G.y)) - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - break; - } - } - } - } - } - } - mpi_free (tmp); - } - - point_free (&E.G); - - return result; -} - - -static gcry_err_code_t -ecc_check_secret_key (int algo, gcry_mpi_t *skey) -{ - gpg_err_code_t err; - ECC_secret_key sk; - - (void)algo; - - /* FIXME: This check looks a bit fishy: Now long is the array? */ - if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5] - || !skey[6]) - return GPG_ERR_BAD_MPI; - - sk.E.p = skey[0]; - sk.E.a = skey[1]; - sk.E.b = skey[2]; - point_init (&sk.E.G); - err = os2ec (&sk.E.G, skey[3]); - if (err) - { - point_free (&sk.E.G); - return err; - } - sk.E.n = skey[4]; - point_init (&sk.Q); - err = os2ec (&sk.Q, skey[5]); - if (err) - { - point_free (&sk.E.G); - point_free (&sk.Q); - return err; - } - - sk.d = skey[6]; - - if (check_secret_key (&sk)) - { - point_free (&sk.E.G); - point_free (&sk.Q); - return GPG_ERR_BAD_SECKEY; - } - point_free (&sk.E.G); - point_free (&sk.Q); - return 0; -} - - -static gcry_err_code_t -ecc_sign (int algo, gcry_mpi_t *resarr, gcry_mpi_t data, gcry_mpi_t *skey) -{ - gpg_err_code_t err; - ECC_secret_key sk; - - (void)algo; - - if (!data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] - || !skey[5] || !skey[6] ) - return GPG_ERR_BAD_MPI; - - sk.E.p = skey[0]; - sk.E.a = skey[1]; - sk.E.b = skey[2]; - point_init (&sk.E.G); - err = os2ec (&sk.E.G, skey[3]); - if (err) - { - point_free (&sk.E.G); - return err; - } - sk.E.n = skey[4]; - point_init (&sk.Q); - err = os2ec (&sk.Q, skey[5]); - if (err) - { - point_free (&sk.E.G); - point_free (&sk.Q); - return err; - } - sk.d = skey[6]; - - resarr[0] = mpi_alloc (mpi_get_nlimbs (sk.E.p)); - resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.E.p)); - err = sign (data, &sk, resarr[0], resarr[1]); - if (err) - { - mpi_free (resarr[0]); - mpi_free (resarr[1]); - resarr[0] = NULL; /* Mark array as released. */ - } - point_free (&sk.E.G); - point_free (&sk.Q); - return err; -} - - -static gcry_err_code_t -ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey, - int (*cmp)(void *, gcry_mpi_t), void *opaquev) -{ - gpg_err_code_t err; - ECC_public_key pk; - - (void)algo; - (void)cmp; - (void)opaquev; - - if (!data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2] - || !pkey[3] || !pkey[4] || !pkey[5] ) - return GPG_ERR_BAD_MPI; - - pk.E.p = pkey[0]; - pk.E.a = pkey[1]; - pk.E.b = pkey[2]; - point_init (&pk.E.G); - err = os2ec (&pk.E.G, pkey[3]); - if (err) - { - point_free (&pk.E.G); - return err; - } - pk.E.n = pkey[4]; - point_init (&pk.Q); - err = os2ec (&pk.Q, pkey[5]); - if (err) - { - point_free (&pk.E.G); - point_free (&pk.Q); - return err; - } - - err = verify (hash, &pk, data[0], data[1]); - - point_free (&pk.E.G); - point_free (&pk.Q); - return err; -} - - -/* ecdh raw is classic 2-round DH protocol published in 1976. - * - * Overview of ecc_encrypt_raw and ecc_decrypt_raw. - * - * As with any PK operation, encrypt version uses a public key and - * decrypt -- private. - * - * Symbols used below: - * G - field generator point - * d - private long-term scalar - * dG - public long-term key - * k - ephemeral scalar - * kG - ephemeral public key - * dkG - shared secret - * - * ecc_encrypt_raw description: - * input: - * data[0] : private scalar (k) - * output: - * result[0] : shared point (kdG) - * result[1] : generated ephemeral public key (kG) - * - * ecc_decrypt_raw description: - * input: - * data[0] : a point kG (ephemeral public key) - * output: - * result[0] : shared point (kdG) - */ -static gcry_err_code_t -ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k, - gcry_mpi_t *pkey, int flags) -{ - ECC_public_key pk; - mpi_ec_t ctx; - gcry_mpi_t result[2]; - int err; - - (void)algo; - (void)flags; - - if (!k - || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5]) - return GPG_ERR_BAD_MPI; - - pk.E.p = pkey[0]; - pk.E.a = pkey[1]; - pk.E.b = pkey[2]; - point_init (&pk.E.G); - err = os2ec (&pk.E.G, pkey[3]); - if (err) - { - point_free (&pk.E.G); - return err; - } - pk.E.n = pkey[4]; - point_init (&pk.Q); - err = os2ec (&pk.Q, pkey[5]); - if (err) - { - point_free (&pk.E.G); - point_free (&pk.Q); - return err; - } - - ctx = _gcry_mpi_ec_init (pk.E.p, pk.E.a); - - /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */ - { - mpi_point_t R; /* Result that we return. */ - gcry_mpi_t x, y; - - x = mpi_new (0); - y = mpi_new (0); - - point_init (&R); - - /* R = kQ <=> R = kdG */ - _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx); - - if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) - log_fatal ("ecdh: Failed to get affine coordinates for kdG\n"); - - result[0] = ec2os (x, y, pk.E.p); - - /* R = kG */ - _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx); - - if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) - log_fatal ("ecdh: Failed to get affine coordinates for kG\n"); - - result[1] = ec2os (x, y, pk.E.p); - - mpi_free (x); - mpi_free (y); - - point_free (&R); - } - - _gcry_mpi_ec_free (ctx); - point_free (&pk.E.G); - point_free (&pk.Q); - - if (!result[0] || !result[1]) - { - mpi_free (result[0]); - mpi_free (result[1]); - return GPG_ERR_ENOMEM; - } - - /* Success. */ - resarr[0] = result[0]; - resarr[1] = result[1]; - - return 0; -} - -/* input: - * data[0] : a point kG (ephemeral public key) - * output: - * resaddr[0] : shared point kdG - * - * see ecc_encrypt_raw for details. - */ -static gcry_err_code_t -ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data, - gcry_mpi_t *skey, int flags) -{ - ECC_secret_key sk; - mpi_point_t R; /* Result that we return. */ - mpi_point_t kG; - mpi_ec_t ctx; - gcry_mpi_t r; - int err; - - (void)algo; - (void)flags; - - *result = NULL; - - if (!data || !data[0] - || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] - || !skey[5] || !skey[6] ) - return GPG_ERR_BAD_MPI; - - point_init (&kG); - err = os2ec (&kG, data[0]); - if (err) - { - point_free (&kG); - return err; - } - - - sk.E.p = skey[0]; - sk.E.a = skey[1]; - sk.E.b = skey[2]; - point_init (&sk.E.G); - err = os2ec (&sk.E.G, skey[3]); - if (err) - { - point_free (&kG); - point_free (&sk.E.G); - return err; - } - sk.E.n = skey[4]; - point_init (&sk.Q); - err = os2ec (&sk.Q, skey[5]); - if (err) - { - point_free (&kG); - point_free (&sk.E.G); - point_free (&sk.Q); - return err; - } - sk.d = skey[6]; - - ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a); - - /* R = dkG */ - point_init (&R); - _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx); - - point_free (&kG); - - /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */ - { - gcry_mpi_t x, y; - - x = mpi_new (0); - y = mpi_new (0); - - if (_gcry_mpi_ec_get_affine (x, y, &R, ctx)) - log_fatal ("ecdh: Failed to get affine coordinates\n"); - - r = ec2os (x, y, sk.E.p); - mpi_free (x); - mpi_free (y); - } - - point_free (&R); - _gcry_mpi_ec_free (ctx); - point_free (&kG); - point_free (&sk.E.G); - point_free (&sk.Q); - - if (!r) - return GPG_ERR_ENOMEM; - - /* Success. */ - - *result = r; - - return 0; -} - - -static unsigned int -ecc_get_nbits (int algo, gcry_mpi_t *pkey) -{ - (void)algo; - - return mpi_get_nbits (pkey[0]); -} - - -/* See rsa.c for a description of this function. */ -static gpg_err_code_t -compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam) -{ -#define N_COMPONENTS 6 - static const char names[N_COMPONENTS+1] = "pabgnq"; - gpg_err_code_t ec = 0; - gcry_sexp_t l1; - gcry_mpi_t values[N_COMPONENTS]; - int idx; - - /* Clear the values for easier error cleanup. */ - for (idx=0; idx < N_COMPONENTS; idx++) - values[idx] = NULL; - - /* Fill values with all provided parameters. */ - for (idx=0; idx < N_COMPONENTS; idx++) - { - l1 = gcry_sexp_find_token (keyparam, names+idx, 1); - if (l1) - { - values[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); - gcry_sexp_release (l1); - if (!values[idx]) - { - ec = GPG_ERR_INV_OBJ; - goto leave; - } - } - } - - /* Check whether a curve parameter is available and use that to fill - in missing values. */ - l1 = gcry_sexp_find_token (keyparam, "curve", 5); - if (l1) - { - char *curve; - gcry_mpi_t tmpvalues[N_COMPONENTS]; - - for (idx = 0; idx < N_COMPONENTS; idx++) - tmpvalues[idx] = NULL; - - curve = _gcry_sexp_nth_string (l1, 1); - gcry_sexp_release (l1); - if (!curve) - { - ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */ - goto leave; - } - ec = ecc_get_param (curve, tmpvalues); - gcry_free (curve); - if (ec) - goto leave; - - for (idx = 0; idx < N_COMPONENTS; idx++) - { - if (!values[idx]) - values[idx] = tmpvalues[idx]; - else - mpi_free (tmpvalues[idx]); - } - } - - /* Check that all parameters are known and normalize all MPIs (that - should not be required but we use an internal function later and - thus we better make 100% sure that they are normalized). */ - for (idx = 0; idx < N_COMPONENTS; idx++) - if (!values[idx]) - { - ec = GPG_ERR_NO_OBJ; - goto leave; - } - else - _gcry_mpi_normalize (values[idx]); - - /* Hash them all. */ - for (idx = 0; idx < N_COMPONENTS; idx++) - { - char buf[30]; - unsigned char *rawmpi; - unsigned int rawmpilen; - - rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL); - if (!rawmpi) - { - ec = gpg_err_code_from_syserror (); - goto leave; - } - snprintf (buf, sizeof buf, "(1:%c%u:", names[idx], rawmpilen); - gcry_md_write (md, buf, strlen (buf)); - gcry_md_write (md, rawmpi, rawmpilen); - gcry_md_write (md, ")", 1); - gcry_free (rawmpi); - } - - leave: - for (idx = 0; idx < N_COMPONENTS; idx++) - _gcry_mpi_release (values[idx]); - - return ec; -#undef N_COMPONENTS -} - - - - - -/* - Self-test section. - */ - - -static gpg_err_code_t -selftests_ecdsa (selftest_report_func_t report) -{ - const char *what; - const char *errtxt; - - what = "low-level"; - errtxt = NULL; /*selftest ();*/ - if (errtxt) - goto failed; - - /* FIXME: need more tests. */ - - return 0; /* Succeeded. */ - - failed: - if (report) - report ("pubkey", GCRY_PK_ECDSA, what, errtxt); - return GPG_ERR_SELFTEST_FAILED; -} - - -/* Run a full self-test for ALGO and return 0 on success. */ -static gpg_err_code_t -run_selftests (int algo, int extended, selftest_report_func_t report) -{ - gpg_err_code_t ec; - - (void)extended; - - switch (algo) - { - case GCRY_PK_ECDSA: - ec = selftests_ecdsa (report); - break; - default: - ec = GPG_ERR_PUBKEY_ALGO; - break; - - } - return ec; -} - - - - -static const char *ecdsa_names[] = - { - "ecdsa", - "ecc", - NULL, - }; -static const char *ecdh_names[] = - { - "ecdh", - "ecc", - NULL, - }; - -gcry_pk_spec_t _gcry_pubkey_spec_ecdsa = - { - "ECDSA", ecdsa_names, - "pabgnq", "pabgnqd", "", "rs", "pabgnq", - GCRY_PK_USAGE_SIGN, - ecc_generate, - ecc_check_secret_key, - NULL, - NULL, - ecc_sign, - ecc_verify, - ecc_get_nbits - }; - -gcry_pk_spec_t _gcry_pubkey_spec_ecdh = - { - "ECDH", ecdh_names, - "pabgnq", "pabgnqd", "se", "", "pabgnq", - GCRY_PK_USAGE_ENCR, - ecc_generate, - ecc_check_secret_key, - ecc_encrypt_raw, - ecc_decrypt_raw, - NULL, - NULL, - ecc_get_nbits - }; - - -pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa = - { - run_selftests, - ecc_generate_ext, - compute_keygrip, - ecc_get_param, - ecc_get_curve, - ecc_get_param_sexp - }; diff --git a/hobble-libgcrypt b/hobble-libgcrypt index 1062d6e..5eade9d 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -6,4 +6,6 @@ set -e -x # Clean out patent-or-otherwise-encumbered code. # EC: ????????? ??/??/2015 -rm -f cipher/ecc.c +rm -f cipher/ecc-curves.c +rm -f tests/curves.c +rm -f tests/t_mpi_point.c diff --git a/libgcrypt-1.5.0-leak.patch b/libgcrypt-1.5.0-leak.patch deleted file mode 100644 index 5f0d191..0000000 --- a/libgcrypt-1.5.0-leak.patch +++ /dev/null @@ -1,73 +0,0 @@ -diff -up libgcrypt-1.5.0/cipher/elgamal.c.leak libgcrypt-1.5.0/cipher/elgamal.c ---- libgcrypt-1.5.0/cipher/elgamal.c.leak 2011-02-04 20:09:38.000000000 +0100 -+++ libgcrypt-1.5.0/cipher/elgamal.c 2012-12-03 14:51:10.743067964 +0100 -@@ -641,7 +641,10 @@ elg_generate_ext (int algo, unsigned int - } - - if (xvalue) -- ec = generate_using_x (&sk, nbits, xvalue, retfactors); -+ { -+ ec = generate_using_x (&sk, nbits, xvalue, retfactors); -+ gcry_mpi_release(xvalue); -+ } - else - { - generate (&sk, nbits, retfactors); -diff -up libgcrypt-1.5.0/cipher/primegen.c.leak libgcrypt-1.5.0/cipher/primegen.c ---- libgcrypt-1.5.0/cipher/primegen.c.leak 2012-04-05 15:37:52.000000000 +0200 -+++ libgcrypt-1.5.0/cipher/primegen.c 2012-12-03 14:44:14.610010867 +0100 -@@ -1198,10 +1198,7 @@ gcry_prime_group_generator (gcry_mpi_t * - gcry_mpi_t prime, gcry_mpi_t *factors, - gcry_mpi_t start_g) - { -- gcry_mpi_t tmp = gcry_mpi_new (0); -- gcry_mpi_t b = gcry_mpi_new (0); -- gcry_mpi_t pmin1 = gcry_mpi_new (0); -- gcry_mpi_t g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3); -+ gcry_mpi_t tmp, b, pmin1, g; - int first = 1; - int i, n; - -@@ -1214,6 +1211,11 @@ gcry_prime_group_generator (gcry_mpi_t * - if (n < 2) - return gpg_error (GPG_ERR_INV_ARG); - -+ tmp = gcry_mpi_new (0); -+ b = gcry_mpi_new (0); -+ pmin1 = gcry_mpi_new (0); -+ g = start_g? gcry_mpi_copy (start_g) : gcry_mpi_set_ui (NULL, 3); -+ - /* Extra sanity check - usually disabled. */ - /* mpi_set (tmp, factors[0]); */ - /* for(i = 1; i < n; i++) */ -diff -up libgcrypt-1.5.0/cipher/pubkey.c.leak libgcrypt-1.5.0/cipher/pubkey.c ---- libgcrypt-1.5.0/cipher/pubkey.c.leak 2011-06-13 12:23:50.000000000 +0200 -+++ libgcrypt-1.5.0/cipher/pubkey.c 2012-12-03 15:23:42.377183489 +0100 -@@ -2853,6 +2853,8 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gc - - REGISTER_DEFAULT_PUBKEYS; - -+ init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey)); -+ - /* Get the key. */ - rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module); - if (rc) -@@ -2873,7 +2875,6 @@ gcry_pk_encrypt (gcry_sexp_t *r_ciph, gc - algo_elems = pubkey->elements_enc; - - /* Get the stuff we want to encrypt. */ -- init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey)); - rc = sexp_data_to_mpi (s_data, &data, &ctx); - if (rc) - goto leave; -diff -up libgcrypt-1.5.0/src/hmac256.c.leak libgcrypt-1.5.0/src/hmac256.c ---- libgcrypt-1.5.0/src/hmac256.c.leak 2011-02-04 20:17:33.000000000 +0100 -+++ libgcrypt-1.5.0/src/hmac256.c 2012-12-03 15:37:36.504955809 +0100 -@@ -435,7 +435,6 @@ _gcry_hmac256_finalize (hmac256_context_ - tmphd = _gcry_hmac256_new (NULL, 0); - if (!tmphd) - { -- free (hd); - return NULL; - } - _gcry_hmac256_update (tmphd, hd->opad, 64); diff --git a/libgcrypt-1.5.0-noecc.patch b/libgcrypt-1.5.0-noecc.patch deleted file mode 100644 index 7905c71..0000000 --- a/libgcrypt-1.5.0-noecc.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up libgcrypt-1.5.0/tests/Makefile.noecc libgcrypt-1.5.0/tests/Makefile ---- libgcrypt-1.5.0/tests/Makefile.in.noecc 2011-07-21 15:34:33.000000000 +0200 -+++ libgcrypt-1.5.0/tests/Makefile.in 2011-07-21 15:39:35.000000000 +0200 -@@ -57,7 +57,7 @@ TESTS = version$(EXEEXT) t-mpi-bit$(EXEE - ac-data$(EXEEXT) basic$(EXEEXT) mpitests$(EXEEXT) \ - tsexp$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \ - keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \ -- curves$(EXEEXT) t-kdf$(EXEEXT) pkcs1v2$(EXEEXT) \ -+ t-kdf$(EXEEXT) pkcs1v2$(EXEEXT) \ - $(am__EXEEXT_1) benchmark$(EXEEXT) - - # random.c uses fork() thus a test for W32 does not make any sense. diff --git a/libgcrypt-1.5.0-tests.patch b/libgcrypt-1.5.0-tests.patch deleted file mode 100644 index 277438f..0000000 --- a/libgcrypt-1.5.0-tests.patch +++ /dev/null @@ -1,214 +0,0 @@ -diff -up libgcrypt-1.5.0/cipher/dsa.c.tests libgcrypt-1.5.0/cipher/dsa.c ---- libgcrypt-1.5.0/cipher/dsa.c.tests 2011-06-13 12:24:46.000000000 +0200 -+++ libgcrypt-1.5.0/cipher/dsa.c 2011-07-20 16:44:51.000000000 +0200 -@@ -479,22 +479,21 @@ generate_fips186 (DSA_secret_key *sk, un - initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1, - &initial_seed.seedlen); - } -- -- /* Fixme: Enable 186-3 after it has been approved and after fixing -- the generation function. */ -- /* if (use_fips186_2) */ -- (void)use_fips186_2; -- ec = _gcry_generate_fips186_2_prime (nbits, qbits, -- initial_seed.seed, -+ -+ if (use_fips186_2) -+ ec = _gcry_generate_fips186_2_prime (nbits, qbits, -+ initial_seed.seed, - initial_seed.seedlen, - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -- /* else */ -- /* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */ -- /* &prime_q, &prime_p, */ -- /* r_counter, */ -- /* r_seed, r_seedlen, NULL); */ -+ else -+ ec = _gcry_generate_fips186_3_prime (nbits, qbits, -+ initial_seed.seed, -+ initial_seed.seedlen, -+ &prime_q, &prime_p, -+ r_counter, -+ r_seed, r_seedlen, NULL); - gcry_sexp_release (initial_seed.sexp); - if (ec) - goto leave; -diff -up libgcrypt-1.5.0/cipher/primegen.c.tests libgcrypt-1.5.0/cipher/primegen.c ---- libgcrypt-1.5.0/cipher/primegen.c.tests 2011-03-28 14:19:52.000000000 +0200 -+++ libgcrypt-1.5.0/cipher/primegen.c 2011-07-21 14:36:03.000000000 +0200 -@@ -1647,7 +1647,7 @@ _gcry_generate_fips186_3_prime (unsigned - gpg_err_code_t ec; - unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */ - unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */ -- unsigned char digest[256/8]; /* Helper buffer for SHA-1 digest. */ -+ unsigned char digest[256/8]; /* Helper buffer for SHA-x digest. */ - gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */ - gcry_mpi_t tmpval = NULL; /* Helper variable. */ - int hashalgo; /* The id of the Approved Hash Function. */ -@@ -1737,7 +1737,7 @@ _gcry_generate_fips186_3_prime (unsigned - } - gcry_mpi_release (prime_q); prime_q = NULL; - ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, -- value_u, sizeof value_u, NULL)); -+ value_u, qbits/8, NULL)); - if (ec) - goto leave; - mpi_set_highbit (prime_q, qbits-1 ); -@@ -1782,11 +1782,11 @@ _gcry_generate_fips186_3_prime (unsigned - if (seed_plus[i]) - break; - } -- gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen); -+ gcry_md_hash_buffer (hashalgo, digest, seed_plus, seedlen); - - gcry_mpi_release (tmpval); tmpval = NULL; - ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG, -- digest, sizeof digest, NULL)); -+ digest, qbits/8, NULL)); - if (ec) - goto leave; - if (value_j == value_n) -@@ -1822,11 +1822,11 @@ _gcry_generate_fips186_3_prime (unsigned - } - - /* Step 12: Save p, q, counter and seed. */ -- log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", -+/* log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", - mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); - log_printhex("fips186-3 seed:", seed, seedlen); - log_mpidump ("fips186-3 prime p", prime_p); -- log_mpidump ("fips186-3 prime q", prime_q); -+ log_mpidump ("fips186-3 prime q", prime_q); */ - if (r_q) - { - *r_q = prime_q; -diff -up libgcrypt-1.5.0/cipher/rsa.c.tests libgcrypt-1.5.0/cipher/rsa.c ---- libgcrypt-1.5.0/cipher/rsa.c.tests 2011-06-10 10:53:41.000000000 +0200 -+++ libgcrypt-1.5.0/cipher/rsa.c 2011-07-21 14:36:59.000000000 +0200 -@@ -388,7 +388,7 @@ generate_x931 (RSA_secret_key *sk, unsig - - *swapped = 0; - -- if (e_value == 1) /* Alias for a secure value. */ -+ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ - e_value = 65537; - - /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ -diff -up libgcrypt-1.5.0/random/random-fips.c.tests libgcrypt-1.5.0/random/random-fips.c ---- libgcrypt-1.5.0/random/random-fips.c.tests 2011-07-20 16:40:59.000000000 +0200 -+++ libgcrypt-1.5.0/random/random-fips.c 2011-07-20 16:40:59.000000000 +0200 -@@ -691,6 +691,7 @@ get_random (void *buffer, size_t length, - - check_guards (rng_ctx); - -+ reinitialize: - /* Initialize the cipher handle and thus setup the key if needed. */ - if (!rng_ctx->cipher_hd) - { -@@ -710,13 +711,11 @@ get_random (void *buffer, size_t length, - if (rng_ctx->key_init_pid != getpid () - || rng_ctx->seed_init_pid != getpid ()) - { -- /* We are in a child of us. Because we have no way yet to do -- proper re-initialization (including self-checks etc), the -- only chance we have is to bail out. Obviusly a fork/exec -- won't harm because the exec overwrites the old image. */ -- fips_signal_error ("fork without proper re-initialization " -- "detected in RNG"); -- goto bailout; -+ /* Just reinitialize the key & seed. */ -+ gcry_cipher_close(rng_ctx->cipher_hd); -+ rng_ctx->cipher_hd = NULL; -+ rng_ctx->is_seeded = 0; -+ goto reinitialize; - } - - if (x931_aes_driver (buffer, length, rng_ctx)) -diff -up libgcrypt-1.5.0/tests/ac.c.tests libgcrypt-1.5.0/tests/ac.c ---- libgcrypt-1.5.0/tests/ac.c.tests 2011-02-04 20:18:20.000000000 +0100 -+++ libgcrypt-1.5.0/tests/ac.c 2011-07-20 16:40:59.000000000 +0200 -@@ -150,6 +150,9 @@ main (int argc, char **argv) - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); -+ if (gcry_fips_mode_active()) -+ /* ac not functional in the fips mode, skip it */ -+ return 77; - if (debug) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); - /* No valuable keys are create, so we can speed up our RNG. */ -diff -up libgcrypt-1.5.0/tests/ac-data.c.tests libgcrypt-1.5.0/tests/ac-data.c ---- libgcrypt-1.5.0/tests/ac-data.c.tests 2011-02-04 20:18:20.000000000 +0100 -+++ libgcrypt-1.5.0/tests/ac-data.c 2011-07-20 16:40:59.000000000 +0200 -@@ -198,6 +198,9 @@ main (int argc, char **argv) - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); -+ if (gcry_fips_mode_active()) -+ /* ac not functional in the fips mode, skip it */ -+ return 77; - if (debug) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); - -diff -up libgcrypt-1.5.0/tests/ac-schemes.c.tests libgcrypt-1.5.0/tests/ac-schemes.c ---- libgcrypt-1.5.0/tests/ac-schemes.c.tests 2011-02-04 20:18:20.000000000 +0100 -+++ libgcrypt-1.5.0/tests/ac-schemes.c 2011-07-20 16:40:59.000000000 +0200 -@@ -338,6 +338,9 @@ main (int argc, char **argv) - if (! gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); -+ if (gcry_fips_mode_active()) -+ /* ac not functional in the fips mode, skip it */ -+ return 77; - if (debug) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); - -diff -up libgcrypt-1.5.0/tests/keygen.c.tests libgcrypt-1.5.0/tests/keygen.c ---- libgcrypt-1.5.0/tests/keygen.c.tests 2011-02-04 20:18:20.000000000 +0100 -+++ libgcrypt-1.5.0/tests/keygen.c 2011-07-21 14:39:03.000000000 +0200 -@@ -148,12 +148,12 @@ check_rsa_keys (void) - } - - if (verbose) -- fprintf (stderr, "creating 1536 bit DSA key\n"); -+ fprintf (stderr, "creating 2048 bit DSA key\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (dsa\n" -- " (nbits 4:1536)\n" -- " (qbits 3:224)\n" -+ " (nbits 4:2048)\n" -+ " (qbits 3:256)\n" - " ))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gpg_strerror (rc)); -@@ -190,11 +190,11 @@ check_rsa_keys (void) - - - if (verbose) -- fprintf (stderr, "creating 512 bit RSA key with e=257\n"); -+ fprintf (stderr, "creating 1024 bit RSA key with e=257\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" -- " (nbits 3:512)\n" -+ " (nbits 4:1024)\n" - " (rsa-use-e 3:257)\n" - " ))", 0, 1); - if (rc) -@@ -208,11 +208,11 @@ check_rsa_keys (void) - gcry_sexp_release (key); - - if (verbose) -- fprintf (stderr, "creating 512 bit RSA key with default e\n"); -+ fprintf (stderr, "creating 1024 bit RSA key with default secure e\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" -- " (nbits 3:512)\n" -+ " (nbits 4:1024)\n" - " (rsa-use-e 1:0)\n" - " ))", 0, 1); - if (rc) diff --git a/libgcrypt-1.5.0-use-fipscheck.patch b/libgcrypt-1.5.0-use-fipscheck.patch index 1cef010..704bb52 100644 --- a/libgcrypt-1.5.0-use-fipscheck.patch +++ b/libgcrypt-1.5.0-use-fipscheck.patch @@ -60,7 +60,7 @@ diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c else { - fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 ); -+ fname = gcry_malloc (strlen (libpath) + 1 + 5 + 1 ); ++ fname = _gcry_malloc (strlen (libpath) + 1 + 5 + 1 ); if (!fname) err = gpg_error_from_syserror (); else diff --git a/libgcrypt-1.5.2-mpicoder-gccopt.patch b/libgcrypt-1.5.2-mpicoder-gccopt.patch deleted file mode 100644 index c374709..0000000 --- a/libgcrypt-1.5.2-mpicoder-gccopt.patch +++ /dev/null @@ -1,102 +0,0 @@ -diff -up libgcrypt-1.5.2/mpi/mpicoder.c.gccopt libgcrypt-1.5.2/mpi/mpicoder.c ---- libgcrypt-1.5.2/mpi/mpicoder.c.gccopt 2013-04-18 16:48:42.000000000 +0200 -+++ libgcrypt-1.5.2/mpi/mpicoder.c 2013-06-20 10:24:57.241510589 +0200 -@@ -555,16 +555,16 @@ gcry_mpi_print (enum gcry_mpi_format for - extra=1; - } - -- if (buffer && n > len) -- { -- /* The provided buffer is too short. */ -- gcry_free (tmp); -- return gcry_error (GPG_ERR_TOO_SHORT); -- } - if (buffer) - { - unsigned char *s = buffer; - -+ if (n > len) -+ { -+ /* The provided buffer is too short. */ -+ gcry_free (tmp); -+ return gcry_error (GPG_ERR_TOO_SHORT); -+ } - if (extra) - *s++ = 0; - memcpy (s, tmp, n-extra); -@@ -580,12 +580,12 @@ gcry_mpi_print (enum gcry_mpi_format for - /* Note: We ignore the sign for this format. */ - /* FIXME: for performance reasons we should put this into - mpi_aprint because we can then use the buffer directly. */ -- if (buffer && n > len) -- return gcry_error (GPG_ERR_TOO_SHORT); - if (buffer) - { - unsigned char *tmp; - -+ if (n > len) -+ return gcry_error (GPG_ERR_TOO_SHORT); - tmp = _gcry_mpi_get_buffer (a, &n, NULL); - if (!tmp) - return gpg_error_from_syserror (); -@@ -603,14 +603,13 @@ gcry_mpi_print (enum gcry_mpi_format for - if( a->sign ) - return gcry_error (GPG_ERR_INV_ARG); - -- if (buffer && n+2 > len) -- return gcry_error (GPG_ERR_TOO_SHORT); -- - if (buffer) - { - unsigned char *tmp; - unsigned char *s = buffer; - -+ if (n+2 > len) -+ return gcry_error (GPG_ERR_TOO_SHORT); - s[0] = nbits >> 8; - s[1] = nbits; - -@@ -641,16 +640,16 @@ gcry_mpi_print (enum gcry_mpi_format for - extra=1; - } - -- if (buffer && n+4 > len) -- { -- gcry_free(tmp); -- return gcry_error (GPG_ERR_TOO_SHORT); -- } -- - if (buffer) - { - unsigned char *s = buffer; - -+ if (n+4 > len) -+ { -+ gcry_free(tmp); -+ return gcry_error (GPG_ERR_TOO_SHORT); -+ } -+ - *s++ = n >> 24; - *s++ = n >> 16; - *s++ = n >> 8; -@@ -677,15 +676,15 @@ gcry_mpi_print (enum gcry_mpi_format for - if (!n || (*tmp & 0x80)) - extra = 2; - -- if (buffer && 2*n + extra + !!a->sign + 1 > len) -- { -- gcry_free(tmp); -- return gcry_error (GPG_ERR_TOO_SHORT); -- } - if (buffer) - { - unsigned char *s = buffer; - -+ if (2*n + extra + !!a->sign + 1 > len) -+ { -+ gcry_free(tmp); -+ return gcry_error (GPG_ERR_TOO_SHORT); -+ } - if (a->sign) - *s++ = '-'; - if (extra) diff --git a/libgcrypt-1.5.3-ecc-test-fix.patch b/libgcrypt-1.5.3-ecc-test-fix.patch deleted file mode 100644 index a5cca64..0000000 --- a/libgcrypt-1.5.3-ecc-test-fix.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -up libgcrypt-1.5.3/tests/benchmark.c.eccfix libgcrypt-1.5.3/tests/benchmark.c ---- libgcrypt-1.5.3/tests/benchmark.c.eccfix 2013-10-20 23:45:32.157297611 +0100 -+++ libgcrypt-1.5.3/tests/benchmark.c 2013-10-20 23:45:42.683275072 +0100 -@@ -962,7 +962,7 @@ ecc_bench (int iterations, int print_hea - { - #if USE_ECC - gpg_error_t err; -- int p_sizes[] = { 192, 224, 256, 384, 521 }; -+ int p_sizes[] = { 256, 384 }; - int testno; - - if (print_header) diff --git a/libgcrypt-1.5.3-pbkdf-speedup.patch b/libgcrypt-1.5.3-pbkdf-speedup.patch deleted file mode 100644 index 7017367..0000000 --- a/libgcrypt-1.5.3-pbkdf-speedup.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff -up libgcrypt-1.5.3/cipher/kdf.c.pbkdf-speedup libgcrypt-1.5.3/cipher/kdf.c ---- libgcrypt-1.5.3/cipher/kdf.c.pbkdf-speedup 2014-01-21 15:49:22.676638703 +0100 -+++ libgcrypt-1.5.3/cipher/kdf.c 2014-01-21 15:52:40.115047218 +0100 -@@ -172,19 +172,21 @@ pkdf2 (const void *passphrase, size_t pa - return ec; - } - -+ ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen)); -+ if (ec) -+ { -+ gcry_md_close (md); -+ gcry_free (sbuf); -+ return ec; -+ } -+ - /* Step 3 and 4. */ - memcpy (sbuf, salt, saltlen); - for (lidx = 1; lidx <= l; lidx++) - { - for (iter = 0; iter < iterations; iter++) - { -- ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen)); -- if (ec) -- { -- gcry_md_close (md); -- gcry_free (sbuf); -- return ec; -- } -+ gcry_md_reset (md); - if (!iter) /* Compute U_1: */ - { - sbuf[saltlen] = (lidx >> 24); diff --git a/libgcrypt-1.5.3-whirlpool-bug.patch b/libgcrypt-1.5.3-whirlpool-bug.patch deleted file mode 100644 index f64c94f..0000000 --- a/libgcrypt-1.5.3-whirlpool-bug.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff -up libgcrypt-1.5.3/cipher/whirlpool.c.whirlpool-bug libgcrypt-1.5.3/cipher/whirlpool.c ---- libgcrypt-1.5.3/cipher/whirlpool.c.whirlpool-bug 2013-05-22 18:02:54.000000000 +0200 -+++ libgcrypt-1.5.3/cipher/whirlpool.c 2014-01-21 15:45:51.308919415 +0100 -@@ -56,6 +56,7 @@ typedef struct { - unsigned char buffer[BLOCK_SIZE]; - size_t count; - unsigned char length[32]; -+ int bug; - } whirlpool_context_t; - - -@@ -1185,6 +1186,7 @@ whirlpool_init (void *ctx) - whirlpool_context_t *context = ctx; - - memset (context, 0, sizeof (*context)); -+ context->bug = secure_getenv("GCRYPT_WHIRLPOOL_BUG") != NULL; - } - - -@@ -1316,7 +1318,7 @@ whirlpool_add (whirlpool_context_t *cont - buffer_n--; - } - whirlpool_add (context, NULL, 0); -- if (!buffer_n) -+ if (context->bug && !buffer_n) - /* Done. */ - return; - } diff --git a/libgcrypt-1.6.1-ecc-test-fix.patch b/libgcrypt-1.6.1-ecc-test-fix.patch new file mode 100644 index 0000000..7e12c1b --- /dev/null +++ b/libgcrypt-1.6.1-ecc-test-fix.patch @@ -0,0 +1,214 @@ +diff -up libgcrypt-1.6.1/tests/benchmark.c.eccfix libgcrypt-1.6.1/tests/benchmark.c +--- libgcrypt-1.6.1/tests/benchmark.c.eccfix 2014-01-27 14:36:43.000000000 +0100 ++++ libgcrypt-1.6.1/tests/benchmark.c 2014-02-28 16:14:13.042505538 +0100 +@@ -1087,8 +1087,7 @@ ecc_bench (int iterations, int print_hea + { + #if USE_ECC + gpg_error_t err; +- const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", +- "gost256", "gost512" }; ++ const char *p_sizes[] = { "256", "384", "521", "Ed25519" }; + int testno; + + if (print_header) +diff -up libgcrypt-1.6.1/tests/dsa-rfc6979.c.eccfix libgcrypt-1.6.1/tests/dsa-rfc6979.c +--- libgcrypt-1.6.1/tests/dsa-rfc6979.c.eccfix 2013-12-16 18:44:32.000000000 +0100 ++++ libgcrypt-1.6.1/tests/dsa-rfc6979.c 2014-02-28 16:18:44.138771523 +0100 +@@ -210,27 +210,6 @@ check_dsa_rfc6979 (void) + " ))" + }, + { +- "ECDSA, 192 bits (prime field)", +- "(private-key" +- " (ecdsa" +- " (curve \"NIST P-192\")" +- " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" +- " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" +- " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" +- " ))" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "(private-key" +- " (ecdsa" +- " (curve \"NIST P-224\")" +- " (q #04" +- " 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C" +- " EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)" +- " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)" +- " ))" +- }, +- { + "ECDSA, 256 bits (prime field)", + "(private-key" + " (ecdsa" +@@ -443,169 +422,6 @@ check_dsa_rfc6979 (void) + "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1" + }, + { +- "ECDSA, 192 bits (prime field)", +- "With SHA-1, message = \"sample\"", +- "sha1", "sample", +- "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", +- "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", +- "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-224, message = \"sample\"", +- "sha224", "sample", +- "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8", +- "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", +- "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-256, message = \"sample\"", +- "sha256", "sample", +- "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", +- "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", +- "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-384, message = \"sample\"", +- "sha384", "sample", +- "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311", +- "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", +- "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-512, message = \"sample\"", +- "sha512", "sample", +- "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", +- "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", +- "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-1, message = \"test\"", +- "sha1", "test", +- "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", +- "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", +- "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-224, message = \"test\"", +- "sha224", "test", +- "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE", +- "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", +- "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-256, message = \"test\"", +- "sha256", "test", +- "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", +- "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", +- "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-384, message = \"test\"", +- "sha384", "test", +- "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693", +- "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", +- "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-512, message = \"test\"", +- "sha512", "test", +- "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", +- "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", +- "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290" +- }, +- +- +- +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-1, message = \"sample\"", +- "sha1", "sample", +- "7EEFADD91110D8DE6C2C470831387C50D3357F7F4D477054B8B426BC", +- "22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC", +- "66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-224, message = \"sample\"", +- "sha224", "sample", +- "C1D1F2F10881088301880506805FEB4825FE09ACB6816C36991AA06D", +- "1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E", +- "A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-256, message = \"sample\"", +- "sha256", "sample", +- "AD3029E0278F80643DE33917CE6908C70A8FF50A411F06E41DEDFCDC", +- "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA", +- "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-384, message = \"sample\"", +- "sha384", "sample", +- "52B40F5A9D3D13040F494E83D3906C6079F29981035C7BD51E5CAC40", +- "0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953", +- "830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-512, message = \"sample\"", +- "sha512", "sample", +- "9DB103FFEDEDF9CFDBA05184F925400C1653B8501BAB89CEA0FBEC14", +- "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397", +- "A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-1, message = \"test\"", +- "sha1", "test", +- "2519178F82C3F0E4F87ED5883A4E114E5B7A6E374043D8EFD329C253", +- "DEAA646EC2AF2EA8AD53ED66B2E2DDAA49A12EFD8356561451F3E21C", +- "95987796F6CF2062AB8135271DE56AE55366C045F6D9593F53787BD2" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-224, message = \"test\"", +- "sha224", "test", +- "DF8B38D40DCA3E077D0AC520BF56B6D565134D9B5F2EAE0D34900524", +- "C441CE8E261DED634E4CF84910E4C5D1D22C5CF3B732BB204DBEF019", +- "902F42847A63BDC5F6046ADA114953120F99442D76510150F372A3F4" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-256, message = \"test\"", +- "sha256", "test", +- "FF86F57924DA248D6E44E8154EB69F0AE2AEBAEE9931D0B5A969F904", +- "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6", +- "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-384, message = \"test\"", +- "sha384", "test", +- "7046742B839478C1B5BD31DB2E862AD868E1A45C863585B5F22BDC2D", +- "389B92682E399B26518A95506B52C03BC9379A9DADF3391A21FB0EA4", +- "414A718ED3249FF6DBC5B50C27F71F01F070944DA22AB1F78F559AAB" +- }, +- { +- "ECDSA, 224 bits (prime field)", +- "With SHA-512, message = \"test\"", +- "sha512", "test", +- "E39C2AA4EA6BE2306C72126D40ED77BF9739BB4D6EF2BBB1DCB6169D", +- "049F050477C5ADD858CAC56208394B5A55BAEBBE887FDF765047C17C", +- "077EB13E7005929CEFA3CD0403C7CDCC077ADF4E44F3C41B2F60ECFF" +- }, +- { + "ECDSA, 256 bits (prime field)", + "With SHA-1, message = \"sample\"", + "sha1", "sample", diff --git a/libgcrypt-1.5.0-fips-cavs.patch b/libgcrypt-1.6.1-fips-cavs.patch similarity index 91% rename from libgcrypt-1.5.0-fips-cavs.patch rename to libgcrypt-1.6.1-fips-cavs.patch index ac999f9..55aa66a 100644 --- a/libgcrypt-1.5.0-fips-cavs.patch +++ b/libgcrypt-1.6.1-fips-cavs.patch @@ -1,57 +1,6 @@ -diff -up libgcrypt-1.5.0/cipher/dsa.c.cavs libgcrypt-1.5.0/cipher/dsa.c ---- libgcrypt-1.5.0/cipher/dsa.c.cavs 2011-07-21 14:56:35.000000000 +0200 -+++ libgcrypt-1.5.0/cipher/dsa.c 2011-07-21 14:58:06.000000000 +0200 -@@ -479,7 +479,6 @@ generate_fips186 (DSA_secret_key *sk, un - initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1, - &initial_seed.seedlen); - } -- - if (use_fips186_2) - ec = _gcry_generate_fips186_2_prime (nbits, qbits, - initial_seed.seed, -@@ -487,13 +486,22 @@ generate_fips186 (DSA_secret_key *sk, un - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -- else -+ else if (!domain->p || !domain->q) - ec = _gcry_generate_fips186_3_prime (nbits, qbits, - initial_seed.seed, - initial_seed.seedlen, - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen, NULL); -+ else -+ { -+ /* Domain parameters p and q are given; use them. */ -+ prime_p = mpi_copy (domain->p); -+ prime_q = mpi_copy (domain->q); -+ gcry_assert (mpi_get_nbits (prime_p) == nbits); -+ gcry_assert (mpi_get_nbits (prime_q) == qbits); -+ ec = 0; -+ } - gcry_sexp_release (initial_seed.sexp); - if (ec) - goto leave; -@@ -784,13 +792,12 @@ dsa_generate_ext (int algo, unsigned int - gcry_sexp_release (l1); - gcry_sexp_release (domainsexp); - -- /* Check that all domain parameters are available. */ -- if (!domain.p || !domain.q || !domain.g) -+ /* Check that p and q domain parameters are available. */ -+ if (!domain.p || !domain.q || (!domain.g && !use_fips186)) - { - gcry_mpi_release (domain.p); - gcry_mpi_release (domain.q); - gcry_mpi_release (domain.g); -- gcry_sexp_release (deriveparms); - return GPG_ERR_MISSING_VALUE; - } - -diff -up libgcrypt-1.5.0/tests/cavs_driver.pl.cavs libgcrypt-1.5.0/tests/cavs_driver.pl ---- libgcrypt-1.5.0/tests/cavs_driver.pl.cavs 2011-02-04 20:18:20.000000000 +0100 -+++ libgcrypt-1.5.0/tests/cavs_driver.pl 2011-07-21 15:01:47.000000000 +0200 +diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_driver.pl +--- libgcrypt-1.6.1/tests/cavs_driver.pl.cavs 2013-03-15 20:25:38.000000000 +0100 ++++ libgcrypt-1.6.1/tests/cavs_driver.pl 2014-02-28 14:46:16.436544639 +0100 @@ -1,9 +1,11 @@ #!/usr/bin/env perl # @@ -725,9 +674,9 @@ diff -up libgcrypt-1.5.0/tests/cavs_driver.pl.cavs libgcrypt-1.5.0/tests/cavs_dr $dsa_sign = \&libgcrypt_dsa_sign; $dsa_verify = \&libgcrypt_dsa_verify; $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; -diff -up libgcrypt-1.5.0/tests/cavs_tests.sh.cavs libgcrypt-1.5.0/tests/cavs_tests.sh ---- libgcrypt-1.5.0/tests/cavs_tests.sh.cavs 2011-02-04 20:18:20.000000000 +0100 -+++ libgcrypt-1.5.0/tests/cavs_tests.sh 2011-07-21 15:02:16.000000000 +0200 +diff -up libgcrypt-1.6.1/tests/cavs_tests.sh.cavs libgcrypt-1.6.1/tests/cavs_tests.sh +--- libgcrypt-1.6.1/tests/cavs_tests.sh.cavs 2013-03-15 20:25:38.000000000 +0100 ++++ libgcrypt-1.6.1/tests/cavs_tests.sh 2014-02-28 14:46:16.437544662 +0100 @@ -55,7 +55,7 @@ function run_one_test () { [ -d "$respdir" ] || mkdir "$respdir" [ -f "$rspfile" ] && rm "$rspfile" @@ -737,9 +686,9 @@ diff -up libgcrypt-1.5.0/tests/cavs_tests.sh.cavs libgcrypt-1.5.0/tests/cavs_tes dflag="-D" fi -diff -up libgcrypt-1.5.0/tests/fipsdrv.c.cavs libgcrypt-1.5.0/tests/fipsdrv.c ---- libgcrypt-1.5.0/tests/fipsdrv.c.cavs 2011-02-04 20:18:20.000000000 +0100 -+++ libgcrypt-1.5.0/tests/fipsdrv.c 2011-07-21 15:06:44.000000000 +0200 +diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c +--- libgcrypt-1.6.1/tests/fipsdrv.c.cavs 2013-12-16 18:44:32.000000000 +0100 ++++ libgcrypt-1.6.1/tests/fipsdrv.c 2014-02-28 14:46:16.437544662 +0100 @@ -893,6 +893,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); diff --git a/libgcrypt-1.5.0-fips-cfgrandom.patch b/libgcrypt-1.6.1-fips-cfgrandom.patch similarity index 50% rename from libgcrypt-1.5.0-fips-cfgrandom.patch rename to libgcrypt-1.6.1-fips-cfgrandom.patch index 1384c25..8aae15f 100644 --- a/libgcrypt-1.5.0-fips-cfgrandom.patch +++ b/libgcrypt-1.6.1-fips-cfgrandom.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.5.0/random/random-fips.c.cfgrandom libgcrypt-1.5.0/random/random-fips.c ---- libgcrypt-1.5.0/random/random-fips.c.cfgrandom 2011-07-21 14:50:34.000000000 +0200 -+++ libgcrypt-1.5.0/random/random-fips.c 2011-07-21 14:50:34.000000000 +0200 +diff -up libgcrypt-1.6.1/random/random-fips.c.cfgrandom libgcrypt-1.6.1/random/random-fips.c +--- libgcrypt-1.6.1/random/random-fips.c.cfgrandom 2014-02-28 16:06:20.026572478 +0100 ++++ libgcrypt-1.6.1/random/random-fips.c 2014-02-28 16:06:34.851915121 +0100 @@ -27,10 +27,10 @@ There are 3 random context which map to the different levels of random quality: @@ -44,65 +44,76 @@ diff -up libgcrypt-1.5.0/random/random-fips.c.cfgrandom libgcrypt-1.5.0/random/r #elif USE_RNDW32 do { -diff -up libgcrypt-1.5.0/random/rndlinux.c.cfgrandom libgcrypt-1.5.0/random/rndlinux.c ---- libgcrypt-1.5.0/random/rndlinux.c.cfgrandom 2011-02-04 20:16:03.000000000 +0100 -+++ libgcrypt-1.5.0/random/rndlinux.c 2011-07-21 14:50:34.000000000 +0200 +@@ -713,7 +719,7 @@ get_random (void *buffer, size_t length, + || rng_ctx->seed_init_pid != getpid ()) + { + /* Just reinitialize the key & seed. */ +- gcry_cipher_close(rng_ctx->cipher_hd); ++ _gcry_cipher_close(rng_ctx->cipher_hd); + rng_ctx->cipher_hd = NULL; + rng_ctx->is_seeded = 0; + goto reinitialize; +diff -up libgcrypt-1.6.1/random/rndlinux.c.cfgrandom libgcrypt-1.6.1/random/rndlinux.c +--- libgcrypt-1.6.1/random/rndlinux.c.cfgrandom 2013-12-16 18:44:32.000000000 +0100 ++++ libgcrypt-1.6.1/random/rndlinux.c 2014-02-28 16:06:20.027572501 +0100 @@ -36,7 +36,9 @@ #include "g10lib.h" #include "rand-internal.h" --static int open_device ( const char *name ); +-static int open_device (const char *name, int retry); +#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed" + -+static int open_device ( const char *name, int fatal ); ++static int open_device (const char *name, int retry, int fatal); static int -@@ -57,13 +59,17 @@ set_cloexec_flag (int fd) - * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it exists)). +@@ -59,7 +61,7 @@ set_cloexec_flag (int fd) + * a fatal error but retries until it is able to reopen the device. */ static int --open_device ( const char *name ) -+open_device ( const char *name, int fatal ) +-open_device (const char *name, int retry) ++open_device (const char *name, int retry, int fatal) { int fd; - fd = open ( name, O_RDONLY ); - if ( fd == -1 ) -- log_fatal ("can't open %s: %s\n", name, strerror(errno) ); -+ { -+ if (! fatal) -+ return fd; -+ log_fatal ("can't open %s: %s\n", name, strerror(errno) ); -+ } - - if (set_cloexec_flag (fd)) - log_error ("error setting FD_CLOEXEC on fd %d: %s\n", -@@ -92,6 +98,7 @@ _gcry_rndlinux_gather_random (void (*add +@@ -67,6 +69,8 @@ open_device (const char *name, int retry + _gcry_random_progress ("open_dev_random", 'X', 1, 0); + again: + fd = open (name, O_RDONLY); ++ if (fd == -1 && !fatal) ++ return fd; + if (fd == -1 && retry) + { + struct timeval tv; +@@ -111,6 +115,7 @@ _gcry_rndlinux_gather_random (void (*add { static int fd_urandom = -1; static int fd_random = -1; + static int fd_configured = -1; + static unsigned char ever_opened; int fd; int n; - byte buffer[768]; -@@ -100,6 +107,7 @@ _gcry_rndlinux_gather_random (void (*add - size_t last_so_far = 0; - int any_need_entropy = 0; - int delay; -+ size_t orig_length = length; +@@ -134,6 +139,11 @@ _gcry_rndlinux_gather_random (void (*add + close (fd_urandom); + fd_urandom = -1; + } ++ if (fd_configured != -1) ++ { ++ close (fd_configured); ++ fd_configured = -1; ++ } + return 0; + } - /* First read from a hardware source. However let it account only - for up to 50% of the requested bytes. */ -@@ -110,16 +118,26 @@ _gcry_rndlinux_gather_random (void (*add - length -= n_hw; - - /* Open the requested device. */ +@@ -153,20 +163,30 @@ _gcry_rndlinux_gather_random (void (*add + that we always require the device to be existent but want a more + graceful behaviour if the rarely needed close operation has been + used and the device needs to be re-opened later. */ + + if (level == -1) + { + if (fd_configured == -1) -+ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0 ); ++ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0, 0 ); + fd = fd_configured; + if (fd == -1) + return -1; @@ -110,17 +121,21 @@ diff -up libgcrypt-1.5.0/random/rndlinux.c.cfgrandom libgcrypt-1.5.0/random/rndl + if (level >= 2) { - if( fd_random == -1 ) -- fd_random = open_device ( NAME_OF_DEV_RANDOM ); -+ fd_random = open_device ( NAME_OF_DEV_RANDOM, 1 ); + if (fd_random == -1) + { +- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1)); ++ fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); + ever_opened |= 1; + } fd = fd_random; } - else + else if (level != -1) { - if( fd_urandom == -1 ) -- fd_urandom = open_device ( NAME_OF_DEV_URANDOM ); -+ fd_urandom = open_device ( NAME_OF_DEV_URANDOM, 1 ); + if (fd_urandom == -1) + { +- fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); ++ fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1); + ever_opened |= 2; + } fd = fd_urandom; - } - diff --git a/libgcrypt-1.6.1-leak.patch b/libgcrypt-1.6.1-leak.patch new file mode 100644 index 0000000..df3cc08 --- /dev/null +++ b/libgcrypt-1.6.1-leak.patch @@ -0,0 +1,38 @@ +diff -up libgcrypt-1.6.1/cipher/primegen.c.leak libgcrypt-1.6.1/cipher/primegen.c +--- libgcrypt-1.6.1/cipher/primegen.c.leak 2014-02-28 15:06:24.394464790 +0100 ++++ libgcrypt-1.6.1/cipher/primegen.c 2014-02-28 15:09:22.938591664 +0100 +@@ -1204,10 +1204,7 @@ _gcry_prime_group_generator (gcry_mpi_t + gcry_mpi_t prime, gcry_mpi_t *factors, + gcry_mpi_t start_g) + { +- gcry_mpi_t tmp = mpi_new (0); +- gcry_mpi_t b = mpi_new (0); +- gcry_mpi_t pmin1 = mpi_new (0); +- gcry_mpi_t g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); ++ gcry_mpi_t tmp, b, pmin1, g; + int first = 1; + int i, n; + +@@ -1220,6 +1217,11 @@ _gcry_prime_group_generator (gcry_mpi_t + if (n < 2) + return GPG_ERR_INV_ARG; + ++ tmp = mpi_new (0); ++ b = mpi_new (0); ++ pmin1 = mpi_new (0); ++ g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); ++ + /* Extra sanity check - usually disabled. */ + /* mpi_set (tmp, factors[0]); */ + /* for(i = 1; i < n; i++) */ +diff -up libgcrypt-1.6.1/src/hmac256.c.leak libgcrypt-1.6.1/src/hmac256.c +--- libgcrypt-1.6.1/src/hmac256.c.leak 2013-12-16 18:44:32.000000000 +0100 ++++ libgcrypt-1.6.1/src/hmac256.c 2014-02-28 15:06:24.394464790 +0100 +@@ -427,7 +427,6 @@ _gcry_hmac256_finalize (hmac256_context_ + tmphd = _gcry_hmac256_new (NULL, 0); + if (!tmphd) + { +- free (hd); + return NULL; + } + _gcry_hmac256_update (tmphd, hd->opad, 64); diff --git a/libgcrypt-1.6.1-mpicoder-gccopt.patch b/libgcrypt-1.6.1-mpicoder-gccopt.patch new file mode 100644 index 0000000..12555d3 --- /dev/null +++ b/libgcrypt-1.6.1-mpicoder-gccopt.patch @@ -0,0 +1,104 @@ +diff -up libgcrypt-1.6.1/mpi/mpicoder.c.gccopt libgcrypt-1.6.1/mpi/mpicoder.c +--- libgcrypt-1.6.1/mpi/mpicoder.c.gccopt 2014-02-28 15:37:53.983139821 +0100 ++++ libgcrypt-1.6.1/mpi/mpicoder.c 2014-02-28 15:47:35.312576387 +0100 +@@ -627,16 +627,16 @@ _gcry_mpi_print (enum gcry_mpi_format fo + extra = 1; + } + +- if (buffer && n > len) +- { +- /* The provided buffer is too short. */ +- xfree (tmp); +- return GPG_ERR_TOO_SHORT; +- } + if (buffer) + { + unsigned char *s = buffer; + ++ if (n > len) ++ { ++ /* The provided buffer is too short. */ ++ xfree (tmp); ++ return GPG_ERR_TOO_SHORT; ++ } + if (extra == 1) + *s++ = 0; + else if (extra) +@@ -654,13 +654,12 @@ _gcry_mpi_print (enum gcry_mpi_format fo + /* Note: We ignore the sign for this format. */ + /* FIXME: for performance reasons we should put this into + mpi_aprint because we can then use the buffer directly. */ +- +- if (buffer && n > len) +- return GPG_ERR_TOO_SHORT; + if (buffer) + { + unsigned char *tmp; + ++ if (n > len) ++ return GPG_ERR_TOO_SHORT; + tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL); + if (!tmp) + return gpg_err_code_from_syserror (); +@@ -678,14 +677,14 @@ _gcry_mpi_print (enum gcry_mpi_format fo + if (negative) + return GPG_ERR_INV_ARG; + +- if (buffer && n+2 > len) +- return GPG_ERR_TOO_SHORT; +- + if (buffer) + { + unsigned char *tmp; + unsigned char *s = buffer; + ++ if (n+2 > len) ++ return GPG_ERR_TOO_SHORT; ++ + s[0] = nbits >> 8; + s[1] = nbits; + +@@ -724,16 +723,16 @@ _gcry_mpi_print (enum gcry_mpi_format fo + extra=1; + } + +- if (buffer && n+4 > len) +- { +- xfree(tmp); +- return GPG_ERR_TOO_SHORT; +- } +- + if (buffer) + { + unsigned char *s = buffer; + ++ if (n+4 > len) ++ { ++ xfree(tmp); ++ return GPG_ERR_TOO_SHORT; ++ } ++ + *s++ = n >> 24; + *s++ = n >> 16; + *s++ = n >> 8; +@@ -761,15 +760,15 @@ _gcry_mpi_print (enum gcry_mpi_format fo + if (!n || (*tmp & 0x80)) + extra = 2; + +- if (buffer && 2*n + extra + negative + 1 > len) +- { +- xfree(tmp); +- return GPG_ERR_TOO_SHORT; +- } + if (buffer) + { + unsigned char *s = buffer; + ++ if (2*n + extra + negative + 1 > len) ++ { ++ xfree(tmp); ++ return GPG_ERR_TOO_SHORT; ++ } + if (negative) + *s++ = '-'; + if (extra) diff --git a/libgcrypt-1.6.1-tests.patch b/libgcrypt-1.6.1-tests.patch new file mode 100644 index 0000000..0c00458 --- /dev/null +++ b/libgcrypt-1.6.1-tests.patch @@ -0,0 +1,198 @@ +diff -up libgcrypt-1.6.1/cipher/dsa.c.tests libgcrypt-1.6.1/cipher/dsa.c +--- libgcrypt-1.6.1/cipher/dsa.c.tests 2014-02-28 13:39:01.727288335 +0100 ++++ libgcrypt-1.6.1/cipher/dsa.c 2014-02-28 13:46:21.727458285 +0100 +@@ -423,22 +423,29 @@ generate_fips186 (DSA_secret_key *sk, un + initial_seed.seed = sexp_nth_data (initial_seed.sexp, 1, + &initial_seed.seedlen); + } +- +- /* Fixme: Enable 186-3 after it has been approved and after fixing +- the generation function. */ +- /* if (use_fips186_2) */ +- (void)use_fips186_2; +- ec = _gcry_generate_fips186_2_prime (nbits, qbits, ++ if (use_fips186_2) ++ ec = _gcry_generate_fips186_2_prime (nbits, qbits, + initial_seed.seed, + initial_seed.seedlen, + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen); +- /* else */ +- /* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */ +- /* &prime_q, &prime_p, */ +- /* r_counter, */ +- /* r_seed, r_seedlen, NULL); */ ++ else if (!domain->p || !domain->q) ++ ec = _gcry_generate_fips186_3_prime (nbits, qbits, ++ initial_seed.seed, ++ initial_seed.seedlen, ++ &prime_q, &prime_p, ++ r_counter, ++ r_seed, r_seedlen, NULL); ++ else ++ { ++ /* Domain parameters p and q are given; use them. */ ++ prime_p = mpi_copy (domain->p); ++ prime_q = mpi_copy (domain->q); ++ gcry_assert (mpi_get_nbits (prime_p) == nbits); ++ gcry_assert (mpi_get_nbits (prime_q) == qbits); ++ ec = 0; ++ } + sexp_release (initial_seed.sexp); + if (ec) + goto leave; +@@ -829,13 +829,12 @@ dsa_generate (const gcry_sexp_t genparms + sexp_release (l1); + sexp_release (domainsexp); + +- /* Check that all domain parameters are available. */ +- if (!domain.p || !domain.q || !domain.g) ++ /* Check that p and q domain parameters are available. */ ++ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) + { + _gcry_mpi_release (domain.p); + _gcry_mpi_release (domain.q); + _gcry_mpi_release (domain.g); +- sexp_release (deriveparms); + return GPG_ERR_MISSING_VALUE; + } + +diff -up libgcrypt-1.6.1/cipher/primegen.c.tests libgcrypt-1.6.1/cipher/primegen.c +--- libgcrypt-1.6.1/cipher/primegen.c.tests 2014-01-29 10:48:38.000000000 +0100 ++++ libgcrypt-1.6.1/cipher/primegen.c 2014-02-28 13:49:52.291325147 +0100 +@@ -1649,7 +1649,7 @@ _gcry_generate_fips186_3_prime (unsigned + gpg_err_code_t ec; + unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */ + unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */ +- unsigned char digest[256/8]; /* Helper buffer for SHA-1 digest. */ ++ unsigned char digest[256/8]; /* Helper buffer for SHA-x digest. */ + gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */ + gcry_mpi_t tmpval = NULL; /* Helper variable. */ + int hashalgo; /* The id of the Approved Hash Function. */ +@@ -1739,7 +1739,7 @@ _gcry_generate_fips186_3_prime (unsigned + } + _gcry_mpi_release (prime_q); prime_q = NULL; + ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, +- value_u, sizeof value_u, NULL); ++ value_u, qbits/8, NULL); + if (ec) + goto leave; + mpi_set_highbit (prime_q, qbits-1 ); +@@ -1784,11 +1784,11 @@ _gcry_generate_fips186_3_prime (unsigned + if (seed_plus[i]) + break; + } +- _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen); ++ _gcry_md_hash_buffer (hashalgo, digest, seed_plus, seedlen); + + _gcry_mpi_release (tmpval); tmpval = NULL; + ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG, +- digest, sizeof digest, NULL); ++ digest, qbits/8, NULL); + if (ec) + goto leave; + if (value_j == value_n) +@@ -1824,11 +1824,11 @@ _gcry_generate_fips186_3_prime (unsigned + } + + /* Step 12: Save p, q, counter and seed. */ +- log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", ++ /* log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", + mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); + log_printhex ("fips186-3 seed", seed, seedlen); + log_printmpi ("fips186-3 p", prime_p); +- log_printmpi ("fips186-3 q", prime_q); ++ log_printmpi ("fips186-3 q", prime_q); */ + if (r_q) + { + *r_q = prime_q; +diff -up libgcrypt-1.6.1/cipher/rsa.c.tests libgcrypt-1.6.1/cipher/rsa.c +--- libgcrypt-1.6.1/cipher/rsa.c.tests 2014-01-29 08:49:49.000000000 +0100 ++++ libgcrypt-1.6.1/cipher/rsa.c 2014-02-28 13:39:01.727288335 +0100 +@@ -399,7 +399,7 @@ generate_x931 (RSA_secret_key *sk, unsig + + *swapped = 0; + +- if (e_value == 1) /* Alias for a secure value. */ ++ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ + e_value = 65537; + + /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ +diff -up libgcrypt-1.6.1/random/random-fips.c.tests libgcrypt-1.6.1/random/random-fips.c +--- libgcrypt-1.6.1/random/random-fips.c.tests 2014-01-29 10:48:38.000000000 +0100 ++++ libgcrypt-1.6.1/random/random-fips.c 2014-02-28 13:39:01.727288335 +0100 +@@ -692,6 +692,7 @@ get_random (void *buffer, size_t length, + + check_guards (rng_ctx); + ++ reinitialize: + /* Initialize the cipher handle and thus setup the key if needed. */ + if (!rng_ctx->cipher_hd) + { +@@ -711,13 +712,11 @@ get_random (void *buffer, size_t length, + if (rng_ctx->key_init_pid != getpid () + || rng_ctx->seed_init_pid != getpid ()) + { +- /* We are in a child of us. Because we have no way yet to do +- proper re-initialization (including self-checks etc), the +- only chance we have is to bail out. Obviusly a fork/exec +- won't harm because the exec overwrites the old image. */ +- fips_signal_error ("fork without proper re-initialization " +- "detected in RNG"); +- goto bailout; ++ /* Just reinitialize the key & seed. */ ++ gcry_cipher_close(rng_ctx->cipher_hd); ++ rng_ctx->cipher_hd = NULL; ++ rng_ctx->is_seeded = 0; ++ goto reinitialize; + } + + if (x931_aes_driver (buffer, length, rng_ctx)) +diff -up libgcrypt-1.6.1/tests/keygen.c.tests libgcrypt-1.6.1/tests/keygen.c +--- libgcrypt-1.6.1/tests/keygen.c.tests 2014-02-28 13:39:01.728288358 +0100 ++++ libgcrypt-1.6.1/tests/keygen.c 2014-02-28 13:42:18.288831563 +0100 +@@ -215,11 +215,11 @@ check_rsa_keys (void) + + + if (verbose) +- show ("creating 512 bit RSA key with e=257\n"); ++ show ("creating 1024 bit RSA key with e=257\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" +- " (nbits 3:512)\n" ++ " (nbits 4:1024)\n" + " (rsa-use-e 3:257)\n" + " ))", 0, 1); + if (rc) +@@ -233,11 +233,11 @@ check_rsa_keys (void) + gcry_sexp_release (key); + + if (verbose) +- show ("creating 512 bit RSA key with default e\n"); ++ show ("creating 1024 bit RSA key with default e\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" +- " (nbits 3:512)\n" ++ " (nbits 4:1024)\n" + " (rsa-use-e 1:0)\n" + " ))", 0, 1); + if (rc) +@@ -307,12 +307,12 @@ check_dsa_keys (void) + } + + if (verbose) +- show ("creating 1536 bit DSA key\n"); ++ show ("creating 2048 bit DSA key\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (dsa\n" +- " (nbits 4:1536)\n" +- " (qbits 3:224)\n" ++ " (nbits 4:2048)\n" ++ " (qbits 3:256)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); diff --git a/libgcrypt-1.5.1-use-poll.patch b/libgcrypt-1.6.1-use-poll.patch similarity index 54% rename from libgcrypt-1.5.1-use-poll.patch rename to libgcrypt-1.6.1-use-poll.patch index f6ed0b7..2fcaebf 100644 --- a/libgcrypt-1.5.1-use-poll.patch +++ b/libgcrypt-1.6.1-use-poll.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.5.1/random/rndlinux.c.use-poll libgcrypt-1.5.1/random/rndlinux.c ---- libgcrypt-1.5.1/random/rndlinux.c.use-poll 2013-03-20 15:33:26.504867356 +0100 -+++ libgcrypt-1.5.1/random/rndlinux.c 2013-03-20 15:37:24.999944048 +0100 +diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndlinux.c +--- libgcrypt-1.6.1/random/rndlinux.c.use-poll 2014-02-28 15:17:55.294433915 +0100 ++++ libgcrypt-1.6.1/random/rndlinux.c 2014-02-28 15:34:52.505945274 +0100 @@ -32,6 +32,7 @@ #include #include @@ -9,14 +9,7 @@ diff -up libgcrypt-1.5.1/random/rndlinux.c.use-poll libgcrypt-1.5.1/random/rndli #include "types.h" #include "g10lib.h" #include "rand-internal.h" -@@ -142,49 +143,37 @@ _gcry_rndlinux_gather_random (void (*add - } - - /* Enter the read loop. */ -- delay = 0; /* Start with 0 seconds so that we do no block on the -+ delay = 100; /* Start with 0 seconds so that we do no block on the - first iteration and in turn call the progress function - before blocking. To give the OS a better chance to +@@ -199,9 +200,11 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) { @@ -24,6 +17,15 @@ diff -up libgcrypt-1.5.1/random/rndlinux.c.use-poll libgcrypt-1.5.1/random/rndli - struct timeval tv; int rc; + struct pollfd pfd; ++ ++ pfd.fd = fd; ++ pfd.events = POLLIN; + + /* If we collected some bytes update the progress indicator. We + do this always and not just if the select timed out because +@@ -215,33 +218,18 @@ _gcry_rndlinux_gather_random (void (*add + any_need_entropy = 1; + } - /* If the system has no limit on the number of file descriptors - and we encounter an fd which is larger than the fd_set size, @@ -33,49 +35,36 @@ diff -up libgcrypt-1.5.1/random/rndlinux.c.use-poll libgcrypt-1.5.1/random/rndli -#ifdef FD_SETSIZE - if (fd < FD_SETSIZE) -#endif -+ pfd.fd = fd; -+ pfd.events = POLLIN; -+ -+ if ( !(rc=poll(&pfd, 1, delay)) ) - { +- { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = delay; - tv.tv_usec = delay? 0 : 100000; - if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) - { -- if (!any_need_entropy || last_so_far != (want - length) ) -- { -- last_so_far = want - length; -- _gcry_random_progress ("need_entropy", 'X', -- (int)last_so_far, (int)want); -- any_need_entropy = 1; -- } +- any_need_entropy = 1; - delay = 3; /* Use 3 seconds henceforth. */ - continue; - } - else if( rc == -1 ) -+ if (!any_need_entropy || last_so_far != (want - length) ) - { +- { - log_error ("select() error: %s\n", strerror(errno)); - if (!delay) - delay = 1; /* Use 1 second if we encounter an error before -+ last_so_far = want - length; -+ _gcry_random_progress ("need_entropy", 'X', -+ (int)last_so_far, (int)want); -+ any_need_entropy = 1; -+ } +- we have ever blocked. */ +- continue; +- } ++ if ( !(rc=poll(&pfd, 1, delay)) ) ++ { + delay = 3000; /* Use 3 seconds henceforth. */ -+ continue; -+ } -+ else if( rc == -1 ) ++ continue; ++ } ++ else if( rc == -1 ) + { + log_error ("poll() error: %s\n", strerror(errno)); + if (!delay) + delay = 1000; /* Use 1 second if we encounter an error before - we have ever blocked. */ -- continue; -- } ++ we have ever blocked. */ + continue; } diff --git a/libgcrypt.spec b/libgcrypt.spec index cd41803..f2f1916 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.5.3 -Release: 3%{?dist} +Version: 1.6.1 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -11,34 +11,29 @@ Source0: libgcrypt-%{version}-hobbled.tar.xz #Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com Source3: hobble-libgcrypt -# Approved ECC support (from 1.5.3) -Source4: ecc.c +# Approved ECC support (from 1.6.1) +Source4: ecc-curves.c Source5: curves.c +Source6: t-mpi-point.c # make FIPS hmac compatible with fipscheck - non upstreamable Patch2: libgcrypt-1.5.0-use-fipscheck.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen -Patch5: libgcrypt-1.5.0-tests.patch +Patch5: libgcrypt-1.6.1-tests.patch # add configurable source of RNG seed and seed by default # from /dev/urandom in the FIPS mode -Patch6: libgcrypt-1.5.0-fips-cfgrandom.patch +Patch6: libgcrypt-1.6.1-fips-cfgrandom.patch # make the FIPS-186-3 DSA CAVS testable -Patch7: libgcrypt-1.5.0-fips-cavs.patch +Patch7: libgcrypt-1.6.1-fips-cavs.patch # fix for memory leaks an other errors found by Coverity scan -Patch9: libgcrypt-1.5.0-leak.patch +Patch9: libgcrypt-1.6.1-leak.patch # use poll instead of select when gathering randomness -Patch11: libgcrypt-1.5.1-use-poll.patch +Patch11: libgcrypt-1.6.1-use-poll.patch # compile rijndael with -fno-strict-aliasing Patch12: libgcrypt-1.5.2-aliasing.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) -Patch13: libgcrypt-1.5.2-mpicoder-gccopt.patch +Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC -Patch14: libgcrypt-1.5.3-ecc-test-fix.patch -# pbkdf2 speedup - upstream -Patch15: libgcrypt-1.5.3-pbkdf-speedup.patch -# fix bug in whirlpool implementation (for backwards compatibility -# with files generated with buggy version set environment -# varible GCRYPT_WHIRLPOOL_BUG -Patch16: libgcrypt-1.5.3-whirlpool-bug.patch +Patch14: libgcrypt-1.6.1-ecc-test-fix.patch %define gcrylibdir %{_libdir} @@ -80,14 +75,11 @@ applications using libgcrypt. %patch7 -p1 -b .cavs %patch9 -p1 -b .leak %patch11 -p1 -b .use-poll -%patch12 -p1 -b .aliasing +#%patch12 -p1 -b .aliasing %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix -%patch15 -p1 -b .pbkdf-speedup -%patch16 -p1 -b .whirlpool-bug cp %{SOURCE4} cipher/ -rm -rf tests/curves.c -cp %{SOURCE5} tests/curves.c +cp %{SOURCE5} %{SOURCE6} tests/ %build %configure --disable-static \ @@ -98,6 +90,7 @@ cp %{SOURCE5} tests/curves.c --enable-hmac-binary-check \ --enable-pubkey-ciphers='dsa elgamal rsa ecc' \ --disable-O-flag-munging +sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool make %{?_smp_mflags} %check @@ -147,8 +140,11 @@ popd # Add soname symlink. /sbin/ldconfig -n $RPM_BUILD_ROOT/%{_lib}/ + %endif +# temporary compat library for buildroots +install %{gcrylibdir}/libgcrypt.so.11.*.* $RPM_BUILD_ROOT/%{_libdir} # Create /etc/gcrypt (hardwired, not dependent on the configure invocation) so # that _someone_ owns it. @@ -181,14 +177,20 @@ exit 0 %{_bindir}/%{name}-config %{_bindir}/dumpsexp %{_bindir}/hmac256 +%{_bindir}/mpicalc %{_includedir}/* %{_libdir}/*.so %{_datadir}/aclocal/* +%{_mandir}/man1/* %{_infodir}/gcrypt.info* %doc COPYING %changelog +* Fri Feb 28 2014 Tomáš Mráz 1.6.1-1 +- new upstream version breaking ABI compatibility +- this release temporarily includes old compatibility .so + * Tue Jan 21 2014 Tomáš Mráz 1.5.3-3 - add back the nistp521r1 EC curve - fix a bug in the Whirlpool hash implementation diff --git a/t-mpi-point.c b/t-mpi-point.c new file mode 100644 index 0000000..2c977c5 --- /dev/null +++ b/t-mpi-point.c @@ -0,0 +1,970 @@ +/* t-mpi-point.c - Tests for mpi point functions + * Copyright (C) 2013 g10 Code GmbH + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt 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 program; if not, see . + */ + +#ifdef HAVE_CONFIG_H +# include +#endif +#include +#include +#include +#include +#include + +#include "../src/gcrypt-int.h" + +#define PGM "t-mpi-point" + +static const char *wherestr; +static int verbose; +static int debug; +static int error_count; + + +#define my_isascii(c) (!((c) & 0x80)) +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) +#define xmalloc(a) gcry_xmalloc ((a)) +#define xcalloc(a,b) gcry_xcalloc ((a),(b)) +#define xfree(a) gcry_free ((a)) +#define pass() do { ; } while (0) + + +static struct +{ + const char *desc; /* Description of the curve. */ + const char *p; /* Order of the prime field. */ + const char *a, *b; /* The coefficients. */ + const char *n; /* The order of the base point. */ + const char *g_x, *g_y; /* Base point. */ +} test_curve[] = + { + { + "NIST P-256", + "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", + "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", + "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", + "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", + + "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + }, + { + "NIST P-384", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + "ffffffff0000000000000000ffffffff", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" + "ffffffff0000000000000000fffffffc", + "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" + "c656398d8a2ed19d2a85c8edd3ec2aef", + "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" + "581a0db248b0a77aecec196accc52973", + + "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" + "5502f25dbf55296c3a545e3872760ab7", + "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" + "0a60b1ce1d7e819d7a431d7c90ea0e5f" + }, + { + "NIST P-521", + "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", + "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", + "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" + "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", + "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", + + "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" + "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", + "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" + "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + }, + { + "Ed25519", + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", + "-0x01", + "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", + "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", + "0x6666666666666666666666666666666666666666666666666666666666666658" + }, + { NULL, NULL, NULL, NULL, NULL } + }; + +/* A sample public key for NIST P-256. */ +static const char sample_p256_q[] = + "04" + "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E" + "E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; +static const char sample_p256_q_x[] = + "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E"; +static const char sample_p256_q_y[] = + "00E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; + + +/* A sample public key for Ed25519. */ +static const char sample_ed25519_q[] = + "04" + "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce" + "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7"; +static const char sample_ed25519_q_x[] = + "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce"; +static const char sample_ed25519_q_y[] = + "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7"; +static const char sample_ed25519_q_eddsa[] = + "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; +static const char sample_ed25519_d[] = + "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"; + + +static void +show (const char *format, ...) +{ + va_list arg_ptr; + + if (!verbose) + return; + fprintf (stderr, "%s: ", PGM); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); +} + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + if (wherestr) + fprintf (stderr, "%s: ", wherestr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + if (wherestr) + fprintf (stderr, "%s: ", wherestr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + +static void +print_mpi_2 (const char *text, const char *text2, gcry_mpi_t a) +{ + gcry_error_t err; + char *buf; + void *bufaddr = &buf; + + err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); + if (err) + fprintf (stderr, "%s%s: [error printing number: %s]\n", + text, text2? text2:"", gpg_strerror (err)); + else + { + fprintf (stderr, "%s%s: %s\n", text, text2? text2:"", buf); + gcry_free (buf); + } +} + + +static void +print_mpi (const char *text, gcry_mpi_t a) +{ + print_mpi_2 (text, NULL, a); +} + + +static void +print_point (const char *text, gcry_mpi_point_t a) +{ + gcry_mpi_t x, y, z; + + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + gcry_mpi_point_get (x, y, z, a); + print_mpi_2 (text, ".x", x); + print_mpi_2 (text, ".y", y); + print_mpi_2 (text, ".z", z); + gcry_mpi_release (x); + gcry_mpi_release (y); + gcry_mpi_release (z); +} + + +static void +print_sexp (const char *prefix, gcry_sexp_t a) +{ + char *buf; + size_t size; + + if (prefix) + fputs (prefix, stderr); + size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); + buf = gcry_xmalloc (size); + + gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); + fprintf (stderr, "%.*s", (int)size, buf); + gcry_free (buf); +} + + +static gcry_mpi_t +hex2mpi (const char *string) +{ + gpg_error_t err; + gcry_mpi_t val; + + err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); + if (err) + die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err)); + return val; +} + + +/* Convert STRING consisting of hex characters into its binary + representation and return it as an allocated buffer. The valid + length of the buffer is returned at R_LENGTH. The string is + delimited by end of string. The function returns NULL on + error. */ +static void * +hex2buffer (const char *string, size_t *r_length) +{ + const char *s; + unsigned char *buffer; + size_t length; + + buffer = xmalloc (strlen(string)/2+1); + length = 0; + for (s=string; *s; s +=2 ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + return NULL; /* Invalid hex digits. */ + ((unsigned char*)buffer)[length++] = xtoi_2 (s); + } + *r_length = length; + return buffer; +} + + +static gcry_mpi_t +hex2mpiopa (const char *string) +{ + char *buffer; + size_t buflen; + gcry_mpi_t val; + + buffer = hex2buffer (string, &buflen); + if (!buffer) + die ("hex2mpiopa '%s' failed: parser error\n", string); + val = gcry_mpi_set_opaque (NULL, buffer, buflen*8); + if (!buffer) + die ("hex2mpiopa '%s' failed: set_opaque error%s\n", string); + return val; +} + + +/* Compare A to B, where B is given as a hex string. */ +static int +cmp_mpihex (gcry_mpi_t a, const char *b) +{ + gcry_mpi_t bval; + int res; + + if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) + bval = hex2mpiopa (b); + else + bval = hex2mpi (b); + res = gcry_mpi_cmp (a, bval); + gcry_mpi_release (bval); + return res; +} + + +/* Wrapper to emulate the libgcrypt internal EC context allocation + function. */ +static gpg_error_t +ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a) +{ + gpg_error_t err; + gcry_sexp_t sexp; + + if (p && a) + err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m)(a %m))", p, a); + else if (p) + err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m))", p); + else if (a) + err = gcry_sexp_build (&sexp, NULL, "(ecdsa (a %m))", a); + else + err = gcry_sexp_build (&sexp, NULL, "(ecdsa)"); + if (err) + return err; + err = gcry_mpi_ec_new (r_ctx, sexp, NULL); + gcry_sexp_release (sexp); + return err; +} + + + +static void +set_get_point (void) +{ + gcry_mpi_point_t point; + gcry_mpi_t x, y, z; + + wherestr = "set_get_point"; + show ("checking point setting functions\n"); + + point = gcry_mpi_point_new (0); + x = gcry_mpi_set_ui (NULL, 17); + y = gcry_mpi_set_ui (NULL, 42); + z = gcry_mpi_set_ui (NULL, 11371); + gcry_mpi_point_get (x, y, z, point); + if (gcry_mpi_cmp_ui (x, 0) + || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) + fail ("new point not initialized to (0,0,0)\n"); + gcry_mpi_point_snatch_get (x, y, z, point); + point = NULL; + if (gcry_mpi_cmp_ui (x, 0) + || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) + fail ("snatch_get failed\n"); + gcry_mpi_release (x); + gcry_mpi_release (y); + gcry_mpi_release (z); + + point = gcry_mpi_point_new (0); + x = gcry_mpi_set_ui (NULL, 17); + y = gcry_mpi_set_ui (NULL, 42); + z = gcry_mpi_set_ui (NULL, 11371); + gcry_mpi_point_set (point, x, y, z); + gcry_mpi_set_ui (x, 23); + gcry_mpi_set_ui (y, 24); + gcry_mpi_set_ui (z, 25); + gcry_mpi_point_get (x, y, z, point); + if (gcry_mpi_cmp_ui (x, 17) + || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) + fail ("point_set/point_get failed\n"); + gcry_mpi_point_snatch_set (point, x, y, z); + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + gcry_mpi_point_get (x, y, z, point); + if (gcry_mpi_cmp_ui (x, 17) + || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) + fail ("point_snatch_set/point_get failed\n"); + + gcry_mpi_point_release (point); + gcry_mpi_release (x); + gcry_mpi_release (y); + gcry_mpi_release (z); +} + + +static void +context_alloc (void) +{ + gpg_error_t err; + gcry_ctx_t ctx; + gcry_mpi_t p, a; + + wherestr = "context_alloc"; + show ("checking context functions\n"); + + p = gcry_mpi_set_ui (NULL, 1); + a = gcry_mpi_set_ui (NULL, 1); + err = ec_p_new (&ctx, p, a); + if (err) + die ("ec_p_new returned an error: %s\n", gpg_strerror (err)); + gcry_mpi_release (p); + gcry_mpi_release (a); + gcry_ctx_release (ctx); + + p = gcry_mpi_set_ui (NULL, 0); + a = gcry_mpi_set_ui (NULL, 0); + err = ec_p_new (&ctx, p, a); + if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) + fail ("ec_p_new: bad parameter detection failed (1)\n"); + + gcry_mpi_set_ui (p, 1); + err = ec_p_new (&ctx, p, a); + if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) + fail ("ec_p_new: bad parameter detection failed (2)\n"); + + gcry_mpi_release (p); + p = NULL; + err = ec_p_new (&ctx, p, a); + if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) + fail ("ec_p_new: bad parameter detection failed (3)\n"); + + gcry_mpi_release (a); + a = NULL; + err = ec_p_new (&ctx, p, a); + if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) + fail ("ec_p_new: bad parameter detection failed (4)\n"); + +} + + +static int +get_and_cmp_mpi (const char *name, const char *mpistring, const char *desc, + gcry_ctx_t ctx) +{ + gcry_mpi_t mpi; + + mpi = gcry_mpi_ec_get_mpi (name, ctx, 1); + if (!mpi) + { + fail ("error getting parameter '%s' of curve '%s'\n", name, desc); + return 1; + } + if (debug) + print_mpi (name, mpi); + if (cmp_mpihex (mpi, mpistring)) + { + fail ("parameter '%s' of curve '%s' does not match\n", name, desc); + gcry_mpi_release (mpi); + return 1; + } + gcry_mpi_release (mpi); + return 0; +} + + +static int +get_and_cmp_point (const char *name, + const char *mpi_x_string, const char *mpi_y_string, + const char *desc, gcry_ctx_t ctx) +{ + gcry_mpi_point_t point; + gcry_mpi_t x, y, z; + int result = 0; + + point = gcry_mpi_ec_get_point (name, ctx, 1); + if (!point) + { + fail ("error getting point parameter '%s' of curve '%s'\n", name, desc); + return 1; + } + if (debug) + print_point (name, point); + + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + gcry_mpi_point_snatch_get (x, y, z, point); + if (cmp_mpihex (x, mpi_x_string)) + { + fail ("x coordinate of '%s' of curve '%s' does not match\n", name, desc); + result = 1; + } + if (cmp_mpihex (y, mpi_y_string)) + { + fail ("y coordinate of '%s' of curve '%s' does not match\n", name, desc); + result = 1; + } + if (cmp_mpihex (z, "01")) + { + fail ("z coordinate of '%s' of curve '%s' is not 1\n", name, desc); + result = 1; + } + gcry_mpi_release (x); + gcry_mpi_release (y); + gcry_mpi_release (z); + return result; +} + + +static void +context_param (void) +{ + gpg_error_t err; + int idx; + gcry_ctx_t ctx = NULL; + gcry_mpi_t q, d; + gcry_sexp_t keyparam; + + wherestr = "context_param"; + + show ("checking standard curves\n"); + for (idx=0; test_curve[idx].desc; idx++) + { + gcry_ctx_release (ctx); + err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc); + if (err) + { + fail ("can't create context for curve '%s': %s\n", + test_curve[idx].desc, gpg_strerror (err)); + continue; + } + if (get_and_cmp_mpi ("p", test_curve[idx].p, test_curve[idx].desc, ctx)) + continue; + if (get_and_cmp_mpi ("a", test_curve[idx].a, test_curve[idx].desc, ctx)) + continue; + if (get_and_cmp_mpi ("b", test_curve[idx].b, test_curve[idx].desc, ctx)) + continue; + if (get_and_cmp_mpi ("g.x",test_curve[idx].g_x, test_curve[idx].desc,ctx)) + continue; + if (get_and_cmp_mpi ("g.y",test_curve[idx].g_y, test_curve[idx].desc,ctx)) + continue; + if (get_and_cmp_mpi ("n", test_curve[idx].n, test_curve[idx].desc, ctx)) + continue; + if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y, + test_curve[idx].desc, ctx)) + continue; + + } + + show ("checking sample public key (nistp256)\n"); + q = hex2mpi (sample_p256_q); + err = gcry_sexp_build (&keyparam, NULL, + "(public-key(ecc(curve %s)(q %m)))", + "NIST P-256", q); + if (err) + die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (q); + + /* We can't call gcry_pk_testkey because it is only implemented for + private keys. */ + /* err = gcry_pk_testkey (keyparam); */ + /* if (err) */ + /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ + /* gpg_strerror (err)); */ + + gcry_ctx_release (ctx); + err = gcry_mpi_ec_new (&ctx, keyparam, NULL); + if (err) + fail ("gcry_mpi_ec_new failed for sample public key (nistp256): %s\n", + gpg_strerror (err)); + else + { + gcry_sexp_t sexp; + + get_and_cmp_mpi ("q", sample_p256_q, "nistp256", ctx); + get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "nistp256", + ctx); + + /* Delete Q. */ + err = gcry_mpi_ec_set_mpi ("q", NULL, ctx); + if (err) + fail ("clearing Q for nistp256 failed: %s\n", gpg_strerror (err)); + if (gcry_mpi_ec_get_mpi ("q", ctx, 0)) + fail ("clearing Q for nistp256 did not work\n"); + + /* Set Q again. */ + q = hex2mpi (sample_p256_q); + err = gcry_mpi_ec_set_mpi ("q", q, ctx); + if (err) + fail ("setting Q for nistp256 failed: %s\n", gpg_strerror (err)); + get_and_cmp_mpi ("q", sample_p256_q, "nistp256(2)", ctx); + gcry_mpi_release (q); + + /* Get as s-expression. */ + err = gcry_pubkey_get_sexp (&sexp, 0, ctx); + if (err) + fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); + else if (debug) + print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); + gcry_sexp_release (sexp); + + err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); + if (err) + fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", + gpg_strerror (err)); + else if (debug) + print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); + gcry_sexp_release (sexp); + + err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); + if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) + fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", + gpg_strerror (err)); + gcry_sexp_release (sexp); + } + + show ("checking sample public key (Ed25519)\n"); + q = hex2mpi (sample_ed25519_q); + gcry_sexp_release (keyparam); + err = gcry_sexp_build (&keyparam, NULL, + "(public-key(ecc(curve %s)(flags eddsa)(q %m)))", + "Ed25519", q); + if (err) + die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (q); + + /* We can't call gcry_pk_testkey because it is only implemented for + private keys. */ + /* err = gcry_pk_testkey (keyparam); */ + /* if (err) */ + /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ + /* gpg_strerror (err)); */ + + gcry_ctx_release (ctx); + err = gcry_mpi_ec_new (&ctx, keyparam, NULL); + if (err) + fail ("gcry_mpi_ec_new failed for sample public key: %s\n", + gpg_strerror (err)); + else + { + gcry_sexp_t sexp; + + get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519", ctx); + get_and_cmp_point ("q", sample_ed25519_q_x, sample_ed25519_q_y, + "Ed25519", ctx); + get_and_cmp_mpi ("q@eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx); + + /* Set d to see whether Q is correctly re-computed. */ + d = hex2mpi (sample_ed25519_d); + err = gcry_mpi_ec_set_mpi ("d", d, ctx); + if (err) + fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (d); + get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx); + + /* Delete Q by setting d and then clearing d. The clearing is + required so that we can check whether Q has been cleared and + because further tests only expect a public key. */ + d = hex2mpi (sample_ed25519_d); + err = gcry_mpi_ec_set_mpi ("d", d, ctx); + if (err) + fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (d); + err = gcry_mpi_ec_set_mpi ("d", NULL, ctx); + if (err) + fail ("setting d for Ed25519 failed(2): %s\n", gpg_strerror (err)); + if (gcry_mpi_ec_get_mpi ("q", ctx, 0)) + fail ("setting d for Ed25519 did not reset Q\n"); + + /* Set Q again. We need to use an opaque MPI here because + sample_ed25519_q is in uncompressed format which can only be + auto-detected if passed opaque. */ + q = hex2mpiopa (sample_ed25519_q); + err = gcry_mpi_ec_set_mpi ("q", q, ctx); + if (err) + fail ("setting Q for Ed25519 failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (q); + get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(2)", ctx); + + /* Get as s-expression. */ + err = gcry_pubkey_get_sexp (&sexp, 0, ctx); + if (err) + fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); + else if (debug) + print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); + gcry_sexp_release (sexp); + + err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); + if (err) + fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", + gpg_strerror (err)); + else if (debug) + print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); + gcry_sexp_release (sexp); + + err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); + if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) + fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", + gpg_strerror (err)); + gcry_sexp_release (sexp); + + } + + gcry_ctx_release (ctx); + gcry_sexp_release (keyparam); +} + + + + +/* Create a new point from (X,Y,Z) given as hex strings. */ +gcry_mpi_point_t +make_point (const char *x, const char *y, const char *z) +{ + gcry_mpi_point_t point; + + point = gcry_mpi_point_new (0); + gcry_mpi_point_snatch_set (point, hex2mpi (x), hex2mpi (y), hex2mpi (z)); + + return point; +} + + +/* This tests checks that the low-level EC API yields the same result + as using the high level API. The values have been taken from a + test run using the high level API. */ +static void +basic_ec_math (void) +{ + gpg_error_t err; + gcry_ctx_t ctx; + gcry_mpi_t P, A; + gcry_mpi_point_t G, Q; + gcry_mpi_t d; + gcry_mpi_t x, y, z; + + wherestr = "basic_ec_math"; + show ("checking basic math functions for EC\n"); + + P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); + A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); + G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", + "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", + "1"); + d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D"); + Q = gcry_mpi_point_new (0); + + err = ec_p_new (&ctx, P, A); + if (err) + die ("ec_p_new failed: %s\n", gpg_strerror (err)); + + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + + { + /* A quick check that multiply by zero works. */ + gcry_mpi_t tmp; + + tmp = gcry_mpi_new (0); + gcry_mpi_ec_mul (Q, tmp, G, ctx); + gcry_mpi_release (tmp); + gcry_mpi_point_get (x, y, z, Q); + if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0) + || gcry_mpi_cmp_ui (z, 0)) + fail ("multiply a point by zero failed\n"); + } + + gcry_mpi_ec_mul (Q, d, G, ctx); + gcry_mpi_point_get (x, y, z, Q); + if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66") + || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8") + || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F")) + fail ("computed public key does not match\n"); + if (debug) + { + print_mpi ("Q.x", x); + print_mpi ("Q.y", y); + print_mpi ("Q.z", z); + } + + if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) + fail ("failed to get affine coordinates\n"); + if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE") + || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966")) + fail ("computed affine coordinates of public key do not match\n"); + if (debug) + { + print_mpi ("q.x", x); + print_mpi ("q.y", y); + } + + gcry_mpi_release (z); + gcry_mpi_release (y); + gcry_mpi_release (x); + gcry_mpi_point_release (Q); + gcry_mpi_release (d); + gcry_mpi_point_release (G); + gcry_mpi_release (A); + gcry_mpi_release (P); + gcry_ctx_release (ctx); +} + + +/* Check the math used with Twisted Edwards curves. */ +static void +twistededwards_math (void) +{ + gpg_error_t err; + gcry_ctx_t ctx; + gcry_mpi_point_t G, Q; + gcry_mpi_t k; + gcry_mpi_t w, a, x, y, z, p, n, b, I; + + wherestr = "twistededwards_math"; + show ("checking basic Twisted Edwards math\n"); + + err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519"); + if (err) + die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err)); + + k = hex2mpi + ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004" + "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6"); + G = gcry_mpi_ec_get_point ("g", ctx, 1); + if (!G) + die ("gcry_mpi_ec_get_point(G) failed\n"); + Q = gcry_mpi_point_new (0); + + + w = gcry_mpi_new (0); + a = gcry_mpi_new (0); + x = gcry_mpi_new (0); + y = gcry_mpi_new (0); + z = gcry_mpi_new (0); + I = gcry_mpi_new (0); + p = gcry_mpi_ec_get_mpi ("p", ctx, 1); + n = gcry_mpi_ec_get_mpi ("n", ctx, 1); + b = gcry_mpi_ec_get_mpi ("b", ctx, 1); + + /* Check: 2^{p-1} mod p == 1 */ + gcry_mpi_sub_ui (a, p, 1); + gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p); + if (gcry_mpi_cmp_ui (w, 1)) + fail ("failed assertion: 2^{p-1} mod p == 1\n"); + + /* Check: p % 4 == 1 */ + gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR); + if (gcry_mpi_cmp_ui (w, 1)) + fail ("failed assertion: p % 4 == 1\n"); + + /* Check: 2^{n-1} mod n == 1 */ + gcry_mpi_sub_ui (a, n, 1); + gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n); + if (gcry_mpi_cmp_ui (w, 1)) + fail ("failed assertion: 2^{n-1} mod n == 1\n"); + + /* Check: b^{(p-1)/2} mod p == p-1 */ + gcry_mpi_sub_ui (a, p, 1); + gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1); + gcry_mpi_powm (w, b, x, p); + gcry_mpi_abs (w); + if (gcry_mpi_cmp (w, a)) + fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n"); + + /* I := 2^{(p-1)/4} mod p */ + gcry_mpi_sub_ui (a, p, 1); + gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1); + gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p); + + /* Check: I^2 mod p == p-1 */ + gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p); + if (gcry_mpi_cmp (w, a)) + fail ("failed assertion: I^2 mod p == p-1\n"); + + /* Check: G is on the curve */ + if (!gcry_mpi_ec_curve_point (G, ctx)) + fail ("failed assertion: G is on the curve\n"); + + /* Check: nG == (0,1) */ + gcry_mpi_ec_mul (Q, n, G, ctx); + if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) + fail ("failed to get affine coordinates\n"); + if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1)) + fail ("failed assertion: nG == (0,1)\n"); + + /* Now two arbitrary point operations taken from the ed25519.py + sample data. */ + gcry_mpi_release (a); + a = hex2mpi + ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496" + "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3"); + gcry_mpi_ec_mul (Q, a, G, ctx); + if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) + fail ("failed to get affine coordinates\n"); + if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be" + "00014fecc2165ca5cee9eee19fe4d2c1")) + || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2" + "4025645f0b820e72b8cad4f0a909a092"))) + { + fail ("sample point multiply failed:\n"); + print_mpi ("r", a); + print_mpi ("Rx", x); + print_mpi ("Ry", y); + } + + gcry_mpi_release (a); + a = hex2mpi + ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004" + "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6"); + gcry_mpi_ec_mul (Q, a, G, ctx); + if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) + fail ("failed to get affine coordinates\n"); + if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371" + "82324bd01ce6f3cf81ab44e62959c82a")) + || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784" + "8a826e80cce2869072ac60c3004356e5"))) + { + fail ("sample point multiply failed:\n"); + print_mpi ("r", a); + print_mpi ("Rx", x); + print_mpi ("Ry", y); + } + + + gcry_mpi_release (I); + gcry_mpi_release (b); + gcry_mpi_release (n); + gcry_mpi_release (p); + gcry_mpi_release (w); + gcry_mpi_release (a); + gcry_mpi_release (x); + gcry_mpi_release (y); + gcry_mpi_release (z); + gcry_mpi_point_release (Q); + gcry_mpi_point_release (G); + gcry_mpi_release (k); + gcry_ctx_release (ctx); +} + + +int +main (int argc, char **argv) +{ + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + set_get_point (); + context_alloc (); + context_param (); + basic_ec_math (); + twistededwards_math (); + + show ("All tests completed. Errors: %d\n", error_count); + return error_count ? 1 : 0; +} From 45af5b745bce7bffe85884b0813947fd732eea39 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 28 Feb 2014 16:33:18 +0100 Subject: [PATCH 066/214] new upstream version breaking ABI compatibility - this release temporarily includes old compatibility .so --- .gitignore | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d77b0c1..910f70f 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.5.1-hobbled.tar.xz /libgcrypt-1.5.2-hobbled.tar.xz /libgcrypt-1.5.3-hobbled.tar.xz +/libgcrypt-1.6.1-hobbled.tar.xz diff --git a/sources b/sources index 4838fbc..c971c98 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -99e0f2dc94dac6eceab709d03d613328 libgcrypt-1.5.3-hobbled.tar.xz +3f1076b38a407f4775adcf6e9bf43893 libgcrypt-1.6.1-hobbled.tar.xz From 85a7dd9dad7a5d63d0af4a4aa849d4b52c1500bc Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 24 Apr 2014 16:41:24 +0200 Subject: [PATCH 067/214] drop the temporary compat shared library version - fix the soname version in -use-fipscheck.patch --- libgcrypt-1.5.0-use-fipscheck.patch | 2 +- libgcrypt-1.5.2-aliasing.patch | 30 ------------------------- libgcrypt.spec | 34 ++++++++++++++--------------- 3 files changed, 18 insertions(+), 48 deletions(-) delete mode 100644 libgcrypt-1.5.2-aliasing.patch diff --git a/libgcrypt-1.5.0-use-fipscheck.patch b/libgcrypt-1.5.0-use-fipscheck.patch index 704bb52..476c96c 100644 --- a/libgcrypt-1.5.0-use-fipscheck.patch +++ b/libgcrypt-1.5.0-use-fipscheck.patch @@ -46,7 +46,7 @@ diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c - if (!dladdr ("gcry_check_version", &info)) + const char key[] = "orboDeJITITejsirpADONivirpUkvarP"; + -+ if (get_library_path ("libgcrypt.so.11", "gcry_check_version", libpath, sizeof(libpath))) ++ if (get_library_path ("libgcrypt.so.20", "gcry_check_version", libpath, sizeof(libpath))) err = gpg_error_from_syserror (); else { diff --git a/libgcrypt-1.5.2-aliasing.patch b/libgcrypt-1.5.2-aliasing.patch deleted file mode 100644 index db0e0e0..0000000 --- a/libgcrypt-1.5.2-aliasing.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff -up libgcrypt-1.5.2/cipher/Makefile.am.aliasing libgcrypt-1.5.2/cipher/Makefile.am ---- libgcrypt-1.5.2/cipher/Makefile.am.aliasing 2013-04-18 16:49:13.000000000 +0200 -+++ libgcrypt-1.5.2/cipher/Makefile.am 2013-04-25 21:48:57.867465215 +0200 -@@ -81,3 +81,9 @@ tiger.o: $(srcdir)/tiger.c - - tiger.lo: $(srcdir)/tiger.c - `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` -+ -+rijndael.o: $(srcdir)/rijndael.c -+ `echo $(COMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` -+ -+rijndael.lo: $(srcdir)/rijndael.c -+ `echo $(LTCOMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` -diff -up libgcrypt-1.5.2/cipher/Makefile.in.aliasing libgcrypt-1.5.2/cipher/Makefile.in ---- libgcrypt-1.5.2/cipher/Makefile.in.aliasing 2013-04-18 17:06:03.000000000 +0200 -+++ libgcrypt-1.5.2/cipher/Makefile.in 2013-04-25 21:48:59.164493610 +0200 -@@ -638,6 +638,12 @@ tiger.o: $(srcdir)/tiger.c - tiger.lo: $(srcdir)/tiger.c - `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` - -+rijndael.o: $(srcdir)/rijndael.c -+ `echo $(COMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` -+ -+rijndael.lo: $(srcdir)/rijndael.c -+ `echo $(LTCOMPILE) -fno-strict-aliasing -c $(srcdir)/rijndael.c ` -+ - # Tell versions [3.59,3.63) of GNU make to not export all variables. - # Otherwise a system limit (for SysV at least) may be exceeded. - .NOEXPORT: -diff -up libgcrypt-1.5.2/cipher/rijndael.c.aliasing libgcrypt-1.5.2/cipher/rijndael.c diff --git a/libgcrypt.spec b/libgcrypt.spec index f2f1916..65a5a32 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.1 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -16,6 +16,7 @@ Source4: ecc-curves.c Source5: curves.c Source6: t-mpi-point.c # make FIPS hmac compatible with fipscheck - non upstreamable +# update on soname bump Patch2: libgcrypt-1.5.0-use-fipscheck.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen Patch5: libgcrypt-1.6.1-tests.patch @@ -28,8 +29,6 @@ Patch7: libgcrypt-1.6.1-fips-cavs.patch Patch9: libgcrypt-1.6.1-leak.patch # use poll instead of select when gathering randomness Patch11: libgcrypt-1.6.1-use-poll.patch -# compile rijndael with -fno-strict-aliasing -Patch12: libgcrypt-1.5.2-aliasing.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC @@ -42,7 +41,7 @@ Patch14: libgcrypt-1.6.1-ecc-test-fix.patch # are in the devel subpackage. License: LGPLv2+ Summary: A general-purpose cryptography library -BuildRequires: gawk, libgpg-error-devel >= 1.4, pkgconfig +BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig BuildRequires: fipscheck # This is needed only when patching the .texi doc. BuildRequires: texinfo @@ -75,7 +74,6 @@ applications using libgcrypt. %patch7 -p1 -b .cavs %patch9 -p1 -b .leak %patch11 -p1 -b .use-poll -#%patch12 -p1 -b .aliasing %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix cp %{SOURCE4} cipher/ @@ -129,23 +127,21 @@ for shlib in $RPM_BUILD_ROOT%{_libdir}/*.so* ; do fi done +# Add soname symlink. +/sbin/ldconfig -n $RPM_BUILD_ROOT/%{_lib}/ +%endif + # Overwrite development symlinks. -pushd $RPM_BUILD_ROOT/%{_libdir} -for shlib in %{gcrylibdir}/lib*.so.* ; do - shlib=`echo "$shlib" | sed -e 's,//,/,g'` - target=`basename "$shlib" | sed -e 's,\.so.*,,g'`.so +pushd $RPM_BUILD_ROOT/%{gcrylibdir} +for shlib in lib*.so.?? ; do + target=$RPM_BUILD_ROOT/%{_libdir}/`echo "$shlib" | sed -e 's,\.so.*,,g'`.so +%if "%{gcrylibdir}" != "%{_libdir}" + shlib=%{gcrylibdir}/$shlib +%endif ln -sf $shlib $target done popd -# Add soname symlink. -/sbin/ldconfig -n $RPM_BUILD_ROOT/%{_lib}/ - -%endif - -# temporary compat library for buildroots -install %{gcrylibdir}/libgcrypt.so.11.*.* $RPM_BUILD_ROOT/%{_libdir} - # Create /etc/gcrypt (hardwired, not dependent on the configure invocation) so # that _someone_ owns it. mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt @@ -187,6 +183,10 @@ exit 0 %doc COPYING %changelog +* Thu Apr 24 2014 Tomáš Mráz 1.6.1-2 +- drop the temporary compat shared library version +- fix the soname version in -use-fipscheck.patch + * Fri Feb 28 2014 Tomáš Mráz 1.6.1-1 - new upstream version breaking ABI compatibility - this release temporarily includes old compatibility .so From 4df13ba77fc9093a67f57ca2df2c3632d6351cf6 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Mon, 19 May 2014 16:57:04 -0400 Subject: [PATCH 068/214] disable rijndael, cast5, camellia ARM assembly as it's non-PIC as presently written, which results in .text relocations in the shared library. Resolves: rhbz#1069792 --- libgcrypt-1.6.1-disable-non-PIC-arm.patch | 98 +++++++++++++++++++++++ libgcrypt.spec | 9 ++- 2 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.6.1-disable-non-PIC-arm.patch diff --git a/libgcrypt-1.6.1-disable-non-PIC-arm.patch b/libgcrypt-1.6.1-disable-non-PIC-arm.patch new file mode 100644 index 0000000..fa96ff5 --- /dev/null +++ b/libgcrypt-1.6.1-disable-non-PIC-arm.patch @@ -0,0 +1,98 @@ +diff --git a/cipher/camellia-arm.S b/cipher/camellia-arm.S +index 255a246..214198b 100644 +--- a/cipher/camellia-arm.S ++++ b/cipher/camellia-arm.S +@@ -22,6 +22,7 @@ + + #if defined(__ARMEL__) + #ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS ++#ifndef __PIC__ + + .text + +@@ -609,5 +610,6 @@ _gcry_camellia_arm_decrypt_block: + .long 0x80808000, 0x00010101, 0x40004040, 0xc7c700c7 + .long 0x9e9e9e00, 0x003d3d3d, 0x4f004f4f, 0x9e9e009e + +-#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/ ++#endif /*__PIC__*/ ++#endif /*HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS*/ + #endif /*__ARM_ARCH >= 6*/ +diff --git a/cipher/camellia.h b/cipher/camellia.h +index d0e3c18..c8f9556 100644 +--- a/cipher/camellia.h ++++ b/cipher/camellia.h +@@ -32,7 +32,7 @@ + #include + /* USE_ARM_ASM indicates whether to use ARM assembly code. */ + # undef USE_ARM_ASM +-# if defined(__ARMEL__) ++# if defined(__ARMEL__) && !defined(__PIC__) + # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS + # define USE_ARM_ASM 1 + # endif +diff --git a/cipher/cast5-arm.S b/cipher/cast5-arm.S +index 57c89b7..23c1c12 100644 +--- a/cipher/cast5-arm.S ++++ b/cipher/cast5-arm.S +@@ -22,6 +22,7 @@ + + #if defined(__ARMEL__) + #ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS ++#ifndef __PIC__ + + .text + +@@ -711,5 +712,6 @@ _gcry_cast5_arm_cbc_dec: + .ltorg + .size _gcry_cast5_arm_cbc_dec,.-_gcry_cast5_arm_cbc_dec; + ++#endif /*__PIC__*/ + #endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/ + #endif /*__ARM_ARCH >= 6*/ +diff --git a/cipher/cast5.c b/cipher/cast5.c +index 115e1e6..bf4123e 100644 +--- a/cipher/cast5.c ++++ b/cipher/cast5.c +@@ -54,7 +54,7 @@ + + /* USE_ARM_ASM indicates whether to use ARM assembly code. */ + #undef USE_ARM_ASM +-#if defined(__ARMEL__) ++#if defined(__ARMEL__) && !defined(__PIC__) + # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS + # define USE_ARM_ASM 1 + # endif +diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S +index cea8c51..d5d964f 100644 +--- a/cipher/rijndael-arm.S ++++ b/cipher/rijndael-arm.S +@@ -22,6 +22,7 @@ + + #if defined(__ARMEL__) + #ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS ++#ifndef __PIC__ + + .text + +@@ -849,5 +850,6 @@ _gcry_aes_arm_decrypt_block: + .long 0x6184cb7b, 0x00000055, 0x70b632d5, 0x00000021 + .long 0x745c6c48, 0x0000000c, 0x4257b8d0, 0x0000007d + +-#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/ ++#endif /*__PIC__*/ ++#endif /*HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS*/ + #endif /*__ARMEL__ */ +diff --git a/cipher/rijndael.c b/cipher/rijndael.c +index 8019f0a..1ffc559 100644 +--- a/cipher/rijndael.c ++++ b/cipher/rijndael.c +@@ -69,7 +69,7 @@ + + /* USE_ARM_ASM indicates whether to use ARM assembly code. */ + #undef USE_ARM_ASM +-#if defined(__ARMEL__) ++#if defined(__ARMEL__) && !defined(__PIC__) + # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS + # define USE_ARM_ASM 1 + # endif diff --git a/libgcrypt.spec b/libgcrypt.spec index 65a5a32..44ba426 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.1 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -33,6 +33,7 @@ Patch11: libgcrypt-1.6.1-use-poll.patch Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC Patch14: libgcrypt-1.6.1-ecc-test-fix.patch +Patch15: libgcrypt-1.6.1-disable-non-PIC-arm.patch %define gcrylibdir %{_libdir} @@ -76,6 +77,7 @@ applications using libgcrypt. %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix +%patch15 -p1 -b .pic cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -183,6 +185,11 @@ exit 0 %doc COPYING %changelog +* Mon May 19 2014 Kyle McMartin 1.6.1-3 +- Disable rijndael, cast5, camellia ARM assembly, as it's non-PIC as + presently written, which results in .text relocations in the shared + library. (rhbz#1069792) + * Thu Apr 24 2014 Tomáš Mráz 1.6.1-2 - drop the temporary compat shared library version - fix the soname version in -use-fipscheck.patch From 45283d138ce33c371ac6c8a0fd7a5314a72d1d14 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Thu, 22 May 2014 13:28:35 -0400 Subject: [PATCH 069/214] Re-enable below algos, apply patch from upstream list to make that code -fPIC friendly. (rhbz#1069792) --- libgcrypt-1.6.1-disable-non-PIC-arm.patch | 98 ---------- ...ypt-1.6.1-make-arm-asm-fPIC-friendly.patch | 167 ++++++++++++++++++ libgcrypt.spec | 8 +- 3 files changed, 173 insertions(+), 100 deletions(-) delete mode 100644 libgcrypt-1.6.1-disable-non-PIC-arm.patch create mode 100644 libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch diff --git a/libgcrypt-1.6.1-disable-non-PIC-arm.patch b/libgcrypt-1.6.1-disable-non-PIC-arm.patch deleted file mode 100644 index fa96ff5..0000000 --- a/libgcrypt-1.6.1-disable-non-PIC-arm.patch +++ /dev/null @@ -1,98 +0,0 @@ -diff --git a/cipher/camellia-arm.S b/cipher/camellia-arm.S -index 255a246..214198b 100644 ---- a/cipher/camellia-arm.S -+++ b/cipher/camellia-arm.S -@@ -22,6 +22,7 @@ - - #if defined(__ARMEL__) - #ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS -+#ifndef __PIC__ - - .text - -@@ -609,5 +610,6 @@ _gcry_camellia_arm_decrypt_block: - .long 0x80808000, 0x00010101, 0x40004040, 0xc7c700c7 - .long 0x9e9e9e00, 0x003d3d3d, 0x4f004f4f, 0x9e9e009e - --#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/ -+#endif /*__PIC__*/ -+#endif /*HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS*/ - #endif /*__ARM_ARCH >= 6*/ -diff --git a/cipher/camellia.h b/cipher/camellia.h -index d0e3c18..c8f9556 100644 ---- a/cipher/camellia.h -+++ b/cipher/camellia.h -@@ -32,7 +32,7 @@ - #include - /* USE_ARM_ASM indicates whether to use ARM assembly code. */ - # undef USE_ARM_ASM --# if defined(__ARMEL__) -+# if defined(__ARMEL__) && !defined(__PIC__) - # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS - # define USE_ARM_ASM 1 - # endif -diff --git a/cipher/cast5-arm.S b/cipher/cast5-arm.S -index 57c89b7..23c1c12 100644 ---- a/cipher/cast5-arm.S -+++ b/cipher/cast5-arm.S -@@ -22,6 +22,7 @@ - - #if defined(__ARMEL__) - #ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS -+#ifndef __PIC__ - - .text - -@@ -711,5 +712,6 @@ _gcry_cast5_arm_cbc_dec: - .ltorg - .size _gcry_cast5_arm_cbc_dec,.-_gcry_cast5_arm_cbc_dec; - -+#endif /*__PIC__*/ - #endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/ - #endif /*__ARM_ARCH >= 6*/ -diff --git a/cipher/cast5.c b/cipher/cast5.c -index 115e1e6..bf4123e 100644 ---- a/cipher/cast5.c -+++ b/cipher/cast5.c -@@ -54,7 +54,7 @@ - - /* USE_ARM_ASM indicates whether to use ARM assembly code. */ - #undef USE_ARM_ASM --#if defined(__ARMEL__) -+#if defined(__ARMEL__) && !defined(__PIC__) - # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS - # define USE_ARM_ASM 1 - # endif -diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S -index cea8c51..d5d964f 100644 ---- a/cipher/rijndael-arm.S -+++ b/cipher/rijndael-arm.S -@@ -22,6 +22,7 @@ - - #if defined(__ARMEL__) - #ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS -+#ifndef __PIC__ - - .text - -@@ -849,5 +850,6 @@ _gcry_aes_arm_decrypt_block: - .long 0x6184cb7b, 0x00000055, 0x70b632d5, 0x00000021 - .long 0x745c6c48, 0x0000000c, 0x4257b8d0, 0x0000007d - --#endif /*HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS*/ -+#endif /*__PIC__*/ -+#endif /*HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS*/ - #endif /*__ARMEL__ */ -diff --git a/cipher/rijndael.c b/cipher/rijndael.c -index 8019f0a..1ffc559 100644 ---- a/cipher/rijndael.c -+++ b/cipher/rijndael.c -@@ -69,7 +69,7 @@ - - /* USE_ARM_ASM indicates whether to use ARM assembly code. */ - #undef USE_ARM_ASM --#if defined(__ARMEL__) -+#if defined(__ARMEL__) && !defined(__PIC__) - # ifdef HAVE_COMPATIBLE_GCC_ARM_PLATFORM_AS - # define USE_ARM_ASM 1 - # endif diff --git a/libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch b/libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch new file mode 100644 index 0000000..b49006d --- /dev/null +++ b/libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch @@ -0,0 +1,167 @@ +Fix ARM assembly when building __PIC__ + +From: Jussi Kivilinna + +* cipher/camellia-arm.S (GET_DATA_POINTER): New. +(_gcry_camellia_arm_encrypt_block): Use GET_DATA_POINTER. +(_gcry_camellia_arm_decrypt_block): Ditto. +* cipher/cast5-arm.S (GET_DATA_POINTER): New. +(_gcry_cast5_arm_encrypt_block, _gcry_cast5_arm_decrypt_block) +(_gcry_cast5_arm_enc_blk2, _gcry_cast5_arm_dec_blk2): Use +GET_DATA_POINTER. +* cipher/rijndael-arm.S (GET_DATA_POINTER): New. +(_gcry_aes_arm_encrypt_block, _gcry_aes_arm_decrypt_block): Use +GET_DATA_POINTER. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/camellia-arm.S | 17 +++++++++++++++-- + cipher/cast5-arm.S | 21 +++++++++++++++++---- + cipher/rijndael-arm.S | 17 +++++++++++++++-- + 3 files changed, 47 insertions(+), 8 deletions(-) + +diff --git a/cipher/camellia-arm.S b/cipher/camellia-arm.S +index c30d194..cdeaf8b 100644 +--- a/cipher/camellia-arm.S ++++ b/cipher/camellia-arm.S +@@ -28,6 +28,19 @@ + .syntax unified + .arm + ++#ifdef __PIC__ ++# define GET_DATA_POINTER(reg, name, rtmp) \ ++ ldr reg, 1f; \ ++ ldr rtmp, 2f; \ ++ b 3f; \ ++ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \ ++ 2: .word name(GOT); \ ++ 3: add reg, pc, reg; \ ++ ldr reg, [reg, rtmp]; ++#else ++# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name ++#endif ++ + /* struct camellia_ctx: */ + #define key_table 0 + +@@ -261,7 +274,7 @@ _gcry_camellia_arm_encrypt_block: + */ + push {%r1, %r4-%r11, %ip, %lr}; + +- ldr RTAB1, =.Lcamellia_sp1110; ++ GET_DATA_POINTER(RTAB1, .Lcamellia_sp1110, RTAB3); + mov RMASK, #0xff; + add RTAB3, RTAB1, #(2 * 4); + push {%r3}; +@@ -309,7 +322,7 @@ _gcry_camellia_arm_decrypt_block: + */ + push {%r1, %r4-%r11, %ip, %lr}; + +- ldr RTAB1, =.Lcamellia_sp1110; ++ GET_DATA_POINTER(RTAB1, .Lcamellia_sp1110, RTAB3); + mov RMASK, #0xff; + add RTAB3, RTAB1, #(2 * 4); + mov RMASK, RMASK, lsl#4 /* byte mask */ +diff --git a/cipher/cast5-arm.S b/cipher/cast5-arm.S +index ce7fa93..db96db4 100644 +--- a/cipher/cast5-arm.S ++++ b/cipher/cast5-arm.S +@@ -30,6 +30,19 @@ + + .extern _gcry_cast5_s1to4; + ++#ifdef __PIC__ ++# define GET_DATA_POINTER(reg, name, rtmp) \ ++ ldr reg, 1f; \ ++ ldr rtmp, 2f; \ ++ b 3f; \ ++ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \ ++ 2: .word name(GOT); \ ++ 3: add reg, pc, reg; \ ++ ldr reg, [reg, rtmp]; ++#else ++# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name ++#endif ++ + /* structure of crypto context */ + #define Km 0 + #define Kr (Km + (16 * 4)) +@@ -260,7 +273,7 @@ _gcry_cast5_arm_encrypt_block: + */ + push {%r1, %r4-%r11, %ip, %lr}; + +- ldr Rs1, =_gcry_cast5_s1to4; ++ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2); + mov RMASK, #(0xff << 2); + add Rs2, Rs1, #(0x100*4); + add Rs3, Rs1, #(0x100*4*2); +@@ -306,7 +319,7 @@ _gcry_cast5_arm_decrypt_block: + */ + push {%r1, %r4-%r11, %ip, %lr}; + +- ldr Rs1, =_gcry_cast5_s1to4; ++ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2); + mov RMASK, #(0xff << 2); + add Rs2, Rs1, #(0x100 * 4); + add Rs3, Rs1, #(0x100 * 4 * 2); +@@ -500,7 +513,7 @@ _gcry_cast5_arm_enc_blk2: + */ + push {%lr}; + +- ldr Rs1, =_gcry_cast5_s1to4; ++ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2); + mov RMASK, #(0xff << 2); + add Rs2, Rs1, #(0x100 * 4); + +@@ -631,7 +644,7 @@ _gcry_cast5_arm_dec_blk2: + * [RR0, RL0], [RR1, RL1]: dst + */ + +- ldr Rs1, =_gcry_cast5_s1to4; ++ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2); + mov RMASK, #(0xff << 2); + add Rs2, Rs1, #(0x100 * 4); + +diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S +index 22c350c..421c3b4 100644 +--- a/cipher/rijndael-arm.S ++++ b/cipher/rijndael-arm.S +@@ -28,6 +28,19 @@ + .syntax unified + .arm + ++#ifdef __PIC__ ++# define GET_DATA_POINTER(reg, name, rtmp) \ ++ ldr reg, 1f; \ ++ ldr rtmp, 2f; \ ++ b 3f; \ ++ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \ ++ 2: .word name(GOT); \ ++ 3: add reg, pc, reg; \ ++ ldr reg, [reg, rtmp]; ++#else ++# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name ++#endif ++ + /* register macros */ + #define CTX %r0 + #define RTAB %lr +@@ -249,7 +262,7 @@ _gcry_aes_arm_encrypt_block: + 2: + sub %sp, #16; + +- ldr RTAB, =.LtableE0; ++ GET_DATA_POINTER(RTAB, .LtableE0, RMASK); + + str %r1, [%sp, #4]; /* dst */ + mov RMASK, #0xff; +@@ -503,7 +516,7 @@ _gcry_aes_arm_decrypt_block: + 2: + sub %sp, #16; + +- ldr RTAB, =.LtableD0; ++ GET_DATA_POINTER(RTAB, .LtableD0, RMASK); + + mov RMASK, #0xff; + str %r1, [%sp, #4]; /* dst */ diff --git a/libgcrypt.spec b/libgcrypt.spec index 44ba426..ec5b2fa 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.1 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -33,7 +33,7 @@ Patch11: libgcrypt-1.6.1-use-poll.patch Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC Patch14: libgcrypt-1.6.1-ecc-test-fix.patch -Patch15: libgcrypt-1.6.1-disable-non-PIC-arm.patch +Patch15: libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch %define gcrylibdir %{_libdir} @@ -185,6 +185,10 @@ exit 0 %doc COPYING %changelog +* Tue May 20 2014 Kyle McMartin 1.6.1-4 +- Re-enable below algos, apply patch from upstream list to make + that code -fPIC friendly. (rhbz#1069792) + * Mon May 19 2014 Kyle McMartin 1.6.1-3 - Disable rijndael, cast5, camellia ARM assembly, as it's non-PIC as presently written, which results in .text relocations in the shared From 147485e2a2983cfb1d476a58e41bc069bab099ef Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Fri, 6 Jun 2014 22:26:35 -0500 Subject: [PATCH 070/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index ec5b2fa..63ebf34 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.1 -Release: 4%{?dist} +Release: 5%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -185,6 +185,9 @@ exit 0 %doc COPYING %changelog +* Sat Jun 07 2014 Fedora Release Engineering - 1.6.1-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + * Tue May 20 2014 Kyle McMartin 1.6.1-4 - Re-enable below algos, apply patch from upstream list to make that code -fPIC friendly. (rhbz#1069792) From 4b3e9442765830ecc564f07f737e0ccf88398e90 Mon Sep 17 00:00:00 2001 From: Tom Callaway Date: Thu, 17 Jul 2014 14:40:00 -0400 Subject: [PATCH 071/214] fix license handling --- libgcrypt.spec | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 63ebf34..4887098 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.1 -Release: 5%{?dist} +Release: 6%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -168,7 +168,9 @@ exit 0 %dir /etc/gcrypt %{gcrylibdir}/libgcrypt.so.* %{gcrylibdir}/.libgcrypt.so.*.hmac -%doc COPYING.LIB AUTHORS NEWS THANKS +%{!?_licensedir:%global license %%doc} +%license COPYING.LIB +%doc AUTHORS NEWS THANKS %files devel %defattr(-,root,root,-) @@ -182,9 +184,13 @@ exit 0 %{_mandir}/man1/* %{_infodir}/gcrypt.info* -%doc COPYING +%{!?_licensedir:%global license %%doc} +%license COPYING %changelog +* Thu Jul 17 2014 Tom Callaway - 1.6.1-6 +- fix license handling + * Sat Jun 07 2014 Fedora Release Engineering - 1.6.1-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild From c5ea1db092b765c1d636360d0c4015fdea39fd81 Mon Sep 17 00:00:00 2001 From: Tom Callaway Date: Thu, 17 Jul 2014 14:40:23 -0400 Subject: [PATCH 072/214] fix license handling --- libgcrypt.spec | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 63ebf34..4887098 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.1 -Release: 5%{?dist} +Release: 6%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -168,7 +168,9 @@ exit 0 %dir /etc/gcrypt %{gcrylibdir}/libgcrypt.so.* %{gcrylibdir}/.libgcrypt.so.*.hmac -%doc COPYING.LIB AUTHORS NEWS THANKS +%{!?_licensedir:%global license %%doc} +%license COPYING.LIB +%doc AUTHORS NEWS THANKS %files devel %defattr(-,root,root,-) @@ -182,9 +184,13 @@ exit 0 %{_mandir}/man1/* %{_infodir}/gcrypt.info* -%doc COPYING +%{!?_licensedir:%global license %%doc} +%license COPYING %changelog +* Thu Jul 17 2014 Tom Callaway - 1.6.1-6 +- fix license handling + * Sat Jun 07 2014 Fedora Release Engineering - 1.6.1-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild From 7dc558c93fc4a8480f0ab2a8efb462fdeb7ce205 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 17 Aug 2014 03:24:07 +0000 Subject: [PATCH 073/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 4887098..44ad3f8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.1 -Release: 6%{?dist} +Release: 7%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -188,6 +188,9 @@ exit 0 %license COPYING %changelog +* Sun Aug 17 2014 Fedora Release Engineering - 1.6.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + * Thu Jul 17 2014 Tom Callaway - 1.6.1-6 - fix license handling From 892ffb36292942de5cecc7f1847d99f60d233720 Mon Sep 17 00:00:00 2001 From: Peter Robinson Date: Sun, 17 Aug 2014 03:24:18 +0000 Subject: [PATCH 074/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 4887098..44ad3f8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.1 -Release: 6%{?dist} +Release: 7%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -188,6 +188,9 @@ exit 0 %license COPYING %changelog +* Sun Aug 17 2014 Fedora Release Engineering - 1.6.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + * Thu Jul 17 2014 Tom Callaway - 1.6.1-6 - fix license handling From 040c39b7c3527508fe238a794d4f18487ab48f58 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 8 Dec 2014 17:29:08 +0100 Subject: [PATCH 075/214] new upstream version --- .gitignore | 1 + ecc-curves.c | 2 +- ...ypt-1.6.1-make-arm-asm-fPIC-friendly.patch | 167 - libgcrypt-1.6.2-drbg.patch | 2700 +++++++++++++++++ libgcrypt-1.6.2-fips-cavs.patch | 1400 +++++++++ libgcrypt-1.6.2-fips-ctor.patch | 56 + libgcrypt-1.6.2-fips-reqs.patch | 345 +++ libgcrypt-1.6.2-fips-test.patch | 31 + libgcrypt-1.6.2-rsa-fips-keygen.patch | 375 +++ ...tch => libgcrypt-1.6.2-use-fipscheck.patch | 24 +- libgcrypt.spec | 30 +- sources | 2 +- 12 files changed, 4945 insertions(+), 188 deletions(-) delete mode 100644 libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch create mode 100644 libgcrypt-1.6.2-drbg.patch create mode 100644 libgcrypt-1.6.2-fips-cavs.patch create mode 100644 libgcrypt-1.6.2-fips-ctor.patch create mode 100644 libgcrypt-1.6.2-fips-reqs.patch create mode 100644 libgcrypt-1.6.2-fips-test.patch create mode 100644 libgcrypt-1.6.2-rsa-fips-keygen.patch rename libgcrypt-1.5.0-use-fipscheck.patch => libgcrypt-1.6.2-use-fipscheck.patch (71%) diff --git a/.gitignore b/.gitignore index 910f70f..3ea085c 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.5.2-hobbled.tar.xz /libgcrypt-1.5.3-hobbled.tar.xz /libgcrypt-1.6.1-hobbled.tar.xz +/libgcrypt-1.6.2-hobbled.tar.xz diff --git a/ecc-curves.c b/ecc-curves.c index b8679da..ef8ff94 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -889,7 +889,7 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) unsigned char *encpk; unsigned int encpklen; - if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, + if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0, &encpk, &encpklen)) return mpi_set_opaque (NULL, encpk, encpklen*8); } diff --git a/libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch b/libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch deleted file mode 100644 index b49006d..0000000 --- a/libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch +++ /dev/null @@ -1,167 +0,0 @@ -Fix ARM assembly when building __PIC__ - -From: Jussi Kivilinna - -* cipher/camellia-arm.S (GET_DATA_POINTER): New. -(_gcry_camellia_arm_encrypt_block): Use GET_DATA_POINTER. -(_gcry_camellia_arm_decrypt_block): Ditto. -* cipher/cast5-arm.S (GET_DATA_POINTER): New. -(_gcry_cast5_arm_encrypt_block, _gcry_cast5_arm_decrypt_block) -(_gcry_cast5_arm_enc_blk2, _gcry_cast5_arm_dec_blk2): Use -GET_DATA_POINTER. -* cipher/rijndael-arm.S (GET_DATA_POINTER): New. -(_gcry_aes_arm_encrypt_block, _gcry_aes_arm_decrypt_block): Use -GET_DATA_POINTER. --- - -Signed-off-by: Jussi Kivilinna ---- - cipher/camellia-arm.S | 17 +++++++++++++++-- - cipher/cast5-arm.S | 21 +++++++++++++++++---- - cipher/rijndael-arm.S | 17 +++++++++++++++-- - 3 files changed, 47 insertions(+), 8 deletions(-) - -diff --git a/cipher/camellia-arm.S b/cipher/camellia-arm.S -index c30d194..cdeaf8b 100644 ---- a/cipher/camellia-arm.S -+++ b/cipher/camellia-arm.S -@@ -28,6 +28,19 @@ - .syntax unified - .arm - -+#ifdef __PIC__ -+# define GET_DATA_POINTER(reg, name, rtmp) \ -+ ldr reg, 1f; \ -+ ldr rtmp, 2f; \ -+ b 3f; \ -+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \ -+ 2: .word name(GOT); \ -+ 3: add reg, pc, reg; \ -+ ldr reg, [reg, rtmp]; -+#else -+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name -+#endif -+ - /* struct camellia_ctx: */ - #define key_table 0 - -@@ -261,7 +274,7 @@ _gcry_camellia_arm_encrypt_block: - */ - push {%r1, %r4-%r11, %ip, %lr}; - -- ldr RTAB1, =.Lcamellia_sp1110; -+ GET_DATA_POINTER(RTAB1, .Lcamellia_sp1110, RTAB3); - mov RMASK, #0xff; - add RTAB3, RTAB1, #(2 * 4); - push {%r3}; -@@ -309,7 +322,7 @@ _gcry_camellia_arm_decrypt_block: - */ - push {%r1, %r4-%r11, %ip, %lr}; - -- ldr RTAB1, =.Lcamellia_sp1110; -+ GET_DATA_POINTER(RTAB1, .Lcamellia_sp1110, RTAB3); - mov RMASK, #0xff; - add RTAB3, RTAB1, #(2 * 4); - mov RMASK, RMASK, lsl#4 /* byte mask */ -diff --git a/cipher/cast5-arm.S b/cipher/cast5-arm.S -index ce7fa93..db96db4 100644 ---- a/cipher/cast5-arm.S -+++ b/cipher/cast5-arm.S -@@ -30,6 +30,19 @@ - - .extern _gcry_cast5_s1to4; - -+#ifdef __PIC__ -+# define GET_DATA_POINTER(reg, name, rtmp) \ -+ ldr reg, 1f; \ -+ ldr rtmp, 2f; \ -+ b 3f; \ -+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \ -+ 2: .word name(GOT); \ -+ 3: add reg, pc, reg; \ -+ ldr reg, [reg, rtmp]; -+#else -+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name -+#endif -+ - /* structure of crypto context */ - #define Km 0 - #define Kr (Km + (16 * 4)) -@@ -260,7 +273,7 @@ _gcry_cast5_arm_encrypt_block: - */ - push {%r1, %r4-%r11, %ip, %lr}; - -- ldr Rs1, =_gcry_cast5_s1to4; -+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2); - mov RMASK, #(0xff << 2); - add Rs2, Rs1, #(0x100*4); - add Rs3, Rs1, #(0x100*4*2); -@@ -306,7 +319,7 @@ _gcry_cast5_arm_decrypt_block: - */ - push {%r1, %r4-%r11, %ip, %lr}; - -- ldr Rs1, =_gcry_cast5_s1to4; -+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2); - mov RMASK, #(0xff << 2); - add Rs2, Rs1, #(0x100 * 4); - add Rs3, Rs1, #(0x100 * 4 * 2); -@@ -500,7 +513,7 @@ _gcry_cast5_arm_enc_blk2: - */ - push {%lr}; - -- ldr Rs1, =_gcry_cast5_s1to4; -+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2); - mov RMASK, #(0xff << 2); - add Rs2, Rs1, #(0x100 * 4); - -@@ -631,7 +644,7 @@ _gcry_cast5_arm_dec_blk2: - * [RR0, RL0], [RR1, RL1]: dst - */ - -- ldr Rs1, =_gcry_cast5_s1to4; -+ GET_DATA_POINTER(Rs1, _gcry_cast5_s1to4, Rs2); - mov RMASK, #(0xff << 2); - add Rs2, Rs1, #(0x100 * 4); - -diff --git a/cipher/rijndael-arm.S b/cipher/rijndael-arm.S -index 22c350c..421c3b4 100644 ---- a/cipher/rijndael-arm.S -+++ b/cipher/rijndael-arm.S -@@ -28,6 +28,19 @@ - .syntax unified - .arm - -+#ifdef __PIC__ -+# define GET_DATA_POINTER(reg, name, rtmp) \ -+ ldr reg, 1f; \ -+ ldr rtmp, 2f; \ -+ b 3f; \ -+ 1: .word _GLOBAL_OFFSET_TABLE_-(3f+8); \ -+ 2: .word name(GOT); \ -+ 3: add reg, pc, reg; \ -+ ldr reg, [reg, rtmp]; -+#else -+# define GET_DATA_POINTER(reg, name, rtmp) ldr reg, =name -+#endif -+ - /* register macros */ - #define CTX %r0 - #define RTAB %lr -@@ -249,7 +262,7 @@ _gcry_aes_arm_encrypt_block: - 2: - sub %sp, #16; - -- ldr RTAB, =.LtableE0; -+ GET_DATA_POINTER(RTAB, .LtableE0, RMASK); - - str %r1, [%sp, #4]; /* dst */ - mov RMASK, #0xff; -@@ -503,7 +516,7 @@ _gcry_aes_arm_decrypt_block: - 2: - sub %sp, #16; - -- ldr RTAB, =.LtableD0; -+ GET_DATA_POINTER(RTAB, .LtableD0, RMASK); - - mov RMASK, #0xff; - str %r1, [%sp, #4]; /* dst */ diff --git a/libgcrypt-1.6.2-drbg.patch b/libgcrypt-1.6.2-drbg.patch new file mode 100644 index 0000000..7978b32 --- /dev/null +++ b/libgcrypt-1.6.2-drbg.patch @@ -0,0 +1,2700 @@ +diff -up libgcrypt-1.6.2/random/drbg.c.drbg libgcrypt-1.6.2/random/drbg.c +--- libgcrypt-1.6.2/random/drbg.c.drbg 2014-12-08 16:31:33.513992141 +0100 ++++ libgcrypt-1.6.2/random/drbg.c 2014-12-08 16:39:40.799012486 +0100 +@@ -0,0 +1,2335 @@ ++/* ++ * DRBG: Deterministic Random Bits Generator ++ * Based on NIST Recommended DRBG from NIST SP800-90A with the following ++ * properties: ++ * * CTR DRBG with DF with AES-128, AES-192, AES-256 cores ++ * * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores ++ * * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores ++ * * with and without prediction resistance ++ * ++ * Copyright Stephan Mueller , 2014 ++ * ++ * 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, and the entire permission notice in its entirety, ++ * including the disclaimer of warranties. ++ * 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. ++ * 3. The name of the author may not be used to endorse or promote ++ * products derived from this software without specific prior ++ * written permission. ++ * ++ * ALTERNATIVELY, this product may be distributed under the terms of ++ * LGPLv2+, in which case the provisions of the LGPL are ++ * required INSTEAD OF the above restrictions. (This clause is ++ * necessary due to a potential bad interaction between the LGPL and ++ * the restrictions contained in a BSD-style copyright.) ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF ++ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH ++ * DAMAGE. ++ * ++ * ++ * gcry_control GCRYCTL_DRBG_REINIT ++ * ================================ ++ * This control request re-initializes the DRBG completely, i.e. the entire ++ * state of the DRBG is zeroized (with two exceptions listed in ++ * GCRYCTL_DRBG_SET_ENTROPY). ++ * ++ * The control request takes the following values which influences how the DRBG ++ * is re-initialized: ++ * * u32 flags: This variable specifies the DRBG type to be used for the ++ * next initialization. If set to 0, the previous DRBG type is ++ * used for the initialization. The DRBG type is an OR of the ++ * mandatory flags of the requested DRBG strength and DRBG ++ * cipher type. Optionally, the prediction resistance flag ++ * can be ORed into the flags variable. For example: ++ * - CTR-DRBG with AES-128 without prediction resistance: ++ * DRBG_CTRAES128 ++ * - HMAC-DRBG with SHA-512 with prediction resistance: ++ * DRBG_HMACSHA512 | DRBG_PREDICTION_RESIST ++ * * struct gcry_drbg_string *pers: personalization string to be used for ++ * initialization. ++ * The variable of flags is independent from the pers/perslen variables. If ++ * flags is set to 0 and perslen is set to 0, the current DRBG type is ++ * completely reset without using a personalization string. ++ * ++ * DRBG Usage ++ * ========== ++ * The SP 800-90A DRBG allows the user to specify a personalization string ++ * for initialization as well as an additional information string for each ++ * random number request. The following code fragments show how a caller ++ * uses the kernel crypto API to use the full functionality of the DRBG. ++ * ++ * Usage without any additional data ++ * --------------------------------- ++ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); ++ * ++ * ++ * Usage with personalization string during initialization ++ * ------------------------------------------------------- ++ * struct gcry_drbg_string pers; ++ * char personalization[11] = "some-string"; ++ * ++ * gcry_drbg_string_fill(&pers, personalization, strlen(personalization)); ++ * // The reset completely re-initializes the DRBG with the provided ++ * // personalization string without changing the DRBG type ++ * ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, &pers); ++ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); ++ * ++ * ++ * Usage with additional information string during random number request ++ * --------------------------------------------------------------------- ++ * struct gcry_drbg_string addtl; ++ * char addtl_string[11] = "some-string"; ++ * ++ * gcry_drbg_string_fill(&addtl, addtl_string, strlen(addtl_string)); ++ * // The following call is a wrapper to gcry_randomize() and returns ++ * // the same error codes. ++ * gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, &addtl); ++ * ++ * ++ * Usage with personalization and additional information strings ++ * ------------------------------------------------------------- ++ * Just mix both scenarios above. ++ * ++ * ++ * Switch the DRBG type to some other type ++ * --------------------------------------- ++ * // Switch to CTR DRBG AES-128 without prediction resistance ++ * ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_NOPR_CTRAES128, NULL); ++ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "g10lib.h" ++#include "random.h" ++#include "rand-internal.h" ++#include "../cipher/bithelp.h" ++#include "ath.h" ++ ++/****************************************************************** ++ * Common data structures ++ ******************************************************************/ ++ ++struct gcry_drbg_state; ++ ++struct gcry_drbg_core ++{ ++ u32 flags; /* flags for the cipher */ ++ ushort statelen; /* maximum state length */ ++ ushort blocklen_bytes; /* block size of output in bytes */ ++ int backend_cipher; /* libgcrypt backend cipher */ ++}; ++ ++struct gcry_drbg_state_ops ++{ ++ gpg_err_code_t (*update) (struct gcry_drbg_state * drbg, ++ struct gcry_drbg_string * seed, int reseed); ++ gpg_err_code_t (*generate) (struct gcry_drbg_state * drbg, ++ unsigned char *buf, unsigned int buflen, ++ struct gcry_drbg_string * addtl); ++}; ++ ++/* DRBG test data */ ++struct gcry_drbg_test_data ++{ ++ struct gcry_drbg_string *testentropy; /* TEST PARAMETER: test entropy */ ++ int fail_seed_source:1; /* if set, the seed function will return an error */ ++}; ++ ++ ++struct gcry_drbg_state ++{ ++ unsigned char *V; /* internal state 10.1.1.1 1a) */ ++ unsigned char *C; /* hash: static value 10.1.1.1 1b) ++ * hmac / ctr: key */ ++ size_t reseed_ctr; /* Number of RNG requests since last reseed -- ++ * 10.1.1.1 1c) */ ++ unsigned char *scratchpad; /* some memory the DRBG can use for its ++ * operation -- allocated during init */ ++ int seeded:1; /* DRBG fully seeded? */ ++ int pr:1; /* Prediction resistance enabled? */ ++ int fips_primed:1; /* Continuous test primed? */ ++ unsigned char *prev; /* previous output value of gcry_drbg_blocklen ++ * for FIPS 140-2 continuous test */ ++ /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the ++ * process which did the initialization so that we can detect a fork. ++ * The volatile modifier is required so that the compiler does not ++ * optimize it away in case the getpid function is badly attributed. */ ++ pid_t seed_init_pid; ++ const struct gcry_drbg_state_ops *d_ops; ++ const struct gcry_drbg_core *core; ++ struct gcry_drbg_test_data *test_data; ++}; ++ ++enum gcry_drbg_prefixes ++{ ++ DRBG_PREFIX0 = 0x00, ++ DRBG_PREFIX1, ++ DRBG_PREFIX2, ++ DRBG_PREFIX3 ++}; ++ ++#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) ++ ++/*************************************************************** ++ * Backend cipher definitions available to DRBG ++ ***************************************************************/ ++ ++static const struct gcry_drbg_core gcry_drbg_cores[] = { ++ /* Hash DRBGs */ ++ {GCRY_DRBG_HASHSHA1, 55, 20, GCRY_MD_SHA1}, ++ {GCRY_DRBG_HASHSHA256, 55, 32, GCRY_MD_SHA256}, ++ {GCRY_DRBG_HASHSHA384, 111, 48, GCRY_MD_SHA384}, ++ {GCRY_DRBG_HASHSHA512, 111, 64, GCRY_MD_SHA512}, ++ /* HMAC DRBGs */ ++ {GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC, 20, 20, GCRY_MD_SHA1}, ++ {GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC, 32, 32, GCRY_MD_SHA256}, ++ {GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC, 48, 48, GCRY_MD_SHA384}, ++ {GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC, 64, 64, GCRY_MD_SHA512}, ++ /* block ciphers */ ++ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128, 32, 16, GCRY_CIPHER_AES128}, ++ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192, 40, 16, GCRY_CIPHER_AES192}, ++ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256, 48, 16, GCRY_CIPHER_AES256}, ++}; ++ ++static gpg_err_code_t gcry_drbg_sym (struct gcry_drbg_state *drbg, ++ const unsigned char *key, ++ unsigned char *outval, ++ const struct gcry_drbg_string *buf); ++static gpg_err_code_t gcry_drbg_hmac (struct gcry_drbg_state *drbg, ++ const unsigned char *key, ++ unsigned char *outval, ++ const struct gcry_drbg_string *buf); ++ ++/****************************************************************** ++ ****************************************************************** ++ ****************************************************************** ++ * Generic DRBG code ++ ****************************************************************** ++ ****************************************************************** ++ ******************************************************************/ ++ ++/****************************************************************** ++ * Generic helper functions ++ ******************************************************************/ ++ ++#if 0 ++#define dbg(x) do { log_debug x; } while(0) ++#else ++#define dbg(x) ++#endif ++ ++static inline ushort ++gcry_drbg_statelen (struct gcry_drbg_state *drbg) ++{ ++ if (drbg && drbg->core) ++ return drbg->core->statelen; ++ return 0; ++} ++ ++static inline ushort ++gcry_drbg_blocklen (struct gcry_drbg_state *drbg) ++{ ++ if (drbg && drbg->core) ++ return drbg->core->blocklen_bytes; ++ return 0; ++} ++ ++static inline ushort ++gcry_drbg_keylen (struct gcry_drbg_state *drbg) ++{ ++ if (drbg && drbg->core) ++ return (drbg->core->statelen - drbg->core->blocklen_bytes); ++ return 0; ++} ++ ++static inline size_t ++gcry_drbg_max_request_bytes (void) ++{ ++ /* SP800-90A requires the limit 2**19 bits, but we return bytes */ ++ return (1 << 16); ++} ++ ++static inline size_t ++gcry_drbg_max_addtl (void) ++{ ++ /* SP800-90A requires 2**35 bytes additional info str / pers str */ ++#ifdef __LP64__ ++ return (1UL << 35); ++#else ++ /* ++ * SP800-90A allows smaller maximum numbers to be returned -- we ++ * return SIZE_MAX - 1 to allow the verification of the enforcement ++ * of this value in gcry_drbg_healthcheck_sanity. ++ */ ++ return (SIZE_MAX - 1); ++#endif ++} ++ ++static inline size_t ++gcry_drbg_max_requests (void) ++{ ++ /* SP800-90A requires 2**48 maximum requests before reseeding */ ++#ifdef __LP64__ ++ return (1UL << 48); ++#else ++ return SIZE_MAX; ++#endif ++} ++ ++/* ++ * Return strength of DRBG according to SP800-90A section 8.4 ++ * ++ * flags: DRBG flags reference ++ * ++ * Return: normalized strength value or 32 as a default to counter ++ * programming errors ++ */ ++static inline unsigned short ++gcry_drbg_sec_strength (u32 flags) ++{ ++ if ((flags & GCRY_DRBG_HASHSHA1) || (flags & GCRY_DRBG_SYM128)) ++ return 16; ++ else if (flags & GCRY_DRBG_SYM192) ++ return 24; ++ else if ((flags & GCRY_DRBG_SYM256) || (flags & GCRY_DRBG_HASHSHA256) || ++ (flags & GCRY_DRBG_HASHSHA384) || (flags & GCRY_DRBG_HASHSHA512)) ++ return 32; ++ else ++ return 32; ++} ++ ++/* ++ * FIPS 140-2 continuous self test ++ * The test is performed on the result of one round of the output ++ * function. Thus, the function implicitly knows the size of the ++ * buffer. ++ * ++ * @drbg DRBG handle ++ * @buf output buffer of random data to be checked ++ * ++ * return: ++ * false on error ++ * true on success ++ */ ++static gpg_err_code_t ++gcry_drbg_fips_continuous_test (struct gcry_drbg_state *drbg, ++ const unsigned char *buf) ++{ ++ gpg_err_code_t ret = 0; ++ /* skip test if we test the overall system */ ++ if (drbg->test_data) ++ return 1; ++ /* only perform test in FIPS mode */ ++ if (0 == fips_mode ()) ++ return 1; ++ if (!drbg->fips_primed) ++ { ++ /* Priming of FIPS test */ ++ memcpy (drbg->prev, buf, gcry_drbg_blocklen (drbg)); ++ drbg->fips_primed = 1; ++ /* return false due to priming, i.e. another round is needed */ ++ return 0; ++ } ++ ret = memcmp (drbg->prev, buf, gcry_drbg_blocklen (drbg)); ++ memcpy (drbg->prev, buf, gcry_drbg_blocklen (drbg)); ++ /* the test shall pass when the two compared values are not equal */ ++ if (ret == 0) ++ fips_signal_error ("duplicate block returned by DRBG"); ++ ++ return ret != 0; ++} ++ ++/* ++ * Convert an integer into a byte representation of this integer. ++ * The byte representation is big-endian ++ * ++ * @val value to be converted ++ * @buf buffer holding the converted integer -- caller must ensure that ++ * buffer size is at least 32 bit ++ */ ++static inline void ++gcry_drbg_cpu_to_be32 (u32 val, unsigned char *buf) ++{ ++ struct s ++ { ++ u32 conv; ++ }; ++ struct s *conversion = (struct s *) buf; ++ ++ conversion->conv = be_bswap32 (val); ++} ++ ++static void ++gcry_drbg_add_buf (unsigned char *dst, size_t dstlen, ++ unsigned char *add, size_t addlen) ++{ ++ /* implied: dstlen > addlen */ ++ unsigned char *dstptr, *addptr; ++ unsigned int remainder = 0; ++ size_t len = addlen; ++ ++ dstptr = dst + (dstlen - 1); ++ addptr = add + (addlen - 1); ++ while (len) ++ { ++ remainder += *dstptr + *addptr; ++ *dstptr = remainder & 0xff; ++ remainder >>= 8; ++ len--; ++ dstptr--; ++ addptr--; ++ } ++ len = dstlen - addlen; ++ while (len && remainder > 0) ++ { ++ remainder = *dstptr + 1; ++ *dstptr = remainder & 0xff; ++ remainder >>= 8; ++ len--; ++ dstptr--; ++ } ++} ++ ++/* Helper variables for read_cb(). ++ * ++ * The _gcry_rnd*_gather_random interface does not allow to provide a ++ * data pointer. Thus we need to use a global variable for ++ * communication. However, the then required locking is anyway a good ++ * idea because it does not make sense to have several readers of (say ++ * /dev/random). It is easier to serve them one after the other. */ ++static unsigned char *read_cb_buffer; /* The buffer. */ ++static size_t read_cb_size; /* Size of the buffer. */ ++static size_t read_cb_len; /* Used length. */ ++ ++/* Callback for generating seed from kernel device. */ ++static void ++gcry_drbg_read_cb (const void *buffer, size_t length, ++ enum random_origins origin) ++{ ++ const unsigned char *p = buffer; ++ ++ (void) origin; ++ gcry_assert (read_cb_buffer); ++ ++ /* Note that we need to protect against gatherers returning more ++ * than the requested bytes (e.g. rndw32). */ ++ while (length-- && read_cb_len < read_cb_size) ++ read_cb_buffer[read_cb_len++] = *p++; ++} ++ ++static inline int ++gcry_drbg_get_entropy (struct gcry_drbg_state *drbg, unsigned char *buffer, ++ size_t len) ++{ ++ int rc = 0; ++ ++ /* Perform testing as defined in 11.3.2 */ ++ if (drbg->test_data && drbg->test_data->fail_seed_source) ++ return -1; ++ ++ read_cb_buffer = buffer; ++ read_cb_size = len; ++ read_cb_len = 0; ++#if USE_RNDLINUX ++ _gcry_rndlinux_gather_random (gcry_drbg_read_cb, 0, len, ++ -1); ++ read_cb_len = 0; ++ rc = _gcry_rndlinux_gather_random (gcry_drbg_read_cb, 0, len, ++ GCRY_STRONG_RANDOM); ++#elif USE_RNDUNIX ++ rc = _gcry_rndunix_gather_random (read_cb, 0, length, ++ GCRY_VERY_STRONG_RANDOM); ++#elif USE_RNDW32 ++ do ++ { ++ rc = _gcry_rndw32_gather_random (read_cb, 0, length, ++ GCRY_VERY_STRONG_RANDOM); ++ } ++ while (rc >= 0 && read_cb_len < read_cb_size); ++#else ++ rc = -1; ++#endif ++ return rc; ++} ++ ++/****************************************************************** ++ * CTR DRBG callback functions ++ ******************************************************************/ ++ ++/* BCC function for CTR DRBG as defined in 10.4.3 */ ++static gpg_err_code_t ++gcry_drbg_ctr_bcc (struct gcry_drbg_state *drbg, ++ unsigned char *out, const unsigned char *key, ++ struct gcry_drbg_string *in) ++{ ++ gpg_err_code_t ret = GPG_ERR_GENERAL; ++ struct gcry_drbg_string *curr = in; ++ size_t inpos = curr->len; ++ const unsigned char *pos = curr->buf; ++ struct gcry_drbg_string data; ++ ++ gcry_drbg_string_fill (&data, out, gcry_drbg_blocklen (drbg)); ++ ++ /* 10.4.3 step 1 */ ++ memset (out, 0, gcry_drbg_blocklen (drbg)); ++ ++ /* 10.4.3 step 2 / 4 */ ++ while (inpos) ++ { ++ short cnt = 0; ++ /* 10.4.3 step 4.1 */ ++ for (cnt = 0; cnt < gcry_drbg_blocklen (drbg); cnt++) ++ { ++ out[cnt] ^= *pos; ++ pos++; ++ inpos--; ++ /* the following branch implements the linked list ++ * iteration. If we are at the end of the current data ++ * set, we have to start using the next data set if ++ * available -- the inpos value always points to the ++ * current byte and will be zero if we have processed ++ * the last byte of the last linked list member */ ++ if (0 == inpos) ++ { ++ curr = curr->next; ++ if (NULL != curr) ++ { ++ pos = curr->buf; ++ inpos = curr->len; ++ } ++ else ++ { ++ inpos = 0; ++ break; ++ } ++ } ++ } ++ /* 10.4.3 step 4.2 */ ++ ret = gcry_drbg_sym (drbg, key, out, &data); ++ if (ret) ++ return ret; ++ /* 10.4.3 step 2 */ ++ } ++ return 0; ++} ++ ++ ++/* ++ * scratchpad usage: gcry_drbg_ctr_update is interlinked with gcry_drbg_ctr_df ++ * (and gcry_drbg_ctr_bcc, but this function does not need any temporary buffers), ++ * the scratchpad is used as follows: ++ * gcry_drbg_ctr_update: ++ * temp ++ * start: drbg->scratchpad ++ * length: gcry_drbg_statelen(drbg) + gcry_drbg_blocklen(drbg) ++ * note: the cipher writing into this variable works ++ * blocklen-wise. Now, when the statelen is not a multiple ++ * of blocklen, the generateion loop below "spills over" ++ * by at most blocklen. Thus, we need to give sufficient ++ * memory. ++ * df_data ++ * start: drbg->scratchpad + ++ * gcry_drbg_statelen(drbg) + ++ * gcry_drbg_blocklen(drbg) ++ * length: gcry_drbg_statelen(drbg) ++ * ++ * gcry_drbg_ctr_df: ++ * pad ++ * start: df_data + gcry_drbg_statelen(drbg) ++ * length: gcry_drbg_blocklen(drbg) ++ * iv ++ * start: pad + gcry_drbg_blocklen(drbg) ++ * length: gcry_drbg_blocklen(drbg) ++ * temp ++ * start: iv + gcry_drbg_blocklen(drbg) ++ * length: gcry_drbg_satelen(drbg) + gcry_drbg_blocklen(drbg) ++ * note: temp is the buffer that the BCC function operates ++ * on. BCC operates blockwise. gcry_drbg_statelen(drbg) ++ * is sufficient when the DRBG state length is a multiple ++ * of the block size. For AES192 (and maybe other ciphers) ++ * this is not correct and the length for temp is ++ * insufficient (yes, that also means for such ciphers, ++ * the final output of all BCC rounds are truncated). ++ * Therefore, add gcry_drbg_blocklen(drbg) to cover all ++ * possibilities. ++ */ ++ ++/* Derivation Function for CTR DRBG as defined in 10.4.2 */ ++static gpg_err_code_t ++gcry_drbg_ctr_df (struct gcry_drbg_state *drbg, unsigned char *df_data, ++ size_t bytes_to_return, struct gcry_drbg_string *addtl) ++{ ++ gpg_err_code_t ret = GPG_ERR_GENERAL; ++ unsigned char L_N[8]; ++ /* S3 is input */ ++ struct gcry_drbg_string S1, S2, S4, cipherin; ++ struct gcry_drbg_string *tempstr = addtl; ++ unsigned char *pad = df_data + gcry_drbg_statelen (drbg); ++ unsigned char *iv = pad + gcry_drbg_blocklen (drbg); ++ unsigned char *temp = iv + gcry_drbg_blocklen (drbg); ++ size_t padlen = 0; ++ unsigned int templen = 0; ++ /* 10.4.2 step 7 */ ++ unsigned int i = 0; ++ /* 10.4.2 step 8 */ ++ const unsigned char *K = (unsigned char *) ++ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" ++ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; ++ unsigned char *X; ++ size_t generated_len = 0; ++ size_t inputlen = 0; ++ ++ memset (pad, 0, gcry_drbg_blocklen (drbg)); ++ memset (iv, 0, gcry_drbg_blocklen (drbg)); ++ memset (temp, 0, gcry_drbg_statelen (drbg)); ++ ++ /* 10.4.2 step 1 is implicit as we work byte-wise */ ++ ++ /* 10.4.2 step 2 */ ++ if ((512 / 8) < bytes_to_return) ++ return GPG_ERR_INV_ARG; ++ ++ /* 10.4.2 step 2 -- calculate the entire length of all input data */ ++ for (; NULL != tempstr; tempstr = tempstr->next) ++ inputlen += tempstr->len; ++ gcry_drbg_cpu_to_be32 (inputlen, &L_N[0]); ++ ++ /* 10.4.2 step 3 */ ++ gcry_drbg_cpu_to_be32 (bytes_to_return, &L_N[4]); ++ ++ /* 10.4.2 step 5: length is size of L_N, input_string, one byte, padding */ ++ padlen = (inputlen + sizeof (L_N) + 1) % (gcry_drbg_blocklen (drbg)); ++ /* wrap the padlen appropriately */ ++ if (padlen) ++ padlen = gcry_drbg_blocklen (drbg) - padlen; ++ /* pad / padlen contains the 0x80 byte and the following zero bytes, so ++ * add one for byte for 0x80 */ ++ padlen++; ++ pad[0] = 0x80; ++ ++ /* 10.4.2 step 4 -- first fill the linked list and then order it */ ++ gcry_drbg_string_fill (&S1, iv, gcry_drbg_blocklen (drbg)); ++ gcry_drbg_string_fill (&S2, L_N, sizeof (L_N)); ++ gcry_drbg_string_fill (&S4, pad, padlen); ++ S1.next = &S2; ++ S2.next = addtl; ++ ++ /* Splice in addtl between S2 and S4 -- we place S4 at the end of the ++ * input data chain. As this code is only triggered when addtl is not ++ * NULL, no NULL checks are necessary.*/ ++ tempstr = addtl; ++ while (tempstr->next) ++ tempstr = tempstr->next; ++ tempstr->next = &S4; ++ ++ /* 10.4.2 step 9 */ ++ while (templen < (gcry_drbg_keylen (drbg) + (gcry_drbg_blocklen (drbg)))) ++ { ++ /* 10.4.2 step 9.1 - the padding is implicit as the buffer ++ * holds zeros after allocation -- even the increment of i ++ * is irrelevant as the increment remains within length of i */ ++ gcry_drbg_cpu_to_be32 (i, iv); ++ /* 10.4.2 step 9.2 -- BCC and concatenation with temp */ ++ ret = gcry_drbg_ctr_bcc (drbg, temp + templen, K, &S1); ++ if (ret) ++ goto out; ++ /* 10.4.2 step 9.3 */ ++ i++; ++ templen += gcry_drbg_blocklen (drbg); ++ } ++ ++ /* 10.4.2 step 11 */ ++ /* implicit key len with seedlen - blocklen according to table 3 */ ++ X = temp + (gcry_drbg_keylen (drbg)); ++ gcry_drbg_string_fill (&cipherin, X, gcry_drbg_blocklen (drbg)); ++ ++ /* 10.4.2 step 12: overwriting of outval */ ++ ++ /* 10.4.2 step 13 */ ++ while (generated_len < bytes_to_return) ++ { ++ short blocklen = 0; ++ /* 10.4.2 step 13.1 */ ++ /* the truncation of the key length is implicit as the key ++ * is only gcry_drbg_blocklen in size -- check for the implementation ++ * of the cipher function callback */ ++ ret = gcry_drbg_sym (drbg, temp, X, &cipherin); ++ if (ret) ++ goto out; ++ blocklen = (gcry_drbg_blocklen (drbg) < ++ (bytes_to_return - generated_len)) ? ++ gcry_drbg_blocklen (drbg) : (bytes_to_return - generated_len); ++ /* 10.4.2 step 13.2 and 14 */ ++ memcpy (df_data + generated_len, X, blocklen); ++ generated_len += blocklen; ++ } ++ ++ ret = 0; ++ ++out: ++ memset (iv, 0, gcry_drbg_blocklen (drbg)); ++ memset (temp, 0, gcry_drbg_statelen (drbg)); ++ memset (pad, 0, gcry_drbg_blocklen (drbg)); ++ return ret; ++} ++ ++/* ++ * update function of CTR DRBG as defined in 10.2.1.2 ++ * ++ * The reseed variable has an enhanced meaning compared to the update ++ * functions of the other DRBGs as follows: ++ * 0 => initial seed from initialization ++ * 1 => reseed via gcry_drbg_seed ++ * 2 => first invocation from gcry_drbg_ctr_update when addtl is present. In ++ * this case, the df_data scratchpad is not deleted so that it is ++ * available for another calls to prevent calling the DF function ++ * again. ++ * 3 => second invocation from gcry_drbg_ctr_update. When the update function ++ * was called with addtl, the df_data memory already contains the ++ * DFed addtl information and we do not need to call DF again. ++ */ ++static gpg_err_code_t ++gcry_drbg_ctr_update (struct gcry_drbg_state *drbg, ++ struct gcry_drbg_string *addtl, int reseed) ++{ ++ gpg_err_code_t ret = GPG_ERR_GENERAL; ++ /* 10.2.1.2 step 1 */ ++ unsigned char *temp = drbg->scratchpad; ++ unsigned char *df_data = drbg->scratchpad + ++ gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); ++ unsigned char *temp_p, *df_data_p; /* pointer to iterate over buffers */ ++ unsigned int len = 0; ++ struct gcry_drbg_string cipherin; ++ unsigned char prefix = DRBG_PREFIX1; ++ ++ memset (temp, 0, gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg)); ++ if (3 > reseed) ++ memset (df_data, 0, gcry_drbg_statelen (drbg)); ++ ++ /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ ++ /* TODO use reseed variable to avoid re-doing DF operation */ ++ (void) reseed; ++ if (addtl && 0 < addtl->len) ++ { ++ ret = ++ gcry_drbg_ctr_df (drbg, df_data, gcry_drbg_statelen (drbg), addtl); ++ if (ret) ++ goto out; ++ } ++ ++ gcry_drbg_string_fill (&cipherin, drbg->V, gcry_drbg_blocklen (drbg)); ++ /* 10.2.1.3.2 step 2 and 3 -- are already covered as we memset(0) ++ * all memory during initialization */ ++ while (len < (gcry_drbg_statelen (drbg))) ++ { ++ /* 10.2.1.2 step 2.1 */ ++ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); ++ /* 10.2.1.2 step 2.2 */ ++ /* using target of temp + len: 10.2.1.2 step 2.3 and 3 */ ++ ret = gcry_drbg_sym (drbg, drbg->C, temp + len, &cipherin); ++ if (ret) ++ goto out; ++ /* 10.2.1.2 step 2.3 and 3 */ ++ len += gcry_drbg_blocklen (drbg); ++ } ++ ++ /* 10.2.1.2 step 4 */ ++ temp_p = temp; ++ df_data_p = df_data; ++ for (len = 0; len < gcry_drbg_statelen (drbg); len++) ++ { ++ *temp_p ^= *df_data_p; ++ df_data_p++; ++ temp_p++; ++ } ++ ++ /* 10.2.1.2 step 5 */ ++ memcpy (drbg->C, temp, gcry_drbg_keylen (drbg)); ++ /* 10.2.1.2 step 6 */ ++ memcpy (drbg->V, temp + gcry_drbg_keylen (drbg), gcry_drbg_blocklen (drbg)); ++ ret = 0; ++ ++out: ++ memset (temp, 0, gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg)); ++ if (2 != reseed) ++ memset (df_data, 0, gcry_drbg_statelen (drbg)); ++ return ret; ++} ++ ++/* ++ * scratchpad use: gcry_drbg_ctr_update is called independently from ++ * gcry_drbg_ctr_extract_bytes. Therefore, the scratchpad is reused ++ */ ++/* Generate function of CTR DRBG as defined in 10.2.1.5.2 */ ++static gpg_err_code_t ++gcry_drbg_ctr_generate (struct gcry_drbg_state *drbg, ++ unsigned char *buf, unsigned int buflen, ++ struct gcry_drbg_string *addtl) ++{ ++ gpg_err_code_t ret = 0; ++ unsigned int len = 0; ++ struct gcry_drbg_string data; ++ unsigned char prefix = DRBG_PREFIX1; ++ ++ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); ++ ++ /* 10.2.1.5.2 step 2 */ ++ if (addtl && 0 < addtl->len) ++ { ++ addtl->next = NULL; ++ ret = gcry_drbg_ctr_update (drbg, addtl, 2); ++ if (ret) ++ return ret; ++ } ++ ++ /* 10.2.1.5.2 step 4.1 */ ++ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); ++ gcry_drbg_string_fill (&data, drbg->V, gcry_drbg_blocklen (drbg)); ++ while (len < buflen) ++ { ++ unsigned int outlen = 0; ++ /* 10.2.1.5.2 step 4.2 */ ++ ret = gcry_drbg_sym (drbg, drbg->C, drbg->scratchpad, &data); ++ if (ret) ++ goto out; ++ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? ++ gcry_drbg_blocklen (drbg) : (buflen - len); ++ if (!gcry_drbg_fips_continuous_test (drbg, drbg->scratchpad)) ++ { ++ /* 10.2.1.5.2 step 6 */ ++ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); ++ continue; ++ } ++ /* 10.2.1.5.2 step 4.3 */ ++ memcpy (buf + len, drbg->scratchpad, outlen); ++ len += outlen; ++ /* 10.2.1.5.2 step 6 */ ++ if (len < buflen) ++ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); ++ } ++ ++ /* 10.2.1.5.2 step 6 */ ++ if (addtl) ++ addtl->next = NULL; ++ ret = gcry_drbg_ctr_update (drbg, addtl, 3); ++ ++out: ++ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); ++ return ret; ++} ++ ++static struct gcry_drbg_state_ops gcry_drbg_ctr_ops = { ++ gcry_drbg_ctr_update, ++ gcry_drbg_ctr_generate, ++}; ++ ++/****************************************************************** ++ * HMAC DRBG callback functions ++ ******************************************************************/ ++ ++static gpg_err_code_t ++gcry_drbg_hmac_update (struct gcry_drbg_state *drbg, ++ struct gcry_drbg_string *seed, int reseed) ++{ ++ gpg_err_code_t ret = GPG_ERR_GENERAL; ++ int i = 0; ++ struct gcry_drbg_string seed1, seed2, cipherin; ++ ++ if (!reseed) ++ /* 10.1.2.3 step 2 already implicitly covered with ++ * the initial memset(0) of drbg->C */ ++ memset (drbg->V, 1, gcry_drbg_statelen (drbg)); ++ ++ /* build linked list which implements the concatenation and fill ++ * first part*/ ++ gcry_drbg_string_fill (&seed1, drbg->V, gcry_drbg_statelen (drbg)); ++ /* buffer will be filled in for loop below with one byte */ ++ gcry_drbg_string_fill (&seed2, NULL, 1); ++ seed1.next = &seed2; ++ /* seed may be NULL */ ++ seed2.next = seed; ++ ++ gcry_drbg_string_fill (&cipherin, drbg->V, gcry_drbg_statelen (drbg)); ++ /* we execute two rounds of V/K massaging */ ++ for (i = 2; 0 < i; i--) ++ { ++ /* first round uses 0x0, second 0x1 */ ++ unsigned char prefix = DRBG_PREFIX0; ++ if (1 == i) ++ prefix = DRBG_PREFIX1; ++ /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */ ++ seed2.buf = &prefix; ++ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->C, &seed1); ++ if (ret) ++ return ret; ++ ++ /* 10.1.2.2 step 2 and 5 -- HMAC for V */ ++ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->V, &cipherin); ++ if (ret) ++ return ret; ++ ++ /* 10.1.2.2 step 3 */ ++ if (!seed || 0 == seed->len) ++ return ret; ++ } ++ return 0; ++} ++ ++/* generate function of HMAC DRBG as defined in 10.1.2.5 */ ++static gpg_err_code_t ++gcry_drbg_hmac_generate (struct gcry_drbg_state *drbg, ++ unsigned char *buf, ++ unsigned int buflen, struct gcry_drbg_string *addtl) ++{ ++ gpg_err_code_t ret = 0; ++ unsigned int len = 0; ++ struct gcry_drbg_string data; ++ ++ /* 10.1.2.5 step 2 */ ++ if (addtl && 0 < addtl->len) ++ { ++ addtl->next = NULL; ++ ret = gcry_drbg_hmac_update (drbg, addtl, 1); ++ if (ret) ++ return ret; ++ } ++ ++ gcry_drbg_string_fill (&data, drbg->V, gcry_drbg_statelen (drbg)); ++ while (len < buflen) ++ { ++ unsigned int outlen = 0; ++ /* 10.1.2.5 step 4.1 */ ++ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->V, &data); ++ if (ret) ++ return ret; ++ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? ++ gcry_drbg_blocklen (drbg) : (buflen - len); ++ if (!gcry_drbg_fips_continuous_test (drbg, drbg->V)) ++ continue; ++ ++ /* 10.1.2.5 step 4.2 */ ++ memcpy (buf + len, drbg->V, outlen); ++ len += outlen; ++ } ++ ++ /* 10.1.2.5 step 6 */ ++ if (addtl) ++ addtl->next = NULL; ++ ret = gcry_drbg_hmac_update (drbg, addtl, 1); ++ ++ return ret; ++} ++ ++static struct gcry_drbg_state_ops gcry_drbg_hmac_ops = { ++ gcry_drbg_hmac_update, ++ gcry_drbg_hmac_generate, ++}; ++ ++/****************************************************************** ++ * Hash DRBG callback functions ++ ******************************************************************/ ++ ++/* ++ * scratchpad usage: as gcry_drbg_hash_update and gcry_drbg_hash_df are used ++ * interlinked, the scratchpad is used as follows: ++ * gcry_drbg_hash_update ++ * start: drbg->scratchpad ++ * length: gcry_drbg_statelen(drbg) ++ * gcry_drbg_hash_df: ++ * start: drbg->scratchpad + gcry_drbg_statelen(drbg) ++ * length: gcry_drbg_blocklen(drbg) ++ */ ++/* Derivation Function for Hash DRBG as defined in 10.4.1 */ ++static gpg_err_code_t ++gcry_drbg_hash_df (struct gcry_drbg_state *drbg, ++ unsigned char *outval, size_t outlen, ++ struct gcry_drbg_string *entropy) ++{ ++ gpg_err_code_t ret = 0; ++ size_t len = 0; ++ unsigned char input[5]; ++ unsigned char *tmp = drbg->scratchpad + gcry_drbg_statelen (drbg); ++ struct gcry_drbg_string data1; ++ ++ memset (tmp, 0, gcry_drbg_blocklen (drbg)); ++ ++ /* 10.4.1 step 3 */ ++ input[0] = 1; ++ gcry_drbg_cpu_to_be32 ((outlen * 8), &input[1]); ++ ++ /* 10.4.1 step 4.1 -- concatenation of data for input into hash */ ++ gcry_drbg_string_fill (&data1, input, 5); ++ data1.next = entropy; ++ ++ /* 10.4.1 step 4 */ ++ while (len < outlen) ++ { ++ short blocklen = 0; ++ /* 10.4.1 step 4.1 */ ++ ret = gcry_drbg_hmac (drbg, NULL, tmp, &data1); ++ if (ret) ++ goto out; ++ /* 10.4.1 step 4.2 */ ++ input[0]++; ++ blocklen = (gcry_drbg_blocklen (drbg) < (outlen - len)) ? ++ gcry_drbg_blocklen (drbg) : (outlen - len); ++ memcpy (outval + len, tmp, blocklen); ++ len += blocklen; ++ } ++ ++out: ++ memset (tmp, 0, gcry_drbg_blocklen (drbg)); ++ return ret; ++} ++ ++/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */ ++static gpg_err_code_t ++gcry_drbg_hash_update (struct gcry_drbg_state *drbg, ++ struct gcry_drbg_string *seed, int reseed) ++{ ++ gpg_err_code_t ret = 0; ++ struct gcry_drbg_string data1, data2; ++ unsigned char *V = drbg->scratchpad; ++ unsigned char prefix = DRBG_PREFIX1; ++ ++ memset (drbg->scratchpad, 0, gcry_drbg_statelen (drbg)); ++ if (!seed) ++ return GPG_ERR_INV_ARG; ++ ++ if (reseed) ++ { ++ /* 10.1.1.3 step 1: string length is concatenation of ++ * 1 byte, V and seed (which is concatenated entropy/addtl ++ * input) ++ */ ++ memcpy (V, drbg->V, gcry_drbg_statelen (drbg)); ++ gcry_drbg_string_fill (&data1, &prefix, 1); ++ gcry_drbg_string_fill (&data2, V, gcry_drbg_statelen (drbg)); ++ data1.next = &data2; ++ data2.next = seed; ++ } ++ else ++ { ++ gcry_drbg_string_fill (&data1, seed->buf, seed->len); ++ data1.next = seed->next; ++ } ++ ++ /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */ ++ ret = gcry_drbg_hash_df (drbg, drbg->V, gcry_drbg_statelen (drbg), &data1); ++ if (ret) ++ goto out; ++ ++ /* 10.1.1.2 / 10.1.1.3 step 4 -- concatenation */ ++ prefix = DRBG_PREFIX0; ++ gcry_drbg_string_fill (&data1, &prefix, 1); ++ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); ++ data1.next = &data2; ++ /* 10.1.1.2 / 10.1.1.3 step 4 -- df operation */ ++ ret = gcry_drbg_hash_df (drbg, drbg->C, gcry_drbg_statelen (drbg), &data1); ++ ++out: ++ memset (drbg->scratchpad, 0, gcry_drbg_statelen (drbg)); ++ return ret; ++} ++ ++/* processing of additional information string for Hash DRBG */ ++static gpg_err_code_t ++gcry_drbg_hash_process_addtl (struct gcry_drbg_state *drbg, ++ struct gcry_drbg_string *addtl) ++{ ++ gpg_err_code_t ret = 0; ++ struct gcry_drbg_string data1, data2; ++ struct gcry_drbg_string *data3; ++ unsigned char prefix = DRBG_PREFIX2; ++ ++ /* this is value w as per documentation */ ++ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); ++ ++ /* 10.1.1.4 step 2 */ ++ if (!addtl || 0 == addtl->len) ++ return 0; ++ ++ /* 10.1.1.4 step 2a -- concatenation */ ++ gcry_drbg_string_fill (&data1, &prefix, 1); ++ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); ++ data3 = addtl; ++ data1.next = &data2; ++ data2.next = data3; ++ data3->next = NULL; ++ /* 10.1.1.4 step 2a -- cipher invocation */ ++ ret = gcry_drbg_hmac (drbg, NULL, drbg->scratchpad, &data1); ++ if (ret) ++ goto out; ++ ++ /* 10.1.1.4 step 2b */ ++ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), ++ drbg->scratchpad, gcry_drbg_blocklen (drbg)); ++ ++out: ++ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); ++ return ret; ++} ++ ++/* ++ * Hashgen defined in 10.1.1.4 ++ */ ++static gpg_err_code_t ++gcry_drbg_hash_hashgen (struct gcry_drbg_state *drbg, ++ unsigned char *buf, unsigned int buflen) ++{ ++ gpg_err_code_t ret = 0; ++ unsigned int len = 0; ++ unsigned char *src = drbg->scratchpad; ++ unsigned char *dst = drbg->scratchpad + gcry_drbg_statelen (drbg); ++ struct gcry_drbg_string data; ++ unsigned char prefix = DRBG_PREFIX1; ++ ++ /* use the scratchpad as a lookaside buffer */ ++ memset (src, 0, gcry_drbg_statelen (drbg)); ++ memset (dst, 0, gcry_drbg_blocklen (drbg)); ++ ++ /* 10.1.1.4 step hashgen 2 */ ++ memcpy (src, drbg->V, gcry_drbg_statelen (drbg)); ++ ++ gcry_drbg_string_fill (&data, src, gcry_drbg_statelen (drbg)); ++ while (len < buflen) ++ { ++ unsigned int outlen = 0; ++ /* 10.1.1.4 step hashgen 4.1 */ ++ ret = gcry_drbg_hmac (drbg, NULL, dst, &data); ++ if (ret) ++ goto out; ++ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? ++ gcry_drbg_blocklen (drbg) : (buflen - len); ++ if (!gcry_drbg_fips_continuous_test (drbg, dst)) ++ { ++ gcry_drbg_add_buf (src, gcry_drbg_statelen (drbg), &prefix, 1); ++ continue; ++ } ++ /* 10.1.1.4 step hashgen 4.2 */ ++ memcpy (buf + len, dst, outlen); ++ len += outlen; ++ /* 10.1.1.4 hashgen step 4.3 */ ++ if (len < buflen) ++ gcry_drbg_add_buf (src, gcry_drbg_statelen (drbg), &prefix, 1); ++ } ++ ++out: ++ memset (drbg->scratchpad, 0, ++ (gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg))); ++ return ret; ++} ++ ++/* generate function for Hash DRBG as defined in 10.1.1.4 */ ++static gpg_err_code_t ++gcry_drbg_hash_generate (struct gcry_drbg_state *drbg, ++ unsigned char *buf, unsigned int buflen, ++ struct gcry_drbg_string *addtl) ++{ ++ gpg_err_code_t ret = 0; ++ unsigned char prefix = DRBG_PREFIX3; ++ struct gcry_drbg_string data1, data2; ++ union ++ { ++ unsigned char req[8]; ++ u64 req_int; ++ } u; ++ ++ /* ++ * scratchpad usage: gcry_drbg_hash_process_addtl uses the scratchpad, but ++ * fully completes before returning. Thus, we can reuse the scratchpad ++ */ ++ /* 10.1.1.4 step 2 */ ++ ret = gcry_drbg_hash_process_addtl (drbg, addtl); ++ if (ret) ++ return ret; ++ /* 10.1.1.4 step 3 -- invocation of the Hashgen function defined in ++ * 10.1.1.4 */ ++ ret = gcry_drbg_hash_hashgen (drbg, buf, buflen); ++ if (ret) ++ return ret; ++ ++ /* this is the value H as documented in 10.1.1.4 */ ++ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); ++ /* 10.1.1.4 step 4 */ ++ gcry_drbg_string_fill (&data1, &prefix, 1); ++ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); ++ data1.next = &data2; ++ ret = gcry_drbg_hmac (drbg, NULL, drbg->scratchpad, &data1); ++ if (ret) ++ goto out; ++ ++ /* 10.1.1.4 step 5 */ ++ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), ++ drbg->scratchpad, gcry_drbg_blocklen (drbg)); ++ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), drbg->C, ++ gcry_drbg_statelen (drbg)); ++ u.req_int = be_bswap64 (drbg->reseed_ctr); ++ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), u.req, ++ sizeof (u.req)); ++ ++out: ++ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); ++ return ret; ++} ++ ++/* ++ * scratchpad usage: as update and generate are used isolated, both ++ * can use the scratchpad ++ */ ++static struct gcry_drbg_state_ops gcry_drbg_hash_ops = { ++ gcry_drbg_hash_update, ++ gcry_drbg_hash_generate, ++}; ++ ++/****************************************************************** ++ * Functions common for DRBG implementations ++ ******************************************************************/ ++ ++/* ++ * Seeding or reseeding of the DRBG ++ * ++ * @drbg: DRBG state struct ++ * @pers: personalization / additional information buffer ++ * @reseed: 0 for initial seed process, 1 for reseeding ++ * ++ * return: ++ * 0 on success ++ * error value otherwise ++ */ ++static gpg_err_code_t ++gcry_drbg_seed (struct gcry_drbg_state *drbg, struct gcry_drbg_string *pers, ++ int reseed) ++{ ++ gpg_err_code_t ret = 0; ++ unsigned char *entropy = NULL; ++ size_t entropylen = 0; ++ struct gcry_drbg_string data1; ++ ++ /* 9.1 / 9.2 / 9.3.1 step 3 */ ++ if (pers && pers->len > (gcry_drbg_max_addtl ())) ++ { ++ dbg (("DRBG: personalization string too long %lu\n", pers->len)); ++ return GPG_ERR_INV_ARG; ++ } ++ if (drbg->test_data && drbg->test_data->testentropy) ++ { ++ gcry_drbg_string_fill (&data1, drbg->test_data->testentropy->buf, ++ drbg->test_data->testentropy->len); ++ dbg (("DRBG: using test entropy\n")); ++ } ++ else ++ { ++ /* Gather entropy equal to the security strength of the DRBG. ++ * With a derivation function, a nonce is required in addition ++ * to the entropy. A nonce must be at least 1/2 of the security ++ * strength of the DRBG in size. Thus, entropy * nonce is 3/2 ++ * of the strength. The consideration of a nonce is only ++ * applicable during initial seeding. */ ++ entropylen = gcry_drbg_sec_strength (drbg->core->flags); ++ if (!entropylen) ++ return GPG_ERR_GENERAL; ++ if (0 == reseed) ++ /* make sure we round up strength/2 in ++ * case it is not divisible by 2 */ ++ entropylen = ((entropylen + 1) / 2) * 3; ++ dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen)); ++ entropy = xcalloc_secure (1, entropylen); ++ if (!entropy) ++ return GPG_ERR_ENOMEM; ++ ret = gcry_drbg_get_entropy (drbg, entropy, entropylen); ++ if (ret) ++ goto out; ++ gcry_drbg_string_fill (&data1, entropy, entropylen); ++ } ++ ++ /* concatenation of entropy with personalization str / addtl input) ++ * the variable pers is directly handed by the caller, check its ++ * contents whether it is appropriate */ ++ if (pers && pers->buf && 0 < pers->len && NULL == pers->next) ++ { ++ data1.next = pers; ++ dbg (("DRBG: using personalization string\n")); ++ } ++ ++ ret = drbg->d_ops->update (drbg, &data1, reseed); ++ dbg (("DRBG: state updated with seed\n")); ++ if (ret) ++ goto out; ++ drbg->seeded = 1; ++ /* 10.1.1.2 / 10.1.1.3 step 5 */ ++ drbg->reseed_ctr = 1; ++ ++out: ++ xfree (entropy); ++ return ret; ++} ++ ++/************************************************************************* ++ * exported interfaces ++ *************************************************************************/ ++ ++/* ++ * DRBG generate function as required by SP800-90A - this function ++ * generates random numbers ++ * ++ * @drbg DRBG state handle ++ * @buf Buffer where to store the random numbers -- the buffer must already ++ * be pre-allocated by caller ++ * @buflen Length of output buffer - this value defines the number of random ++ * bytes pulled from DRBG ++ * @addtl Additional input that is mixed into state, may be NULL -- note ++ * the entropy is pulled by the DRBG internally unconditionally ++ * as defined in SP800-90A. The additional input is mixed into ++ * the state in addition to the pulled entropy. ++ * ++ * return: generated number of bytes ++ */ ++static gpg_err_code_t ++gcry_drbg_generate (struct gcry_drbg_state *drbg, ++ unsigned char *buf, unsigned int buflen, ++ struct gcry_drbg_string *addtl) ++{ ++ gpg_err_code_t ret = GPG_ERR_INV_ARG; ++ ++ if (0 == buflen || !buf) ++ { ++ dbg (("DRBG: no buffer provided\n")); ++ return ret; ++ } ++ if (addtl && NULL == addtl->buf && 0 < addtl->len) ++ { ++ dbg (("DRBG: wrong format of additional information\n")); ++ return ret; ++ } ++ ++ /* 9.3.1 step 2 */ ++ if (buflen > (gcry_drbg_max_request_bytes ())) ++ { ++ dbg (("DRBG: requested random numbers too large %u\n", buflen)); ++ return ret; ++ } ++ /* 9.3.1 step 3 is implicit with the chosen DRBG */ ++ /* 9.3.1 step 4 */ ++ if (addtl && addtl->len > (gcry_drbg_max_addtl ())) ++ { ++ dbg (("DRBG: additional information string too long %lu\n", ++ addtl->len)); ++ return ret; ++ } ++ /* 9.3.1 step 5 is implicit with the chosen DRBG */ ++ /* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c -- the spec is a ++ * bit convoluted here, we make it simpler */ ++ if ((gcry_drbg_max_requests ()) < drbg->reseed_ctr) ++ drbg->seeded = 0; ++ ++ if (drbg->pr || !drbg->seeded) ++ { ++ dbg (("DRBG: reseeding before generation (prediction resistance: %s, state %s)\n", drbg->pr ? "true" : "false", drbg->seeded ? "seeded" : "unseeded")); ++ /* 9.3.1 steps 7.1 through 7.3 */ ++ ret = gcry_drbg_seed (drbg, addtl, 1); ++ if (ret) ++ return ret; ++ /* 9.3.1 step 7.4 */ ++ addtl = NULL; ++ } ++ ++ if (addtl && addtl->buf) ++ { ++ dbg (("DRBG: using additional information string\n")); ++ } ++ ++ /* 9.3.1 step 8 and 10 */ ++ ret = drbg->d_ops->generate (drbg, buf, buflen, addtl); ++ ++ /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */ ++ drbg->reseed_ctr++; ++ if (ret) ++ return ret; ++ ++ /* 11.3.3 -- re-perform self tests after some generated random ++ * numbers, the chosen value after which self test is performed ++ * is arbitrary, but it should be reasonable */ ++ /* Here we do not perform the self tests because of the following ++ * reasons: it is mathematically impossible that the initial self tests ++ * were successfully and the following are not. If the initial would ++ * pass and the following would not, the system integrity is violated. ++ * In this case, the entire system operation is questionable and it ++ * is unlikely that the integrity violation only affects to the ++ * correct operation of the DRBG. ++ */ ++#if 0 ++ if (drbg->reseed_ctr && !(drbg->reseed_ctr % 4096)) ++ { ++ dbg (("DRBG: start to perform self test\n")); ++ ret = gcry_drbg_healthcheck (); ++ if (ret) ++ { ++ log_fatal (("DRBG: self test failed\n")); ++ return ret; ++ } ++ else ++ { ++ dbg (("DRBG: self test successful\n")); ++ } ++ } ++#endif ++ ++ return ret; ++} ++ ++/* ++ * Wrapper around gcry_drbg_generate which can pull arbitrary long strings ++ * from the DRBG without hitting the maximum request limitation. ++ * ++ * Parameters: see gcry_drbg_generate ++ * Return codes: see gcry_drbg_generate -- if one gcry_drbg_generate request fails, ++ * the entire gcry_drbg_generate_long request fails ++ */ ++static gpg_err_code_t ++gcry_drbg_generate_long (struct gcry_drbg_state *drbg, ++ unsigned char *buf, unsigned int buflen, ++ struct gcry_drbg_string *addtl) ++{ ++ gpg_err_code_t ret = 0; ++ unsigned int slice = 0; ++ unsigned char *buf_p = buf; ++ unsigned len = 0; ++ do ++ { ++ unsigned int chunk = 0; ++ slice = ((buflen - len) / gcry_drbg_max_request_bytes ()); ++ chunk = slice ? gcry_drbg_max_request_bytes () : (buflen - len); ++ ret = gcry_drbg_generate (drbg, buf_p, chunk, addtl); ++ if (ret) ++ return ret; ++ buf_p += chunk; ++ len += chunk; ++ } ++ while (slice > 0 && (len < buflen)); ++ return ret; ++} ++ ++/* ++ * DRBG uninstantiate function as required by SP800-90A - this function ++ * frees all buffers and the DRBG handle ++ * ++ * @drbg DRBG state handle ++ * ++ * return ++ * 0 on success ++ */ ++static gpg_err_code_t ++gcry_drbg_uninstantiate (struct gcry_drbg_state *drbg) ++{ ++ if (!drbg) ++ return GPG_ERR_INV_ARG; ++ xfree (drbg->V); ++ drbg->V = NULL; ++ xfree (drbg->C); ++ drbg->C = NULL; ++ drbg->reseed_ctr = 0; ++ xfree (drbg->scratchpad); ++ drbg->scratchpad = NULL; ++ drbg->seeded = 0; ++ drbg->pr = 0; ++ drbg->fips_primed = 0; ++ xfree (drbg->prev); ++ drbg->prev = NULL; ++ drbg->seed_init_pid = 0; ++ return 0; ++} ++ ++/* ++ * DRBG instantiation function as required by SP800-90A - this function ++ * sets up the DRBG handle, performs the initial seeding and all sanity ++ * checks required by SP800-90A ++ * ++ * @drbg memory of state -- if NULL, new memory is allocated ++ * @pers Personalization string that is mixed into state, may be NULL -- note ++ * the entropy is pulled by the DRBG internally unconditionally ++ * as defined in SP800-90A. The additional input is mixed into ++ * the state in addition to the pulled entropy. ++ * @coreref reference to core ++ * @flags Flags defining the requested DRBG type and cipher type. The flags ++ * are defined in drbg.h and may be XORed. Beware, if you XOR multiple ++ * cipher types together, the code picks the core on a first come first ++ * serve basis as it iterates through the available cipher cores and ++ * uses the one with the first match. The minimum required flags are: ++ * cipher type flag ++ * ++ * return ++ * 0 on success ++ * error value otherwise ++ */ ++static gpg_err_code_t ++gcry_drbg_instantiate (struct gcry_drbg_state *drbg, ++ struct gcry_drbg_string *pers, int coreref, int pr) ++{ ++ gpg_err_code_t ret = GPG_ERR_ENOMEM; ++ unsigned int sb_size = 0; ++ ++ if (!drbg) ++ return GPG_ERR_INV_ARG; ++ ++ dbg (("DRBG: Initializing DRBG core %d with prediction resistance %s\n", ++ coreref, pr ? "enabled" : "disabled")); ++ drbg->core = &gcry_drbg_cores[coreref]; ++ drbg->pr = pr; ++ drbg->seeded = 0; ++ if (drbg->core->flags & GCRY_DRBG_HMAC) ++ drbg->d_ops = &gcry_drbg_hmac_ops; ++ else if (drbg->core->flags & GCRY_DRBG_HASH_MASK) ++ drbg->d_ops = &gcry_drbg_hash_ops; ++ else if (drbg->core->flags & GCRY_DRBG_CTR_MASK) ++ drbg->d_ops = &gcry_drbg_ctr_ops; ++ else ++ return GPG_ERR_GENERAL; ++ /* 9.1 step 1 is implicit with the selected DRBG type -- see ++ * gcry_drbg_sec_strength() */ ++ ++ /* 9.1 step 2 is implicit as caller can select prediction resistance ++ * and the flag is copied into drbg->flags -- ++ * all DRBG types support prediction resistance */ ++ ++ /* 9.1 step 4 is implicit in gcry_drbg_sec_strength */ ++ ++ /* no allocation of drbg as this is done by the kernel crypto API */ ++ drbg->V = xcalloc_secure (1, gcry_drbg_statelen (drbg)); ++ if (!drbg->V) ++ goto err; ++ drbg->C = xcalloc_secure (1, gcry_drbg_statelen (drbg)); ++ if (!drbg->C) ++ goto err; ++ drbg->prev = xcalloc_secure (1, gcry_drbg_blocklen (drbg)); ++ if (!drbg->prev) ++ goto err; ++ drbg->fips_primed = 0; ++ /* scratchpad is only generated for CTR and Hash */ ++ if (drbg->core->flags & GCRY_DRBG_HMAC) ++ sb_size = 0; ++ else if (drbg->core->flags & GCRY_DRBG_CTR_MASK) ++ sb_size = gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg) + /* temp */ ++ gcry_drbg_statelen (drbg) + /* df_data */ ++ gcry_drbg_blocklen (drbg) + /* pad */ ++ gcry_drbg_blocklen (drbg) + /* iv */ ++ gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); /* temp */ ++ else ++ sb_size = gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); ++ ++ if (0 < sb_size) ++ { ++ drbg->scratchpad = xcalloc_secure (1, sb_size); ++ if (!drbg->scratchpad) ++ goto err; ++ } ++ dbg (("DRBG: state allocated with scratchpad size %u bytes\n", sb_size)); ++ ++ /* 9.1 step 6 through 11 */ ++ ret = gcry_drbg_seed (drbg, pers, 0); ++ if (ret) ++ goto err; ++ ++ dbg (("DRBG: core %d %s prediction resistance successfully initialized\n", ++ coreref, pr ? "with" : "without")); ++ return 0; ++ ++err: ++ gcry_drbg_uninstantiate (drbg); ++ return ret; ++} ++ ++/* ++ * DRBG reseed function as required by SP800-90A ++ * ++ * @drbg DRBG state handle ++ * @addtl Additional input that is mixed into state, may be NULL -- note ++ * the entropy is pulled by the DRBG internally unconditionally ++ * as defined in SP800-90A. The additional input is mixed into ++ * the state in addition to the pulled entropy. ++ * ++ * return ++ * 0 on success ++ * error value otherwise ++ */ ++static gpg_err_code_t ++gcry_drbg_reseed (struct gcry_drbg_state *drbg, ++ struct gcry_drbg_string *addtl) ++{ ++ gpg_err_code_t ret = 0; ++ ret = gcry_drbg_seed (drbg, addtl, 1); ++ return ret; ++} ++ ++/****************************************************************** ++ ****************************************************************** ++ ****************************************************************** ++ * libgcrypt integration code ++ ****************************************************************** ++ ****************************************************************** ++ ******************************************************************/ ++ ++/*************************************************************** ++ * libgcrypt backend functions to the RNG API code ++ ***************************************************************/ ++ ++/* global state variable holding the current instance of the DRBG -- the ++ * default DRBG type is defined in _gcry_gcry_drbg_init */ ++static struct gcry_drbg_state *gcry_drbg = NULL; ++ ++/* This is the lock we use to serialize access to this RNG. */ ++static ath_mutex_t drbg_lock; ++ ++static inline void ++gcry_drbg_lock (void) ++{ ++ int my_errno; ++ ++ my_errno = ath_mutex_lock (&drbg_lock); ++ if (my_errno) ++ log_fatal ("failed to acquire the RNG lock: %s\n", strerror (my_errno)); ++} ++ ++static inline void ++gcry_drbg_unlock (void) ++{ ++ int my_errno; ++ ++ my_errno = ath_mutex_unlock (&drbg_lock); ++ if (my_errno) ++ log_fatal ("failed to release the RNG lock: %s\n", strerror (my_errno)); ++} ++ ++/* Basic initialization is required to initialize mutexes and ++ do a few checks on the implementation. */ ++static void ++basic_initialization (void) ++{ ++ static int initialized; ++ int my_errno; ++ ++ if (initialized) ++ return; ++ initialized = 1; ++ ++ my_errno = ath_mutex_init (&drbg_lock); ++ if (my_errno) ++ log_fatal ("failed to create the RNG lock: %s\n", strerror (my_errno)); ++} ++ ++/****** helper functions where lock must be held by caller *****/ ++ ++/* Check whether given flags are known to point to an applicable DRBG */ ++static gpg_err_code_t ++gcry_drbg_algo_available (u32 flags, int *coreref) ++{ ++ int i = 0; ++ for (i = 0; ARRAY_SIZE (gcry_drbg_cores) > i; i++) ++ { ++ if ((gcry_drbg_cores[i].flags & GCRY_DRBG_CIPHER_MASK) == ++ (flags & GCRY_DRBG_CIPHER_MASK)) ++ { ++ *coreref = i; ++ return 0; ++ } ++ } ++ return GPG_ERR_GENERAL; ++} ++ ++static gpg_err_code_t ++_gcry_drbg_init_internal (u32 flags, struct gcry_drbg_string *pers) ++{ ++ gpg_err_code_t ret = 0; ++ static u32 oldflags = 0; ++ int coreref = 0; ++ int pr = 0; ++ ++ /* If a caller provides 0 as flags, use the flags of the previous ++ * initialization, otherwise use the current flags and remember them ++ * for the next invocation ++ */ ++ if (0 == flags) ++ flags = oldflags; ++ else ++ oldflags = flags; ++ ++ ret = gcry_drbg_algo_available (flags, &coreref); ++ if (ret) ++ return ret; ++ ++ if (NULL != gcry_drbg) ++ { ++ gcry_drbg_uninstantiate (gcry_drbg); ++ } ++ else ++ { ++ gcry_drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); ++ if (!gcry_drbg) ++ return GPG_ERR_ENOMEM; ++ } ++ if (flags & GCRY_DRBG_PREDICTION_RESIST) ++ pr = 1; ++ ret = gcry_drbg_instantiate (gcry_drbg, pers, coreref, pr); ++ if (ret) ++ fips_signal_error ("DRBG cannot be initialized"); ++ else ++ gcry_drbg->seed_init_pid = getpid (); ++ return ret; ++} ++ ++/************* calls available to common RNG code **************/ ++ ++/* ++ * Initialize one DRBG invoked by the libgcrypt API ++ */ ++void ++_gcry_drbg_init (int full) ++{ ++ (void) full; /* ignore for now */ ++ /* default DRBG */ ++ u32 flags = GCRY_DRBG_NOPR_HMACSHA256; ++ basic_initialization (); ++ gcry_drbg_lock (); ++ _gcry_drbg_init_internal (flags, NULL); ++ gcry_drbg_unlock (); ++} ++ ++/* ++ * Backend handler function for GCRYCTL_DRBG_REINIT ++ * ++ * Select a different DRBG type and initialize it. ++ * Function checks whether requested DRBG type exists and returns an error in ++ * case it does not. In case of an error, the previous instantiated DRBG is ++ * left untouched and alive. Thus, in case of an error, a DRBG is always ++ * available, even if it is not the chosen one. ++ * ++ * Re-initialization will be performed in any case regardless whether flags ++ * or personalization string are set. ++ * ++ * If flags == 0, do not change current DRBG ++ * If personalization string is NULL or its length is 0, re-initialize without ++ * personalization string ++ */ ++gpg_err_code_t ++_gcry_drbg_reinit (u32 flags, struct gcry_drbg_string *pers) ++{ ++ gpg_err_code_t ret = GPG_ERR_GENERAL; ++ dbg (("DRBG: reinitialize internal DRBG state with flags %u\n", flags)); ++ gcry_drbg_lock (); ++ ret = _gcry_drbg_init_internal (flags, pers); ++ gcry_drbg_unlock (); ++ return ret; ++} ++ ++/* Try to close the FDs of the random gather module. This is ++ * currently only implemented for rndlinux. */ ++void ++_gcry_drbg_close_fds (void) ++{ ++#if USE_RNDLINUX ++ gcry_drbg_lock (); ++ _gcry_rndlinux_gather_random (NULL, 0, 0, 0); ++ gcry_drbg_unlock (); ++#endif ++} ++ ++/* Print some statistics about the RNG. */ ++void ++_gcry_drbg_dump_stats (void) ++{ ++ /* Not yet implemented. */ ++ /* Maybe dumping of reseed counter? */ ++} ++ ++/* This function returns true if no real RNG is available or the ++ * quality of the RNG has been degraded for test purposes. */ ++int ++_gcry_drbg_is_faked (void) ++{ ++ return 0; /* Faked random is not allowed. */ ++} ++ ++/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY ++ * should be in the range of 0..100 to indicate the goodness of the ++ * entropy added, or -1 for goodness not known. */ ++gcry_error_t ++_gcry_drbg_add_bytes (const void *buf, size_t buflen, int quality) ++{ ++ gpg_err_code_t ret = 0; ++ struct gcry_drbg_string seed; ++ (void) quality; ++ if (NULL == gcry_drbg) ++ return GPG_ERR_GENERAL; ++ gcry_drbg_string_fill (&seed, (unsigned char *) buf, buflen); ++ gcry_drbg_lock (); ++ ret = gcry_drbg_reseed (gcry_drbg, &seed); ++ gcry_drbg_unlock (); ++ return ret; ++} ++ ++/* This function is to be used for all types of random numbers, including ++ * nonces ++ */ ++void ++_gcry_drbg_randomize (void *buffer, size_t length, ++ enum gcry_random_level level) ++{ ++ (void) level; ++ gcry_drbg_lock (); ++ if (NULL == gcry_drbg) ++ { ++ fips_signal_error ("DRBG is not initialized"); ++ goto bailout; ++ } ++ ++ /* As reseeding changes the entire state of the DRBG, including any ++ * key, either a re-init or a reseed is sufficient for a fork */ ++ if (gcry_drbg->seed_init_pid != getpid ()) ++ { ++ /* We are in a child of us. Perform a reseeding. */ ++ if (gcry_drbg_reseed (gcry_drbg, NULL)) ++ { ++ fips_signal_error ("reseeding upon fork failed"); ++ log_fatal ("severe error getting random\n"); ++ goto bailout; ++ } ++ gcry_drbg->seed_init_pid = getpid (); ++ } ++ /* potential integer overflow is covered by gcry_drbg_generate which ++ * ensures that length cannot overflow an unsigned int */ ++ if (0 < length) ++ { ++ if (!buffer) ++ goto bailout; ++ if (gcry_drbg_generate_long ++ (gcry_drbg, buffer, (unsigned int) length, NULL)) ++ log_fatal ("No random numbers generated\n"); ++ } ++ else ++ { ++ struct gcry_drbg_gen *data = (struct gcry_drbg_gen *) buffer; ++ /* catch NULL pointer */ ++ if (!data || !data->outbuf) ++ { ++ fips_signal_error ("No output buffer provided"); ++ goto bailout; ++ } ++ if (gcry_drbg_generate_long (gcry_drbg, data->outbuf, data->outlen, ++ data->addtl)) ++ log_fatal ("No random numbers generated\n"); ++ } ++bailout: ++ gcry_drbg_unlock (); ++ return; ++ ++} ++ ++/*************************************************************** ++ * Self-test code ++ ***************************************************************/ ++ ++/* ++ * Test vectors from ++ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip ++ */ ++struct gcry_drbg_test_vector gcry_drbg_test_pr[] = { ++ { ++ .flags = (GCRY_DRBG_PR_HASHSHA256), ++ .entropy = (unsigned char *) ++ "\x5d\xf2\x14\xbc\xf6\xb5\x4e\x0b\xf0\x0d\x6f\x2d" ++ "\xe2\x01\x66\x7b\xd0\xa4\x73\xa4\x21\xdd\xb0\xc0" ++ "\x51\x79\x09\xf4\xea\xa9\x08\xfa\xa6\x67\xe0\xe1" ++ "\xd1\x88\xa8\xad\xee\x69\x74\xb3\x55\x06\x9b\xf6", ++ .entropylen = 48, ++ .entpra = (unsigned char *) ++ "\xef\x48\x06\xa2\xc2\x45\xf1\x44\xfa\x34\x2c\xeb" ++ "\x8d\x78\x3c\x09\x8f\x34\x72\x20\xf2\xe7\xfd\x13" ++ "\x76\x0a\xf6\xdc\x3c\xf5\xc0\x15", ++ .entprb = (unsigned char *) ++ "\x4b\xbe\xe5\x24\xed\x6a\x2d\x0c\xdb\x73\x5e\x09" ++ "\xf9\xad\x67\x7c\x51\x47\x8b\x6b\x30\x2a\xc6\xde" ++ "\x76\xaa\x55\x04\x8b\x0a\x72\x95", ++ .entprlen = 32, ++ .expected = (unsigned char *) ++ "\x3b\x14\x71\x99\xa1\xda\xa0\x42\xe6\xc8\x85\x32" ++ "\x70\x20\x32\x53\x9a\xbe\xd1\x1e\x15\xef\xfb\x4c" ++ "\x25\x6e\x19\x3a\xf0\xb9\xcb\xde\xf0\x3b\xc6\x18" ++ "\x4d\x85\x5a\x9b\xf1\xe3\xc2\x23\x03\x93\x08\xdb" ++ "\xa7\x07\x4b\x33\x78\x40\x4d\xeb\x24\xf5\x6e\x81" ++ "\x4a\x1b\x6e\xa3\x94\x52\x43\xb0\xaf\x2e\x21\xf4" ++ "\x42\x46\x8e\x90\xed\x34\x21\x75\xea\xda\x67\xb6" ++ "\xe4\xf6\xff\xc6\x31\x6c\x9a\x5a\xdb\xb3\x97\x13" ++ "\x09\xd3\x20\x98\x33\x2d\x6d\xd7\xb5\x6a\xa8\xa9" ++ "\x9a\x5b\xd6\x87\x52\xa1\x89\x2b\x4b\x9c\x64\x60" ++ "\x50\x47\xa3\x63\x81\x16\xaf\x19", ++ .expectedlen = 128, ++ .addtla = (unsigned char *) ++ "\xbe\x13\xdb\x2a\xe9\xa8\xfe\x09\x97\xe1\xce\x5d" ++ "\xe8\xbb\xc0\x7c\x4f\xcb\x62\x19\x3f\x0f\xd2\xad" ++ "\xa9\xd0\x1d\x59\x02\xc4\xff\x70", ++ .addtlb = (unsigned char *) ++ "\x6f\x96\x13\xe2\xa7\xf5\x6c\xfe\xdf\x66\xe3\x31" ++ "\x63\x76\xbf\x20\x27\x06\x49\xf1\xf3\x01\x77\x41" ++ "\x9f\xeb\xe4\x38\xfe\x67\x00\xcd", ++ .addtllen = 32, ++ .pers = NULL, ++ .perslen = 0, ++ }, ++ { ++ .flags = (GCRY_DRBG_PR_HMACSHA256), ++ .entropy = (unsigned char *) ++ "\x13\x54\x96\xfc\x1b\x7d\x28\xf3\x18\xc9\xa7\x89" ++ "\xb6\xb3\xc8\x72\xac\x00\xd4\x59\x36\x25\x05\xaf" ++ "\xa5\xdb\x96\xcb\x3c\x58\x46\x87\xa5\xaa\xbf\x20" ++ "\x3b\xfe\x23\x0e\xd1\xc7\x41\x0f\x3f\xc9\xb3\x67", ++ .entropylen = 48, ++ .entpra = (unsigned char *) ++ "\xe2\xbd\xb7\x48\x08\x06\xf3\xe1\x93\x3c\xac\x79" ++ "\xa7\x2b\x11\xda\xe3\x2e\xe1\x91\xa5\x02\x19\x57" ++ "\x20\x28\xad\xf2\x60\xd7\xcd\x45", ++ .entprb = (unsigned char *) ++ "\x8b\xd4\x69\xfc\xff\x59\x95\x95\xc6\x51\xde\x71" ++ "\x68\x5f\xfc\xf9\x4a\xab\xec\x5a\xcb\xbe\xd3\x66" ++ "\x1f\xfa\x74\xd3\xac\xa6\x74\x60", ++ .entprlen = 32, ++ .expected = (unsigned char *) ++ "\x1f\x9e\xaf\xe4\xd2\x46\xb7\x47\x41\x4c\x65\x99" ++ "\x01\xe9\x3b\xbb\x83\x0c\x0a\xb0\xc1\x3a\xe2\xb3" ++ "\x31\x4e\xeb\x93\x73\xee\x0b\x26\xc2\x63\xa5\x75" ++ "\x45\x99\xd4\x5c\x9f\xa1\xd4\x45\x87\x6b\x20\x61" ++ "\x40\xea\x78\xa5\x32\xdf\x9e\x66\x17\xaf\xb1\x88" ++ "\x9e\x2e\x23\xdd\xc1\xda\x13\x97\x88\xa5\xb6\x5e" ++ "\x90\x14\x4e\xef\x13\xab\x5c\xd9\x2c\x97\x9e\x7c" ++ "\xd7\xf8\xce\xea\x81\xf5\xcd\x71\x15\x49\x44\xce" ++ "\x83\xb6\x05\xfb\x7d\x30\xb5\x57\x2c\x31\x4f\xfc" ++ "\xfe\x80\xb6\xc0\x13\x0c\x5b\x9b\x2e\x8f\x3d\xfc" ++ "\xc2\xa3\x0c\x11\x1b\x80\x5f\xf3", ++ .expectedlen = 128, ++ .addtla = NULL, ++ .addtlb = NULL, ++ .addtllen = 0, ++ .pers = (unsigned char *) ++ "\x64\xb6\xfc\x60\xbc\x61\x76\x23\x6d\x3f\x4a\x0f" ++ "\xe1\xb4\xd5\x20\x9e\x70\xdd\x03\x53\x6d\xbf\xce" ++ "\xcd\x56\x80\xbc\xb8\x15\xc8\xaa", ++ .perslen = 32, ++ }, ++ { ++ .flags = (GCRY_DRBG_PR_CTRAES128), ++ .entropy = (unsigned char *) ++ "\x92\x89\x8f\x31\xfa\x1c\xff\x6d\x18\x2f\x26\x06" ++ "\x43\xdf\xf8\x18\xc2\xa4\xd9\x72\xc3\xb9\xb6\x97", ++ .entropylen = 24, ++ .entpra = (unsigned char *) ++ "\x20\x72\x8a\x06\xf8\x6f\x8d\xd4\x41\xe2\x72\xb7" ++ "\xc4\x2c\xe8\x10", ++ .entprb = (unsigned char *) ++ "\x3d\xb0\xf0\x94\xf3\x05\x50\x33\x17\x86\x3e\x22" ++ "\x08\xf7\xa5\x01", ++ .entprlen = 16, ++ .expected = (unsigned char *) ++ "\x5a\x35\x39\x87\x0f\x4d\x22\xa4\x09\x24\xee\x71" ++ "\xc9\x6f\xac\x72\x0a\xd6\xf0\x88\x82\xd0\x83\x28" ++ "\x73\xec\x3f\x93\xd8\xab\x45\x23\xf0\x7e\xac\x45" ++ "\x14\x5e\x93\x9f\xb1\xd6\x76\x43\x3d\xb6\xe8\x08" ++ "\x88\xf6\xda\x89\x08\x77\x42\xfe\x1a\xf4\x3f\xc4" ++ "\x23\xc5\x1f\x68", ++ .expectedlen = 64, ++ .addtla = (unsigned char *) ++ "\x1a\x40\xfa\xe3\xcc\x6c\x7c\xa0\xf8\xda\xba\x59" ++ "\x23\x6d\xad\x1d", ++ .addtlb = (unsigned char *) ++ "\x9f\x72\x76\x6c\xc7\x46\xe5\xed\x2e\x53\x20\x12" ++ "\xbc\x59\x31\x8c", ++ .addtllen = 16, ++ .pers = (unsigned char *) ++ "\xea\x65\xee\x60\x26\x4e\x7e\xb6\x0e\x82\x68\xc4" ++ "\x37\x3c\x5c\x0b", ++ .perslen = 16, ++ }, ++}; ++ ++struct gcry_drbg_test_vector gcry_drbg_test_nopr[] = { ++ { ++ .flags = GCRY_DRBG_NOPR_HASHSHA256, ++ .entropy = (unsigned char *) ++ "\x73\xd3\xfb\xa3\x94\x5f\x2b\x5f\xb9\x8f\xf6\x9c" ++ "\x8a\x93\x17\xae\x19\xc3\x4c\xc3\xd6\xca\xa3\x2d" ++ "\x16\xfc\x42\xd2\x2d\xd5\x6f\x56\xcc\x1d\x30\xff" ++ "\x9e\x06\x3e\x09\xce\x58\xe6\x9a\x35\xb3\xa6\x56", ++ .entropylen = 48, ++ .expected = (unsigned char *) ++ "\x71\x7b\x93\x46\x1a\x40\xaa\x35\xa4\xaa\xc5\xe7" ++ "\x6d\x5b\x5b\x8a\xa0\xdf\x39\x7d\xae\x71\x58\x5b" ++ "\x3c\x7c\xb4\xf0\x89\xfa\x4a\x8c\xa9\x5c\x54\xc0" ++ "\x40\xdf\xbc\xce\x26\x81\x34\xf8\xba\x7d\x1c\xe8" ++ "\xad\x21\xe0\x74\xcf\x48\x84\x30\x1f\xa1\xd5\x4f" ++ "\x81\x42\x2f\xf4\xdb\x0b\x23\xf8\x73\x27\xb8\x1d" ++ "\x42\xf8\x44\x58\xd8\x5b\x29\x27\x0a\xf8\x69\x59" ++ "\xb5\x78\x44\xeb\x9e\xe0\x68\x6f\x42\x9a\xb0\x5b" ++ "\xe0\x4e\xcb\x6a\xaa\xe2\xd2\xd5\x33\x25\x3e\xe0" ++ "\x6c\xc7\x6a\x07\xa5\x03\x83\x9f\xe2\x8b\xd1\x1c" ++ "\x70\xa8\x07\x59\x97\xeb\xf6\xbe", ++ .expectedlen = 128, ++ .addtla = (unsigned char *) ++ "\xf4\xd5\x98\x3d\xa8\xfc\xfa\x37\xb7\x54\x67\x73" ++ "\xc7\xc3\xdd\x47\x34\x71\x02\x5d\xc1\xa0\xd3\x10" ++ "\xc1\x8b\xbd\xf5\x66\x34\x6f\xdd", ++ .addtlb = (unsigned char *) ++ "\xf7\x9e\x6a\x56\x0e\x73\xe9\xd9\x7a\xd1\x69\xe0" ++ "\x6f\x8c\x55\x1c\x44\xd1\xce\x6f\x28\xcc\xa4\x4d" ++ "\xa8\xc0\x85\xd1\x5a\x0c\x59\x40", ++ .addtllen = 32, ++ .pers = NULL, ++ .perslen = 0, ++ }, ++ { ++ .flags = GCRY_DRBG_NOPR_HMACSHA256, ++ .entropy = (unsigned char *) ++ "\x8d\xf0\x13\xb4\xd1\x03\x52\x30\x73\x91\x7d\xdf" ++ "\x6a\x86\x97\x93\x05\x9e\x99\x43\xfc\x86\x54\x54" ++ "\x9e\x7a\xb2\x2f\x7c\x29\xf1\x22\xda\x26\x25\xaf" ++ "\x2d\xdd\x4a\xbc\xce\x3c\xf4\xfa\x46\x59\xd8\x4e", ++ .entropylen = 48, ++ .expected = (unsigned char *) ++ "\xb9\x1c\xba\x4c\xc8\x4f\xa2\x5d\xf8\x61\x0b\x81" ++ "\xb6\x41\x40\x27\x68\xa2\x09\x72\x34\x93\x2e\x37" ++ "\xd5\x90\xb1\x15\x4c\xbd\x23\xf9\x74\x52\xe3\x10" ++ "\xe2\x91\xc4\x51\x46\x14\x7f\x0d\xa2\xd8\x17\x61" ++ "\xfe\x90\xfb\xa6\x4f\x94\x41\x9c\x0f\x66\x2b\x28" ++ "\xc1\xed\x94\xda\x48\x7b\xb7\xe7\x3e\xec\x79\x8f" ++ "\xbc\xf9\x81\xb7\x91\xd1\xbe\x4f\x17\x7a\x89\x07" ++ "\xaa\x3c\x40\x16\x43\xa5\xb6\x2b\x87\xb8\x9d\x66" ++ "\xb3\xa6\x0e\x40\xd4\xa8\xe4\xe9\xd8\x2a\xf6\xd2" ++ "\x70\x0e\x6f\x53\x5c\xdb\x51\xf7\x5c\x32\x17\x29" ++ "\x10\x37\x41\x03\x0c\xcc\x3a\x56", ++ .expectedlen = 128, ++ .addtla = NULL, ++ .addtlb = NULL, ++ .addtllen = 0, ++ .pers = (unsigned char *) ++ "\xb5\x71\xe6\x6d\x7c\x33\x8b\xc0\x7b\x76\xad\x37" ++ "\x57\xbb\x2f\x94\x52\xbf\x7e\x07\x43\x7a\xe8\x58" ++ "\x1c\xe7\xbc\x7c\x3a\xc6\x51\xa9", ++ .perslen = 32, ++ }, ++ { ++ .flags = GCRY_DRBG_NOPR_CTRAES128, ++ .entropy = (unsigned char *) ++ "\xc0\x70\x1f\x92\x50\x75\x8f\xcd\xf2\xbe\x73\x98" ++ "\x80\xdb\x66\xeb\x14\x68\xb4\xa5\x87\x9c\x2d\xa6", ++ .entropylen = 24, ++ .expected = (unsigned char *) ++ "\x97\xc0\xc0\xe5\xa0\xcc\xf2\x4f\x33\x63\x48\x8a" ++ "\xdb\x13\x0a\x35\x89\xbf\x80\x65\x62\xee\x13\x95" ++ "\x7c\x33\xd3\x7d\xf4\x07\x77\x7a\x2b\x65\x0b\x5f" ++ "\x45\x5c\x13\xf1\x90\x77\x7f\xc5\x04\x3f\xcc\x1a" ++ "\x38\xf8\xcd\x1b\xbb\xd5\x57\xd1\x4a\x4c\x2e\x8a" ++ "\x2b\x49\x1e\x5c", ++ .expectedlen = 64, ++ .addtla = (unsigned char *) ++ "\xf9\x01\xf8\x16\x7a\x1d\xff\xde\x8e\x3c\x83\xe2" ++ "\x44\x85\xe7\xfe", ++ .addtlb = (unsigned char *) ++ "\x17\x1c\x09\x38\xc2\x38\x9f\x97\x87\x60\x55\xb4" ++ "\x82\x16\x62\x7f", ++ .addtllen = 16, ++ .pers = (unsigned char *) ++ "\x80\x08\xae\xe8\xe9\x69\x40\xc5\x08\x73\xc7\x9f" ++ "\x8e\xcf\xe0\x02", ++ .perslen = 16, ++ }, ++}; ++ ++ ++/* ++ * Tests implement the CAVS test approach as documented in ++ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf ++ */ ++ ++/* ++ * CAVS test ++ * ++ * This function is not static as it is needed for as a private API ++ * call for the CAVS test tool. ++ */ ++gpg_err_code_t ++gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, unsigned char *buf) ++{ ++ gpg_err_code_t ret = 0; ++ struct gcry_drbg_state *drbg = NULL; ++ struct gcry_drbg_test_data test_data; ++ struct gcry_drbg_string addtl, pers, testentropy; ++ int coreref = 0; ++ int pr = 0; ++ ++ ret = gcry_drbg_algo_available (test->flags, &coreref); ++ if (ret) ++ goto outbuf; ++ ++ drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); ++ if (!drbg) ++ { ++ ret = GPG_ERR_ENOMEM; ++ goto outbuf; ++ } ++ ++ if (test->flags & GCRY_DRBG_PREDICTION_RESIST) ++ pr = 1; ++ ++ test_data.testentropy = &testentropy; ++ gcry_drbg_string_fill (&testentropy, test->entropy, test->entropylen); ++ drbg->test_data = &test_data; ++ gcry_drbg_string_fill (&pers, test->pers, test->perslen); ++ ret = gcry_drbg_instantiate (drbg, &pers, coreref, pr); ++ if (ret) ++ goto outbuf; ++ ++ gcry_drbg_string_fill (&addtl, test->addtla, test->addtllen); ++ if (test->entpra) ++ { ++ gcry_drbg_string_fill (&testentropy, test->entpra, test->entprlen); ++ drbg->test_data = &test_data; ++ } ++ gcry_drbg_generate_long (drbg, buf, test->expectedlen, &addtl); ++ ++ gcry_drbg_string_fill (&addtl, test->addtlb, test->addtllen); ++ if (test->entprb) ++ { ++ gcry_drbg_string_fill (&testentropy, test->entprb, test->entprlen); ++ drbg->test_data = &test_data; ++ } ++ gcry_drbg_generate_long (drbg, buf, test->expectedlen, &addtl); ++ gcry_drbg_uninstantiate (drbg); ++ ++outbuf: ++ xfree (drbg); ++ return ret; ++} ++ ++/* ++ * Invoke the CAVS test and perform the final check whether the ++ * calculated random value matches the expected one. ++ * ++ * This function is not static as it is needed for as a private API ++ * call for the CAVS test tool. ++ */ ++gpg_err_code_t ++gcry_drbg_healthcheck_one (struct gcry_drbg_test_vector * test) ++{ ++ gpg_err_code_t ret = GPG_ERR_ENOMEM; ++ unsigned char *buf = xcalloc_secure (1, test->expectedlen); ++ if (!buf) ++ return GPG_ERR_ENOMEM; ++ ++ ret = gcry_drbg_cavs_test (test, buf); ++ ret = memcmp (test->expected, buf, test->expectedlen); ++ ++ xfree (buf); ++ return ret; ++} ++ ++/* ++ * Tests as defined in 11.3.2 in addition to the cipher tests: testing ++ * of the error handling. ++ * ++ * Note, testing the reseed counter is not done as an automatic reseeding ++ * is performed in gcry_drbg_generate when the reseed counter is too large. ++ */ ++static gpg_err_code_t ++gcry_drbg_healthcheck_sanity (struct gcry_drbg_test_vector *test) ++{ ++ unsigned int len = 0; ++ struct gcry_drbg_state *drbg = NULL; ++ gpg_err_code_t ret = GPG_ERR_GENERAL; ++ gpg_err_code_t tmpret = GPG_ERR_GENERAL; ++ struct gcry_drbg_test_data test_data; ++ struct gcry_drbg_string addtl, testentropy; ++ int coreref = 0; ++ unsigned char *buf = NULL; ++ size_t max_addtllen, max_request_bytes; ++ ++ /* only perform test in FIPS mode */ ++ if (0 == fips_mode ()) ++ return 0; ++ ++ buf = xcalloc_secure (1, test->expectedlen); ++ if (!buf) ++ return GPG_ERR_ENOMEM; ++ tmpret = gcry_drbg_algo_available (test->flags, &coreref); ++ if (tmpret) ++ goto outbuf; ++ drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); ++ if (!drbg) ++ goto outbuf; ++ ++ /* if the following tests fail, it is likely that there is a buffer ++ * overflow and we get a SIGSEV */ ++ ret = gcry_drbg_instantiate (drbg, NULL, coreref, 1); ++ if (ret) ++ goto outbuf; ++ max_addtllen = gcry_drbg_max_addtl (); ++ max_request_bytes = gcry_drbg_max_request_bytes (); ++ /* overflow addtllen with additonal info string */ ++ gcry_drbg_string_fill (&addtl, test->addtla, (max_addtllen + 1)); ++ len = gcry_drbg_generate (drbg, buf, test->expectedlen, &addtl); ++ if (len) ++ goto outdrbg; ++ ++ /* overflow max_bits */ ++ len = gcry_drbg_generate (drbg, buf, (max_request_bytes + 1), NULL); ++ if (len) ++ goto outdrbg; ++ gcry_drbg_uninstantiate (drbg); ++ ++ /* test failing entropy source as defined in 11.3.2 */ ++ test_data.testentropy = NULL; ++ test_data.fail_seed_source = 1; ++ drbg->test_data = &test_data; ++ tmpret = gcry_drbg_instantiate (drbg, NULL, coreref, 0); ++ if (!tmpret) ++ goto outdrbg; ++ test_data.fail_seed_source = 0; ++ ++ test_data.testentropy = &testentropy; ++ gcry_drbg_string_fill (&testentropy, test->entropy, test->entropylen); ++ /* overflow max addtllen with personalization string */ ++ tmpret = gcry_drbg_instantiate (drbg, &addtl, coreref, 0); ++ if (!tmpret) ++ goto outdrbg; ++ ++ dbg (("DRBG: Sanity tests for failure code paths successfully completed\n")); ++ ret = 0; ++ ++outdrbg: ++ gcry_drbg_uninstantiate (drbg); ++outbuf: ++ xfree (buf); ++ xfree (drbg); ++ return ret; ++} ++ ++/* ++ * DRBG Healthcheck function as required in SP800-90A ++ * ++ * return: ++ * 0 on success (all tests pass) ++ * >0 on error (return code indicate the number of failures) ++ */ ++static int ++gcry_drbg_healthcheck (void) ++{ ++ int ret = 0; ++ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[0]); ++ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[1]); ++ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[2]); ++ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[0]); ++ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[1]); ++ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[2]); ++ ret += gcry_drbg_healthcheck_sanity (&gcry_drbg_test_nopr[0]); ++ return ret; ++} ++ ++/* Run the self-tests. */ ++gcry_error_t ++_gcry_drbg_selftest (selftest_report_func_t report) ++{ ++ gcry_err_code_t ec; ++ const char *errtxt = NULL; ++ gcry_drbg_lock (); ++ if (0 != gcry_drbg_healthcheck ()) ++ errtxt = "RNG output does not match known value"; ++ gcry_drbg_unlock (); ++ if (report && errtxt) ++ report ("random", 0, "KAT", errtxt); ++ ec = errtxt ? GPG_ERR_SELFTEST_FAILED : 0; ++ return gpg_error (ec); ++} ++ ++/*************************************************************** ++ * Cipher invocations requested by DRBG ++ ***************************************************************/ ++ ++static gpg_err_code_t ++gcry_drbg_hmac (struct gcry_drbg_state *drbg, const unsigned char *key, ++ unsigned char *outval, const struct gcry_drbg_string *buf) ++{ ++ gpg_error_t err; ++ gcry_md_hd_t hd; ++ ++ if (key) ++ { ++ err = ++ _gcry_md_open (&hd, drbg->core->backend_cipher, GCRY_MD_FLAG_HMAC); ++ if (err) ++ return err; ++ err = _gcry_md_setkey (hd, key, gcry_drbg_statelen (drbg)); ++ if (err) ++ return err; ++ } ++ else ++ { ++ err = _gcry_md_open (&hd, drbg->core->backend_cipher, 0); ++ if (err) ++ return err; ++ } ++ for (; NULL != buf; buf = buf->next) ++ _gcry_md_write (hd, buf->buf, buf->len); ++ _gcry_md_final (hd); ++ memcpy (outval, _gcry_md_read (hd, drbg->core->backend_cipher), ++ gcry_drbg_blocklen (drbg)); ++ _gcry_md_close (hd); ++ return 0; ++} ++ ++static gpg_err_code_t ++gcry_drbg_sym (struct gcry_drbg_state *drbg, const unsigned char *key, ++ unsigned char *outval, const struct gcry_drbg_string *buf) ++{ ++ gpg_error_t err; ++ gcry_cipher_hd_t hd; ++ ++ if (gcry_drbg_blocklen (drbg) != ++ _gcry_cipher_get_algo_blklen (drbg->core->backend_cipher)) ++ return -GPG_ERR_NO_ERROR; ++ if (gcry_drbg_blocklen (drbg) < buf->len) ++ return -GPG_ERR_NO_ERROR; ++ err = ++ _gcry_cipher_open (&hd, drbg->core->backend_cipher, GCRY_CIPHER_MODE_ECB, ++ 0); ++ if (err) ++ return err; ++ err = _gcry_cipher_setkey (hd, key, gcry_drbg_keylen (drbg)); ++ if (err) ++ { ++ _gcry_cipher_close (hd); ++ return err; ++ } ++ /* in is only component */ ++ _gcry_cipher_encrypt (hd, outval, gcry_drbg_blocklen (drbg), buf->buf, ++ buf->len); ++ _gcry_cipher_close (hd); ++ return 0; ++} +diff -up libgcrypt-1.6.2/random/Makefile.am.drbg libgcrypt-1.6.2/random/Makefile.am +--- libgcrypt-1.6.2/random/Makefile.am.drbg 2014-08-18 08:46:51.000000000 +0200 ++++ libgcrypt-1.6.2/random/Makefile.am 2014-12-08 16:31:33.513992141 +0100 +@@ -35,6 +35,7 @@ random.c random.h \ + rand-internal.h \ + random-csprng.c \ + random-fips.c \ ++drbg.c \ + random-system.c \ + rndhw.c + +diff -up libgcrypt-1.6.2/random/Makefile.in.drbg libgcrypt-1.6.2/random/Makefile.in +--- libgcrypt-1.6.2/random/Makefile.in.drbg 2014-08-21 15:14:08.000000000 +0200 ++++ libgcrypt-1.6.2/random/Makefile.in 2014-12-08 16:31:33.514992163 +0100 +@@ -92,11 +92,11 @@ CONFIG_CLEAN_VPATH_FILES = + LTLIBRARIES = $(noinst_LTLIBRARIES) + am__DEPENDENCIES_1 = + am__librandom_la_SOURCES_DIST = random.c random.h rand-internal.h \ +- random-csprng.c random-fips.c random-system.c rndhw.c \ ++ random-csprng.c random-fips.c drbg.c random-system.c rndhw.c \ + random-daemon.c + @USE_RANDOM_DAEMON_TRUE@am__objects_1 = random-daemon.lo + am_librandom_la_OBJECTS = random.lo random-csprng.lo random-fips.lo \ +- random-system.lo rndhw.lo $(am__objects_1) ++ drbg.lo random-system.lo rndhw.lo $(am__objects_1) + librandom_la_OBJECTS = $(am_librandom_la_OBJECTS) + AM_V_lt = $(am__v_lt_@AM_V@) + am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +@@ -310,7 +310,7 @@ GCRYPT_MODULES = @GCRYPT_RANDOM@ + librandom_la_DEPENDENCIES = $(GCRYPT_MODULES) + librandom_la_LIBADD = $(GCRYPT_MODULES) + librandom_la_SOURCES = random.c random.h rand-internal.h \ +- random-csprng.c random-fips.c random-system.c rndhw.c \ ++ random-csprng.c random-fips.c drbg.c random-system.c rndhw.c \ + $(am__append_1) + EXTRA_librandom_la_SOURCES = \ + rndlinux.c \ +@@ -374,6 +374,7 @@ distclean-compile: + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-csprng.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-daemon.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-fips.Plo@am__quote@ ++@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drbg.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-system.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@ + @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndegd.Plo@am__quote@ +diff -up libgcrypt-1.6.2/random/rand-internal.h.drbg libgcrypt-1.6.2/random/rand-internal.h +--- libgcrypt-1.6.2/random/rand-internal.h.drbg 2014-08-18 08:46:51.000000000 +0200 ++++ libgcrypt-1.6.2/random/rand-internal.h 2014-12-08 16:31:33.514992163 +0100 +@@ -88,6 +88,15 @@ gcry_err_code_t _gcry_rngfips_run_extern + char *buffer, size_t buflen); + void _gcry_rngfips_deinit_external_test (void *context); + ++/* drbg-gcry.h */ ++void _gcry_drbg_init(int full); ++void _gcry_drbg_close_fds(void); ++void _gcry_drbg_dump_stats(void); ++int _gcry_drbg_is_faked (void); ++gcry_error_t _gcry_drbg_add_bytes (const void *buf, size_t buflen, int quality); ++void _gcry_drbg_randomize (void *buffer, size_t length, ++ enum gcry_random_level level); ++gcry_error_t _gcry_drbg_selftest (selftest_report_func_t report); + + /*-- random-system.c --*/ + void _gcry_rngsystem_initialize (int full); +diff -up libgcrypt-1.6.2/random/random.c.drbg libgcrypt-1.6.2/random/random.c +--- libgcrypt-1.6.2/random/random.c.drbg 2014-08-21 14:50:39.000000000 +0200 ++++ libgcrypt-1.6.2/random/random.c 2014-12-08 16:31:33.514992163 +0100 +@@ -153,11 +153,11 @@ _gcry_random_initialize (int full) + } + + if (fips_mode ()) +- _gcry_rngfips_initialize (full); ++ _gcry_drbg_init(full); + else if (rng_types.standard) + _gcry_rngcsprng_initialize (full); + else if (rng_types.fips) +- _gcry_rngfips_initialize (full); ++ _gcry_drbg_init(full); + else if (rng_types.system) + _gcry_rngsystem_initialize (full); + else +@@ -174,11 +174,11 @@ _gcry_random_close_fds (void) + the entropy gatherer. */ + + if (fips_mode ()) +- _gcry_rngfips_close_fds (); ++ _gcry_drbg_close_fds (); + else if (rng_types.standard) + _gcry_rngcsprng_close_fds (); + else if (rng_types.fips) +- _gcry_rngfips_close_fds (); ++ _gcry_drbg_close_fds (); + else if (rng_types.system) + _gcry_rngsystem_close_fds (); + else +@@ -212,7 +212,7 @@ void + _gcry_random_dump_stats (void) + { + if (fips_mode ()) +- _gcry_rngfips_dump_stats (); ++ _gcry_drbg_dump_stats (); + else + _gcry_rngcsprng_dump_stats (); + } +@@ -271,7 +271,7 @@ int + _gcry_random_is_faked (void) + { + if (fips_mode ()) +- return _gcry_rngfips_is_faked (); ++ return _gcry_drbg_is_faked (); + else + return _gcry_rngcsprng_is_faked (); + } +@@ -301,11 +301,11 @@ static void + do_randomize (void *buffer, size_t length, enum gcry_random_level level) + { + if (fips_mode ()) +- _gcry_rngfips_randomize (buffer, length, level); ++ _gcry_drbg_randomize (buffer, length, level); + else if (rng_types.standard) + _gcry_rngcsprng_randomize (buffer, length, level); + else if (rng_types.fips) +- _gcry_rngfips_randomize (buffer, length, level); ++ _gcry_drbg_randomize (buffer, length, level); + else if (rng_types.system) + _gcry_rngsystem_randomize (buffer, length, level); + else /* default */ +@@ -437,7 +437,7 @@ _gcry_create_nonce (void *buffer, size_t + nonce generator which is seeded by the RNG actual in use. */ + if (fips_mode ()) + { +- _gcry_rngfips_create_nonce (buffer, length); ++ _gcry_drbg_randomize (buffer, length, GCRY_WEAK_RANDOM); + return; + } + +@@ -514,7 +514,7 @@ gpg_error_t + _gcry_random_selftest (selftest_report_func_t report) + { + if (fips_mode ()) +- return _gcry_rngfips_selftest (report); ++ return _gcry_drbg_selftest (report); + else + return 0; /* No selftests yet. */ + } +@@ -530,6 +530,7 @@ _gcry_random_init_external_test (void ** + const void *seed, size_t seedlen, + const void *dt, size_t dtlen) + { ++ return GPG_ERR_NOT_SUPPORTED; + (void)flags; + if (fips_mode ()) + return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, +@@ -544,6 +545,7 @@ _gcry_random_init_external_test (void ** + gcry_err_code_t + _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) + { ++ return GPG_ERR_NOT_SUPPORTED; + if (fips_mode ()) + return _gcry_rngfips_run_external_test (context, buffer, buflen); + else +@@ -554,6 +556,7 @@ _gcry_random_run_external_test (void *co + void + _gcry_random_deinit_external_test (void *context) + { ++ return; + if (fips_mode ()) + _gcry_rngfips_deinit_external_test (context); + } +diff -up libgcrypt-1.6.2/random/random.h.drbg libgcrypt-1.6.2/random/random.h +--- libgcrypt-1.6.2/random/random.h.drbg 2014-08-18 08:46:51.000000000 +0200 ++++ libgcrypt-1.6.2/random/random.h 2014-12-08 16:31:33.514992163 +0100 +@@ -54,7 +54,29 @@ gcry_err_code_t _gcry_random_run_externa + char *buffer, size_t buflen); + void _gcry_random_deinit_external_test (void *context); + ++/*-- drbg.c --*/ ++gpg_err_code_t _gcry_drbg_reinit (u32 flags, struct gcry_drbg_string *pers); ++/* private interfaces for testing of DRBG */ ++struct gcry_drbg_test_vector ++{ ++ u32 flags; ++ unsigned char *entropy; ++ size_t entropylen; ++ unsigned char *entpra; ++ unsigned char *entprb; ++ size_t entprlen; ++ unsigned char *addtla; ++ unsigned char *addtlb; ++ size_t addtllen; ++ unsigned char *pers; ++ size_t perslen; ++ unsigned char *expected; ++ size_t expectedlen; ++}; + ++gpg_err_code_t gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, ++ unsigned char *buf); ++gpg_err_code_t gcry_drbg_healthcheck_one (struct gcry_drbg_test_vector *test); + /*-- rndegd.c --*/ + gpg_error_t _gcry_rndegd_set_socket_name (const char *name); + +diff -up libgcrypt-1.6.2/src/gcrypt.h.in.drbg libgcrypt-1.6.2/src/gcrypt.h.in +--- libgcrypt-1.6.2/src/gcrypt.h.in.drbg 2014-08-21 14:50:39.000000000 +0200 ++++ libgcrypt-1.6.2/src/gcrypt.h.in 2014-12-08 16:31:33.515992186 +0100 +@@ -329,7 +329,9 @@ enum gcry_ctl_cmds + GCRYCTL_SET_CCM_LENGTHS = 69, + GCRYCTL_CLOSE_RANDOM_DEVICE = 70, + GCRYCTL_INACTIVATE_FIPS_FLAG = 71, +- GCRYCTL_REACTIVATE_FIPS_FLAG = 72 ++ GCRYCTL_REACTIVATE_FIPS_FLAG = 72, ++ GCRYCTL_DRBG_REINIT = 74 ++ /* Note: 75 is used internally */ + }; + + /* Perform various operations defined by CMD. */ +@@ -1668,6 +1670,112 @@ int gcry_is_secure (const void *a) _GCRY + /* Return true if Libgcrypt is in FIPS mode. */ + #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) + ++/* DRBG input data structure for DRBG generate with additional information ++ * string */ ++struct gcry_drbg_gen { ++ unsigned char *outbuf; /* output buffer for random numbers */ ++ unsigned int outlen; /* size of output buffer */ ++ struct gcry_drbg_string *addtl; /* input buffer for ++ * additional information string */ ++}; ++ ++/* ++ * Concatenation Helper and string operation helper ++ * ++ * SP800-90A requires the concatenation of different data. To avoid copying ++ * buffers around or allocate additional memory, the following data structure ++ * is used to point to the original memory with its size. In addition, it ++ * is used to build a linked list. The linked list defines the concatenation ++ * of individual buffers. The order of memory block referenced in that ++ * linked list determines the order of concatenation. ++ */ ++/* DRBG string definition */ ++struct gcry_drbg_string { ++ const unsigned char *buf; ++ size_t len; ++ struct gcry_drbg_string *next; ++}; ++ ++static inline void gcry_drbg_string_fill(struct gcry_drbg_string *string, ++ const unsigned char *buf, size_t len) ++{ ++ string->buf = buf; ++ string->len = len; ++ string->next = NULL; ++} ++ ++/* this is a wrapper function for users of libgcrypt */ ++static inline void gcry_randomize_drbg(void *outbuf, size_t outlen, ++ enum gcry_random_level level, ++ struct gcry_drbg_string *addtl) ++{ ++ struct gcry_drbg_gen genbuf; ++ genbuf.outbuf = (unsigned char *)outbuf; ++ genbuf.outlen = outlen; ++ genbuf.addtl = addtl; ++ gcry_randomize(&genbuf, 0, level); ++} ++ ++/* ++ * DRBG flags bitmasks ++ * ++ * 31 (B) 28 19 (A) 0 ++ * +-+-+-+--------+---+-----------+-----+ ++ * |~|~|u|~~~~~~~~| 3 | 2 | 1 | ++ * +-+-+-+--------+- -+-----------+-----+ ++ * ctl flg| |drbg use selection flags ++ * ++ */ ++ ++/* internal state control flags (B) */ ++#define GCRY_DRBG_PREDICTION_RESIST ((u_int32_t)1<<28) ++ ++/* CTR type modifiers (A.1)*/ ++#define GCRY_DRBG_CTRAES ((u_int32_t)1<<0) ++#define GCRY_DRBG_CTRSERPENT ((u_int32_t)1<<1) ++#define GCRY_DRBG_CTRTWOFISH ((u_int32_t)1<<2) ++#define GCRY_DRBG_CTR_MASK (GCRY_DRBG_CTRAES | GCRY_DRBG_CTRSERPENT | GCRY_DRBG_CTRTWOFISH) ++ ++/* HASH type modifiers (A.2)*/ ++#define GCRY_DRBG_HASHSHA1 ((u_int32_t)1<<4) ++#define GCRY_DRBG_HASHSHA224 ((u_int32_t)1<<5) ++#define GCRY_DRBG_HASHSHA256 ((u_int32_t)1<<6) ++#define GCRY_DRBG_HASHSHA384 ((u_int32_t)1<<7) ++#define GCRY_DRBG_HASHSHA512 ((u_int32_t)1<<8) ++#define GCRY_DRBG_HASH_MASK (GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HASHSHA224 | \ ++ GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HASHSHA384 | \ ++ GCRY_DRBG_HASHSHA512) ++/* type modifiers (A.3)*/ ++#define GCRY_DRBG_HMAC ((u_int32_t)1<<12) ++#define GCRY_DRBG_SYM128 ((u_int32_t)1<<13) ++#define GCRY_DRBG_SYM192 ((u_int32_t)1<<14) ++#define GCRY_DRBG_SYM256 ((u_int32_t)1<<15) ++#define GCRY_DRBG_TYPE_MASK (GCRY_DRBG_HMAC | GCRY_DRBG_SYM128 | GCRY_DRBG_SYM192 | \ ++ GCRY_DRBG_SYM256) ++#define GCRY_DRBG_CIPHER_MASK (GCRY_DRBG_CTR_MASK | GCRY_DRBG_HASH_MASK | GCRY_DRBG_TYPE_MASK) ++ ++#define GCRY_DRBG_PR_CTRAES128 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128) ++#define GCRY_DRBG_PR_CTRAES192 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192) ++#define GCRY_DRBG_PR_CTRAES256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256) ++#define GCRY_DRBG_NOPR_CTRAES128 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128) ++#define GCRY_DRBG_NOPR_CTRAES192 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192) ++#define GCRY_DRBG_NOPR_CTRAES256 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256) ++#define GCRY_DRBG_PR_HASHSHA1 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA1) ++#define GCRY_DRBG_PR_HASHSHA256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA256) ++#define GCRY_DRBG_PR_HASHSHA384 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA384) ++#define GCRY_DRBG_PR_HASHSHA512 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA512) ++#define GCRY_DRBG_NOPR_HASHSHA1 (GCRY_DRBG_HASHSHA1) ++#define GCRY_DRBG_NOPR_HASHSHA256 (GCRY_DRBG_HASHSHA256) ++#define GCRY_DRBG_NOPR_HASHSHA384 (GCRY_DRBG_HASHSHA384) ++#define GCRY_DRBG_NOPR_HASHSHA512 (GCRY_DRBG_HASHSHA512) ++#define GCRY_DRBG_PR_HMACSHA1 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC) ++#define GCRY_DRBG_PR_HMACSHA256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC) ++#define GCRY_DRBG_PR_HMACSHA384 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC) ++#define GCRY_DRBG_PR_HMACSHA512 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC) ++#define GCRY_DRBG_NOPR_HMACSHA1 (GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC) ++#define GCRY_DRBG_NOPR_HMACSHA256 (GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC) ++#define GCRY_DRBG_NOPR_HMACSHA384 (GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC) ++#define DRBG_NOPR_HMACSHA512 (GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC) + + #if 0 /* (Keep Emacsens' auto-indent happy.) */ + { +diff -up libgcrypt-1.6.2/src/global.c.drbg libgcrypt-1.6.2/src/global.c +--- libgcrypt-1.6.2/src/global.c.drbg 2014-08-21 14:50:39.000000000 +0200 ++++ libgcrypt-1.6.2/src/global.c 2014-12-08 16:31:33.515992186 +0100 +@@ -680,6 +680,28 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, + rc = GPG_ERR_NOT_IMPLEMENTED; + break; + ++ case GCRYCTL_DRBG_REINIT: ++ { ++ u32 flags = va_arg (arg_ptr, u32); ++ struct gcry_drbg_string *pers = va_arg (arg_ptr, ++ struct gcry_drbg_string *); ++ rc = _gcry_drbg_reinit(flags, pers); ++ } ++ break; ++ ++ case 75: ++ { ++ struct gcry_drbg_test_vector *test = ++ va_arg (arg_ptr, struct gcry_drbg_test_vector *); ++ unsigned char *buf = va_arg (arg_ptr, unsigned char *); ++ ++ if (buf) ++ rc = gcry_drbg_cavs_test (test, buf); ++ else ++ rc = gcry_drbg_healthcheck_one (test); ++ } ++ break; ++ + default: + _gcry_set_preferred_rng_type (0); + rc = GPG_ERR_INV_OP; diff --git a/libgcrypt-1.6.2-fips-cavs.patch b/libgcrypt-1.6.2-fips-cavs.patch new file mode 100644 index 0000000..52067b0 --- /dev/null +++ b/libgcrypt-1.6.2-fips-cavs.patch @@ -0,0 +1,1400 @@ +diff -up libgcrypt-1.5.3/tests/cavs_driver.pl.cavs libgcrypt-1.5.3/tests/cavs_driver.pl +--- libgcrypt-1.5.3/tests/cavs_driver.pl.cavs 2013-05-22 18:02:55.000000000 +0200 ++++ libgcrypt-1.5.3/tests/cavs_driver.pl 2014-10-21 09:38:34.250691408 +0200 +@@ -1,9 +1,11 @@ + #!/usr/bin/env perl + # +-# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ ++# $Id: cavs_driver.pl 2124 2010-12-20 07:56:30Z smueller $ + # + # CAVS test driver (based on the OpenSSL driver) + # Written by: Stephan Müller ++# Werner Koch (libgcrypt interface) ++# Tomas Mraz (addition of DSA2) + # Copyright (c) atsec information security corporation + # + # Permission is hereby granted, free of charge, to any person obtaining a copy +@@ -85,13 +87,16 @@ + # T[CBC|CFB??|ECB|OFB]varkey + # T[CBC|CFB??|ECB|OFB]invperm + # T[CBC|CFB??|ECB|OFB]vartext ++# WARNING: TDES in CFB and OFB mode problems see below + # + # ANSI X9.31 RNG + # ANSI931_AES128MCT + # ANSI931_AES128VST + # +-# DSA ++# DSA2 + # PQGGen ++# PQGVer ++# KeyPair + # SigGen + # SigVer + # +@@ -101,6 +106,36 @@ + # RC4PltBD + # RC4REGT + # ++# ++# TDES MCT for CFB and OFB: ++# ------------------------- ++# The inner loop cannot be handled by this script. If you want to have tests ++# for these cipher types, implement your own inner loop and add it to ++# crypto_mct. ++# ++# the value $next_source in crypto_mct is NOT set by the standard implementation ++# of this script. It would need to be set as follows for these two (code take ++# from fipsdrv.c from libgcrypt - the value input at the end will contain the ++# the value for $next_source: ++# ++# ... inner loop ... ++# ... ++# get_current_iv (hd, last_iv, blocklen); ++# ... encrypt / decrypt (input is the data to be en/decrypted and output is the ++# result of operation) ... ++# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) ++# memcpy (input, last_iv, blocklen); ++# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) ++# memcpy (input, last_iv, blocklen); ++# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) ++# { ++# /* Reconstruct the output vector. */ ++# int i; ++# for (i=0; i < blocklen; i++) ++# input[i] ^= output[i]; ++# } ++# ... inner loop ends ... ++# ==> now, the value of input is to be put into $next_source + + use strict; + use warnings; +@@ -226,6 +261,8 @@ my $hmac; + # Generate the P, Q, G, Seed, counter, h (value used to generate g) values + # for DSA + # $1: modulus size ++# $2: q size ++# $3: seed (might be empty string) + # return: string with the calculated values in hex format, where each value + # is separated from the previous with a \n in the following order: + # P\n +@@ -236,6 +273,19 @@ my $hmac; + # h + my $dsa_pqggen; + ++# Generate the G value from P and Q ++# for DSA ++# $1: modulus size ++# $2: q size ++# $3: P in hex form ++# $4: Q in hex form ++# return: string with the calculated values in hex format, where each value ++# is separated from the previous with a \n in the following order: ++# P\n ++# Q\n ++# G\n ++my $dsa_ggen; ++ + # + # Generate an DSA public key from the provided parameters: + # $1: Name of file to create +@@ -255,16 +305,30 @@ my $dsa_verify; + + # generate a new DSA key with the following properties: + # PEM format +-# $1 keyfile name +-# return: file created, hash with keys of P, Q, G in hex format ++# $1: modulus size ++# $2: q size ++# $3 keyfile name ++# return: file created with key, string with values of P, Q, G in hex format + my $gen_dsakey; + ++# generate a new DSA private key XY parameters in domain: ++# PEM format ++# $1: P in hex form ++# $2: Q in hex form ++# $3: G in hex form ++# return: string with values of X, Y in hex format ++my $gen_dsakey_domain; ++ + # Sign a message with DSA + # $1: data to be signed in hex form + # $2: Key file in PEM format with the private key + # return: hash of digest information in hex format with Y, R, S as keys + my $dsa_sign; + ++my $rsa_keygen; ++ ++my $rsa_keygen_kat; ++ + ################################################################ + ##### OpenSSL interface functions + ################################################################ +@@ -404,6 +468,35 @@ sub libgcrypt_rsa_derive($$$$$$$$) { + } + + ++sub libgcrypt_rsa_keygen($) { ++ my $n = shift; ++ my $sexp; ++ ++ $n = sprintf ("%u", $n); ++ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")))\n"; ++ ++ return pipe_through_program($sexp, "fipsdrv rsa-keygen"); ++} ++ ++ ++sub libgcrypt_rsa_keygen_kat($$$$) { ++ my $n = shift; ++ my $e = shift; ++ my $p = shift; ++ my $q = shift; ++ my $sexp; ++ ++ $n = sprintf ("%u", $n); ++ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" ++ . "(test-parms" ++ . "(e #$e#)" ++ . "(p #$p#)" ++ . "(q #$q#))))\n"; ++ ++ return pipe_through_program($sexp, "fipsdrv rsa-keygen-kat"); ++} ++ ++ + sub libgcrypt_rsa_sign($$$) { + my $data = shift; + my $hashalgo = shift; +@@ -500,17 +593,32 @@ sub libgcrypt_hmac($$$$) { + return pipe_through_program($msg, $program); + } + +-sub libgcrypt_dsa_pqggen($) { ++sub libgcrypt_dsa_pqggen($$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $seed = shift; ++ ++ my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; ++ return pipe_through_program($seed, $program); ++} ++ ++sub libgcrypt_dsa_ggen($$$$) { + my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $domain = "(domain (p #$p#)(q #$q#))"; + +- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; ++ my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; + return pipe_through_program("", $program); + } + +-sub libgcrypt_gen_dsakey($) { ++sub libgcrypt_gen_dsakey($$$) { ++ my $mod = shift; ++ my $qsize = shift; + my $file = shift; + +- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; ++ my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; + my $tmp; + my %ret; + +@@ -519,10 +627,21 @@ sub libgcrypt_gen_dsakey($) { + $tmp = pipe_through_program("", $program); + die "dsa key gen failed: file $file not created" if (! -f $file); + +- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); ++ @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); + return %ret; + } + ++sub libgcrypt_gen_dsakey_domain($$$) { ++ my $p = shift; ++ my $q = shift; ++ my $g = shift; ++ my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; ++ ++ my $program = "fipsdrv --key '$domain' dsa-gen-key"; ++ ++ return pipe_through_program("", $program); ++} ++ + sub libgcrypt_dsa_genpubkey($$$$$) { + my $filename = shift; + my $p = shift; +@@ -1139,7 +1258,7 @@ sub hmac_kat($$$$) { + $out .= "Tlen = $tlen\n"; + $out .= "Key = $key\n"; + $out .= "Msg = $msg\n"; +- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; ++ $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; + + return $out; + } +@@ -1205,7 +1324,7 @@ sub crypto_mct($$$$$$$$) { + } + my ($CO, $CI); + my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); +- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); ++ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); + my $pid = open2($CO, $CI, $cipher_imp); + + my $calc_data = $iv; # CT[j] +@@ -1213,8 +1332,8 @@ sub crypto_mct($$$$$$$$) { + my $old_old_calc_data; # CT[j-2] + my $next_source; + +- # TDES inner loop implements logic within driver +- if ($cipher =~ /des/) { ++ # TDES inner loop implements logic within driver of libgcrypt ++ if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { + # Need to provide a dummy IV in case of ECB mode. + my $iv_arg = (defined($iv) && $iv ne "") + ? bin2hex($iv) +@@ -1238,6 +1357,10 @@ sub crypto_mct($$$$$$$$) { + $line = <$CO>; + } else { + for (my $j = 0; $j < $iloop; ++$j) { ++ if ($cipher =~ /des-ede3-ofb/ || ++ (!$enc && $cipher =~ /des-ede3-cfb/)) { ++ die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; ++ } + $old_old_calc_data = $old_calc_data; + $old_calc_data = $calc_data; + +@@ -1429,7 +1552,7 @@ sub rsa_sigver($$$$$) { + # $7 xq2 + # $8 Xq + # return: string formatted as expected by CAVS +-sub rsa_keygen($$$$$$$$) { ++sub rsa_keygen_x931($$$$$$$$) { + my $modulus = shift; + my $e = shift; + my $xp1 = shift; +@@ -1503,21 +1626,23 @@ sub rngx931($$$$) { + return $out; + } + +-# DSA PQGGen test ++# DSA PQGen test + # $1 modulus size +-# $2 number of rounds to perform the test ++# $2 q size ++# $3 number of rounds to perform the test + # return: string formatted as expected by CAVS +-sub dsa_pqggen_driver($$) { ++sub dsa_pqgen_driver($$$) { + my $mod = shift; ++ my $qsize = shift; + my $rounds = shift; + + my $out = ""; + for(my $i=0; $i<$rounds; $i++) { +- my $ret = &$dsa_pqggen($mod); ++ my $ret = &$dsa_pqggen($mod, $qsize, ""); + my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); +- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" +- if (!defined($P) || !defined($Q) || !defined($G) || +- !defined($Seed) || !defined($c) || !defined($H)); ++ die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || ++ !defined($Seed) || !defined($c)); + + # now change the counter to decimal as CAVS wants decimal + # counter value although all other is HEX +@@ -1525,15 +1650,166 @@ sub dsa_pqggen_driver($$) { + + $out .= "P = $P\n"; + $out .= "Q = $Q\n"; +- $out .= "G = $G\n"; +- $out .= "Seed = $Seed\n"; +- $out .= "c = $c\n"; +- $out .= "H = $H\n\n"; ++ $out .= "domain_parameter_seed = $Seed\n"; ++ $out .= "counter = $c\n\n"; + } + + return $out; + } + ++# DSA GGen test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# return: string formatted as expected by CAVS ++sub dsa_ggen_driver($$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_ggen($mod, $qsize, $p, $q); ++ my ($P, $Q, $G) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G for dsa_ggen" ++ if (!defined($P) || !defined($Q) || !defined($G)); ++ ++ $out .= "G = $G\n\n"; ++ ++ return $out; ++} ++ ++sub hexcomp($$) { ++ my $a = lc shift; ++ my $b = lc shift; ++ ++ if (length $a < length $b) { ++ my $c = $a; ++ $a = $b; ++ $b = $a; ++ } ++ ++ while (length $b < length $a) { ++ $b = "00$b"; ++ } ++ ++ return $a eq $b; ++} ++ ++# DSA PQVer test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# $5 seed in hex form ++# $6 c decimal counter ++# return: string formatted as expected by CAVS ++sub dsa_pqver_driver($$$$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $seed = shift; ++ my $c = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_pqggen($mod, $qsize, $seed); ++ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || !defined($G) || ++ !defined($seed2) || !defined($c2)); ++ ++ $c2 = hex($c2); ++ ++ $out .= "Seed = $seed\n"; ++ $out .= "c = $c\n"; ++ ++ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($seed, $seed2) && $c == $c2) { ++ $out .= "Result = P\n\n"; ++ } ++ else { ++ $out .= "Result = F\n\n"; ++ } ++ return $out; ++} ++ ++# DSA PQGVer test ++# $1 modulus size ++# $2 q size ++# $3 p in hex form ++# $4 q in hex form ++# $5 g in hex form ++# $6 seed in hex form ++# $7 c decimal counter ++# $8 h in hex form ++# return: string formatted as expected by CAVS ++sub dsa_pqgver_driver($$$$$$$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $p = shift; ++ my $q = shift; ++ my $g = shift; ++ my $seed = shift; ++ my $c = shift; ++ my $h = shift; ++ ++ my $out = ""; ++ my $ret = &$dsa_pqggen($mod, $qsize, $seed); ++ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" ++ if (!defined($P) || !defined($Q) || !defined($G) || ++ !defined($seed2) || !defined($c2) || !defined($h2)); ++ ++ ++ ++ $out .= "Seed = $seed\n"; ++ $out .= "c = $c\n"; ++ $out .= "H = $h\n"; ++ ++ $c2 = hex($c2); ++ ++ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && ++ $c == $c2 && hex($h) == hex($h2)) { ++ $out .= "Result = P\n\n"; ++ } ++ else { ++ $out .= "Result = F\n\n"; ++ } ++ ++ return $out; ++} ++ ++# DSA Keypair test ++# $1 modulus size ++# $2 q size ++# $3 number of rounds to perform the test ++# return: string formatted as expected by CAVS ++sub dsa_keypair_driver($$$) { ++ my $mod = shift; ++ my $qsize = shift; ++ my $rounds = shift; ++ ++ my $out = ""; ++ my $tmpkeyfile = "dsa_siggen.tmp.$$"; ++ my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); ++ $out .= "P = " . $pqg{'P'} . "\n"; ++ $out .= "Q = " . $pqg{'Q'} . "\n"; ++ $out .= "G = " . $pqg{'G'} . "\n\n"; ++ unlink($tmpkeyfile); ++ ++ for(my $i=0; $i<$rounds; $i++) { ++ my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); ++ my ($X, $Y) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" ++ if (!defined($X) || !defined($Y)); ++ ++ $out .= "X = $X\n"; ++ $out .= "Y = $Y\n\n"; ++ } ++ ++ return $out; ++} + + # DSA SigGen test + # $1: Message to be signed in hex form +@@ -1598,6 +1874,53 @@ sub dsa_sigver($$$$$$$$) { + return $out; + } + ++# RSA Keygen RPP test ++# $1 modulus size ++# $2 number of rounds to perform the test ++# return: string formatted as expected by CAVS ++sub rsa_keygen_driver($$) { ++ my $mod = shift; ++ my $rounds = shift; ++ ++ my $out = ""; ++ ++ for(my $i=0; $i<$rounds; $i++) { ++ my $ret = &$rsa_keygen($mod); ++ my ($e, $p, $q, $n, $d) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of e, p, q, n, d for rsa_keygen" ++ if (!defined($e) || !defined($p) || !defined($q) || !defined($n) || !defined($d)); ++ ++ $out .= "e = $e\n"; ++ $out .= "p = $p\n"; ++ $out .= "q = $q\n"; ++ $out .= "n = $n\n"; ++ $out .= "d = $d\n\n"; ++ } ++ ++ return $out; ++} ++ ++# RSA RPP Keygen KAT test ++# $1 modulus size ++# $2 p in hex form ++# $3 q in hex form ++# return: string formatted as expected by CAVS ++sub rsa_keygen_kat_driver($$$) { ++ my $mod = shift; ++ my $p = shift; ++ my $q = shift; ++ ++ my $out = ""; ++ my $ret = &$rsa_keygen_kat($mod, $p, $q); ++ my ($Result) = split(/\n/, $ret); ++ die "Return value does not contain all expected values of Result for rsa_keygen_kat" ++ if (!defined($Result)); ++ ++ $out .= "Result = $Result\n\n"; ++ return $out; ++} ++ ++ + ############################################################## + # Parser of input file and generator of result file + # +@@ -1658,12 +1981,18 @@ sub parse($$) { + my $klen = ""; + my $tlen = ""; + my $modulus = ""; ++ my $qsize = ""; + my $capital_n = 0; ++ my $num = 0; + my $capital_p = ""; + my $capital_q = ""; + my $capital_g = ""; + my $capital_y = ""; + my $capital_r = ""; ++ my $capital_h = ""; ++ my $c = ""; ++ my $prandom = ""; ++ my $qrandom = ""; + my $xp1 = ""; + my $xp2 = ""; + my $Xp = ""; +@@ -1700,7 +2029,7 @@ sub parse($$) { + + ##### Extract cipher + # XXX there may be more - to be added +- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { ++ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyGen - Random Probably Prime|KeyPair|PQGVer)/) { + if ($tmpline =~ /CBC/) { $mode="cbc"; } + elsif ($tmpline =~ /ECB/) { $mode="ecb"; } + elsif ($tmpline =~ /OFB/) { $mode="ofb"; } +@@ -1749,7 +2078,23 @@ sub parse($$) { + + if ($tt == 0) { + ##### Identify the test type +- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { ++ if ($tmpline =~ /KeyGen - Random Probably Prime Known Answer Test/) { ++ $tt = 19; ++ die "Interface function rsa_keygen_kat for RSA key generation KAT not defined for tested library" ++ if (!defined($rsa_keygen_kat)); ++ } elsif ($tmpline =~ /KeyGen - Random Probably Prime Test/) { ++ $tt = 18; ++ die "Interface function rsa_keygen for RSA key generation not defined for tested library" ++ if (!defined($rsa_keygen)); ++ } elsif ($tmpline =~ /PQGVer/) { ++ $tt = 16; ++ die "Interface function for DSA PQGVer testing not defined for tested library" ++ if (!defined($dsa_pqggen)); ++ } elsif ($tmpline =~ /KeyPair/) { ++ $tt = 14; ++ die "Interface function dsa_keygen for DSA key generation not defined for tested library" ++ if (!defined($gen_dsakey_domain)); ++ } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { + $tt = 13; + die "Interface function rsa_derive for RSA key generation not defined for tested library" + if (!defined($rsa_derive)); +@@ -1760,11 +2105,11 @@ sub parse($$) { + } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { + $tt = 11; + die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" +- if (!defined($dsa_sign) || !defined($gen_rsakey)); ++ if (!defined($dsa_sign) || !defined($gen_dsakey)); + } elsif ($tmpline =~ /PQGGen/) { + $tt = 10; + die "Interface function for DSA PQGGen testing not defined for tested library" +- if (!defined($dsa_pqggen)); ++ if (!defined($dsa_pqggen) || !defined($dsa_ggen)); + } elsif ($tmpline =~ /Hash sizes tested/) { + $tt = 9; + die "Interface function hmac for HMAC testing not defined for tested library" +@@ -1792,7 +2137,7 @@ sub parse($$) { + } elsif ($tmpline =~ /Monte|MCT|Carlo/) { + $tt = 2; + die "Interface function state_cipher for Stateful Cipher operation defined for tested library" +- if (!defined($state_cipher) || !defined($state_cipher_des)); ++ if (!defined($state_cipher) && !defined($state_cipher_des)); + } elsif ($cipher =~ /^sha/) { + $tt = 3; + die "Interface function hash for Hashing not defined for tested library" +@@ -1875,18 +2220,44 @@ sub parse($$) { + die "Msg/Seed seen twice - input file crap" if ($pt ne ""); + $pt=$2; + } +- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests ++ elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request ++ $out .= $line . "\n"; # print it ++ if ($tt == 10) { ++ # now generate G from PQ ++ $tt = 15; ++ } ++ } ++ elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request ++ $out .= $line . "\n"; # print it ++ if ($tt == 16) { ++ # now verify PQG ++ $tt = 17; ++ } ++ } ++ elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests + $modulus = $1; ++ $qsize = $2; + $out .= $line . "\n\n"; # print it ++ # clear eventual PQG ++ $capital_p = ""; ++ $capital_q = ""; ++ $capital_g = ""; + # generate the private key with given bit length now + # as we have the required key length in bit + if ($tt == 11) { + $dsa_keyfile = "dsa_siggen.tmp.$$"; +- my %pqg = &$gen_dsakey($dsa_keyfile); ++ my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); + $out .= "P = " . $pqg{'P'} . "\n"; + $out .= "Q = " . $pqg{'Q'} . "\n"; +- $out .= "G = " . $pqg{'G'} . "\n"; +- } elsif ( $tt == 5 ) { ++ $out .= "G = " . $pqg{'G'} . "\n\n"; ++ } ++ } ++ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests ++ $modulus = $1; ++ $out .= $line . "\n\n"; # print it ++ # generate the private key with given bit length now ++ # as we have the required key length in bit ++ if ( $tt == 5 ) { + # XXX maybe a secure temp file name is better here + # but since it is not run on a security sensitive + # system, I hope that this is fine +@@ -1907,6 +2278,9 @@ sub parse($$) { + } + elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests + $e=$1; ++ if ($tt == 19) { ++ $out .= $line . "\n"; # print it ++ } + } + elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests + die "S seen twice - input file crap" if ($signature ne ""); +@@ -1932,11 +2306,16 @@ sub parse($$) { + if ($tlen ne ""); + $tlen=$1; + } +- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen ++ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair + die "N seen twice - check input file" + if ($capital_n); + $capital_n = $1; + } ++ elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen ++ die "Num seen twice - check input file" ++ if ($num); ++ $num = $1; ++ } + elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer + die "P seen twice - check input file" + if ($capital_p); +@@ -1965,6 +2344,16 @@ sub parse($$) { + if ($capital_r); + $capital_r = $1; + } ++ elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer ++ die "H seen twice - check input file" ++ if ($capital_h); ++ $capital_h = $1; ++ } ++ elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer ++ die "c seen twice - check input file" ++ if ($c); ++ $c = $1; ++ } + elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen + die "xp1 seen twice - check input file" + if ($xp1); +@@ -1995,6 +2384,22 @@ sub parse($$) { + if ($Xq); + $Xq = $1; + } ++ elsif ($line =~ /^prandom\s*=\s*(.*)/) { #RSA key gen KAT ++ die "prandom seen twice - check input file" ++ if ($prandom); ++ $prandom = $1; ++ $out .= $line . "\n"; # print it ++ } ++ elsif ($line =~ /^qrandom\s*=\s*(.*)/) { #RSA key gen KAT ++ die "qrandom seen twice - check input file" ++ if ($qrandom); ++ $qrandom = $1; ++ $out .= $line . "\n"; # print it ++ } ++ elsif ($tt == 19 && $line =~ /^ / && $qrandom eq "") { #RSA key gen KAT ++ $qrandom = "00"; ++ $out .= $line . "\n"; # print it ++ } + else { + $out .= $line . "\n"; + } +@@ -2074,11 +2479,10 @@ sub parse($$) { + } + } + elsif ($tt == 10) { +- if ($modulus ne "" && $capital_n > 0) { +- $out .= dsa_pqggen_driver($modulus, $capital_n); +- #$mod is not resetted +- $capital_n = 0; +- } ++ if ($modulus ne "" && $qsize ne "" && $num > 0) { ++ $out .= dsa_pqgen_driver($modulus, $qsize, $num); ++ $num = 0; ++ } + } + elsif ($tt == 11) { + if ($pt ne "" && $dsa_keyfile ne "") { +@@ -2124,7 +2528,7 @@ sub parse($$) { + $xq1 ne "" && + $xq2 ne "" && + $Xq ne "") { +- $out .= rsa_keygen($modulus, ++ $out .= rsa_keygen_x931($modulus, + $e, + $xp1, + $xp2, +@@ -2141,6 +2545,96 @@ sub parse($$) { + $Xq = ""; + } + } ++ elsif ($tt == 14) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_n > 0) { ++ $out .= dsa_keypair_driver($modulus, ++ $qsize, ++ $capital_n); ++ $capital_n = 0; ++ } ++ } ++ elsif ($tt == 15) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "") { ++ $out .= dsa_ggen_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q); ++ $capital_p = ""; ++ $capital_q = ""; ++ $num--; ++ } ++ } ++ elsif ($tt == 16) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "" && ++ $pt ne "" && ++ $c ne "") { ++ $out .= dsa_pqver_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q, ++ $pt, ++ $c); ++ $capital_p = ""; ++ $capital_q = ""; ++ $pt = ""; ++ $c = ""; ++ } ++ } ++ elsif ($tt == 17) { ++ if ($modulus ne "" && ++ $qsize ne "" && ++ $capital_p ne "" && ++ $capital_q ne "" && ++ $capital_g ne "" && ++ $pt ne "" && ++ $c ne "" && ++ $capital_h ne "") { ++ $out .= dsa_pqgver_driver($modulus, ++ $qsize, ++ $capital_p, ++ $capital_q, ++ $capital_g, ++ $pt, ++ $c, ++ $capital_h); ++ $capital_p = ""; ++ $capital_q = ""; ++ $capital_g = ""; ++ $pt = ""; ++ $c = ""; ++ $capital_h = ""; ++ } ++ } ++ elsif ($tt == 18) { ++ if ($modulus ne "" && ++ $capital_n > 0) { ++ $out .= rsa_keygen_driver($modulus, ++ $capital_n); ++ $capital_n = 0; ++ } ++ } ++ elsif ($tt == 19) { ++ if ($modulus ne "" && ++ $e ne "" && ++ $prandom ne "" && ++ $qrandom ne "") { ++ $out .= rsa_keygen_kat_driver($modulus, ++ $e, ++ $prandom, ++ $qrandom); ++ $prandom = ""; ++ $qrandom = ""; ++ $e = ""; ++ } ++ } + elsif ($tt > 0) { + die "Test case $tt not defined"; + } +@@ -2199,10 +2693,14 @@ sub main() { + $state_rng = \&libgcrypt_state_rng; + $hmac = \&libgcrypt_hmac; + $dsa_pqggen = \&libgcrypt_dsa_pqggen; ++ $dsa_ggen = \&libgcrypt_dsa_ggen; + $gen_dsakey = \&libgcrypt_gen_dsakey; ++ $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; + $dsa_sign = \&libgcrypt_dsa_sign; + $dsa_verify = \&libgcrypt_dsa_verify; + $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; ++ $rsa_keygen = \&libgcrypt_rsa_keygen; ++ $rsa_keygen_kat = \&libgcrypt_rsa_keygen_kat; + } else { + die "Invalid interface option given"; + } +diff -up libgcrypt-1.5.3/tests/cavs_tests.sh.cavs libgcrypt-1.5.3/tests/cavs_tests.sh +--- libgcrypt-1.5.3/tests/cavs_tests.sh.cavs 2013-05-22 18:02:55.000000000 +0200 ++++ libgcrypt-1.5.3/tests/cavs_tests.sh 2014-09-26 17:45:38.434674884 +0200 +@@ -55,7 +55,7 @@ function run_one_test () { + [ -d "$respdir" ] || mkdir "$respdir" + [ -f "$rspfile" ] && rm "$rspfile" + +- if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then ++ if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then + dflag="-D" + fi + +diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c +--- libgcrypt-1.5.3/tests/fipsdrv.c.cavs 2013-07-25 11:10:04.000000000 +0200 ++++ libgcrypt-1.5.3/tests/fipsdrv.c 2014-10-21 09:30:30.796777225 +0200 +@@ -893,6 +893,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) + die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); + + p = buf; ++ while (*p) ++ *p++ = tolower(*p); ++ p = buf; + if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) + p += 2; + +@@ -1346,6 +1349,69 @@ run_rsa_derive (const void *data, size_t + } + + ++/* Generate RSA key using the S-expression in (DATA,DATALEN). This ++ S-expression is used directly as input to gcry_pk_genkey. The ++ result is printed to stdout with one parameter per line in hex ++ format and in this order: e, p, q, n, d. */ ++static void ++run_rsa_keygen (const void *data, size_t datalen, int test) ++{ ++ gpg_error_t err; ++ gcry_sexp_t s_keyspec, s_key, s_top, l1; ++ gcry_mpi_t mpi; ++ const char *parmlist; ++ int idx; ++ ++ if (!datalen) ++ err = gpg_error (GPG_ERR_NO_DATA); ++ else ++ err = gcry_sexp_new (&s_keyspec, data, datalen, 1); ++ if (err) ++ die ("gcry_sexp_new failed for RSA key generation: %s\n", ++ gpg_strerror (err)); ++ ++ err = gcry_pk_genkey (&s_key, s_keyspec); ++ ++ gcry_sexp_release (s_keyspec); ++ ++ if (test) { ++ if (err) ++ printf("F\n"); ++ else { ++ gcry_sexp_release (s_key); ++ printf("P\n"); ++ } ++ return; ++ } ++ ++ if (err) ++ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); ++ ++ parmlist = "epqnd"; ++ ++ /* Parse and print the parameters. */ ++ l1 = gcry_sexp_find_token (s_key, "private-key", 0); ++ s_top = gcry_sexp_find_token (l1, "rsa", 0); ++ gcry_sexp_release (l1); ++ if (!s_top) ++ die ("private-key part not found in result\n"); ++ ++ for (idx=0; parmlist[idx]; idx++) ++ { ++ l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1); ++ mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); ++ gcry_sexp_release (l1); ++ if (!mpi) ++ die ("parameter %c missing in private-key\n", parmlist[idx]); ++ print_mpi_line (mpi, 1); ++ gcry_mpi_release (mpi); ++ } ++ ++ gcry_sexp_release (s_top); ++ gcry_sexp_release (s_key); ++} ++ ++ + + static size_t + compute_tag_length (size_t n) +@@ -1675,14 +1741,14 @@ run_rsa_verify (const void *data, size_t + /* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ + static gcry_sexp_t +-dsa_gen (int keysize) ++dsa_gen (int keysize, int qsize) + { + gpg_error_t err; + gcry_sexp_t keyspec, key; + + err = gcry_sexp_build (&keyspec, NULL, +- "(genkey (dsa (nbits %d)(use-fips186-2)))", +- keysize); ++ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", ++ keysize, qsize); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); +@@ -1700,7 +1766,7 @@ dsa_gen (int keysize) + /* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ + static gcry_sexp_t +-dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) ++dsa_gen_with_seed (int keysize, int qsize, const void *seed, size_t seedlen) + { + gpg_error_t err; + gcry_sexp_t keyspec, key; +@@ -1709,10 +1775,11 @@ dsa_gen_with_seed (int keysize, const vo + "(genkey" + " (dsa" + " (nbits %d)" +- " (use-fips186-2)" ++ " (qbits %d)" ++ " (use-fips186)" + " (derive-parms" + " (seed %b))))", +- keysize, (int)seedlen, seed); ++ keysize, qsize, (int)seedlen, seed); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); +@@ -1720,6 +1787,37 @@ dsa_gen_with_seed (int keysize, const vo + err = gcry_pk_genkey (&key, keyspec); + if (err) + die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); ++ ++ gcry_sexp_release (keyspec); ++ ++ return key; ++} ++ ++/* Generate a DSA key with specified domain parameters and return the complete ++ S-expression. */ ++static gcry_sexp_t ++dsa_gen_key (const char *domain) ++{ ++ gpg_error_t err; ++ gcry_sexp_t keyspec, key, domspec; ++ ++ err = gcry_sexp_new (&domspec, domain, strlen(domain), 0); ++ if (err) ++ die ("gcry_sexp_build failed for domain spec: %s\n", ++ gpg_strerror (err)); ++ ++ err = gcry_sexp_build (&keyspec, NULL, ++ "(genkey" ++ " (dsa" ++ " (use-fips186)" ++ " %S))", ++ domspec); ++ if (err) ++ die ("gcry_sexp_build failed for DSA key generation: %s\n", ++ gpg_strerror (err)); ++ err = gcry_pk_genkey (&key, keyspec); ++ if (err) ++ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); + + gcry_sexp_release (keyspec); + +@@ -1732,7 +1830,7 @@ dsa_gen_with_seed (int keysize, const vo + with one parameter per line in hex format using this order: p, q, + g, seed, counter, h. */ + static void +-print_dsa_domain_parameters (gcry_sexp_t key) ++print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) + { + gcry_sexp_t l1, l2; + gcry_mpi_t mpi; +@@ -1768,6 +1866,9 @@ print_dsa_domain_parameters (gcry_sexp_t + } + gcry_sexp_release (l1); + ++ if (!print_misc) ++ return; ++ + /* Extract the seed values. */ + l1 = gcry_sexp_find_token (key, "misc-key-info", 0); + if (!l1) +@@ -1819,38 +1920,106 @@ print_dsa_domain_parameters (gcry_sexp_t + } + + +-/* Generate DSA domain parameters for a modulus size of KEYSIZE. The ++/* Print just the XY private key parameters. KEY ++ is the complete key as returned by dsa_gen. We print to stdout ++ with one parameter per line in hex format using this order: x, y. */ ++static void ++print_dsa_xy (gcry_sexp_t key) ++{ ++ gcry_sexp_t l1, l2; ++ gcry_mpi_t mpi; ++ int idx; ++ ++ l1 = gcry_sexp_find_token (key, "private-key", 0); ++ if (!l1) ++ die ("private key not found in genkey result\n"); ++ ++ l2 = gcry_sexp_find_token (l1, "dsa", 0); ++ if (!l2) ++ die ("returned private key not formed as expected\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ /* Extract the parameters from the S-expression and print them to stdout. */ ++ for (idx=0; "xy"[idx]; idx++) ++ { ++ l2 = gcry_sexp_find_token (l1, "xy"+idx, 1); ++ if (!l2) ++ die ("no %c parameter in returned public key\n", "xy"[idx]); ++ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); ++ if (!mpi) ++ die ("no value for %c parameter in returned private key\n","xy"[idx]); ++ gcry_sexp_release (l2); ++ if (standalone_mode) ++ printf ("%c = ", "XY"[idx]); ++ print_mpi_line (mpi, 1); ++ gcry_mpi_release (mpi); ++ } ++ ++ gcry_sexp_release (l1); ++} ++ ++ ++/* Generate DSA pq domain parameters for a modulus size of KEYSIZE. The + result is printed to stdout with one parameter per line in hex +- format and in this order: p, q, g, seed, counter, h. If SEED is ++ format and in this order: p, q, seed, counter. If SEED is + not NULL this seed value will be used for the generation. */ + static void +-run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) ++run_dsa_pqg_gen (int keysize, int qsize, const void *seed, size_t seedlen) + { + gcry_sexp_t key; + + if (seed) +- key = dsa_gen_with_seed (keysize, seed, seedlen); ++ key = dsa_gen_with_seed (keysize, qsize, seed, seedlen); + else +- key = dsa_gen (keysize); +- print_dsa_domain_parameters (key); ++ key = dsa_gen (keysize, qsize); ++ print_dsa_domain_parameters (key, 1); ++ gcry_sexp_release (key); ++} ++ ++ ++/* Generate DSA domain parameters for a modulus size of KEYSIZE. The ++ result is printed to stdout with one parameter per line in hex ++ format and in this order: p, q, g, seed, counter, h. If SEED is ++ not NULL this seed value will be used for the generation. */ ++static void ++run_dsa_g_gen (int keysize, int qsize, const char *domain) ++{ ++ gcry_sexp_t key; ++ ++ key = dsa_gen_key (domain); ++ print_dsa_domain_parameters (key, 0); ++ gcry_sexp_release (key); ++} ++ ++/* Generate a DSA key with specified domain parameters ++ and print the XY values. */ ++static void ++run_dsa_gen_key (const char *domain) ++{ ++ gcry_sexp_t key; ++ ++ key = dsa_gen_key (domain); ++ print_dsa_xy (key); ++ + gcry_sexp_release (key); + } + + + /* Generate a DSA key of size of KEYSIZE and write the private key to + FILENAME. Also write the parameters to stdout in the same way as +- run_dsa_pqg_gen. */ ++ run_dsa_g_gen. */ + static void +-run_dsa_gen (int keysize, const char *filename) ++run_dsa_gen (int keysize, int qsize, const char *filename) + { + gcry_sexp_t key, private_key; + FILE *fp; + +- key = dsa_gen (keysize); ++ key = dsa_gen (keysize, qsize); + private_key = gcry_sexp_find_token (key, "private-key", 0); + if (!private_key) + die ("private key not found in genkey result\n"); +- print_dsa_domain_parameters (key); ++ print_dsa_domain_parameters (key, 1); + + fp = fopen (filename, "wb"); + if (!fp) +@@ -1863,6 +2032,53 @@ run_dsa_gen (int keysize, const char *fi + } + + ++static int ++dsa_hash_from_key(gcry_sexp_t s_key) ++{ ++ gcry_sexp_t l1, l2; ++ gcry_mpi_t q; ++ unsigned int qbits; ++ ++ l1 = gcry_sexp_find_token (s_key, "public-key", 0); ++ if (!l1) ++ { ++ l1 = gcry_sexp_find_token (s_key, "private-key", 0); ++ if (!l1) ++ die ("neither private nor public key found in the loaded key\n"); ++ } ++ ++ l2 = gcry_sexp_find_token (l1, "dsa", 0); ++ if (!l2) ++ die ("public key not formed as expected - no dsa\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ l2 = gcry_sexp_find_token (l1, "q", 0); ++ if (!l2) ++ die ("public key not formed as expected - no q\n"); ++ gcry_sexp_release (l1); ++ l1 = l2; ++ ++ q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); ++ if (!q) ++ die ("public key not formed as expected - no mpi in q\n"); ++ qbits = gcry_mpi_get_nbits(q); ++ gcry_sexp_release(l1); ++ gcry_mpi_release(q); ++ switch(qbits) ++ { ++ case 160: ++ return GCRY_MD_SHA1; ++ case 224: ++ return GCRY_MD_SHA224; ++ case 256: ++ return GCRY_MD_SHA256; ++ default: ++ die("bad number bits (%d) of q in key\n", qbits); ++ } ++ return GCRY_MD_NONE; ++} ++ + + /* Sign DATA of length DATALEN using the key taken from the S-expression + encoded KEYFILE. */ +@@ -1872,11 +2088,16 @@ run_dsa_sign (const void *data, size_t d + { + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; +- char hash[20]; ++ char hash[128]; + gcry_mpi_t tmpmpi; ++ int algo; + +- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); +- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); ++ ++ gcry_md_hash_buffer (algo, hash, data, datalen); ++ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, ++ gcry_md_get_algo_dlen(algo), NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, +@@ -1887,8 +2108,6 @@ run_dsa_sign (const void *data, size_t d + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + +- s_key = read_sexp_from_file (keyfile); +- + err = gcry_pk_sign (&s_sig, s_data, s_key); + if (err) + { +@@ -1964,13 +2183,18 @@ run_dsa_verify (const void *data, size_t + { + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig; +- char hash[20]; ++ char hash[128]; + gcry_mpi_t tmpmpi; ++ int algo; ++ ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); + +- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); ++ gcry_md_hash_buffer (algo, hash, data, datalen); + /* Note that we can't simply use %b with HASH to build the + S-expression, because that might yield a negative value. */ +- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); ++ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, ++ gcry_md_get_algo_dlen(algo), NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, +@@ -1981,7 +2205,6 @@ run_dsa_verify (const void *data, size_t + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + +- s_key = read_sexp_from_file (keyfile); + s_sig = read_sexp_from_file (sigfile); + + err = gcry_pk_verify (s_sig, s_data, s_key); +@@ -2014,7 +2237,7 @@ usage (int show_help) + "Run a crypto operation using hex encoded input and output.\n" + "MODE:\n" + " encrypt, decrypt, digest, random, hmac-sha,\n" +- " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" ++ " rsa-{derive,gen,sign,verify}, dsa-{pq-gen,g-gen,gen,sign,verify}\n" + "OPTIONS:\n" + " --verbose Print additional information\n" + " --binary Input and output is in binary form\n" +@@ -2024,6 +2247,7 @@ usage (int show_help) + " --dt DT Use the hex encoded DT for the RNG\n" + " --algo NAME Use algorithm NAME\n" + " --keysize N Use a keysize of N bits\n" ++ " --qize N Use a DSA q parameter size of N bits\n" + " --signature NAME Take signature from file NAME\n" + " --chunk N Read in chunks of N bytes (implies --binary)\n" + " --pkcs1 Use PKCS#1 encoding\n" +@@ -2050,6 +2274,7 @@ main (int argc, char **argv) + const char *dt_string = NULL; + const char *algo_string = NULL; + const char *keysize_string = NULL; ++ const char *qsize_string = NULL; + const char *signature_string = NULL; + FILE *input; + void *data; +@@ -2143,6 +2368,14 @@ main (int argc, char **argv) + keysize_string = *argv; + argc--; argv++; + } ++ else if (!strcmp (*argv, "--qsize")) ++ { ++ argc--; argv++; ++ if (!argc) ++ usage (0); ++ qsize_string = *argv; ++ argc--; argv++; ++ } + else if (!strcmp (*argv, "--signature")) + { + argc--; argv++; +@@ -2406,6 +2639,18 @@ main (int argc, char **argv) + die ("no data available (do not use --chunk)\n"); + run_rsa_derive (data, datalen); + } ++ else if (!strcmp (mode_string, "rsa-keygen")) ++ { ++ if (!data) ++ die ("no data available (do not use --chunk)\n"); ++ run_rsa_keygen (data, datalen, 0); ++ } ++ else if (!strcmp (mode_string, "rsa-keygen-kat")) ++ { ++ if (!data) ++ die ("no data available (do not use --chunk)\n"); ++ run_rsa_keygen (data, datalen, 1); ++ } + else if (!strcmp (mode_string, "rsa-gen")) + { + int keysize; +@@ -2463,23 +2708,49 @@ main (int argc, char **argv) + } + else if (!strcmp (mode_string, "dsa-pqg-gen")) + { +- int keysize; ++ int keysize, qsize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); +- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); ++ run_dsa_pqg_gen (keysize, qsize, datalen? data:NULL, datalen); ++ } ++ else if (!strcmp (mode_string, "dsa-g-gen")) ++ { ++ int keysize, qsize; ++ ++ keysize = keysize_string? atoi (keysize_string) : 0; ++ if (keysize < 1024 || keysize > 3072) ++ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); ++ if (!key_string) ++ die ("option --key containing pq domain parameters is required in this mode\n"); ++ run_dsa_g_gen (keysize, qsize, key_string); ++ } ++ else if (!strcmp (mode_string, "dsa-gen-key")) ++ { ++ if (!key_string) ++ die ("option --key containing pqg domain parameters is required in this mode\n"); ++ run_dsa_gen_key (key_string); + } + else if (!strcmp (mode_string, "dsa-gen")) + { +- int keysize; ++ int keysize, qsize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); ++ qsize = qsize_string? atoi (qsize_string) : 0; ++ if (qsize < 160 || qsize > 256) ++ die ("invalid qsize specified; needs to be 160 .. 256\n"); + if (!key_string) + die ("option --key is required in this mode\n"); +- run_dsa_gen (keysize, key_string); ++ run_dsa_gen (keysize, qsize, key_string); + } + else if (!strcmp (mode_string, "dsa-sign")) + { diff --git a/libgcrypt-1.6.2-fips-ctor.patch b/libgcrypt-1.6.2-fips-ctor.patch new file mode 100644 index 0000000..3934669 --- /dev/null +++ b/libgcrypt-1.6.2-fips-ctor.patch @@ -0,0 +1,56 @@ +diff -up libgcrypt-1.6.2/cipher/md.c.fips-ctor libgcrypt-1.6.2/cipher/md.c +--- libgcrypt-1.6.2/cipher/md.c.fips-ctor 2014-08-21 14:50:39.000000000 +0200 ++++ libgcrypt-1.6.2/cipher/md.c 2014-12-08 16:45:01.095256244 +0100 +@@ -413,11 +413,8 @@ md_enable (gcry_md_hd_t hd, int algorith + + if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) + { +- _gcry_inactivate_fips_mode ("MD5 used"); + if (_gcry_enforced_fips_mode () ) + { +- /* We should never get to here because we do not register +- MD5 in enforced fips mode. But better throw an error. */ + err = GPG_ERR_DIGEST_ALGO; + } + } +diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c +--- libgcrypt-1.6.2/src/global.c.fips-ctor 2014-12-08 16:45:01.094256222 +0100 ++++ libgcrypt-1.6.2/src/global.c 2014-12-08 16:46:29.182248403 +0100 +@@ -132,6 +132,28 @@ global_init (void) + } + + ++#ifndef FIPS_MODULE_PATH ++#define FIPS_MODULE_PATH "/etc/system-fips" ++#endif ++ ++void __attribute__ ((constructor)) _gcry_global_constructor (void) ++{ ++ int rv; ++ ++ rv = access (FIPS_MODULE_PATH, F_OK); ++ if (rv < 0 && errno != ENOENT) ++ rv = 0; ++ ++ if (!rv) ++ { ++ /* force selftests */ ++ global_init (); ++ if (fips_mode ()) ++ _gcry_random_initialize (1); ++ _gcry_fips_run_selftests (0); ++ } ++} ++ + /* This function is called by the macro fips_is_operational and makes + sure that the minimal initialization has been done. This is far + from a perfect solution and hides problems with an improper +@@ -635,7 +657,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, + break; + + case GCRYCTL_SET_ENFORCED_FIPS_FLAG: +- if (!any_init_done) ++ if (fips_mode ()) + { + /* Not yet initialized at all. Set the enforced fips mode flag */ + _gcry_set_preferred_rng_type (0); diff --git a/libgcrypt-1.6.2-fips-reqs.patch b/libgcrypt-1.6.2-fips-reqs.patch new file mode 100644 index 0000000..dea7e34 --- /dev/null +++ b/libgcrypt-1.6.2-fips-reqs.patch @@ -0,0 +1,345 @@ +diff -up libgcrypt-1.6.2/cipher/dsa.c.fips-reqs libgcrypt-1.6.2/cipher/dsa.c +--- libgcrypt-1.6.2/cipher/dsa.c.fips-reqs 2014-12-08 17:15:07.198102721 +0100 ++++ libgcrypt-1.6.2/cipher/dsa.c 2014-12-08 17:16:59.636645610 +0100 +@@ -66,42 +66,86 @@ static const char *dsa_names[] = + }; + + +-/* A sample 1024 bit DSA key used for the selftests. */ ++/* A sample 2048 bit DSA key used for the selftests. */ + static const char sample_secret_key[] = + "(private-key" + " (dsa" +-" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" +-" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" +-" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" +-" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)" +-" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)" +-" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" +-" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" +-" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" +-" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)" +-" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" +-" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" +-" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" +-" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)" +-" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))"; +-/* A sample 1024 bit DSA key used for the selftests (public only). */ ++" (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" ++" 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" ++" 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" ++" 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" ++" 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" ++" eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" ++" 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" ++" 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" ++" 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" ++" 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" ++" 2c8d7469db02e24d592394a7dba069e9#)" ++" (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" ++" 7441a0a5#)" ++" (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" ++" 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" ++" ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" ++" 0df242b75b414df372121e53a553f222f836b000f016485b" ++" 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" ++" 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" ++" 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" ++" ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" ++" 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" ++" 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" ++" 45f322f82e4e85ca3ab85591b3c2a966#)" ++" (y #2452f3ccbe9ed5ca7dc74c602b99226e8f2fab38e7d7ddfb" ++" 75539b17155e9fcfd1aba564eb8535d812c9c2dcf9728444" ++" 1bc482243624c7f457580c1c38a57c46c457392470edb52c" ++" b5a6e03fe6287bb6f49a42a2065a054f030839df1fd3149c" ++" 4ca0531dd8ca8aaa9cc7337193387348336118224545e88c" ++" 80ffd8765d74360333ccab9972779b6525a65bdd0d10c675" ++" c109bbd3e5be4d72ef6eba6e438d5226237db888379c5fcc" ++" 47a3847ff63711baed6d03afe81e694a413b680bd38ab490" ++" 3f8370a707ef551d4941026d9579d691de8edaa16105eb9d" ++" ba3c2f4c1bec508275aa0207e251b5eccb286a4b01d449d3" ++" 0acb673717a0d2fb3b50c893f7dab14f#)" ++" (x #0c4b3089d1b862cb3c436491f0915470c52796e3acbee800" ++" ec55f6cc#)))"; ++/* A sample 2048 bit DSA key used for the selftests (public only). */ + static const char sample_public_key[] = + "(public-key" + " (dsa" +-" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" +-" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" +-" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" +-" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)" +-" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)" +-" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" +-" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" +-" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" +-" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)" +-" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" +-" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" +-" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" +-" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))"; +- ++" (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" ++" 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" ++" 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" ++" 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" ++" 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" ++" eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" ++" 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" ++" 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" ++" 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" ++" 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" ++" 2c8d7469db02e24d592394a7dba069e9#)" ++" (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" ++" 7441a0a5#)" ++" (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" ++" 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" ++" ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" ++" 0df242b75b414df372121e53a553f222f836b000f016485b" ++" 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" ++" 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" ++" 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" ++" ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" ++" 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" ++" 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" ++" 45f322f82e4e85ca3ab85591b3c2a966#)" ++" (y #2452f3ccbe9ed5ca7dc74c602b99226e8f2fab38e7d7ddfb" ++" 75539b17155e9fcfd1aba564eb8535d812c9c2dcf9728444" ++" 1bc482243624c7f457580c1c38a57c46c457392470edb52c" ++" b5a6e03fe6287bb6f49a42a2065a054f030839df1fd3149c" ++" 4ca0531dd8ca8aaa9cc7337193387348336118224545e88c" ++" 80ffd8765d74360333ccab9972779b6525a65bdd0d10c675" ++" c109bbd3e5be4d72ef6eba6e438d5226237db888379c5fcc" ++" 47a3847ff63711baed6d03afe81e694a413b680bd38ab490" ++" 3f8370a707ef551d4941026d9579d691de8edaa16105eb9d" ++" ba3c2f4c1bec508275aa0207e251b5eccb286a4b01d449d3" ++" 0acb673717a0d2fb3b50c893f7dab14f#)))"; + + + +@@ -1164,14 +1208,14 @@ dsa_get_nbits (gcry_sexp_t parms) + */ + + static const char * +-selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) ++selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey) + { + static const char sample_data[] = + "(data (flags raw)" +- " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))"; ++ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4f1e2d3c4b5a6978879605142#))"; + static const char sample_data_bad[] = + "(data (flags raw)" +- " (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))"; ++ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d401e2d3c4b5a6978879605142#))"; + + const char *errtxt = NULL; + gcry_error_t err; +@@ -1247,7 +1291,7 @@ selftests_dsa (selftest_report_func_t re + } + + what = "sign"; +- errtxt = selftest_sign_1024 (pkey, skey); ++ errtxt = selftest_sign (pkey, skey); + if (errtxt) + goto failed; + +diff -up libgcrypt-1.6.2/cipher/rsa.c.fips-reqs libgcrypt-1.6.2/cipher/rsa.c +--- libgcrypt-1.6.2/cipher/rsa.c.fips-reqs 2014-12-08 17:15:07.218103174 +0100 ++++ libgcrypt-1.6.2/cipher/rsa.c 2014-12-08 17:20:24.666282521 +0100 +@@ -62,33 +62,57 @@ static const char *rsa_names[] = + }; + + +-/* A sample 1024 bit RSA key used for the selftests. */ ++/* A sample 2048 bit RSA key used for the selftests. */ + static const char sample_secret_key[] = + "(private-key" + " (rsa" +-" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" +-" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" +-" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" +-" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)" ++" (n #00c9d56d9d90db43d602ed9688138ab2bf6ea10610b27837a714a8ffdd00" ++" ddb493a045cc9690edada9ddc4d6ca0cf0ed4f725e21499a1812158f905a" ++" dbb63399a3e6b4f0c4972126bbe3baf2ffa072da89638e8b3e089d922abe" ++" 16e14315fc57c71f0911671ca996d18b3e8093c159d06d39f2ac95cc1075" ++" e93124d143af68524be716d749656f26c086adc0070ac1e12f8785863bdc" ++" 5a99bee9f9b9e98227510415ab060e765a288d92bdc5b57ba8df4e47a2c1" ++" e752bf47f762e03a6f4d6a4d4ed4b95969fab214c1eee62f95cd9472aee4" ++" db189ac4cd70bdee3116b74965ac40190eb56d83f136bb082f2e4e9262a4" ++" ff50db2045a2eb167af2d528c1fd4e0371#)" + " (e #010001#)" +-" (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11" +-" 7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd" +-" c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21" +-" c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)" +-" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" +-" fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)" +-" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" +-" 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)" +-" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" +-" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))"; +-/* A sample 1024 bit RSA key used for the selftests (public only). */ ++" (d #36273db1f91bdba7a0417f1223ac232999d53a7b606741076353b4d2e758" ++" 950ac705f34eb2b412d470dc4f8506d3ddd863273e673121243904bc06a4" ++" ccce2b7afe7badde116ea3a5e604530ea34e2db48f31bfca7525520285de" ++" 3db27243b2898a9a3441263f9a67bea4967b0e75baa693d5b8d8b857f24b" ++" 0f1481d1574ef6454ca63bd070cad39d55de2205e78e284dee11cfb66776" ++" 09d3e33c13f99934107bec8138f0b6349c9b506f0b91814d8994047bf03c" ++" f4b1b200488d5a8f889ec5ab3a9e443f54e7d96e47aaa1bd404631f9f034" ++" b604e12b5b7386dd3a921b71c73f32e5c3c2aba17ebfa452a0b06890d120" ++" 1279e9d7c940baf219c7a50092860d01#)" ++" (p #00fc5c6e16ce1f037bcdf7b372b28f1672b856aef7cd67d84e7d07afd543" ++" 26c335be438f4e2f1c434e6bd2b2ec526d97522bcc5c3a6bf414c674da66" ++" 381c7a3f842fe3f95ab865694606a33779b2a15b58ed5ea75f8c6566bbd1" ++" 2436e637a73d49778a8c34d86929f34d5822b05124b640a886590ab7ba5c" ++" 97da57e836da7a9cad#)" ++" (q #00ccbe7b096906ee45bf884738a8f817e5b6ba6755e3e8058bb8e253d68e" ++" ef2ce74f4af74e268d850b3fecc31cd4ebec6ac8722a257dfda67796f01e" ++" cd2857f83730756bbdd47b0c87c56c8740a5bb272c78c9745a545b0b306f" ++" 444afa71e4216166f9ee65de7c04d7fda9155b7fe27aba698672a6068d9b" ++" 9055609e4c5da9b655#)" ++" (u #00afdecbdc5268ea7b1bff7284db7f6757dae3165fd80691ed2bbe8e54a1" ++" 6f7ff950aad059e9695903d93e59ff206ee1470bd2b099ca4e83426a7684" ++" 75a1ecafd3092fec0f008d78fe773174ec6fbff85384f3a91c2e4b1f59f1" ++" 1f2000fee86569f6cab5de338087bc615b90570de4aeb1a9125abbe3834d" ++" 5a69716c0a5fa20603#)))"; ++/* A sample 2048 bit RSA key used for the selftests (public only). */ + static const char sample_public_key[] = + "(public-key" + " (rsa" +-" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" +-" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" +-" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" +-" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)" ++" (n #00c9d56d9d90db43d602ed9688138ab2bf6ea10610b27837a714a8ffdd00" ++" ddb493a045cc9690edada9ddc4d6ca0cf0ed4f725e21499a1812158f905a" ++" dbb63399a3e6b4f0c4972126bbe3baf2ffa072da89638e8b3e089d922abe" ++" 16e14315fc57c71f0911671ca996d18b3e8093c159d06d39f2ac95cc1075" ++" e93124d143af68524be716d749656f26c086adc0070ac1e12f8785863bdc" ++" 5a99bee9f9b9e98227510415ab060e765a288d92bdc5b57ba8df4e47a2c1" ++" e752bf47f762e03a6f4d6a4d4ed4b95969fab214c1eee62f95cd9472aee4" ++" db189ac4cd70bdee3116b74965ac40190eb56d83f136bb082f2e4e9262a4" ++" ff50db2045a2eb167af2d528c1fd4e0371#)" + " (e #010001#)))"; + + +@@ -1610,20 +1634,35 @@ compute_keygrip (gcry_md_hd_t md, gcry_s + */ + + static const char * +-selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) ++selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey) + { + static const char sample_data[] = + "(data (flags pkcs1)" +- " (hash sha1 #11223344556677889900aabbccddeeff10203040#))"; ++ " (hash sha256 #11223344556677889900aabbccddeeffa0b0c0d0102030405060708090a1b1c1#))"; + static const char sample_data_bad[] = + "(data (flags pkcs1)" +- " (hash sha1 #11223344556677889900aabbccddeeff80203040#))"; ++ " (hash sha256 #11223344556677889900aabbccddeeffa0b0c0d0102030405060708091a1b1c1#))"; ++ static const char signature_ka[] = ++ "(sig-val \n" ++ " (rsa \n" ++ " (s #0B12D55738B099D401C81BEEDA54E045B4B7D9CDA5A8769E9C484F696A58912A" ++ "1E5DE7E5A2D181DA15A5C254D802AB75F1056E27406850AC7BE310BC32D2CED8" ++ "6697FE84508F7EFFF4D147C52E955A0873EF2F52ED71F2FC9C3C12D4045CB643" ++ "70158378E1494D8FBAD2248B9B64233D2CC2C1932B0531E539DEB07434B76D3B" ++ "6959E8A37E33B234C0C8C2C8FB1D00939239C9C491B2EBEED77BF952B597E11B" ++ "D4ED0C103D2B88BC78B4E505CF9D8D08B585CE3688D4FBE83ED58D1E1341AC4D" ++ "7C5EFF3CBC565CC7AE61C2F568426763A5239D31C1FFFD366984901679A343C4" ++ "01BB778BBA5E533B7875BA658A19AA9E56170F4A28E4322BF1621175FB06463E#)\n" ++ " )\n" ++ " )\n"; + + const char *errtxt = NULL; + gcry_error_t err; + gcry_sexp_t data = NULL; + gcry_sexp_t data_bad = NULL; + gcry_sexp_t sig = NULL; ++ char buf[1024]; ++ size_t len; + + err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data)); + if (!err) +@@ -1641,6 +1680,12 @@ selftest_sign_1024 (gcry_sexp_t pkey, gc + errtxt = "signing failed"; + goto leave; + } ++ len = sexp_sprint (sig, GCRYSEXP_FMT_ADVANCED, buf, sizeof(buf)); ++ if (len != sizeof (signature_ka) - 1 || memcmp (buf, signature_ka, len) != 0) ++ { ++ errtxt = "signature KAT failed"; ++ goto leave; ++ } + err = _gcry_pk_verify (sig, data, pkey); + if (err) + { +@@ -1697,11 +1742,11 @@ extract_a_from_sexp (gcry_sexp_t encr_da + + + static const char * +-selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) ++selftest_encr (gcry_sexp_t pkey, gcry_sexp_t skey) + { + const char *errtxt = NULL; + gcry_error_t err; +- const unsigned int nbits = 1000; /* Encrypt 1000 random bits. */ ++ const unsigned int nbits = 2000; /* Encrypt 2000 random bits. */ + gcry_mpi_t plaintext = NULL; + gcry_sexp_t plain = NULL; + gcry_sexp_t encr = NULL; +@@ -1822,12 +1867,12 @@ selftests_rsa (selftest_report_func_t re + } + + what = "sign"; +- errtxt = selftest_sign_1024 (pkey, skey); ++ errtxt = selftest_sign (pkey, skey); + if (errtxt) + goto failed; + + what = "encrypt"; +- errtxt = selftest_encr_1024 (pkey, skey); ++ errtxt = selftest_encr (pkey, skey); + if (errtxt) + goto failed; + +diff -up libgcrypt-1.6.2/random/drbg.c.fips-reqs libgcrypt-1.6.2/random/drbg.c +diff -up libgcrypt-1.6.2/src/visibility.c.fips-reqs libgcrypt-1.6.2/src/visibility.c +--- libgcrypt-1.6.2/src/visibility.c.fips-reqs 2014-08-21 14:50:39.000000000 +0200 ++++ libgcrypt-1.6.2/src/visibility.c 2014-12-08 17:23:06.530943221 +0100 +@@ -1259,6 +1259,8 @@ gcry_kdf_derive (const void *passphrase, + unsigned long iterations, + size_t keysize, void *keybuffer) + { ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); + return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, + salt, saltlen, iterations, + keysize, keybuffer)); +@@ -1314,6 +1316,13 @@ void + gcry_mpi_randomize (gcry_mpi_t w, + unsigned int nbits, enum gcry_random_level level) + { ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_fatal_error ("called in non-operational state"); ++ fips_noreturn (); ++ } ++ + _gcry_mpi_randomize (w, nbits, level); + } + +@@ -1339,6 +1348,8 @@ gcry_prime_generate (gcry_mpi_t *prime, + gcry_random_level_t random_level, + unsigned int flags) + { ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); + return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits, + factors, cb_func, cb_arg, + random_level, flags)); diff --git a/libgcrypt-1.6.2-fips-test.patch b/libgcrypt-1.6.2-fips-test.patch new file mode 100644 index 0000000..9c0a64c --- /dev/null +++ b/libgcrypt-1.6.2-fips-test.patch @@ -0,0 +1,31 @@ +diff -up libgcrypt-1.6.2/src/global.c.fips-test libgcrypt-1.6.2/src/global.c +--- libgcrypt-1.6.2/src/global.c.fips-test 2014-12-08 16:54:07.766619659 +0100 ++++ libgcrypt-1.6.2/src/global.c 2014-12-08 16:55:18.555220601 +0100 +@@ -564,8 +564,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, + + case GCRYCTL_FIPS_MODE_P: + if (fips_mode () +- && !_gcry_is_fips_mode_inactive () +- && !no_secure_memory) ++ && !_gcry_is_fips_mode_inactive ()) + rc = GPG_ERR_GENERAL; /* Used as TRUE value */ + break; + +diff -up libgcrypt-1.6.2/tests/basic.c.fips-test libgcrypt-1.6.2/tests/basic.c +--- libgcrypt-1.6.2/tests/basic.c.fips-test 2014-08-21 14:50:39.000000000 +0200 ++++ libgcrypt-1.6.2/tests/basic.c 2014-12-08 16:54:07.767619682 +0100 +@@ -582,6 +582,14 @@ check_ctr_cipher (void) + if (!tv[i].algo) + continue; + ++ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ tv[i].algo); ++ continue; ++ } ++ + err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); + if (!err) + err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); diff --git a/libgcrypt-1.6.2-rsa-fips-keygen.patch b/libgcrypt-1.6.2-rsa-fips-keygen.patch new file mode 100644 index 0000000..f9a3e5f --- /dev/null +++ b/libgcrypt-1.6.2-rsa-fips-keygen.patch @@ -0,0 +1,375 @@ +diff -up libgcrypt-1.6.2/cipher/primegen.c.fips-keygen libgcrypt-1.6.2/cipher/primegen.c +--- libgcrypt-1.6.2/cipher/primegen.c.fips-keygen 2014-12-08 16:55:56.425077059 +0100 ++++ libgcrypt-1.6.2/cipher/primegen.c 2014-12-08 16:59:26.039817665 +0100 +@@ -1198,6 +1198,22 @@ _gcry_prime_check (gcry_mpi_t x, unsigne + return rc; + } + ++/* Check whether the number X is prime according to FIPS 186-4 table C.2. */ ++gcry_err_code_t ++_gcry_fips186_4_prime_check (gcry_mpi_t x, unsigned int bits) ++{ ++ gcry_err_code_t ec = GPG_ERR_NO_ERROR; ++ gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */ ++ ++ /* We use 5 or 4 rounds as specified in table C.2 */ ++ if (! check_prime (x, val_2, bits > 1024 ? 4 : 5, NULL, NULL)) ++ ec = GPG_ERR_NO_PRIME; ++ ++ mpi_free (val_2); ++ ++ return ec; ++} ++ + /* Find a generator for PRIME where the factorization of (prime-1) is + in the NULL terminated array FACTORS. Return the generator as a + newly allocated MPI in R_G. If START_G is not NULL, use this as s +diff -up libgcrypt-1.6.2/cipher/rsa.c.fips-keygen libgcrypt-1.6.2/cipher/rsa.c +--- libgcrypt-1.6.2/cipher/rsa.c.fips-keygen 2014-12-08 16:55:56.407076652 +0100 ++++ libgcrypt-1.6.2/cipher/rsa.c 2014-12-08 17:11:06.770665261 +0100 +@@ -339,6 +339,279 @@ generate_std (RSA_secret_key *sk, unsign + } + + ++/**************** ++ * Generate a key pair with a key of size NBITS. ++ * USE_E = 0 let Libcgrypt decide what exponent to use. ++ * = 1 request the use of a "secure" exponent; this is required by some ++ * specification to be 65537. ++ * > 2 Use this public exponent. If the given exponent ++ * is not odd one is internally added to it. ++ * TESTPARMS: If set, do not generate but test whether the p,q is probably prime ++ * Returns key with zeroes to not break code calling this function. ++ * TRANSIENT_KEY: If true, generate the primes using the standard RNG. ++ * Returns: 2 structures filled with all needed values ++ */ ++static gpg_err_code_t ++generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, ++ gcry_sexp_t testparms, int transient_key) ++{ ++ gcry_mpi_t p, q; /* the two primes */ ++ gcry_mpi_t d; /* the private key */ ++ gcry_mpi_t u; ++ gcry_mpi_t p1, q1; ++ gcry_mpi_t n; /* the public key */ ++ gcry_mpi_t e; /* the exponent */ ++ gcry_mpi_t g; ++ gcry_mpi_t minp; ++ gcry_mpi_t diff, mindiff; ++ gcry_random_level_t random_level; ++ unsigned int pbits = nbits/2; ++ unsigned int i; ++ int pqswitch; ++ gpg_err_code_t ec = GPG_ERR_NO_PRIME; ++ ++ if (nbits < 1024 || (nbits & 0x1FF)) ++ return GPG_ERR_INV_VALUE; ++ if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072) ++ return GPG_ERR_INV_VALUE; ++ ++ /* The random quality depends on the transient_key flag. */ ++ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; ++ ++ if (testparms) ++ { ++ /* Parameters to derive the key are given. */ ++ /* Note that we explicitly need to setup the values of tbl ++ because some compilers (e.g. OpenWatcom, IRIX) don't allow ++ to initialize a structure with automatic variables. */ ++ struct { const char *name; gcry_mpi_t *value; } tbl[] = { ++ { "e" }, ++ { "p" }, ++ { "q" }, ++ { NULL } ++ }; ++ int idx; ++ gcry_sexp_t oneparm; ++ ++ tbl[0].value = &e; ++ tbl[1].value = &p; ++ tbl[2].value = &q; ++ ++ for (idx=0; tbl[idx].name; idx++) ++ { ++ oneparm = sexp_find_token (testparms, tbl[idx].name, 0); ++ if (oneparm) ++ { ++ *tbl[idx].value = sexp_nth_mpi (oneparm, 1, ++ GCRYMPI_FMT_USG); ++ sexp_release (oneparm); ++ } ++ } ++ for (idx=0; tbl[idx].name; idx++) ++ if (!*tbl[idx].value) ++ break; ++ if (tbl[idx].name) ++ { ++ /* At least one parameter is missing. */ ++ for (idx=0; tbl[idx].name; idx++) ++ _gcry_mpi_release (*tbl[idx].value); ++ return GPG_ERR_MISSING_VALUE; ++ } ++ } ++ else ++ { ++ if (use_e < 65537) ++ use_e = 65537; /* This is the smallest value allowed by FIPS */ ++ ++ e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB ); ++ ++ use_e |= 1; /* make sure this is odd */ ++ mpi_set_ui (e, use_e); ++ ++ p = mpi_snew (pbits); ++ q = mpi_snew (pbits); ++ } ++ ++ n = mpi_new (nbits); ++ d = mpi_snew (nbits); ++ u = mpi_snew (nbits); ++ ++ /* prepare approximate minimum p and q */ ++ minp = mpi_new (pbits); ++ mpi_set_ui (minp, 0xB504F334); ++ mpi_lshift (minp, minp, pbits - 32); ++ ++ /* prepare minimum p and q difference */ ++ diff = mpi_new (pbits); ++ mindiff = mpi_new (pbits - 99); ++ mpi_set_ui (mindiff, 1); ++ mpi_lshift (mindiff, mindiff, pbits - 100); ++ ++ p1 = mpi_snew (pbits); ++ q1 = mpi_snew (pbits); ++ g = mpi_snew (pbits); ++ ++retry: ++ /* generate p and q */ ++ for (i = 0; i < 5 * pbits; i++) ++ { ++ ploop: ++ if (!testparms) ++ { ++ _gcry_mpi_randomize (p, pbits, random_level); ++ } ++ if (mpi_cmp (p, minp) < 0) ++ { ++ if (testparms) goto err; ++ goto ploop; ++ } ++ ++ mpi_sub_ui (p1, p, 1); ++ if (mpi_gcd (g, p1, e)) ++ { ++ if (_gcry_fips186_4_prime_check (p, pbits) != GPG_ERR_NO_ERROR) ++ { ++ /* not a prime */ ++ if (testparms) goto err; ++ } ++ else ++ break; ++ } ++ else if (testparms) goto err; ++ } ++ if (i >= 5 * pbits) ++ goto err; ++ ++ for (i = 0; i < 5 * pbits; i++) ++ { ++ qloop: ++ if (!testparms) ++ { ++ _gcry_mpi_randomize (q, pbits, random_level); ++ } ++ if (mpi_cmp (q, minp) < 0) ++ { ++ if (testparms) goto err; ++ goto qloop; ++ } ++ if (mpi_cmp (p, q) < 0) ++ { ++ pqswitch = 1; ++ mpi_sub (diff, q, p); ++ } ++ else ++ { ++ pqswitch = 0; ++ mpi_sub (diff, p, q); ++ } ++ if (mpi_cmp (diff, mindiff) < 0) ++ { ++ if (testparms) goto err; ++ goto qloop; ++ } ++ ++ mpi_sub_ui (q1, q, 1); ++ if (mpi_gcd (g, q1, e)) ++ { ++ if (_gcry_fips186_4_prime_check (q, pbits) != GPG_ERR_NO_ERROR) ++ { ++ /* not a prime */ ++ if (testparms) goto err; ++ } ++ else ++ break; ++ } ++ else if (testparms) goto err; ++ } ++ if (i >= 5 * pbits) ++ goto err; ++ ++ if (testparms) ++ { ++ mpi_clear (p); ++ mpi_clear (q); ++ } ++ else ++ { ++ gcry_mpi_t f; ++ ++ if (pqswitch) ++ { ++ gcry_mpi_t tmp; ++ ++ tmp = p; ++ p = q; ++ q = tmp; ++ } ++ ++ f = mpi_snew (nbits); ++ ++ /* calculate the modulus */ ++ mpi_mul(n, p, q); ++ ++ /* calculate the secret key d = e^1 mod phi */ ++ mpi_gcd (g, p1, q1); ++ mpi_fdiv_q (f, p1, g); ++ mpi_mul (f, f, q1); ++ ++ mpi_invm (d, e, f); ++ ++ _gcry_mpi_release (f); ++ ++ if (mpi_get_nbits (d) < pbits) goto retry; ++ ++ /* calculate the inverse of p and q (used for chinese remainder theorem)*/ ++ mpi_invm(u, p, q ); ++ } ++ ++ ec = 0; ++ ++ if( DBG_CIPHER ) ++ { ++ log_mpidump(" p= ", p ); ++ log_mpidump(" q= ", q ); ++ log_mpidump(" n= ", n ); ++ log_mpidump(" e= ", e ); ++ log_mpidump(" d= ", d ); ++ log_mpidump(" u= ", u ); ++ } ++ ++err: ++ ++ _gcry_mpi_release (p1); ++ _gcry_mpi_release (q1); ++ _gcry_mpi_release (g); ++ _gcry_mpi_release (minp); ++ _gcry_mpi_release (mindiff); ++ _gcry_mpi_release (diff); ++ ++ sk->n = n; ++ sk->e = e; ++ sk->p = p; ++ sk->q = q; ++ sk->d = d; ++ sk->u = u; ++ ++ /* Now we can test our keys. */ ++ if (ec || (!testparms && test_keys (sk, nbits - 64))) ++ { ++ _gcry_mpi_release (sk->n); sk->n = NULL; ++ _gcry_mpi_release (sk->e); sk->e = NULL; ++ _gcry_mpi_release (sk->p); sk->p = NULL; ++ _gcry_mpi_release (sk->q); sk->q = NULL; ++ _gcry_mpi_release (sk->d); sk->d = NULL; ++ _gcry_mpi_release (sk->u); sk->u = NULL; ++ if (!ec) ++ { ++ fips_signal_error ("self-test after key generation failed"); ++ return GPG_ERR_SELFTEST_FAILED; ++ } ++ } ++ ++ return ec; ++} ++ ++ + /* Helper for generate_x931. */ + static gcry_mpi_t + gen_x931_parm_xp (unsigned int nbits) +@@ -799,7 +1072,7 @@ rsa_generate (const gcry_sexp_t genparms + } + } + +- if (deriveparms || (flags & PUBKEY_FLAG_USE_X931) || fips_mode ()) ++ if (deriveparms || (flags & PUBKEY_FLAG_USE_X931)) + { + int swapped; + ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped); +@@ -819,9 +1092,14 @@ rsa_generate (const gcry_sexp_t genparms + sexp_release (l1); + } + } ++ deriveparms = (genparms? ++ sexp_find_token (genparms, "test-parms", 0) : NULL); + /* Generate. */ +- ec = generate_std (&sk, nbits, evalue, +- !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); ++ if (deriveparms || fips_mode()) ++ ec = generate_fips (&sk, nbits, evalue, deriveparms, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); ++ else ++ ec = generate_std (&sk, nbits, evalue, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); ++ sexp_release (deriveparms); + } + + if (!ec) +diff -up libgcrypt-1.6.2/src/g10lib.h.fips-keygen libgcrypt-1.6.2/src/g10lib.h +--- libgcrypt-1.6.2/src/g10lib.h.fips-keygen 2014-08-21 12:29:09.000000000 +0200 ++++ libgcrypt-1.6.2/src/g10lib.h 2014-12-08 16:55:56.426077081 +0100 +@@ -259,6 +259,9 @@ gpg_err_code_t _gcry_generate_fips186_3_ + int *r_counter, + void **r_seed, size_t *r_seedlen, int *r_hashalgo); + ++gpg_err_code_t _gcry_fips186_4_prime_check ++ (const gcry_mpi_t x, unsigned int bits); ++ + + /* Replacements of missing functions (missing-string.c). */ + #ifndef HAVE_STPCPY +diff -up libgcrypt-1.6.2/tests/keygen.c.fips-keygen libgcrypt-1.6.2/tests/keygen.c +--- libgcrypt-1.6.2/tests/keygen.c.fips-keygen 2014-12-08 16:55:56.407076652 +0100 ++++ libgcrypt-1.6.2/tests/keygen.c 2014-12-08 17:13:29.449892067 +0100 +@@ -215,12 +215,12 @@ check_rsa_keys (void) + + + if (verbose) +- show ("creating 1024 bit RSA key with e=257\n"); ++ show ("creating 1024 bit RSA key with e=65539\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" + " (nbits 4:1024)\n" +- " (rsa-use-e 3:257)\n" ++ " (rsa-use-e 5:65539)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); +@@ -229,7 +229,7 @@ check_rsa_keys (void) + if (rc) + die ("error generating RSA key: %s\n", gpg_strerror (rc)); + +- check_generated_rsa_key (key, 257); ++ check_generated_rsa_key (key, 65539); + gcry_sexp_release (key); + + if (verbose) diff --git a/libgcrypt-1.5.0-use-fipscheck.patch b/libgcrypt-1.6.2-use-fipscheck.patch similarity index 71% rename from libgcrypt-1.5.0-use-fipscheck.patch rename to libgcrypt-1.6.2-use-fipscheck.patch index 476c96c..26f31b6 100644 --- a/libgcrypt-1.5.0-use-fipscheck.patch +++ b/libgcrypt-1.6.2-use-fipscheck.patch @@ -1,7 +1,7 @@ -diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c ---- libgcrypt-1.5.0/src/fips.c.use-fipscheck 2011-02-04 20:17:33.000000000 +0100 -+++ libgcrypt-1.5.0/src/fips.c 2011-07-20 16:17:21.000000000 +0200 -@@ -570,23 +570,48 @@ run_random_selftests (void) +diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c +--- libgcrypt-1.6.2/src/fips.c.use-fipscheck 2014-08-21 14:50:39.000000000 +0200 ++++ libgcrypt-1.6.2/src/fips.c 2014-09-26 11:42:20.999588282 +0200 +@@ -578,23 +578,48 @@ run_random_selftests (void) return !!err; } @@ -55,16 +55,16 @@ diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c key, strlen (key)); if (dlen < 0) err = gpg_error_from_syserror (); -@@ -594,7 +619,7 @@ check_binary_integrity (void) +@@ -602,7 +627,7 @@ check_binary_integrity (void) err = gpg_error (GPG_ERR_INTERNAL); else { -- fname = gcry_malloc (strlen (info.dli_fname) + 1 + 5 + 1 ); -+ fname = _gcry_malloc (strlen (libpath) + 1 + 5 + 1 ); +- fname = xtrymalloc (strlen (info.dli_fname) + 1 + 5 + 1 ); ++ fname = xtrymalloc (strlen (libpath) + 1 + 5 + 1 ); if (!fname) err = gpg_error_from_syserror (); else -@@ -603,7 +628,7 @@ check_binary_integrity (void) +@@ -611,7 +636,7 @@ check_binary_integrity (void) char *p; /* Prefix the basename with a dot. */ @@ -73,10 +73,10 @@ diff -up libgcrypt-1.5.0/src/fips.c.use-fipscheck libgcrypt-1.5.0/src/fips.c p = strrchr (fname, '/'); if (p) p++; -diff -up libgcrypt-1.5.0/src/Makefile.in.use-fipscheck libgcrypt-1.5.0/src/Makefile.in ---- libgcrypt-1.5.0/src/Makefile.in.use-fipscheck 2011-06-29 10:58:01.000000000 +0200 -+++ libgcrypt-1.5.0/src/Makefile.in 2011-07-20 16:19:33.000000000 +0200 -@@ -375,7 +375,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \ +diff -up libgcrypt-1.6.2/src/Makefile.in.use-fipscheck libgcrypt-1.6.2/src/Makefile.in +--- libgcrypt-1.6.2/src/Makefile.in.use-fipscheck 2014-08-21 15:14:08.000000000 +0200 ++++ libgcrypt-1.6.2/src/Makefile.in 2014-09-26 11:41:13.271059281 +0200 +@@ -449,7 +449,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \ ../cipher/libcipher.la \ ../random/librandom.la \ ../mpi/libmpi.la \ diff --git a/libgcrypt.spec b/libgcrypt.spec index 44ad3f8..c67d1c2 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.6.1 -Release: 7%{?dist} +Version: 1.6.2 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -17,14 +17,14 @@ Source5: curves.c Source6: t-mpi-point.c # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump -Patch2: libgcrypt-1.5.0-use-fipscheck.patch +Patch2: libgcrypt-1.6.2-use-fipscheck.patch # fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen Patch5: libgcrypt-1.6.1-tests.patch # add configurable source of RNG seed and seed by default # from /dev/urandom in the FIPS mode Patch6: libgcrypt-1.6.1-fips-cfgrandom.patch -# make the FIPS-186-3 DSA CAVS testable -Patch7: libgcrypt-1.6.1-fips-cavs.patch +# update the CAVS tests +Patch7: libgcrypt-1.6.2-fips-cavs.patch # fix for memory leaks an other errors found by Coverity scan Patch9: libgcrypt-1.6.1-leak.patch # use poll instead of select when gathering randomness @@ -33,7 +33,16 @@ Patch11: libgcrypt-1.6.1-use-poll.patch Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC Patch14: libgcrypt-1.6.1-ecc-test-fix.patch -Patch15: libgcrypt-1.6.1-make-arm-asm-fPIC-friendly.patch +# Replace the FIPS RNG with DRBG +Patch15: libgcrypt-1.6.2-drbg.patch +# Run the FIPS mode initialization in the shared library constructor +Patch18: libgcrypt-1.6.2-fips-ctor.patch +# Make it possible to run the test suite in the FIPS mode +Patch19: libgcrypt-1.6.2-fips-test.patch +# Make the FIPS RSA keygen to be FIPS 186-4 compliant +Patch20: libgcrypt-1.6.2-rsa-fips-keygen.patch +# update the selftests for new FIPS requirements +Patch22: libgcrypt-1.6.2-fips-reqs.patch %define gcrylibdir %{_libdir} @@ -77,7 +86,11 @@ applications using libgcrypt. %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix -%patch15 -p1 -b .pic +%patch15 -p1 -b .drbg +%patch18 -p1 -b .fips-ctor +%patch19 -p1 -b .fips-test +%patch20 -p1 -b .fips-keygen +%patch22 -p1 -b .fips-reqs cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -188,6 +201,9 @@ exit 0 %license COPYING %changelog +* Mon Dec 8 2014 Tomáš Mráz 1.6.2-1 +- new upstream version + * Sun Aug 17 2014 Fedora Release Engineering - 1.6.1-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild diff --git a/sources b/sources index c971c98..d296f4f 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -3f1076b38a407f4775adcf6e9bf43893 libgcrypt-1.6.1-hobbled.tar.xz +e682099d3bf9cd13802e5a5e67a66544 libgcrypt-1.6.2-hobbled.tar.xz From 6898eaa051cb657b7169852e6d9e808963ea1a10 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 14 Jan 2015 17:02:08 +0100 Subject: [PATCH 076/214] fix buildability of programs using gcrypt.h with -ansi (#1182200) --- libgcrypt-1.6.2-drbg.patch | 33 +++++++++++++++------------------ libgcrypt.spec | 5 ++++- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/libgcrypt-1.6.2-drbg.patch b/libgcrypt-1.6.2-drbg.patch index 7978b32..386fb98 100644 --- a/libgcrypt-1.6.2-drbg.patch +++ b/libgcrypt-1.6.2-drbg.patch @@ -2553,7 +2553,7 @@ diff -up libgcrypt-1.6.2/src/gcrypt.h.in.drbg libgcrypt-1.6.2/src/gcrypt.h.in }; /* Perform various operations defined by CMD. */ -@@ -1668,6 +1670,112 @@ int gcry_is_secure (const void *a) _GCRY +@@ -1668,6 +1670,109 @@ int gcry_is_secure (const void *a) _GCRY /* Return true if Libgcrypt is in FIPS mode. */ #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) @@ -2583,25 +2583,22 @@ diff -up libgcrypt-1.6.2/src/gcrypt.h.in.drbg libgcrypt-1.6.2/src/gcrypt.h.in + struct gcry_drbg_string *next; +}; + -+static inline void gcry_drbg_string_fill(struct gcry_drbg_string *string, -+ const unsigned char *buf, size_t len) -+{ -+ string->buf = buf; -+ string->len = len; -+ string->next = NULL; -+} ++#define gcry_drbg_string_fill(s, b, l) \ ++do { \ ++ (s)->buf = (b); \ ++ (s)->len = (l); \ ++ (s)->next = NULL; \ ++} while (0) + +/* this is a wrapper function for users of libgcrypt */ -+static inline void gcry_randomize_drbg(void *outbuf, size_t outlen, -+ enum gcry_random_level level, -+ struct gcry_drbg_string *addtl) -+{ -+ struct gcry_drbg_gen genbuf; -+ genbuf.outbuf = (unsigned char *)outbuf; -+ genbuf.outlen = outlen; -+ genbuf.addtl = addtl; -+ gcry_randomize(&genbuf, 0, level); -+} ++#define gcry_randomize_drbg(ob, ol, lvl, add) \ ++do { \ ++ struct gcry_drbg_gen genbuf; \ ++ genbuf.outbuf = (unsigned char *)(ob); \ ++ genbuf.outlen = (ol); \ ++ genbuf.addtl = (add); \ ++ gcry_randomize(&genbuf, 0, (lvl)); \ ++} while (0) + +/* + * DRBG flags bitmasks diff --git a/libgcrypt.spec b/libgcrypt.spec index c67d1c2..9ae35f5 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.2 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -201,6 +201,9 @@ exit 0 %license COPYING %changelog +* Wed Jan 14 2015 Tomáš Mráz 1.6.2-2 +- fix buildability of programs using gcrypt.h with -ansi (#1182200) + * Mon Dec 8 2014 Tomáš Mráz 1.6.2-1 - new upstream version From e731723f38978901a6d3fc9f0de32657680112a5 Mon Sep 17 00:00:00 2001 From: Till Maas Date: Sat, 21 Feb 2015 22:16:54 +0100 Subject: [PATCH 077/214] Rebuilt for Fedora 23 Change https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code --- libgcrypt.spec | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 9ae35f5..3d0d4c3 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.2 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -201,6 +201,10 @@ exit 0 %license COPYING %changelog +* Sat Feb 21 2015 Till Maas - 1.6.2-3 +- Rebuilt for Fedora 23 Change + https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code + * Wed Jan 14 2015 Tomáš Mráz 1.6.2-2 - fix buildability of programs using gcrypt.h with -ansi (#1182200) From eea28299998482345b35df12066b13c5af0b4f06 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 25 Feb 2015 14:22:30 +0100 Subject: [PATCH 078/214] do not initialize secure memory during the selftest (#1195850) --- libgcrypt-1.6.2-fips-ctor.patch | 28 +++++++++++++++++++++++----- libgcrypt-1.6.2-fips-test.patch | 13 ------------- libgcrypt.spec | 5 ++++- 3 files changed, 27 insertions(+), 19 deletions(-) diff --git a/libgcrypt-1.6.2-fips-ctor.patch b/libgcrypt-1.6.2-fips-ctor.patch index 3934669..a1b5501 100644 --- a/libgcrypt-1.6.2-fips-ctor.patch +++ b/libgcrypt-1.6.2-fips-ctor.patch @@ -1,6 +1,6 @@ diff -up libgcrypt-1.6.2/cipher/md.c.fips-ctor libgcrypt-1.6.2/cipher/md.c --- libgcrypt-1.6.2/cipher/md.c.fips-ctor 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/cipher/md.c 2014-12-08 16:45:01.095256244 +0100 ++++ libgcrypt-1.6.2/cipher/md.c 2015-02-25 13:57:21.175704866 +0100 @@ -413,11 +413,8 @@ md_enable (gcry_md_hd_t hd, int algorith if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) @@ -14,9 +14,9 @@ diff -up libgcrypt-1.6.2/cipher/md.c.fips-ctor libgcrypt-1.6.2/cipher/md.c } } diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c ---- libgcrypt-1.6.2/src/global.c.fips-ctor 2014-12-08 16:45:01.094256222 +0100 -+++ libgcrypt-1.6.2/src/global.c 2014-12-08 16:46:29.182248403 +0100 -@@ -132,6 +132,28 @@ global_init (void) +--- libgcrypt-1.6.2/src/global.c.fips-ctor 2015-02-25 13:57:21.174704842 +0100 ++++ libgcrypt-1.6.2/src/global.c 2015-02-25 14:03:07.066864208 +0100 +@@ -132,6 +132,34 @@ global_init (void) } @@ -34,18 +34,36 @@ diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c + + if (!rv) + { ++ int no_secmem_save; ++ ++ /* it should be always 0 at this point but let's keep on the safe side */ ++ no_secmem_save = no_secure_memory; ++ no_secure_memory = 1; + /* force selftests */ + global_init (); + if (fips_mode ()) + _gcry_random_initialize (1); + _gcry_fips_run_selftests (0); ++ no_secure_memory = no_secmem_save; + } +} + /* This function is called by the macro fips_is_operational and makes sure that the minimal initialization has been done. This is far from a perfect solution and hides problems with an improper -@@ -635,7 +657,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, +@@ -542,9 +570,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, + + case GCRYCTL_FIPS_MODE_P: + if (fips_mode () +- && !_gcry_is_fips_mode_inactive () +- && !no_secure_memory) +- rc = GPG_ERR_GENERAL; /* Used as TRUE value */ ++ && !_gcry_is_fips_mode_inactive ()) ++ err = GPG_ERR_GENERAL; /* Used as TRUE value */ + break; + + case GCRYCTL_FORCE_FIPS_MODE: +@@ -635,7 +662,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, break; case GCRYCTL_SET_ENFORCED_FIPS_FLAG: diff --git a/libgcrypt-1.6.2-fips-test.patch b/libgcrypt-1.6.2-fips-test.patch index 9c0a64c..b21d4a1 100644 --- a/libgcrypt-1.6.2-fips-test.patch +++ b/libgcrypt-1.6.2-fips-test.patch @@ -1,16 +1,3 @@ -diff -up libgcrypt-1.6.2/src/global.c.fips-test libgcrypt-1.6.2/src/global.c ---- libgcrypt-1.6.2/src/global.c.fips-test 2014-12-08 16:54:07.766619659 +0100 -+++ libgcrypt-1.6.2/src/global.c 2014-12-08 16:55:18.555220601 +0100 -@@ -564,8 +564,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - - case GCRYCTL_FIPS_MODE_P: - if (fips_mode () -- && !_gcry_is_fips_mode_inactive () -- && !no_secure_memory) -+ && !_gcry_is_fips_mode_inactive ()) - rc = GPG_ERR_GENERAL; /* Used as TRUE value */ - break; - diff -up libgcrypt-1.6.2/tests/basic.c.fips-test libgcrypt-1.6.2/tests/basic.c --- libgcrypt-1.6.2/tests/basic.c.fips-test 2014-08-21 14:50:39.000000000 +0200 +++ libgcrypt-1.6.2/tests/basic.c 2014-12-08 16:54:07.767619682 +0100 diff --git a/libgcrypt.spec b/libgcrypt.spec index 3d0d4c3..1a71b93 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.2 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -201,6 +201,9 @@ exit 0 %license COPYING %changelog +* Wed Feb 25 2015 Tomáš Mráz 1.6.2-4 +- do not initialize secure memory during the selftest (#1195850) + * Sat Feb 21 2015 Till Maas - 1.6.2-3 - Rebuilt for Fedora 23 Change https://fedoraproject.org/wiki/Changes/Harden_all_packages_with_position-independent_code From da1d9089b57175d73948674286f714e2ac79534b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 25 Feb 2015 16:33:37 +0100 Subject: [PATCH 079/214] Fix forward port of the patch. --- libgcrypt-1.6.2-fips-ctor.patch | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libgcrypt-1.6.2-fips-ctor.patch b/libgcrypt-1.6.2-fips-ctor.patch index a1b5501..c53847d 100644 --- a/libgcrypt-1.6.2-fips-ctor.patch +++ b/libgcrypt-1.6.2-fips-ctor.patch @@ -51,18 +51,16 @@ diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c /* This function is called by the macro fips_is_operational and makes sure that the minimal initialization has been done. This is far from a perfect solution and hides problems with an improper -@@ -542,9 +570,8 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, +@@ -542,8 +570,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, case GCRYCTL_FIPS_MODE_P: if (fips_mode () - && !_gcry_is_fips_mode_inactive () - && !no_secure_memory) -- rc = GPG_ERR_GENERAL; /* Used as TRUE value */ + && !_gcry_is_fips_mode_inactive ()) -+ err = GPG_ERR_GENERAL; /* Used as TRUE value */ + rc = GPG_ERR_GENERAL; /* Used as TRUE value */ break; - case GCRYCTL_FORCE_FIPS_MODE: @@ -635,7 +662,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, break; From 69ded97bb964132a7313c571be18bd1a4a0498ad Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 6 Mar 2015 17:30:30 +0100 Subject: [PATCH 080/214] new upstream version --- .gitignore | 1 + libgcrypt-1.6.1-fips-cavs.patch | 1123 ----------------- ...h => libgcrypt-1.6.3-rsa-fips-keygen.patch | 39 +- libgcrypt.spec | 9 +- sources | 2 +- 5 files changed, 29 insertions(+), 1145 deletions(-) delete mode 100644 libgcrypt-1.6.1-fips-cavs.patch rename libgcrypt-1.6.2-rsa-fips-keygen.patch => libgcrypt-1.6.3-rsa-fips-keygen.patch (88%) diff --git a/.gitignore b/.gitignore index 3ea085c..791d596 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.5.3-hobbled.tar.xz /libgcrypt-1.6.1-hobbled.tar.xz /libgcrypt-1.6.2-hobbled.tar.xz +/libgcrypt-1.6.3-hobbled.tar.xz diff --git a/libgcrypt-1.6.1-fips-cavs.patch b/libgcrypt-1.6.1-fips-cavs.patch deleted file mode 100644 index 55aa66a..0000000 --- a/libgcrypt-1.6.1-fips-cavs.patch +++ /dev/null @@ -1,1123 +0,0 @@ -diff -up libgcrypt-1.6.1/tests/cavs_driver.pl.cavs libgcrypt-1.6.1/tests/cavs_driver.pl ---- libgcrypt-1.6.1/tests/cavs_driver.pl.cavs 2013-03-15 20:25:38.000000000 +0100 -+++ libgcrypt-1.6.1/tests/cavs_driver.pl 2014-02-28 14:46:16.436544639 +0100 -@@ -1,9 +1,11 @@ - #!/usr/bin/env perl - # --# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ -+# $Id: cavs_driver.pl 2124 2010-12-20 07:56:30Z smueller $ - # - # CAVS test driver (based on the OpenSSL driver) - # Written by: Stephan Müller -+# Werner Koch (libgcrypt interface) -+# Tomas Mraz (addition of DSA2) - # Copyright (c) atsec information security corporation - # - # Permission is hereby granted, free of charge, to any person obtaining a copy -@@ -85,13 +87,16 @@ - # T[CBC|CFB??|ECB|OFB]varkey - # T[CBC|CFB??|ECB|OFB]invperm - # T[CBC|CFB??|ECB|OFB]vartext -+# WARNING: TDES in CFB and OFB mode problems see below - # - # ANSI X9.31 RNG - # ANSI931_AES128MCT - # ANSI931_AES128VST - # --# DSA -+# DSA2 - # PQGGen -+# PQGVer -+# KeyPair - # SigGen - # SigVer - # -@@ -101,6 +106,36 @@ - # RC4PltBD - # RC4REGT - # -+# -+# TDES MCT for CFB and OFB: -+# ------------------------- -+# The inner loop cannot be handled by this script. If you want to have tests -+# for these cipher types, implement your own inner loop and add it to -+# crypto_mct. -+# -+# the value $next_source in crypto_mct is NOT set by the standard implementation -+# of this script. It would need to be set as follows for these two (code take -+# from fipsdrv.c from libgcrypt - the value input at the end will contain the -+# the value for $next_source: -+# -+# ... inner loop ... -+# ... -+# get_current_iv (hd, last_iv, blocklen); -+# ... encrypt / decrypt (input is the data to be en/decrypted and output is the -+# result of operation) ... -+# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) -+# memcpy (input, last_iv, blocklen); -+# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) -+# memcpy (input, last_iv, blocklen); -+# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) -+# { -+# /* Reconstruct the output vector. */ -+# int i; -+# for (i=0; i < blocklen; i++) -+# input[i] ^= output[i]; -+# } -+# ... inner loop ends ... -+# ==> now, the value of input is to be put into $next_source - - use strict; - use warnings; -@@ -226,6 +261,8 @@ my $hmac; - # Generate the P, Q, G, Seed, counter, h (value used to generate g) values - # for DSA - # $1: modulus size -+# $2: q size -+# $3: seed (might be empty string) - # return: string with the calculated values in hex format, where each value - # is separated from the previous with a \n in the following order: - # P\n -@@ -236,6 +273,19 @@ my $hmac; - # h - my $dsa_pqggen; - -+# Generate the G value from P and Q -+# for DSA -+# $1: modulus size -+# $2: q size -+# $3: P in hex form -+# $4: Q in hex form -+# return: string with the calculated values in hex format, where each value -+# is separated from the previous with a \n in the following order: -+# P\n -+# Q\n -+# G\n -+my $dsa_ggen; -+ - # - # Generate an DSA public key from the provided parameters: - # $1: Name of file to create -@@ -255,10 +305,20 @@ my $dsa_verify; - - # generate a new DSA key with the following properties: - # PEM format --# $1 keyfile name --# return: file created, hash with keys of P, Q, G in hex format -+# $1: modulus size -+# $2: q size -+# $3 keyfile name -+# return: file created with key, string with values of P, Q, G in hex format - my $gen_dsakey; - -+# generate a new DSA private key XY parameters in domain: -+# PEM format -+# $1: P in hex form -+# $2: Q in hex form -+# $3: G in hex form -+# return: string with values of X, Y in hex format -+my $gen_dsakey_domain; -+ - # Sign a message with DSA - # $1: data to be signed in hex form - # $2: Key file in PEM format with the private key -@@ -500,17 +560,32 @@ sub libgcrypt_hmac($$$$) { - return pipe_through_program($msg, $program); - } - --sub libgcrypt_dsa_pqggen($) { -+sub libgcrypt_dsa_pqggen($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $seed = shift; -+ -+ my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; -+ return pipe_through_program($seed, $program); -+} -+ -+sub libgcrypt_dsa_ggen($$$$) { - my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $domain = "(domain (p #$p#)(q #$q#))"; - -- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; - return pipe_through_program("", $program); - } - --sub libgcrypt_gen_dsakey($) { -+sub libgcrypt_gen_dsakey($$$) { -+ my $mod = shift; -+ my $qsize = shift; - my $file = shift; - -- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; - my $tmp; - my %ret; - -@@ -519,10 +594,21 @@ sub libgcrypt_gen_dsakey($) { - $tmp = pipe_through_program("", $program); - die "dsa key gen failed: file $file not created" if (! -f $file); - -- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); -+ @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); - return %ret; - } - -+sub libgcrypt_gen_dsakey_domain($$$) { -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; -+ -+ my $program = "fipsdrv --key '$domain' dsa-gen-key"; -+ -+ return pipe_through_program("", $program); -+} -+ - sub libgcrypt_dsa_genpubkey($$$$$) { - my $filename = shift; - my $p = shift; -@@ -1139,7 +1225,7 @@ sub hmac_kat($$$$) { - $out .= "Tlen = $tlen\n"; - $out .= "Key = $key\n"; - $out .= "Msg = $msg\n"; -- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; -+ $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; - - return $out; - } -@@ -1205,7 +1291,7 @@ sub crypto_mct($$$$$$$$) { - } - my ($CO, $CI); - my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); -- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); -+ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); - my $pid = open2($CO, $CI, $cipher_imp); - - my $calc_data = $iv; # CT[j] -@@ -1213,8 +1299,8 @@ sub crypto_mct($$$$$$$$) { - my $old_old_calc_data; # CT[j-2] - my $next_source; - -- # TDES inner loop implements logic within driver -- if ($cipher =~ /des/) { -+ # TDES inner loop implements logic within driver of libgcrypt -+ if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { - # Need to provide a dummy IV in case of ECB mode. - my $iv_arg = (defined($iv) && $iv ne "") - ? bin2hex($iv) -@@ -1238,6 +1324,10 @@ sub crypto_mct($$$$$$$$) { - $line = <$CO>; - } else { - for (my $j = 0; $j < $iloop; ++$j) { -+ if ($cipher =~ /des-ede3-ofb/ || -+ (!$enc && $cipher =~ /des-ede3-cfb/)) { -+ die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; -+ } - $old_old_calc_data = $old_calc_data; - $old_calc_data = $calc_data; - -@@ -1503,21 +1593,23 @@ sub rngx931($$$$) { - return $out; - } - --# DSA PQGGen test -+# DSA PQGen test - # $1 modulus size --# $2 number of rounds to perform the test -+# $2 q size -+# $3 number of rounds to perform the test - # return: string formatted as expected by CAVS --sub dsa_pqggen_driver($$) { -+sub dsa_pqgen_driver($$$) { - my $mod = shift; -+ my $qsize = shift; - my $rounds = shift; - - my $out = ""; - for(my $i=0; $i<$rounds; $i++) { -- my $ret = &$dsa_pqggen($mod); -+ my $ret = &$dsa_pqggen($mod, $qsize, ""); - my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); -- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" -- if (!defined($P) || !defined($Q) || !defined($G) || -- !defined($Seed) || !defined($c) || !defined($H)); -+ die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || -+ !defined($Seed) || !defined($c)); - - # now change the counter to decimal as CAVS wants decimal - # counter value although all other is HEX -@@ -1525,15 +1617,166 @@ sub dsa_pqggen_driver($$) { - - $out .= "P = $P\n"; - $out .= "Q = $Q\n"; -- $out .= "G = $G\n"; -- $out .= "Seed = $Seed\n"; -- $out .= "c = $c\n"; -- $out .= "H = $H\n\n"; -+ $out .= "domain_parameter_seed = $Seed\n"; -+ $out .= "counter = $c\n\n"; - } - - return $out; - } - -+# DSA GGen test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# return: string formatted as expected by CAVS -+sub dsa_ggen_driver($$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_ggen($mod, $qsize, $p, $q); -+ my ($P, $Q, $G) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G for dsa_ggen" -+ if (!defined($P) || !defined($Q) || !defined($G)); -+ -+ $out .= "G = $G\n\n"; -+ -+ return $out; -+} -+ -+sub hexcomp($$) { -+ my $a = lc shift; -+ my $b = lc shift; -+ -+ if (length $a < length $b) { -+ my $c = $a; -+ $a = $b; -+ $b = $a; -+ } -+ -+ while (length $b < length $a) { -+ $b = "00$b"; -+ } -+ -+ return $a eq $b; -+} -+ -+# DSA PQVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 seed in hex form -+# $6 c decimal counter -+# return: string formatted as expected by CAVS -+sub dsa_pqver_driver($$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $seed = shift; -+ my $c = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2)); -+ -+ $c2 = hex($c2); -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($seed, $seed2) && $c == $c2) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ return $out; -+} -+ -+# DSA PQGVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 g in hex form -+# $6 seed in hex form -+# $7 c decimal counter -+# $8 h in hex form -+# return: string formatted as expected by CAVS -+sub dsa_pqgver_driver($$$$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $seed = shift; -+ my $c = shift; -+ my $h = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2) || !defined($h2)); -+ -+ -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ $out .= "H = $h\n"; -+ -+ $c2 = hex($c2); -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && -+ $c == $c2 && hex($h) == hex($h2)) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ -+ return $out; -+} -+ -+# DSA Keypair test -+# $1 modulus size -+# $2 q size -+# $3 number of rounds to perform the test -+# return: string formatted as expected by CAVS -+sub dsa_keypair_driver($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $rounds = shift; -+ -+ my $out = ""; -+ my $tmpkeyfile = "dsa_siggen.tmp.$$"; -+ my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); -+ $out .= "P = " . $pqg{'P'} . "\n"; -+ $out .= "Q = " . $pqg{'Q'} . "\n"; -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ unlink($tmpkeyfile); -+ -+ for(my $i=0; $i<$rounds; $i++) { -+ my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); -+ my ($X, $Y) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" -+ if (!defined($X) || !defined($Y)); -+ -+ $out .= "X = $X\n"; -+ $out .= "Y = $Y\n\n"; -+ } -+ -+ return $out; -+} - - # DSA SigGen test - # $1: Message to be signed in hex form -@@ -1658,12 +1901,16 @@ sub parse($$) { - my $klen = ""; - my $tlen = ""; - my $modulus = ""; -+ my $qsize = ""; - my $capital_n = 0; -+ my $num = 0; - my $capital_p = ""; - my $capital_q = ""; - my $capital_g = ""; - my $capital_y = ""; - my $capital_r = ""; -+ my $capital_h = ""; -+ my $c = ""; - my $xp1 = ""; - my $xp2 = ""; - my $Xp = ""; -@@ -1700,7 +1947,7 @@ sub parse($$) { - - ##### Extract cipher - # XXX there may be more - to be added -- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { -+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyPair|PQGVer)/) { - if ($tmpline =~ /CBC/) { $mode="cbc"; } - elsif ($tmpline =~ /ECB/) { $mode="ecb"; } - elsif ($tmpline =~ /OFB/) { $mode="ofb"; } -@@ -1749,7 +1996,15 @@ sub parse($$) { - - if ($tt == 0) { - ##### Identify the test type -- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { -+ if ($tmpline =~ /PQGVer/) { -+ $tt = 16; -+ die "Interface function for DSA PQGVer testing not defined for tested library" -+ if (!defined($dsa_pqggen)); -+ } elsif ($tmpline =~ /KeyPair/) { -+ $tt = 14; -+ die "Interface function dsa_keygen for DSA key generation not defined for tested library" -+ if (!defined($gen_dsakey_domain)); -+ } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { - $tt = 13; - die "Interface function rsa_derive for RSA key generation not defined for tested library" - if (!defined($rsa_derive)); -@@ -1760,11 +2015,11 @@ sub parse($$) { - } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { - $tt = 11; - die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" -- if (!defined($dsa_sign) || !defined($gen_rsakey)); -+ if (!defined($dsa_sign) || !defined($gen_dsakey)); - } elsif ($tmpline =~ /PQGGen/) { - $tt = 10; - die "Interface function for DSA PQGGen testing not defined for tested library" -- if (!defined($dsa_pqggen)); -+ if (!defined($dsa_pqggen) || !defined($dsa_ggen)); - } elsif ($tmpline =~ /Hash sizes tested/) { - $tt = 9; - die "Interface function hmac for HMAC testing not defined for tested library" -@@ -1792,7 +2047,7 @@ sub parse($$) { - } elsif ($tmpline =~ /Monte|MCT|Carlo/) { - $tt = 2; - die "Interface function state_cipher for Stateful Cipher operation defined for tested library" -- if (!defined($state_cipher) || !defined($state_cipher_des)); -+ if (!defined($state_cipher) && !defined($state_cipher_des)); - } elsif ($cipher =~ /^sha/) { - $tt = 3; - die "Interface function hash for Hashing not defined for tested library" -@@ -1875,18 +2130,44 @@ sub parse($$) { - die "Msg/Seed seen twice - input file crap" if ($pt ne ""); - $pt=$2; - } -- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request -+ $out .= $line . "\n"; # print it -+ if ($tt == 10) { -+ # now generate G from PQ -+ $tt = 15; -+ } -+ } -+ elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request -+ $out .= $line . "\n"; # print it -+ if ($tt == 16) { -+ # now verify PQG -+ $tt = 17; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests - $modulus = $1; -+ $qsize = $2; - $out .= $line . "\n\n"; # print it -+ # clear eventual PQG -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; - # generate the private key with given bit length now - # as we have the required key length in bit - if ($tt == 11) { - $dsa_keyfile = "dsa_siggen.tmp.$$"; -- my %pqg = &$gen_dsakey($dsa_keyfile); -+ my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); - $out .= "P = " . $pqg{'P'} . "\n"; - $out .= "Q = " . $pqg{'Q'} . "\n"; -- $out .= "G = " . $pqg{'G'} . "\n"; -- } elsif ( $tt == 5 ) { -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ $modulus = $1; -+ $out .= $line . "\n\n"; # print it -+ # generate the private key with given bit length now -+ # as we have the required key length in bit -+ if ( $tt == 5 ) { - # XXX maybe a secure temp file name is better here - # but since it is not run on a security sensitive - # system, I hope that this is fine -@@ -1932,11 +2213,16 @@ sub parse($$) { - if ($tlen ne ""); - $tlen=$1; - } -- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen -+ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair - die "N seen twice - check input file" - if ($capital_n); - $capital_n = $1; - } -+ elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen -+ die "Num seen twice - check input file" -+ if ($num); -+ $num = $1; -+ } - elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer - die "P seen twice - check input file" - if ($capital_p); -@@ -1965,6 +2251,16 @@ sub parse($$) { - if ($capital_r); - $capital_r = $1; - } -+ elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer -+ die "H seen twice - check input file" -+ if ($capital_h); -+ $capital_h = $1; -+ } -+ elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer -+ die "c seen twice - check input file" -+ if ($c); -+ $c = $1; -+ } - elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen - die "xp1 seen twice - check input file" - if ($xp1); -@@ -2074,11 +2370,10 @@ sub parse($$) { - } - } - elsif ($tt == 10) { -- if ($modulus ne "" && $capital_n > 0) { -- $out .= dsa_pqggen_driver($modulus, $capital_n); -- #$mod is not resetted -- $capital_n = 0; -- } -+ if ($modulus ne "" && $qsize ne "" && $num > 0) { -+ $out .= dsa_pqgen_driver($modulus, $qsize, $num); -+ $num = 0; -+ } - } - elsif ($tt == 11) { - if ($pt ne "" && $dsa_keyfile ne "") { -@@ -2141,6 +2436,74 @@ sub parse($$) { - $Xq = ""; - } - } -+ elsif ($tt == 14) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_n > 0) { -+ $out .= dsa_keypair_driver($modulus, -+ $qsize, -+ $capital_n); -+ $capital_n = 0; -+ } -+ } -+ elsif ($tt == 15) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "") { -+ $out .= dsa_ggen_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q); -+ $capital_p = ""; -+ $capital_q = ""; -+ $num--; -+ } -+ } -+ elsif ($tt == 16) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $pt ne "" && -+ $c ne "") { -+ $out .= dsa_pqver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $pt, -+ $c); -+ $capital_p = ""; -+ $capital_q = ""; -+ $pt = ""; -+ $c = ""; -+ } -+ } -+ elsif ($tt == 17) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $capital_g ne "" && -+ $pt ne "" && -+ $c ne "" && -+ $capital_h ne "") { -+ $out .= dsa_pqgver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $capital_g, -+ $pt, -+ $c, -+ $capital_h); -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; -+ $pt = ""; -+ $c = ""; -+ $capital_h = ""; -+ } -+ } - elsif ($tt > 0) { - die "Test case $tt not defined"; - } -@@ -2199,7 +2562,9 @@ sub main() { - $state_rng = \&libgcrypt_state_rng; - $hmac = \&libgcrypt_hmac; - $dsa_pqggen = \&libgcrypt_dsa_pqggen; -+ $dsa_ggen = \&libgcrypt_dsa_ggen; - $gen_dsakey = \&libgcrypt_gen_dsakey; -+ $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; - $dsa_sign = \&libgcrypt_dsa_sign; - $dsa_verify = \&libgcrypt_dsa_verify; - $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; -diff -up libgcrypt-1.6.1/tests/cavs_tests.sh.cavs libgcrypt-1.6.1/tests/cavs_tests.sh ---- libgcrypt-1.6.1/tests/cavs_tests.sh.cavs 2013-03-15 20:25:38.000000000 +0100 -+++ libgcrypt-1.6.1/tests/cavs_tests.sh 2014-02-28 14:46:16.437544662 +0100 -@@ -55,7 +55,7 @@ function run_one_test () { - [ -d "$respdir" ] || mkdir "$respdir" - [ -f "$rspfile" ] && rm "$rspfile" - -- if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then -+ if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then - dflag="-D" - fi - -diff -up libgcrypt-1.6.1/tests/fipsdrv.c.cavs libgcrypt-1.6.1/tests/fipsdrv.c ---- libgcrypt-1.6.1/tests/fipsdrv.c.cavs 2013-12-16 18:44:32.000000000 +0100 -+++ libgcrypt-1.6.1/tests/fipsdrv.c 2014-02-28 14:46:16.437544662 +0100 -@@ -893,6 +893,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) - die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); - - p = buf; -+ while (*p) -+ *p++ = tolower(*p); -+ p = buf; - if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) - p += 2; - -@@ -1675,14 +1678,14 @@ run_rsa_verify (const void *data, size_t - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen (int keysize) -+dsa_gen (int keysize, int qsize) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; - - err = gcry_sexp_build (&keyspec, NULL, -- "(genkey (dsa (nbits %d)(use-fips186-2)))", -- keysize); -+ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", -+ keysize, qsize); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1700,7 +1703,7 @@ dsa_gen (int keysize) - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) -+dsa_gen_with_seed (int keysize, int qsize, const void *seed, size_t seedlen) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; -@@ -1709,10 +1712,11 @@ dsa_gen_with_seed (int keysize, const vo - "(genkey" - " (dsa" - " (nbits %d)" -- " (use-fips186-2)" -+ " (qbits %d)" -+ " (use-fips186)" - " (derive-parms" - " (seed %b))))", -- keysize, (int)seedlen, seed); -+ keysize, qsize, (int)seedlen, seed); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1720,6 +1724,37 @@ dsa_gen_with_seed (int keysize, const vo - err = gcry_pk_genkey (&key, keyspec); - if (err) - die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); -+ -+ gcry_sexp_release (keyspec); -+ -+ return key; -+} -+ -+/* Generate a DSA key with specified domain parameters and return the complete -+ S-expression. */ -+static gcry_sexp_t -+dsa_gen_key (const char *domain) -+{ -+ gpg_error_t err; -+ gcry_sexp_t keyspec, key, domspec; -+ -+ err = gcry_sexp_new (&domspec, domain, strlen(domain), 0); -+ if (err) -+ die ("gcry_sexp_build failed for domain spec: %s\n", -+ gpg_strerror (err)); -+ -+ err = gcry_sexp_build (&keyspec, NULL, -+ "(genkey" -+ " (dsa" -+ " (use-fips186)" -+ " %S))", -+ domspec); -+ if (err) -+ die ("gcry_sexp_build failed for DSA key generation: %s\n", -+ gpg_strerror (err)); -+ err = gcry_pk_genkey (&key, keyspec); -+ if (err) -+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (keyspec); - -@@ -1732,7 +1767,7 @@ dsa_gen_with_seed (int keysize, const vo - with one parameter per line in hex format using this order: p, q, - g, seed, counter, h. */ - static void --print_dsa_domain_parameters (gcry_sexp_t key) -+print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) - { - gcry_sexp_t l1, l2; - gcry_mpi_t mpi; -@@ -1768,6 +1803,9 @@ print_dsa_domain_parameters (gcry_sexp_t - } - gcry_sexp_release (l1); - -+ if (!print_misc) -+ return; -+ - /* Extract the seed values. */ - l1 = gcry_sexp_find_token (key, "misc-key-info", 0); - if (!l1) -@@ -1819,38 +1857,106 @@ print_dsa_domain_parameters (gcry_sexp_t - } - - --/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+/* Print just the XY private key parameters. KEY -+ is the complete key as returned by dsa_gen. We print to stdout -+ with one parameter per line in hex format using this order: x, y. */ -+static void -+print_dsa_xy (gcry_sexp_t key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t mpi; -+ int idx; -+ -+ l1 = gcry_sexp_find_token (key, "private-key", 0); -+ if (!l1) -+ die ("private key not found in genkey result\n"); -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("returned private key not formed as expected\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ /* Extract the parameters from the S-expression and print them to stdout. */ -+ for (idx=0; "xy"[idx]; idx++) -+ { -+ l2 = gcry_sexp_find_token (l1, "xy"+idx, 1); -+ if (!l2) -+ die ("no %c parameter in returned public key\n", "xy"[idx]); -+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); -+ if (!mpi) -+ die ("no value for %c parameter in returned private key\n","xy"[idx]); -+ gcry_sexp_release (l2); -+ if (standalone_mode) -+ printf ("%c = ", "XY"[idx]); -+ print_mpi_line (mpi, 1); -+ gcry_mpi_release (mpi); -+ } -+ -+ gcry_sexp_release (l1); -+} -+ -+ -+/* Generate DSA pq domain parameters for a modulus size of KEYSIZE. The - result is printed to stdout with one parameter per line in hex -- format and in this order: p, q, g, seed, counter, h. If SEED is -+ format and in this order: p, q, seed, counter. If SEED is - not NULL this seed value will be used for the generation. */ - static void --run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) -+run_dsa_pqg_gen (int keysize, int qsize, const void *seed, size_t seedlen) - { - gcry_sexp_t key; - - if (seed) -- key = dsa_gen_with_seed (keysize, seed, seedlen); -+ key = dsa_gen_with_seed (keysize, qsize, seed, seedlen); - else -- key = dsa_gen (keysize); -- print_dsa_domain_parameters (key); -+ key = dsa_gen (keysize, qsize); -+ print_dsa_domain_parameters (key, 1); -+ gcry_sexp_release (key); -+} -+ -+ -+/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+ result is printed to stdout with one parameter per line in hex -+ format and in this order: p, q, g, seed, counter, h. If SEED is -+ not NULL this seed value will be used for the generation. */ -+static void -+run_dsa_g_gen (int keysize, int qsize, const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_domain_parameters (key, 0); -+ gcry_sexp_release (key); -+} -+ -+/* Generate a DSA key with specified domain parameters -+ and print the XY values. */ -+static void -+run_dsa_gen_key (const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_xy (key); -+ - gcry_sexp_release (key); - } - - - /* Generate a DSA key of size of KEYSIZE and write the private key to - FILENAME. Also write the parameters to stdout in the same way as -- run_dsa_pqg_gen. */ -+ run_dsa_g_gen. */ - static void --run_dsa_gen (int keysize, const char *filename) -+run_dsa_gen (int keysize, int qsize, const char *filename) - { - gcry_sexp_t key, private_key; - FILE *fp; - -- key = dsa_gen (keysize); -+ key = dsa_gen (keysize, qsize); - private_key = gcry_sexp_find_token (key, "private-key", 0); - if (!private_key) - die ("private key not found in genkey result\n"); -- print_dsa_domain_parameters (key); -+ print_dsa_domain_parameters (key, 1); - - fp = fopen (filename, "wb"); - if (!fp) -@@ -1863,6 +1969,53 @@ run_dsa_gen (int keysize, const char *fi - } - - -+static int -+dsa_hash_from_key(gcry_sexp_t s_key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t q; -+ unsigned int qbits; -+ -+ l1 = gcry_sexp_find_token (s_key, "public-key", 0); -+ if (!l1) -+ { -+ l1 = gcry_sexp_find_token (s_key, "private-key", 0); -+ if (!l1) -+ die ("neither private nor public key found in the loaded key\n"); -+ } -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("public key not formed as expected - no dsa\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ l2 = gcry_sexp_find_token (l1, "q", 0); -+ if (!l2) -+ die ("public key not formed as expected - no q\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); -+ if (!q) -+ die ("public key not formed as expected - no mpi in q\n"); -+ qbits = gcry_mpi_get_nbits(q); -+ gcry_sexp_release(l1); -+ gcry_mpi_release(q); -+ switch(qbits) -+ { -+ case 160: -+ return GCRY_MD_SHA1; -+ case 224: -+ return GCRY_MD_SHA224; -+ case 256: -+ return GCRY_MD_SHA256; -+ default: -+ die("bad number bits (%d) of q in key\n", qbits); -+ } -+ return GCRY_MD_NONE; -+} -+ - - /* Sign DATA of length DATALEN using the key taken from the S-expression - encoded KEYFILE. */ -@@ -1872,11 +2025,16 @@ run_dsa_sign (const void *data, size_t d - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; -+ -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ gcry_md_hash_buffer (algo, hash, data, datalen); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -1887,8 +2045,6 @@ run_dsa_sign (const void *data, size_t d - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); -- - err = gcry_pk_sign (&s_sig, s_data, s_key); - if (err) - { -@@ -1964,13 +2120,18 @@ run_dsa_verify (const void *data, size_t - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; -+ -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -+ gcry_md_hash_buffer (algo, hash, data, datalen); - /* Note that we can't simply use %b with HASH to build the - S-expression, because that might yield a negative value. */ -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -1981,7 +2142,6 @@ run_dsa_verify (const void *data, size_t - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); - s_sig = read_sexp_from_file (sigfile); - - err = gcry_pk_verify (s_sig, s_data, s_key); -@@ -2014,7 +2174,7 @@ usage (int show_help) - "Run a crypto operation using hex encoded input and output.\n" - "MODE:\n" - " encrypt, decrypt, digest, random, hmac-sha,\n" -- " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" -+ " rsa-{derive,gen,sign,verify}, dsa-{pq-gen,g-gen,gen,sign,verify}\n" - "OPTIONS:\n" - " --verbose Print additional information\n" - " --binary Input and output is in binary form\n" -@@ -2024,6 +2184,7 @@ usage (int show_help) - " --dt DT Use the hex encoded DT for the RNG\n" - " --algo NAME Use algorithm NAME\n" - " --keysize N Use a keysize of N bits\n" -+ " --qize N Use a DSA q parameter size of N bits\n" - " --signature NAME Take signature from file NAME\n" - " --chunk N Read in chunks of N bytes (implies --binary)\n" - " --pkcs1 Use PKCS#1 encoding\n" -@@ -2050,6 +2211,7 @@ main (int argc, char **argv) - const char *dt_string = NULL; - const char *algo_string = NULL; - const char *keysize_string = NULL; -+ const char *qsize_string = NULL; - const char *signature_string = NULL; - FILE *input; - void *data; -@@ -2143,6 +2305,14 @@ main (int argc, char **argv) - keysize_string = *argv; - argc--; argv++; - } -+ else if (!strcmp (*argv, "--qsize")) -+ { -+ argc--; argv++; -+ if (!argc) -+ usage (0); -+ qsize_string = *argv; -+ argc--; argv++; -+ } - else if (!strcmp (*argv, "--signature")) - { - argc--; argv++; -@@ -2463,23 +2633,49 @@ main (int argc, char **argv) - } - else if (!strcmp (mode_string, "dsa-pqg-gen")) - { -- int keysize; -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ run_dsa_pqg_gen (keysize, qsize, datalen? data:NULL, datalen); -+ } -+ else if (!strcmp (mode_string, "dsa-g-gen")) -+ { -+ int keysize, qsize; -+ -+ keysize = keysize_string? atoi (keysize_string) : 0; -+ if (keysize < 1024 || keysize > 3072) -+ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ if (!key_string) -+ die ("option --key containing pq domain parameters is required in this mode\n"); -+ run_dsa_g_gen (keysize, qsize, key_string); -+ } -+ else if (!strcmp (mode_string, "dsa-gen-key")) -+ { -+ if (!key_string) -+ die ("option --key containing pqg domain parameters is required in this mode\n"); -+ run_dsa_gen_key (key_string); - } - else if (!strcmp (mode_string, "dsa-gen")) - { -- int keysize; -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); - if (!key_string) - die ("option --key is required in this mode\n"); -- run_dsa_gen (keysize, key_string); -+ run_dsa_gen (keysize, qsize, key_string); - } - else if (!strcmp (mode_string, "dsa-sign")) - { diff --git a/libgcrypt-1.6.2-rsa-fips-keygen.patch b/libgcrypt-1.6.3-rsa-fips-keygen.patch similarity index 88% rename from libgcrypt-1.6.2-rsa-fips-keygen.patch rename to libgcrypt-1.6.3-rsa-fips-keygen.patch index f9a3e5f..6d2243e 100644 --- a/libgcrypt-1.6.2-rsa-fips-keygen.patch +++ b/libgcrypt-1.6.3-rsa-fips-keygen.patch @@ -1,8 +1,8 @@ -diff -up libgcrypt-1.6.2/cipher/primegen.c.fips-keygen libgcrypt-1.6.2/cipher/primegen.c ---- libgcrypt-1.6.2/cipher/primegen.c.fips-keygen 2014-12-08 16:55:56.425077059 +0100 -+++ libgcrypt-1.6.2/cipher/primegen.c 2014-12-08 16:59:26.039817665 +0100 -@@ -1198,6 +1198,22 @@ _gcry_prime_check (gcry_mpi_t x, unsigne - return rc; +diff -up libgcrypt-1.6.3/cipher/primegen.c.fips-keygen libgcrypt-1.6.3/cipher/primegen.c +--- libgcrypt-1.6.3/cipher/primegen.c.fips-keygen 2015-03-06 16:38:56.698052602 +0100 ++++ libgcrypt-1.6.3/cipher/primegen.c 2015-03-06 16:45:45.848193024 +0100 +@@ -1199,6 +1199,25 @@ _gcry_prime_check (gcry_mpi_t x, unsigne + return GPG_ERR_NO_PRIME; } +/* Check whether the number X is prime according to FIPS 186-4 table C.2. */ @@ -10,23 +10,26 @@ diff -up libgcrypt-1.6.2/cipher/primegen.c.fips-keygen libgcrypt-1.6.2/cipher/pr +_gcry_fips186_4_prime_check (gcry_mpi_t x, unsigned int bits) +{ + gcry_err_code_t ec = GPG_ERR_NO_ERROR; -+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2); /* Used by the Fermat test. */ ++ ++ switch (mpi_cmp_ui (x, 2)) ++ { ++ case 0: return ec; /* 2 is a prime */ ++ case -1: return GPG_ERR_NO_PRIME; /* Only numbers > 1 are primes. */ ++ } + + /* We use 5 or 4 rounds as specified in table C.2 */ -+ if (! check_prime (x, val_2, bits > 1024 ? 4 : 5, NULL, NULL)) ++ if (! check_prime (x, mpi_const (MPI_C_TWO), bits > 1024 ? 4 : 5, NULL, NULL)) + ec = GPG_ERR_NO_PRIME; + -+ mpi_free (val_2); -+ + return ec; +} + /* Find a generator for PRIME where the factorization of (prime-1) is in the NULL terminated array FACTORS. Return the generator as a newly allocated MPI in R_G. If START_G is not NULL, use this as s -diff -up libgcrypt-1.6.2/cipher/rsa.c.fips-keygen libgcrypt-1.6.2/cipher/rsa.c ---- libgcrypt-1.6.2/cipher/rsa.c.fips-keygen 2014-12-08 16:55:56.407076652 +0100 -+++ libgcrypt-1.6.2/cipher/rsa.c 2014-12-08 17:11:06.770665261 +0100 +diff -up libgcrypt-1.6.3/cipher/rsa.c.fips-keygen libgcrypt-1.6.3/cipher/rsa.c +--- libgcrypt-1.6.3/cipher/rsa.c.fips-keygen 2015-03-06 16:38:56.661052411 +0100 ++++ libgcrypt-1.6.3/cipher/rsa.c 2015-03-06 16:38:56.699052607 +0100 @@ -339,6 +339,279 @@ generate_std (RSA_secret_key *sk, unsign } @@ -333,9 +336,9 @@ diff -up libgcrypt-1.6.2/cipher/rsa.c.fips-keygen libgcrypt-1.6.2/cipher/rsa.c } if (!ec) -diff -up libgcrypt-1.6.2/src/g10lib.h.fips-keygen libgcrypt-1.6.2/src/g10lib.h ---- libgcrypt-1.6.2/src/g10lib.h.fips-keygen 2014-08-21 12:29:09.000000000 +0200 -+++ libgcrypt-1.6.2/src/g10lib.h 2014-12-08 16:55:56.426077081 +0100 +diff -up libgcrypt-1.6.3/src/g10lib.h.fips-keygen libgcrypt-1.6.3/src/g10lib.h +--- libgcrypt-1.6.3/src/g10lib.h.fips-keygen 2015-02-23 11:55:58.000000000 +0100 ++++ libgcrypt-1.6.3/src/g10lib.h 2015-03-06 16:38:56.699052607 +0100 @@ -259,6 +259,9 @@ gpg_err_code_t _gcry_generate_fips186_3_ int *r_counter, void **r_seed, size_t *r_seedlen, int *r_hashalgo); @@ -346,9 +349,9 @@ diff -up libgcrypt-1.6.2/src/g10lib.h.fips-keygen libgcrypt-1.6.2/src/g10lib.h /* Replacements of missing functions (missing-string.c). */ #ifndef HAVE_STPCPY -diff -up libgcrypt-1.6.2/tests/keygen.c.fips-keygen libgcrypt-1.6.2/tests/keygen.c ---- libgcrypt-1.6.2/tests/keygen.c.fips-keygen 2014-12-08 16:55:56.407076652 +0100 -+++ libgcrypt-1.6.2/tests/keygen.c 2014-12-08 17:13:29.449892067 +0100 +diff -up libgcrypt-1.6.3/tests/keygen.c.fips-keygen libgcrypt-1.6.3/tests/keygen.c +--- libgcrypt-1.6.3/tests/keygen.c.fips-keygen 2015-03-06 16:38:56.661052411 +0100 ++++ libgcrypt-1.6.3/tests/keygen.c 2015-03-06 16:38:56.699052607 +0100 @@ -215,12 +215,12 @@ check_rsa_keys (void) diff --git a/libgcrypt.spec b/libgcrypt.spec index 1a71b93..418dbc8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.6.2 -Release: 4%{?dist} +Version: 1.6.3 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -40,7 +40,7 @@ Patch18: libgcrypt-1.6.2-fips-ctor.patch # Make it possible to run the test suite in the FIPS mode Patch19: libgcrypt-1.6.2-fips-test.patch # Make the FIPS RSA keygen to be FIPS 186-4 compliant -Patch20: libgcrypt-1.6.2-rsa-fips-keygen.patch +Patch20: libgcrypt-1.6.3-rsa-fips-keygen.patch # update the selftests for new FIPS requirements Patch22: libgcrypt-1.6.2-fips-reqs.patch @@ -201,6 +201,9 @@ exit 0 %license COPYING %changelog +* Fri Mar 6 2015 Tomáš Mráz 1.6.3-1 +- new upstream version + * Wed Feb 25 2015 Tomáš Mráz 1.6.2-4 - do not initialize secure memory during the selftest (#1195850) diff --git a/sources b/sources index d296f4f..04e70c5 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -e682099d3bf9cd13802e5a5e67a66544 libgcrypt-1.6.2-hobbled.tar.xz +cbb7aa4b8c4c63f24e954fbf00e16335 libgcrypt-1.6.3-hobbled.tar.xz From f56a95f03b711eac70ddc8673b6417a93a45c2bd Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 13 Mar 2015 15:07:21 +0100 Subject: [PATCH 081/214] do not use strict aliasing for bufhelp functions (#1201219) --- libgcrypt-1.6.3-aliasing.patch | 177 +++++++++++++++++++++++++++++++++ libgcrypt.spec | 8 +- 2 files changed, 184 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.6.3-aliasing.patch diff --git a/libgcrypt-1.6.3-aliasing.patch b/libgcrypt-1.6.3-aliasing.patch new file mode 100644 index 0000000..9282944 --- /dev/null +++ b/libgcrypt-1.6.3-aliasing.patch @@ -0,0 +1,177 @@ +diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhelp.h +--- libgcrypt-1.6.3/cipher/bufhelp.h.aliasing 2015-02-27 10:54:03.000000000 +0100 ++++ libgcrypt-1.6.3/cipher/bufhelp.h 2015-03-13 15:03:43.301749751 +0100 +@@ -80,7 +80,7 @@ do_bytes: + for (; len; len--) + *dst++ = *src++; + #endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/ +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + + /* Optimized function for buffer xoring */ +@@ -117,7 +117,7 @@ do_bytes: + /* Handle tail. */ + for (; len; len--) + *dst++ = *src1++ ^ *src2++; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + + /* Optimized function for buffer xoring with two destination buffers. Used +@@ -155,7 +155,7 @@ do_bytes: + /* Handle tail. */ + for (; len; len--) + *dst1++ = (*dst2++ ^= *src++); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + + /* Optimized function for combined buffer xoring and copying. Used by mainly +@@ -208,7 +208,7 @@ do_bytes: + *dst_xor++ = *srcdst_cpy ^ *src_xor++; + *srcdst_cpy++ = temp; + } +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + + /* Optimized function for combined buffer xoring and copying. Used by mainly +@@ -234,7 +234,7 @@ buf_eq_const(const void *_a, const void + diff -= !!(a[i] - b[i]); + + return !diff; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + + #ifndef BUFHELP_FAST_UNALIGNED_ACCESS +@@ -246,14 +246,14 @@ static inline u32 buf_get_be32(const voi + const byte *in = _buf; + return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \ + ((u32)in[2] << 8) | (u32)in[3]; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline u32 buf_get_le32(const void *_buf) + { + const byte *in = _buf; + return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \ + ((u32)in[1] << 8) | (u32)in[0]; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline void buf_put_be32(void *_buf, u32 val) + { +@@ -262,7 +262,7 @@ static inline void buf_put_be32(void *_b + out[1] = val >> 16; + out[2] = val >> 8; + out[3] = val; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline void buf_put_le32(void *_buf, u32 val) + { +@@ -271,7 +271,7 @@ static inline void buf_put_le32(void *_b + out[2] = val >> 16; + out[1] = val >> 8; + out[0] = val; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + #ifdef HAVE_U64_TYPEDEF + /* Functions for loading and storing unaligned u64 values of different +@@ -283,7 +283,7 @@ static inline u64 buf_get_be64(const voi + ((u64)in[2] << 40) | ((u64)in[3] << 32) | \ + ((u64)in[4] << 24) | ((u64)in[5] << 16) | \ + ((u64)in[6] << 8) | (u64)in[7]; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline u64 buf_get_le64(const void *_buf) + { +@@ -292,7 +292,7 @@ static inline u64 buf_get_le64(const voi + ((u64)in[5] << 40) | ((u64)in[4] << 32) | \ + ((u64)in[3] << 24) | ((u64)in[2] << 16) | \ + ((u64)in[1] << 8) | (u64)in[0]; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline void buf_put_be64(void *_buf, u64 val) + { +@@ -305,7 +305,7 @@ static inline void buf_put_be64(void *_b + out[5] = val >> 16; + out[6] = val >> 8; + out[7] = val; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline void buf_put_le64(void *_buf, u64 val) + { +@@ -318,7 +318,7 @@ static inline void buf_put_le64(void *_b + out[2] = val >> 16; + out[1] = val >> 8; + out[0] = val; +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + #endif /*HAVE_U64_TYPEDEF*/ + + #else /*BUFHELP_FAST_UNALIGNED_ACCESS*/ +@@ -328,24 +328,24 @@ static inline void buf_put_le64(void *_b + static inline u32 buf_get_be32(const void *_buf) + { + return be_bswap32(*(const u32 *)_buf); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline u32 buf_get_le32(const void *_buf) + { + return le_bswap32(*(const u32 *)_buf); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline void buf_put_be32(void *_buf, u32 val) + { + u32 *out = _buf; + *out = be_bswap32(val); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline void buf_put_le32(void *_buf, u32 val) + { + u32 *out = _buf; + *out = le_bswap32(val); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + #ifdef HAVE_U64_TYPEDEF + /* Functions for loading and storing unaligned u64 values of different +@@ -353,24 +353,24 @@ static inline void buf_put_le32(void *_b + static inline u64 buf_get_be64(const void *_buf) + { + return be_bswap64(*(const u64 *)_buf); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline u64 buf_get_le64(const void *_buf) + { + return le_bswap64(*(const u64 *)_buf); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline void buf_put_be64(void *_buf, u64 val) + { + u64 *out = _buf; + *out = be_bswap64(val); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + + static inline void buf_put_le64(void *_buf, u64 val) + { + u64 *out = _buf; + *out = le_bswap64(val); +-} ++} __attribute__ ((optimize("no-strict-aliasing"))) + #endif /*HAVE_U64_TYPEDEF*/ + + #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ diff --git a/libgcrypt.spec b/libgcrypt.spec index 418dbc8..08030d0 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.3 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -43,6 +43,8 @@ Patch19: libgcrypt-1.6.2-fips-test.patch Patch20: libgcrypt-1.6.3-rsa-fips-keygen.patch # update the selftests for new FIPS requirements Patch22: libgcrypt-1.6.2-fips-reqs.patch +# do not use strict aliasing for bufhelp functions +Patch23: libgcrypt-1.6.3-aliasing.patch %define gcrylibdir %{_libdir} @@ -91,6 +93,7 @@ applications using libgcrypt. %patch19 -p1 -b .fips-test %patch20 -p1 -b .fips-keygen %patch22 -p1 -b .fips-reqs +%patch23 -p1 -b .aliasing cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -201,6 +204,9 @@ exit 0 %license COPYING %changelog +* Fri Mar 13 2015 Tomáš Mráz 1.6.3-2 +- do not use strict aliasing for bufhelp functions (#1201219) + * Fri Mar 6 2015 Tomáš Mráz 1.6.3-1 - new upstream version From 376991d05a1a0e2911242061c41ca5c5a915e339 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 24 Mar 2015 09:57:39 +0100 Subject: [PATCH 082/214] Two selftest bug fixes. - touch only urandom in the selftest and when /dev/random is unavailable for example by SELinux confinement - fix the RSA selftest key (p q swap) (#1204517) --- libgcrypt-1.6.2-fips-reqs.patch | 40 +++++++++++++-------------- libgcrypt-1.6.3-rsa-fips-keygen.patch | 12 ++++---- libgcrypt-1.6.3-urandom-only.patch | 29 +++++++++++++++++++ libgcrypt.spec | 11 +++++++- 4 files changed, 65 insertions(+), 27 deletions(-) create mode 100644 libgcrypt-1.6.3-urandom-only.patch diff --git a/libgcrypt-1.6.2-fips-reqs.patch b/libgcrypt-1.6.2-fips-reqs.patch index dea7e34..4fa5f33 100644 --- a/libgcrypt-1.6.2-fips-reqs.patch +++ b/libgcrypt-1.6.2-fips-reqs.patch @@ -182,30 +182,30 @@ diff -up libgcrypt-1.6.2/cipher/rsa.c.fips-reqs libgcrypt-1.6.2/cipher/rsa.c -" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" -" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))"; -/* A sample 1024 bit RSA key used for the selftests (public only). */ -+" (d #36273db1f91bdba7a0417f1223ac232999d53a7b606741076353b4d2e758" -+" 950ac705f34eb2b412d470dc4f8506d3ddd863273e673121243904bc06a4" -+" ccce2b7afe7badde116ea3a5e604530ea34e2db48f31bfca7525520285de" -+" 3db27243b2898a9a3441263f9a67bea4967b0e75baa693d5b8d8b857f24b" -+" 0f1481d1574ef6454ca63bd070cad39d55de2205e78e284dee11cfb66776" -+" 09d3e33c13f99934107bec8138f0b6349c9b506f0b91814d8994047bf03c" -+" f4b1b200488d5a8f889ec5ab3a9e443f54e7d96e47aaa1bd404631f9f034" -+" b604e12b5b7386dd3a921b71c73f32e5c3c2aba17ebfa452a0b06890d120" -+" 1279e9d7c940baf219c7a50092860d01#)" -+" (p #00fc5c6e16ce1f037bcdf7b372b28f1672b856aef7cd67d84e7d07afd543" -+" 26c335be438f4e2f1c434e6bd2b2ec526d97522bcc5c3a6bf414c674da66" -+" 381c7a3f842fe3f95ab865694606a33779b2a15b58ed5ea75f8c6566bbd1" -+" 2436e637a73d49778a8c34d86929f34d5822b05124b640a886590ab7ba5c" -+" 97da57e836da7a9cad#)" -+" (q #00ccbe7b096906ee45bf884738a8f817e5b6ba6755e3e8058bb8e253d68e" ++" (d #03b1e24a94e50ab21f8619701ec97679be2cf8f733c9331d9e2974dba721" ++" 27e5def480290e78a769f96b19d28397a284868fb614ca9b1fb3a0d7efed" ++" df41451204ce71aceba659f6ed15964ebb317712364e1cfaf2fded77d658" ++" 8561acc49c97c2d7efe75f1534b35bd4f6561e1f468b45590db34553d4d0" ++" c2cb4d806b74e1b2c52740462538865d9792b0aefbbf7b9827f4b3badcb3" ++" 5adab638266a2d2fb8422a7a19142e08848e56af77a66c39b2afafa2e15b" ++" 1a7e4ed1f2c7ed350678c0465d86472af97371b13ef5058662f835ef9087" ++" f6cca8281bbf1b6b155c737b33d9e443350df85e7cc3b507231fb839f41f" ++" 02c654b29017f35d69007c70e13ba0e5#)" ++" (p #00ccbe7b096906ee45bf884738a8f817e5b6ba6755e3e8058bb8e253d68e" +" ef2ce74f4af74e268d850b3fecc31cd4ebec6ac8722a257dfda67796f01e" +" cd2857f83730756bbdd47b0c87c56c8740a5bb272c78c9745a545b0b306f" +" 444afa71e4216166f9ee65de7c04d7fda9155b7fe27aba698672a6068d9b" +" 9055609e4c5da9b655#)" -+" (u #00afdecbdc5268ea7b1bff7284db7f6757dae3165fd80691ed2bbe8e54a1" -+" 6f7ff950aad059e9695903d93e59ff206ee1470bd2b099ca4e83426a7684" -+" 75a1ecafd3092fec0f008d78fe773174ec6fbff85384f3a91c2e4b1f59f1" -+" 1f2000fee86569f6cab5de338087bc615b90570de4aeb1a9125abbe3834d" -+" 5a69716c0a5fa20603#)))"; ++" (q #00fc5c6e16ce1f037bcdf7b372b28f1672b856aef7cd67d84e7d07afd543" ++" 26c335be438f4e2f1c434e6bd2b2ec526d97522bcc5c3a6bf414c674da66" ++" 381c7a3f842fe3f95ab865694606a33779b2a15b58ed5ea75f8c6566bbd1" ++" 2436e637a73d49778a8c34d86929f34d5822b05124b640a886590ab7ba5c" ++" 97da57e836da7a9cad#)" ++" (u #2396c191175e0a83d2dc7b69b2591d3358523f18c709501cb9a1bb4ca238" ++" 404c9a8efe9c9092d0719f899950911f348b745311114a70e2f730d88c80" ++" e1cc9ff163171a7d67294ccb4e747be03e9e2ff4678fecb95c001e7ea27b" ++" 92c96f4ce40ef94863cd50225dbfb69d01336af450be86984fca3f3afacf" ++" 0740c4aaadaebebf#)))"; +/* A sample 2048 bit RSA key used for the selftests (public only). */ static const char sample_public_key[] = "(public-key" diff --git a/libgcrypt-1.6.3-rsa-fips-keygen.patch b/libgcrypt-1.6.3-rsa-fips-keygen.patch index 6d2243e..d160e64 100644 --- a/libgcrypt-1.6.3-rsa-fips-keygen.patch +++ b/libgcrypt-1.6.3-rsa-fips-keygen.patch @@ -189,15 +189,15 @@ diff -up libgcrypt-1.6.3/cipher/rsa.c.fips-keygen libgcrypt-1.6.3/cipher/rsa.c + if (testparms) goto err; + goto qloop; + } -+ if (mpi_cmp (p, q) < 0) ++ if (mpi_cmp (p, q) > 0) + { + pqswitch = 1; -+ mpi_sub (diff, q, p); -+ } ++ mpi_sub (diff, p, q); ++ } + else + { + pqswitch = 0; -+ mpi_sub (diff, p, q); ++ mpi_sub (diff, q, p); + } + if (mpi_cmp (diff, mindiff) < 0) + { @@ -248,7 +248,7 @@ diff -up libgcrypt-1.6.3/cipher/rsa.c.fips-keygen libgcrypt-1.6.3/cipher/rsa.c + mpi_gcd (g, p1, q1); + mpi_fdiv_q (f, p1, g); + mpi_mul (f, f, q1); -+ ++ + mpi_invm (d, e, f); + + _gcry_mpi_release (f); @@ -329,7 +329,7 @@ diff -up libgcrypt-1.6.3/cipher/rsa.c.fips-keygen libgcrypt-1.6.3/cipher/rsa.c - ec = generate_std (&sk, nbits, evalue, - !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); + if (deriveparms || fips_mode()) -+ ec = generate_fips (&sk, nbits, evalue, deriveparms, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); ++ ec = generate_fips (&sk, nbits, evalue, deriveparms, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); + else + ec = generate_std (&sk, nbits, evalue, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); + sexp_release (deriveparms); diff --git a/libgcrypt-1.6.3-urandom-only.patch b/libgcrypt-1.6.3-urandom-only.patch new file mode 100644 index 0000000..cf0901d --- /dev/null +++ b/libgcrypt-1.6.3-urandom-only.patch @@ -0,0 +1,29 @@ +diff -up libgcrypt-1.6.3/random/random-csprng.c.urandom-only libgcrypt-1.6.3/random/random-csprng.c +--- libgcrypt-1.6.3/random/random-csprng.c.urandom-only 2015-02-27 10:54:03.000000000 +0100 ++++ libgcrypt-1.6.3/random/random-csprng.c 2015-03-20 08:29:27.513113519 +0100 +@@ -1125,8 +1125,7 @@ getfnc_gather_random (void))(void (*)(co + enum random_origins, size_t, int); + + #if USE_RNDLINUX +- if ( !access (NAME_OF_DEV_RANDOM, R_OK) +- && !access (NAME_OF_DEV_URANDOM, R_OK)) ++ if (!access (NAME_OF_DEV_URANDOM, R_OK)) + { + fnc = _gcry_rndlinux_gather_random; + return fnc; +diff -up libgcrypt-1.6.3/random/rndlinux.c.urandom-only libgcrypt-1.6.3/random/rndlinux.c +--- libgcrypt-1.6.3/random/rndlinux.c.urandom-only 2015-03-20 08:36:13.472098269 +0100 ++++ libgcrypt-1.6.3/random/rndlinux.c 2015-03-20 08:36:43.765097131 +0100 +@@ -178,7 +178,11 @@ _gcry_rndlinux_gather_random (void (*add + { + if (fd_random == -1) + { +- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); ++ /* We try to open /dev/random first but in case the open fails ++ we gracefully retry with /dev/urandom. */ ++ fd_random = open_device (NAME_OF_DEV_RANDOM, 0, 0); ++ if (fd_random == -1) ++ fd_random = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 1), 1); + ever_opened |= 1; + } + fd = fd_random; diff --git a/libgcrypt.spec b/libgcrypt.spec index 08030d0..18985c6 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.3 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -45,6 +45,8 @@ Patch20: libgcrypt-1.6.3-rsa-fips-keygen.patch Patch22: libgcrypt-1.6.2-fips-reqs.patch # do not use strict aliasing for bufhelp functions Patch23: libgcrypt-1.6.3-aliasing.patch +# use only urandom if /dev/random cannot be opened +Patch24: libgcrypt-1.6.3-urandom-only.patch %define gcrylibdir %{_libdir} @@ -94,6 +96,8 @@ applications using libgcrypt. %patch20 -p1 -b .fips-keygen %patch22 -p1 -b .fips-reqs %patch23 -p1 -b .aliasing +%patch24 -p1 -b .urandom-only + cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -204,6 +208,11 @@ exit 0 %license COPYING %changelog +* Tue Mar 24 2015 Tomáš Mráz 1.6.3-3 +- touch only urandom in the selftest and when /dev/random is + unavailable for example by SELinux confinement +- fix the RSA selftest key (p q swap) (#1204517) + * Fri Mar 13 2015 Tomáš Mráz 1.6.3-2 - do not use strict aliasing for bufhelp functions (#1201219) From ab1d80feb687c3d5c5e22d38fca5f3d957f92b6c Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 3 Apr 2015 16:47:34 +0200 Subject: [PATCH 083/214] deinitialize the RNG after the selftest is run --- libgcrypt-1.6.2-fips-ctor.patch | 8 +++++--- libgcrypt.spec | 5 ++++- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/libgcrypt-1.6.2-fips-ctor.patch b/libgcrypt-1.6.2-fips-ctor.patch index c53847d..fe3ec60 100644 --- a/libgcrypt-1.6.2-fips-ctor.patch +++ b/libgcrypt-1.6.2-fips-ctor.patch @@ -16,7 +16,7 @@ diff -up libgcrypt-1.6.2/cipher/md.c.fips-ctor libgcrypt-1.6.2/cipher/md.c diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c --- libgcrypt-1.6.2/src/global.c.fips-ctor 2015-02-25 13:57:21.174704842 +0100 +++ libgcrypt-1.6.2/src/global.c 2015-02-25 14:03:07.066864208 +0100 -@@ -132,6 +132,34 @@ global_init (void) +@@ -132,6 +132,36 @@ global_init (void) } @@ -44,6 +44,8 @@ diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c + if (fips_mode ()) + _gcry_random_initialize (1); + _gcry_fips_run_selftests (0); ++ if (!fips_mode()) ++ _gcry_random_close_fds (); + no_secure_memory = no_secmem_save; + } +} @@ -51,7 +53,7 @@ diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c /* This function is called by the macro fips_is_operational and makes sure that the minimal initialization has been done. This is far from a perfect solution and hides problems with an improper -@@ -542,8 +570,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, +@@ -542,8 +572,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, case GCRYCTL_FIPS_MODE_P: if (fips_mode () @@ -61,7 +63,7 @@ diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c rc = GPG_ERR_GENERAL; /* Used as TRUE value */ break; -@@ -635,7 +662,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, +@@ -635,7 +664,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, break; case GCRYCTL_SET_ENFORCED_FIPS_FLAG: diff --git a/libgcrypt.spec b/libgcrypt.spec index 18985c6..5224730 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.3 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -208,6 +208,9 @@ exit 0 %license COPYING %changelog +* Fri Apr 3 2015 Tomáš Mráz 1.6.3-4 +- deinitialize the RNG after the selftest is run + * Tue Mar 24 2015 Tomáš Mráz 1.6.3-3 - touch only urandom in the selftest and when /dev/random is unavailable for example by SELinux confinement From f2b1f203bc00406f3172c4bcefe43daf6736890d Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Wed, 17 Jun 2015 15:18:45 +0000 Subject: [PATCH 084/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 5224730..5b7306d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.3 -Release: 4%{?dist} +Release: 5%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -208,6 +208,9 @@ exit 0 %license COPYING %changelog +* Wed Jun 17 2015 Fedora Release Engineering - 1.6.3-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + * Fri Apr 3 2015 Tomáš Mráz 1.6.3-4 - deinitialize the RNG after the selftest is run From e72757d73b62866b64ecdee25f2253c303a0361a Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 6 Aug 2015 08:56:37 +0200 Subject: [PATCH 085/214] Fix a leftover define without GCRY_ prefix in drbg. --- libgcrypt-1.6.2-drbg.patch | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libgcrypt-1.6.2-drbg.patch b/libgcrypt-1.6.2-drbg.patch index 386fb98..306eb27 100644 --- a/libgcrypt-1.6.2-drbg.patch +++ b/libgcrypt-1.6.2-drbg.patch @@ -2553,7 +2553,7 @@ diff -up libgcrypt-1.6.2/src/gcrypt.h.in.drbg libgcrypt-1.6.2/src/gcrypt.h.in }; /* Perform various operations defined by CMD. */ -@@ -1668,6 +1670,109 @@ int gcry_is_secure (const void *a) _GCRY +@@ -1668,6 +1670,110 @@ int gcry_is_secure (const void *a) _GCRY /* Return true if Libgcrypt is in FIPS mode. */ #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) @@ -2659,7 +2659,8 @@ diff -up libgcrypt-1.6.2/src/gcrypt.h.in.drbg libgcrypt-1.6.2/src/gcrypt.h.in +#define GCRY_DRBG_NOPR_HMACSHA1 (GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC) +#define GCRY_DRBG_NOPR_HMACSHA256 (GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC) +#define GCRY_DRBG_NOPR_HMACSHA384 (GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC) -+#define DRBG_NOPR_HMACSHA512 (GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC) ++#define GCRY_DRBG_NOPR_HMACSHA512 (GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC) ++#define DRBG_NOPR_HMACSHA512 GCRY_DRBG_NOPR_HMACSHA512 /* deprecated leftover */ #if 0 /* (Keep Emacsens' auto-indent happy.) */ { From 4ae7a5a6ff3183e6642b372807e0d8da42d18330 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 9 Sep 2015 16:35:09 +0200 Subject: [PATCH 086/214] new upstream version --- .gitignore | 1 + libgcrypt.spec | 7 +++++-- sources | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 791d596..e59def6 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.6.1-hobbled.tar.xz /libgcrypt-1.6.2-hobbled.tar.xz /libgcrypt-1.6.3-hobbled.tar.xz +/libgcrypt-1.6.4-hobbled.tar.xz diff --git a/libgcrypt.spec b/libgcrypt.spec index 5b7306d..bbe6b53 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.6.3 -Release: 5%{?dist} +Version: 1.6.4 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -208,6 +208,9 @@ exit 0 %license COPYING %changelog +* Wed Sep 9 2015 Tomáš Mráz 1.6.4-1 +- new upstream version + * Wed Jun 17 2015 Fedora Release Engineering - 1.6.3-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild diff --git a/sources b/sources index 04e70c5..5bfe5b6 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -cbb7aa4b8c4c63f24e954fbf00e16335 libgcrypt-1.6.3-hobbled.tar.xz +912ad2604bfb6a759e1d93ed26c5e999 libgcrypt-1.6.4-hobbled.tar.xz From 8ac557bc578f588da811c4a8eec4d2fe37f6f970 Mon Sep 17 00:00:00 2001 From: Dennis Gilmore Date: Thu, 4 Feb 2016 03:11:35 +0000 Subject: [PATCH 087/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index bbe6b53..5332c3e 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.6.4 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -208,6 +208,9 @@ exit 0 %license COPYING %changelog +* Thu Feb 04 2016 Fedora Release Engineering - 1.6.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + * Wed Sep 9 2015 Tomáš Mráz 1.6.4-1 - new upstream version From 69a497f0790ecb11776b2394ed7f40655d857038 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 21 Jul 2016 10:59:48 +0200 Subject: [PATCH 088/214] new upstream version fixing low impact issue CVE-2015-7511 --- .gitignore | 1 + hobble-libgcrypt | 2 +- libgcrypt-1.6.3-rsa-fips-keygen.patch | 4 ++++ libgcrypt.spec | 7 +++++-- sources | 2 +- 5 files changed, 12 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index e59def6..6c0c8d7 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.6.2-hobbled.tar.xz /libgcrypt-1.6.3-hobbled.tar.xz /libgcrypt-1.6.4-hobbled.tar.xz +/libgcrypt-1.6.5-hobbled.tar.xz diff --git a/hobble-libgcrypt b/hobble-libgcrypt index 5eade9d..cc53cc1 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -8,4 +8,4 @@ set -e -x rm -f cipher/ecc-curves.c rm -f tests/curves.c -rm -f tests/t_mpi_point.c +rm -f tests/t-mpi-point.c diff --git a/libgcrypt-1.6.3-rsa-fips-keygen.patch b/libgcrypt-1.6.3-rsa-fips-keygen.patch index d160e64..a229039 100644 --- a/libgcrypt-1.6.3-rsa-fips-keygen.patch +++ b/libgcrypt-1.6.3-rsa-fips-keygen.patch @@ -1,3 +1,7 @@ +Add FIPS 186-4 compliant RSA probable prime key generator. + +Signed-off-by: Tomáš Mráz + diff -up libgcrypt-1.6.3/cipher/primegen.c.fips-keygen libgcrypt-1.6.3/cipher/primegen.c --- libgcrypt-1.6.3/cipher/primegen.c.fips-keygen 2015-03-06 16:38:56.698052602 +0100 +++ libgcrypt-1.6.3/cipher/primegen.c 2015-03-06 16:45:45.848193024 +0100 diff --git a/libgcrypt.spec b/libgcrypt.spec index 5332c3e..415e068 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.6.4 -Release: 2%{?dist} +Version: 1.6.5 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -208,6 +208,9 @@ exit 0 %license COPYING %changelog +* Thu Jul 21 2016 Tomáš Mráz 1.6.5-1 +- new upstream version fixing low impact issue CVE-2015-7511 + * Thu Feb 04 2016 Fedora Release Engineering - 1.6.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild diff --git a/sources b/sources index 5bfe5b6..4e90cdb 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -912ad2604bfb6a759e1d93ed26c5e999 libgcrypt-1.6.4-hobbled.tar.xz +2703d21753c0c3fbb74ad4b10e1571a1 libgcrypt-1.6.5-hobbled.tar.xz From 8edb81fb56c5f148a9da3658049751621679092a Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 21 Jul 2016 11:23:26 +0200 Subject: [PATCH 089/214] Update the leak patch. --- libgcrypt-1.6.1-leak.patch | 38 -------------------------------------- libgcrypt-1.6.5-leak.patch | 27 +++++++++++++++++++++++++++ libgcrypt.spec | 4 ++-- 3 files changed, 29 insertions(+), 40 deletions(-) delete mode 100644 libgcrypt-1.6.1-leak.patch create mode 100644 libgcrypt-1.6.5-leak.patch diff --git a/libgcrypt-1.6.1-leak.patch b/libgcrypt-1.6.1-leak.patch deleted file mode 100644 index df3cc08..0000000 --- a/libgcrypt-1.6.1-leak.patch +++ /dev/null @@ -1,38 +0,0 @@ -diff -up libgcrypt-1.6.1/cipher/primegen.c.leak libgcrypt-1.6.1/cipher/primegen.c ---- libgcrypt-1.6.1/cipher/primegen.c.leak 2014-02-28 15:06:24.394464790 +0100 -+++ libgcrypt-1.6.1/cipher/primegen.c 2014-02-28 15:09:22.938591664 +0100 -@@ -1204,10 +1204,7 @@ _gcry_prime_group_generator (gcry_mpi_t - gcry_mpi_t prime, gcry_mpi_t *factors, - gcry_mpi_t start_g) - { -- gcry_mpi_t tmp = mpi_new (0); -- gcry_mpi_t b = mpi_new (0); -- gcry_mpi_t pmin1 = mpi_new (0); -- gcry_mpi_t g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); -+ gcry_mpi_t tmp, b, pmin1, g; - int first = 1; - int i, n; - -@@ -1220,6 +1217,11 @@ _gcry_prime_group_generator (gcry_mpi_t - if (n < 2) - return GPG_ERR_INV_ARG; - -+ tmp = mpi_new (0); -+ b = mpi_new (0); -+ pmin1 = mpi_new (0); -+ g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); -+ - /* Extra sanity check - usually disabled. */ - /* mpi_set (tmp, factors[0]); */ - /* for(i = 1; i < n; i++) */ -diff -up libgcrypt-1.6.1/src/hmac256.c.leak libgcrypt-1.6.1/src/hmac256.c ---- libgcrypt-1.6.1/src/hmac256.c.leak 2013-12-16 18:44:32.000000000 +0100 -+++ libgcrypt-1.6.1/src/hmac256.c 2014-02-28 15:06:24.394464790 +0100 -@@ -427,7 +427,6 @@ _gcry_hmac256_finalize (hmac256_context_ - tmphd = _gcry_hmac256_new (NULL, 0); - if (!tmphd) - { -- free (hd); - return NULL; - } - _gcry_hmac256_update (tmphd, hd->opad, 64); diff --git a/libgcrypt-1.6.5-leak.patch b/libgcrypt-1.6.5-leak.patch new file mode 100644 index 0000000..df51187 --- /dev/null +++ b/libgcrypt-1.6.5-leak.patch @@ -0,0 +1,27 @@ +diff -up libgcrypt-1.6.5/cipher/primegen.c.leak libgcrypt-1.6.5/cipher/primegen.c +--- libgcrypt-1.6.5/cipher/primegen.c.leak 2016-07-21 11:06:32.783421204 +0200 ++++ libgcrypt-1.6.5/cipher/primegen.c 2016-07-21 11:06:32.789421337 +0200 +@@ -1208,10 +1208,7 @@ _gcry_prime_group_generator (gcry_mpi_t + gcry_mpi_t prime, gcry_mpi_t *factors, + gcry_mpi_t start_g) + { +- gcry_mpi_t tmp = mpi_new (0); +- gcry_mpi_t b = mpi_new (0); +- gcry_mpi_t pmin1 = mpi_new (0); +- gcry_mpi_t g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); ++ gcry_mpi_t tmp, b, pmin1, g; + int first = 1; + int i, n; + +@@ -1224,6 +1221,11 @@ _gcry_prime_group_generator (gcry_mpi_t + if (n < 2) + return GPG_ERR_INV_ARG; + ++ tmp = mpi_new (0); ++ b = mpi_new (0); ++ pmin1 = mpi_new (0); ++ g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); ++ + /* Extra sanity check - usually disabled. */ + /* mpi_set (tmp, factors[0]); */ + /* for(i = 1; i < n; i++) */ diff --git a/libgcrypt.spec b/libgcrypt.spec index 415e068..ebd9f98 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -25,8 +25,8 @@ Patch5: libgcrypt-1.6.1-tests.patch Patch6: libgcrypt-1.6.1-fips-cfgrandom.patch # update the CAVS tests Patch7: libgcrypt-1.6.2-fips-cavs.patch -# fix for memory leaks an other errors found by Coverity scan -Patch9: libgcrypt-1.6.1-leak.patch +# fix for memory leaks and other errors found by Coverity scan +Patch9: libgcrypt-1.6.5-leak.patch # use poll instead of select when gathering randomness Patch11: libgcrypt-1.6.1-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) From 055651971a7c6a9c421fe508f7df5e1928870a81 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 17 Aug 2016 22:45:22 +0200 Subject: [PATCH 090/214] new upstream version with important security fix (CVE-2016-6316) --- .gitignore | 1 + libgcrypt.spec | 5 ++++- sources | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 6c0c8d7..e9b7aac 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.6.3-hobbled.tar.xz /libgcrypt-1.6.4-hobbled.tar.xz /libgcrypt-1.6.5-hobbled.tar.xz +/libgcrypt-1.6.6-hobbled.tar.xz diff --git a/libgcrypt.spec b/libgcrypt.spec index ebd9f98..590cabc 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.6.5 +Version: 1.6.6 Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -208,6 +208,9 @@ exit 0 %license COPYING %changelog +* Wed Aug 17 2016 Tomáš Mráz 1.6.6-1 +- new upstream version with important security fix (CVE-2016-6316) + * Thu Jul 21 2016 Tomáš Mráz 1.6.5-1 - new upstream version fixing low impact issue CVE-2015-7511 diff --git a/sources b/sources index 4e90cdb..4a375a0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -2703d21753c0c3fbb74ad4b10e1571a1 libgcrypt-1.6.5-hobbled.tar.xz +67edcc4715a8c239eac70a931e49660d libgcrypt-1.6.6-hobbled.tar.xz From 2c8c02279ae6604816152f4595d8ac31395940ef Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 23 Nov 2016 09:56:34 +0100 Subject: [PATCH 091/214] new upstream version 1.7.3 --- .gitignore | 1 + curves.c | 3 +- ecc-curves.c | 151 +- ecc-gost.c | 56 + hobble-libgcrypt | 1 + libgcrypt-1.6.1-ecc-test-fix.patch | 214 -- libgcrypt-1.6.1-fips-cfgrandom.patch | 141 - libgcrypt-1.6.1-tests.patch | 198 -- libgcrypt-1.6.2-drbg.patch | 2698 ----------------- libgcrypt-1.6.2-fips-reqs.patch | 345 --- libgcrypt-1.6.2-fips-test.patch | 18 - libgcrypt-1.6.3-aliasing.patch | 177 -- libgcrypt-1.6.3-rsa-fips-keygen.patch | 382 --- libgcrypt-1.6.5-leak.patch | 27 - libgcrypt-1.7.3-aliasing.patch | 24 + libgcrypt-1.7.3-ecc-test-fix.patch | 158 + ...s.patch => libgcrypt-1.7.3-fips-cavs.patch | 181 +- libgcrypt-1.7.3-fips-cfgrandom.patch | 104 + libgcrypt-1.7.3-fips-reqs.patch | 35 + libgcrypt-1.7.3-tests.patch | 115 + ...ll.patch => libgcrypt-1.7.3-use-poll.patch | 34 +- libgcrypt.spec | 38 +- sources | 2 +- t-mpi-point.c | 81 +- 24 files changed, 756 insertions(+), 4428 deletions(-) create mode 100644 ecc-gost.c delete mode 100644 libgcrypt-1.6.1-ecc-test-fix.patch delete mode 100644 libgcrypt-1.6.1-fips-cfgrandom.patch delete mode 100644 libgcrypt-1.6.1-tests.patch delete mode 100644 libgcrypt-1.6.2-drbg.patch delete mode 100644 libgcrypt-1.6.2-fips-reqs.patch delete mode 100644 libgcrypt-1.6.2-fips-test.patch delete mode 100644 libgcrypt-1.6.3-aliasing.patch delete mode 100644 libgcrypt-1.6.3-rsa-fips-keygen.patch delete mode 100644 libgcrypt-1.6.5-leak.patch create mode 100644 libgcrypt-1.7.3-aliasing.patch create mode 100644 libgcrypt-1.7.3-ecc-test-fix.patch rename libgcrypt-1.6.2-fips-cavs.patch => libgcrypt-1.7.3-fips-cavs.patch (89%) create mode 100644 libgcrypt-1.7.3-fips-cfgrandom.patch create mode 100644 libgcrypt-1.7.3-fips-reqs.patch create mode 100644 libgcrypt-1.7.3-tests.patch rename libgcrypt-1.6.1-use-poll.patch => libgcrypt-1.7.3-use-poll.patch (77%) diff --git a/.gitignore b/.gitignore index e9b7aac..cb05f79 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.6.4-hobbled.tar.xz /libgcrypt-1.6.5-hobbled.tar.xz /libgcrypt-1.6.6-hobbled.tar.xz +/libgcrypt-1.7.3-hobbled.tar.xz diff --git a/curves.c b/curves.c index fccd1d4..f27346d 100644 --- a/curves.c +++ b/curves.c @@ -29,7 +29,7 @@ #include "../src/gcrypt-int.h" /* Number of curves defined in ../cipger/ecc.c */ -#define N_CURVES 4 +#define N_CURVES 7 /* A real world sample public key. */ static char const sample_key_1[] = @@ -41,6 +41,7 @@ static char const sample_key_1[] = " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n" " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n" +" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n" " (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE" "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n" " ))"; diff --git a/ecc-curves.c b/ecc-curves.c index ef8ff94..a971e0a 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -40,9 +40,13 @@ static const struct const char *other; /* Other name. */ } curve_aliases[] = { - /*{ "Curve25519", "1.3.6.1.4.1.3029.1.5.1" },*/ + { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, + { "NIST P-224", "secp224r1" }, + { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */ + { "NIST P-224", "nistp224" }, /* rfc5656. */ + { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */ { "NIST P-256", "prime256v1" }, { "NIST P-256", "secp256r1" }, @@ -56,6 +60,8 @@ static const struct { "NIST P-521", "1.3.132.0.35" }, { "NIST P-521", "nistp521" }, /* rfc5656. */ + { "secp256k1", "1.3.132.0.10" }, + { NULL, NULL} }; @@ -76,9 +82,11 @@ typedef struct const char *p; /* The prime defining the field. */ const char *a, *b; /* The coefficients. For Twisted Edwards - Curves b is used for d. */ + Curves b is used for d. For Montgomery + Curves (a,b) has ((A-2)/4,B^-1). */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ + const char *h; /* Cofactor. */ } ecc_domain_parms_t; @@ -88,13 +96,38 @@ static const ecc_domain_parms_t domain_parms[] = { /* (-x^2 + y^2 = 1 + dx^2y^2) */ "Ed25519", 256, 0, - MPI_EC_TWISTEDEDWARDS, ECC_DIALECT_ED25519, + MPI_EC_EDWARDS, ECC_DIALECT_ED25519, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", "-0x01", "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658" + "0x6666666666666666666666666666666666666666666666666666666666666658", + "0x08" + }, + { + /* (y^2 = x^3 + 486662*x^2 + x) */ + "Curve25519", 256, 0, + MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD, + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", + "0x01DB41", + "0x01", + "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", + "0x0000000000000000000000000000000000000000000000000000000000000009", + "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9", + "0x08" + }, + { + "NIST P-224", 224, 1, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xffffffffffffffffffffffffffffffff000000000000000000000001", + "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", + "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", + "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , + + "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", + "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", + "0x01" }, { "NIST P-256", 256, 1, @@ -105,7 +138,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "0x01" }, { "NIST P-384", 384, 1, @@ -122,7 +156,8 @@ static const ecc_domain_parms_t domain_parms[] = "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + "0x01" }, { "NIST P-521", 521, 1, @@ -139,10 +174,23 @@ static const ecc_domain_parms_t domain_parms[] = "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" - "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + "0x01" }, - { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL } + { + "secp256k1", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000007", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", + "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", + "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", + "0x01" + }, + + { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } }; @@ -249,10 +297,9 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, switch (domain_parms[idx].model) { case MPI_EC_WEIERSTRASS: - case MPI_EC_TWISTEDEDWARDS: - break; + case MPI_EC_EDWARDS: case MPI_EC_MONTGOMERY: - return GPG_ERR_NOT_SUPPORTED; + break; default: return GPG_ERR_BUG; } @@ -268,11 +315,21 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, if (!curve->p) curve->p = scanval (domain_parms[idx].p); if (!curve->a) - curve->a = scanval (domain_parms[idx].a); + { + curve->a = scanval (domain_parms[idx].a); + if (curve->a->sign) + mpi_add (curve->a, curve->p, curve->a); + } if (!curve->b) - curve->b = scanval (domain_parms[idx].b); + { + curve->b = scanval (domain_parms[idx].b); + if (curve->b->sign) + mpi_add (curve->b, curve->p, curve->b); + } if (!curve->n) curve->n = scanval (domain_parms[idx].n); + if (!curve->h) + curve->h = scanval (domain_parms[idx].h); if (!curve->G.x) curve->G.x = scanval (domain_parms[idx].g_x); if (!curve->G.y) @@ -288,7 +345,7 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, /* Give the name of the curve NAME, store the curve parameters into P, - A, B, G, and N if they point to NULL value. Note that G is returned + A, B, G, N, and H if they point to NULL value. Note that G is returned in standard uncompressed format. Also update MODEL and DIALECT if they are not NULL. */ gpg_err_code_t @@ -296,7 +353,7 @@ _gcry_ecc_update_curve_param (const char *name, enum gcry_mpi_ec_models *model, enum ecc_dialects *dialect, gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, - gcry_mpi_t *g, gcry_mpi_t *n) + gcry_mpi_t *g, gcry_mpi_t *n, gcry_mpi_t *h) { int idx; @@ -346,6 +403,11 @@ _gcry_ecc_update_curve_param (const char *name, _gcry_mpi_release (*n); *n = scanval (domain_parms[idx].n); } + if (h) + { + _gcry_mpi_release (*h); + *h = scanval (domain_parms[idx].h); + } return 0; } @@ -383,8 +445,8 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) /* * Extract the curve parameters.. */ - rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgn", - &E.p, &E.a, &E.b, &mpi_g, &E.n, + rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgnh", + &E.p, &E.a, &E.b, &mpi_g, &E.n, &E.h, NULL)); if (rc == GPG_ERR_NO_OBJ) { @@ -442,17 +504,22 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) if (!mpi_cmp (tmp, E.n)) { mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (!mpi_cmp (tmp, E.G.x)) + tmp = scanval (domain_parms[idx].h); + if (!mpi_cmp (tmp, E.h)) { mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (!mpi_cmp (tmp, E.G.y)) + tmp = scanval (domain_parms[idx].g_x); + if (!mpi_cmp (tmp, E.G.x)) { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - goto leave; + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_y); + if (!mpi_cmp (tmp, E.G.y)) + { + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + goto leave; + } } } } @@ -469,6 +536,7 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) _gcry_mpi_release (mpi_g); _gcry_mpi_point_free_parts (&E.G); _gcry_mpi_release (E.n); + _gcry_mpi_release (E.h); return result; } @@ -600,6 +668,7 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, gcry_mpi_t b = NULL; gcry_mpi_point_t G = NULL; gcry_mpi_t n = NULL; + gcry_mpi_t h = NULL; gcry_mpi_point_t Q = NULL; gcry_mpi_t d = NULL; int flags = 0; @@ -642,6 +711,9 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, errc = mpi_from_keyparam (&n, keyparam, "n"); if (errc) goto leave; + errc = mpi_from_keyparam (&h, keyparam, "h"); + if (errc) + goto leave; } } else @@ -715,6 +787,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, n = E->n; E->n = NULL; } + if (!h) + { + h = E->h; + E->h = NULL; + } _gcry_ecc_curve_free (E); xfree (E); } @@ -741,6 +818,11 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, ec->n = n; n = NULL; } + if (h) + { + ec->h = h; + h = NULL; + } /* Now that we know the curve name we can look for the public key Q. point_from_keyparam needs to know the curve parameters so @@ -779,6 +861,7 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, mpi_free (b); _gcry_mpi_point_release (G); mpi_free (n); + mpi_free (h); _gcry_mpi_point_release (Q); mpi_free (d); return errc; @@ -793,7 +876,7 @@ _gcry_ecc_get_param_sexp (const char *name) elliptic_curve_t E; mpi_ec_t ctx; gcry_mpi_t g_x, g_y; - gcry_mpi_t pkey[6]; + gcry_mpi_t pkey[7]; gcry_sexp_t result; int i; @@ -817,14 +900,15 @@ _gcry_ecc_get_param_sexp (const char *name) pkey[2] = E.b; pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p); pkey[4] = E.n; - pkey[5] = NULL; + pkey[5] = E.h; + pkey[6] = NULL; mpi_free (g_x); mpi_free (g_y); if (sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4])) + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)))", + pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], pkey[5])) result = NULL; for (i=0; pkey[i]; i++) @@ -851,6 +935,8 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); if (!strcmp (name, "n") && ec->n) return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); + if (!strcmp (name, "h") && ec->h) + return mpi_is_const (ec->h) && !copy? ec->h : mpi_copy (ec->h); if (!strcmp (name, "d") && ec->d) return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); @@ -884,7 +970,7 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) if (name[1] != '@') return _gcry_mpi_ec_ec2os (ec->Q, ec); - if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_TWISTEDEDWARDS) + if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_EDWARDS) { unsigned char *encpk; unsigned int encpklen; @@ -949,6 +1035,11 @@ _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) mpi_free (ec->n); ec->n = mpi_copy (newvalue); } + else if (!strcmp (name, "h")) + { + mpi_free (ec->h); + ec->h = mpi_copy (newvalue); + } else if (*name == 'q' && (!name[1] || name[1] == '@')) { if (newvalue) diff --git a/ecc-gost.c b/ecc-gost.c new file mode 100644 index 0000000..75a2a93 --- /dev/null +++ b/ecc-gost.c @@ -0,0 +1,56 @@ +/* ecc-gots.c - Elliptic Curve GOST signatures + * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. + * Copyright (C) 2013 Dmitry Eremin-Solenikov + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt 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 program; if not, see . + */ + +#include +#include +#include +#include +#include + +#include "g10lib.h" +#include "mpi.h" +#include "cipher.h" +#include "context.h" +#include "ec-context.h" +#include "ecc-common.h" +#include "pubkey-internal.h" + + +/* Compute an GOST R 34.10-01/-12 signature. + * Return the signature struct (r,s) from the message hash. The caller + * must have allocated R and S. + */ +gpg_err_code_t +_gcry_ecc_gost_sign (gcry_mpi_t input, ECC_secret_key *skey, + gcry_mpi_t r, gcry_mpi_t s) +{ + return GPG_ERR_UNSUPPORTED_ALGORITHM; +} + + +/* Verify a GOST R 34.10-01/-12 signature. + * Check if R and S verifies INPUT. + */ +gpg_err_code_t +_gcry_ecc_gost_verify (gcry_mpi_t input, ECC_public_key *pkey, + gcry_mpi_t r, gcry_mpi_t s) +{ + return GPG_ERR_UNSUPPORTED_ALGORITHM; +} diff --git a/hobble-libgcrypt b/hobble-libgcrypt index cc53cc1..81bda0f 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -7,5 +7,6 @@ set -e -x # EC: ????????? ??/??/2015 rm -f cipher/ecc-curves.c +rm -f cipher/ecc-gost.c rm -f tests/curves.c rm -f tests/t-mpi-point.c diff --git a/libgcrypt-1.6.1-ecc-test-fix.patch b/libgcrypt-1.6.1-ecc-test-fix.patch deleted file mode 100644 index 7e12c1b..0000000 --- a/libgcrypt-1.6.1-ecc-test-fix.patch +++ /dev/null @@ -1,214 +0,0 @@ -diff -up libgcrypt-1.6.1/tests/benchmark.c.eccfix libgcrypt-1.6.1/tests/benchmark.c ---- libgcrypt-1.6.1/tests/benchmark.c.eccfix 2014-01-27 14:36:43.000000000 +0100 -+++ libgcrypt-1.6.1/tests/benchmark.c 2014-02-28 16:14:13.042505538 +0100 -@@ -1087,8 +1087,7 @@ ecc_bench (int iterations, int print_hea - { - #if USE_ECC - gpg_error_t err; -- const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", -- "gost256", "gost512" }; -+ const char *p_sizes[] = { "256", "384", "521", "Ed25519" }; - int testno; - - if (print_header) -diff -up libgcrypt-1.6.1/tests/dsa-rfc6979.c.eccfix libgcrypt-1.6.1/tests/dsa-rfc6979.c ---- libgcrypt-1.6.1/tests/dsa-rfc6979.c.eccfix 2013-12-16 18:44:32.000000000 +0100 -+++ libgcrypt-1.6.1/tests/dsa-rfc6979.c 2014-02-28 16:18:44.138771523 +0100 -@@ -210,27 +210,6 @@ check_dsa_rfc6979 (void) - " ))" - }, - { -- "ECDSA, 192 bits (prime field)", -- "(private-key" -- " (ecdsa" -- " (curve \"NIST P-192\")" -- " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" -- " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" -- " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" -- " ))" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "(private-key" -- " (ecdsa" -- " (curve \"NIST P-224\")" -- " (q #04" -- " 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C" -- " EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)" -- " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)" -- " ))" -- }, -- { - "ECDSA, 256 bits (prime field)", - "(private-key" - " (ecdsa" -@@ -443,169 +422,6 @@ check_dsa_rfc6979 (void) - "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1" - }, - { -- "ECDSA, 192 bits (prime field)", -- "With SHA-1, message = \"sample\"", -- "sha1", "sample", -- "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", -- "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", -- "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-224, message = \"sample\"", -- "sha224", "sample", -- "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8", -- "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", -- "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-256, message = \"sample\"", -- "sha256", "sample", -- "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", -- "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", -- "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-384, message = \"sample\"", -- "sha384", "sample", -- "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311", -- "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", -- "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-512, message = \"sample\"", -- "sha512", "sample", -- "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", -- "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", -- "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-1, message = \"test\"", -- "sha1", "test", -- "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", -- "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", -- "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-224, message = \"test\"", -- "sha224", "test", -- "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE", -- "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", -- "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-256, message = \"test\"", -- "sha256", "test", -- "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", -- "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", -- "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-384, message = \"test\"", -- "sha384", "test", -- "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693", -- "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", -- "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-512, message = \"test\"", -- "sha512", "test", -- "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", -- "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", -- "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290" -- }, -- -- -- -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-1, message = \"sample\"", -- "sha1", "sample", -- "7EEFADD91110D8DE6C2C470831387C50D3357F7F4D477054B8B426BC", -- "22226F9D40A96E19C4A301CE5B74B115303C0F3A4FD30FC257FB57AC", -- "66D1CDD83E3AF75605DD6E2FEFF196D30AA7ED7A2EDF7AF475403D69" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-224, message = \"sample\"", -- "sha224", "sample", -- "C1D1F2F10881088301880506805FEB4825FE09ACB6816C36991AA06D", -- "1CDFE6662DDE1E4A1EC4CDEDF6A1F5A2FB7FBD9145C12113E6ABFD3E", -- "A6694FD7718A21053F225D3F46197CA699D45006C06F871808F43EBC" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-256, message = \"sample\"", -- "sha256", "sample", -- "AD3029E0278F80643DE33917CE6908C70A8FF50A411F06E41DEDFCDC", -- "61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA", -- "BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-384, message = \"sample\"", -- "sha384", "sample", -- "52B40F5A9D3D13040F494E83D3906C6079F29981035C7BD51E5CAC40", -- "0B115E5E36F0F9EC81F1325A5952878D745E19D7BB3EABFABA77E953", -- "830F34CCDFE826CCFDC81EB4129772E20E122348A2BBD889A1B1AF1D" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-512, message = \"sample\"", -- "sha512", "sample", -- "9DB103FFEDEDF9CFDBA05184F925400C1653B8501BAB89CEA0FBEC14", -- "074BD1D979D5F32BF958DDC61E4FB4872ADCAFEB2256497CDAC30397", -- "A4CECA196C3D5A1FF31027B33185DC8EE43F288B21AB342E5D8EB084" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-1, message = \"test\"", -- "sha1", "test", -- "2519178F82C3F0E4F87ED5883A4E114E5B7A6E374043D8EFD329C253", -- "DEAA646EC2AF2EA8AD53ED66B2E2DDAA49A12EFD8356561451F3E21C", -- "95987796F6CF2062AB8135271DE56AE55366C045F6D9593F53787BD2" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-224, message = \"test\"", -- "sha224", "test", -- "DF8B38D40DCA3E077D0AC520BF56B6D565134D9B5F2EAE0D34900524", -- "C441CE8E261DED634E4CF84910E4C5D1D22C5CF3B732BB204DBEF019", -- "902F42847A63BDC5F6046ADA114953120F99442D76510150F372A3F4" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-256, message = \"test\"", -- "sha256", "test", -- "FF86F57924DA248D6E44E8154EB69F0AE2AEBAEE9931D0B5A969F904", -- "AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6", -- "178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-384, message = \"test\"", -- "sha384", "test", -- "7046742B839478C1B5BD31DB2E862AD868E1A45C863585B5F22BDC2D", -- "389B92682E399B26518A95506B52C03BC9379A9DADF3391A21FB0EA4", -- "414A718ED3249FF6DBC5B50C27F71F01F070944DA22AB1F78F559AAB" -- }, -- { -- "ECDSA, 224 bits (prime field)", -- "With SHA-512, message = \"test\"", -- "sha512", "test", -- "E39C2AA4EA6BE2306C72126D40ED77BF9739BB4D6EF2BBB1DCB6169D", -- "049F050477C5ADD858CAC56208394B5A55BAEBBE887FDF765047C17C", -- "077EB13E7005929CEFA3CD0403C7CDCC077ADF4E44F3C41B2F60ECFF" -- }, -- { - "ECDSA, 256 bits (prime field)", - "With SHA-1, message = \"sample\"", - "sha1", "sample", diff --git a/libgcrypt-1.6.1-fips-cfgrandom.patch b/libgcrypt-1.6.1-fips-cfgrandom.patch deleted file mode 100644 index 8aae15f..0000000 --- a/libgcrypt-1.6.1-fips-cfgrandom.patch +++ /dev/null @@ -1,141 +0,0 @@ -diff -up libgcrypt-1.6.1/random/random-fips.c.cfgrandom libgcrypt-1.6.1/random/random-fips.c ---- libgcrypt-1.6.1/random/random-fips.c.cfgrandom 2014-02-28 16:06:20.026572478 +0100 -+++ libgcrypt-1.6.1/random/random-fips.c 2014-02-28 16:06:34.851915121 +0100 -@@ -27,10 +27,10 @@ - There are 3 random context which map to the different levels of - random quality: - -- Generator Seed and Key Kernel entropy (init/reseed) -- ------------------------------------------------------------ -- GCRY_VERY_STRONG_RANDOM /dev/random 256/128 bits -- GCRY_STRONG_RANDOM /dev/random 256/128 bits -+ Generator Seed and Key Kernel entropy (init/reseed) -+ --------------------------------------------------------------------------------------- -+ GCRY_VERY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits -+ GCRY_STRONG_RANDOM /etc/gcrypt/rngseed+/dev/urandom 256/128 bits - gcry_create_nonce GCRY_STRONG_RANDOM n/a - - All random generators return their data in 128 bit blocks. If the -@@ -40,8 +40,10 @@ - (SEED_TTL) output blocks; the re-seeding is disabled in test mode. - - The GCRY_VERY_STRONG_RANDOM and GCRY_STRONG_RANDOM generators are -- keyed and seeded from the /dev/random device. Thus these -- generators may block until the kernel has collected enough entropy. -+ keyed and seeded with data that is loaded from the /etc/gcrypt/rngseed -+ if the device or symlink to device exists xored with the data -+ from the /dev/urandom device. This allows the system administrator -+ to always seed the RNGs from /dev/random if it is required. - - The gcry_create_nonce generator is keyed and seeded from the - GCRY_STRONG_RANDOM generator. It may also block if the -@@ -560,9 +562,13 @@ get_entropy (size_t nbytes) - entropy_collect_buffer_len = 0; - - #if USE_RNDLINUX -+ _gcry_rndlinux_gather_random (entropy_collect_cb, 0, -+ X931_AES_KEYLEN, -+ -1); -+ entropy_collect_buffer_len = 0; - rc = _gcry_rndlinux_gather_random (entropy_collect_cb, 0, - X931_AES_KEYLEN, -- GCRY_VERY_STRONG_RANDOM); -+ GCRY_STRONG_RANDOM); - #elif USE_RNDW32 - do - { -@@ -713,7 +719,7 @@ get_random (void *buffer, size_t length, - || rng_ctx->seed_init_pid != getpid ()) - { - /* Just reinitialize the key & seed. */ -- gcry_cipher_close(rng_ctx->cipher_hd); -+ _gcry_cipher_close(rng_ctx->cipher_hd); - rng_ctx->cipher_hd = NULL; - rng_ctx->is_seeded = 0; - goto reinitialize; -diff -up libgcrypt-1.6.1/random/rndlinux.c.cfgrandom libgcrypt-1.6.1/random/rndlinux.c ---- libgcrypt-1.6.1/random/rndlinux.c.cfgrandom 2013-12-16 18:44:32.000000000 +0100 -+++ libgcrypt-1.6.1/random/rndlinux.c 2014-02-28 16:06:20.027572501 +0100 -@@ -36,7 +36,9 @@ - #include "g10lib.h" - #include "rand-internal.h" - --static int open_device (const char *name, int retry); -+#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed" -+ -+static int open_device (const char *name, int retry, int fatal); - - - static int -@@ -59,7 +61,7 @@ set_cloexec_flag (int fd) - * a fatal error but retries until it is able to reopen the device. - */ - static int --open_device (const char *name, int retry) -+open_device (const char *name, int retry, int fatal) - { - int fd; - -@@ -67,6 +69,8 @@ open_device (const char *name, int retry - _gcry_random_progress ("open_dev_random", 'X', 1, 0); - again: - fd = open (name, O_RDONLY); -+ if (fd == -1 && !fatal) -+ return fd; - if (fd == -1 && retry) - { - struct timeval tv; -@@ -111,6 +115,7 @@ _gcry_rndlinux_gather_random (void (*add - { - static int fd_urandom = -1; - static int fd_random = -1; -+ static int fd_configured = -1; - static unsigned char ever_opened; - int fd; - int n; -@@ -134,6 +139,11 @@ _gcry_rndlinux_gather_random (void (*add - close (fd_urandom); - fd_urandom = -1; - } -+ if (fd_configured != -1) -+ { -+ close (fd_configured); -+ fd_configured = -1; -+ } - return 0; - } - -@@ -153,20 +163,30 @@ _gcry_rndlinux_gather_random (void (*add - that we always require the device to be existent but want a more - graceful behaviour if the rarely needed close operation has been - used and the device needs to be re-opened later. */ -+ -+ if (level == -1) -+ { -+ if (fd_configured == -1) -+ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0, 0 ); -+ fd = fd_configured; -+ if (fd == -1) -+ return -1; -+ } -+ - if (level >= 2) - { - if (fd_random == -1) - { -- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1)); -+ fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); - ever_opened |= 1; - } - fd = fd_random; - } -- else -+ else if (level != -1) - { - if (fd_urandom == -1) - { -- fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); -+ fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1); - ever_opened |= 2; - } - fd = fd_urandom; diff --git a/libgcrypt-1.6.1-tests.patch b/libgcrypt-1.6.1-tests.patch deleted file mode 100644 index 0c00458..0000000 --- a/libgcrypt-1.6.1-tests.patch +++ /dev/null @@ -1,198 +0,0 @@ -diff -up libgcrypt-1.6.1/cipher/dsa.c.tests libgcrypt-1.6.1/cipher/dsa.c ---- libgcrypt-1.6.1/cipher/dsa.c.tests 2014-02-28 13:39:01.727288335 +0100 -+++ libgcrypt-1.6.1/cipher/dsa.c 2014-02-28 13:46:21.727458285 +0100 -@@ -423,22 +423,29 @@ generate_fips186 (DSA_secret_key *sk, un - initial_seed.seed = sexp_nth_data (initial_seed.sexp, 1, - &initial_seed.seedlen); - } -- -- /* Fixme: Enable 186-3 after it has been approved and after fixing -- the generation function. */ -- /* if (use_fips186_2) */ -- (void)use_fips186_2; -- ec = _gcry_generate_fips186_2_prime (nbits, qbits, -+ if (use_fips186_2) -+ ec = _gcry_generate_fips186_2_prime (nbits, qbits, - initial_seed.seed, - initial_seed.seedlen, - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -- /* else */ -- /* ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, */ -- /* &prime_q, &prime_p, */ -- /* r_counter, */ -- /* r_seed, r_seedlen, NULL); */ -+ else if (!domain->p || !domain->q) -+ ec = _gcry_generate_fips186_3_prime (nbits, qbits, -+ initial_seed.seed, -+ initial_seed.seedlen, -+ &prime_q, &prime_p, -+ r_counter, -+ r_seed, r_seedlen, NULL); -+ else -+ { -+ /* Domain parameters p and q are given; use them. */ -+ prime_p = mpi_copy (domain->p); -+ prime_q = mpi_copy (domain->q); -+ gcry_assert (mpi_get_nbits (prime_p) == nbits); -+ gcry_assert (mpi_get_nbits (prime_q) == qbits); -+ ec = 0; -+ } - sexp_release (initial_seed.sexp); - if (ec) - goto leave; -@@ -829,13 +829,12 @@ dsa_generate (const gcry_sexp_t genparms - sexp_release (l1); - sexp_release (domainsexp); - -- /* Check that all domain parameters are available. */ -- if (!domain.p || !domain.q || !domain.g) -+ /* Check that p and q domain parameters are available. */ -+ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) - { - _gcry_mpi_release (domain.p); - _gcry_mpi_release (domain.q); - _gcry_mpi_release (domain.g); -- sexp_release (deriveparms); - return GPG_ERR_MISSING_VALUE; - } - -diff -up libgcrypt-1.6.1/cipher/primegen.c.tests libgcrypt-1.6.1/cipher/primegen.c ---- libgcrypt-1.6.1/cipher/primegen.c.tests 2014-01-29 10:48:38.000000000 +0100 -+++ libgcrypt-1.6.1/cipher/primegen.c 2014-02-28 13:49:52.291325147 +0100 -@@ -1649,7 +1649,7 @@ _gcry_generate_fips186_3_prime (unsigned - gpg_err_code_t ec; - unsigned char seed_help_buffer[256/8]; /* Used to hold a generated SEED. */ - unsigned char *seed_plus; /* Malloced buffer to hold SEED+x. */ -- unsigned char digest[256/8]; /* Helper buffer for SHA-1 digest. */ -+ unsigned char digest[256/8]; /* Helper buffer for SHA-x digest. */ - gcry_mpi_t val_2 = NULL; /* Helper for the prime test. */ - gcry_mpi_t tmpval = NULL; /* Helper variable. */ - int hashalgo; /* The id of the Approved Hash Function. */ -@@ -1739,7 +1739,7 @@ _gcry_generate_fips186_3_prime (unsigned - } - _gcry_mpi_release (prime_q); prime_q = NULL; - ec = _gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG, -- value_u, sizeof value_u, NULL); -+ value_u, qbits/8, NULL); - if (ec) - goto leave; - mpi_set_highbit (prime_q, qbits-1 ); -@@ -1784,11 +1784,11 @@ _gcry_generate_fips186_3_prime (unsigned - if (seed_plus[i]) - break; - } -- _gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen); -+ _gcry_md_hash_buffer (hashalgo, digest, seed_plus, seedlen); - - _gcry_mpi_release (tmpval); tmpval = NULL; - ec = _gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG, -- digest, sizeof digest, NULL); -+ digest, qbits/8, NULL); - if (ec) - goto leave; - if (value_j == value_n) -@@ -1824,11 +1824,11 @@ _gcry_generate_fips186_3_prime (unsigned - } - - /* Step 12: Save p, q, counter and seed. */ -- log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", -+ /* log_debug ("fips186-3 pbits p=%u q=%u counter=%d\n", - mpi_get_nbits (prime_p), mpi_get_nbits (prime_q), counter); - log_printhex ("fips186-3 seed", seed, seedlen); - log_printmpi ("fips186-3 p", prime_p); -- log_printmpi ("fips186-3 q", prime_q); -+ log_printmpi ("fips186-3 q", prime_q); */ - if (r_q) - { - *r_q = prime_q; -diff -up libgcrypt-1.6.1/cipher/rsa.c.tests libgcrypt-1.6.1/cipher/rsa.c ---- libgcrypt-1.6.1/cipher/rsa.c.tests 2014-01-29 08:49:49.000000000 +0100 -+++ libgcrypt-1.6.1/cipher/rsa.c 2014-02-28 13:39:01.727288335 +0100 -@@ -399,7 +399,7 @@ generate_x931 (RSA_secret_key *sk, unsig - - *swapped = 0; - -- if (e_value == 1) /* Alias for a secure value. */ -+ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ - e_value = 65537; - - /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ -diff -up libgcrypt-1.6.1/random/random-fips.c.tests libgcrypt-1.6.1/random/random-fips.c ---- libgcrypt-1.6.1/random/random-fips.c.tests 2014-01-29 10:48:38.000000000 +0100 -+++ libgcrypt-1.6.1/random/random-fips.c 2014-02-28 13:39:01.727288335 +0100 -@@ -692,6 +692,7 @@ get_random (void *buffer, size_t length, - - check_guards (rng_ctx); - -+ reinitialize: - /* Initialize the cipher handle and thus setup the key if needed. */ - if (!rng_ctx->cipher_hd) - { -@@ -711,13 +712,11 @@ get_random (void *buffer, size_t length, - if (rng_ctx->key_init_pid != getpid () - || rng_ctx->seed_init_pid != getpid ()) - { -- /* We are in a child of us. Because we have no way yet to do -- proper re-initialization (including self-checks etc), the -- only chance we have is to bail out. Obviusly a fork/exec -- won't harm because the exec overwrites the old image. */ -- fips_signal_error ("fork without proper re-initialization " -- "detected in RNG"); -- goto bailout; -+ /* Just reinitialize the key & seed. */ -+ gcry_cipher_close(rng_ctx->cipher_hd); -+ rng_ctx->cipher_hd = NULL; -+ rng_ctx->is_seeded = 0; -+ goto reinitialize; - } - - if (x931_aes_driver (buffer, length, rng_ctx)) -diff -up libgcrypt-1.6.1/tests/keygen.c.tests libgcrypt-1.6.1/tests/keygen.c ---- libgcrypt-1.6.1/tests/keygen.c.tests 2014-02-28 13:39:01.728288358 +0100 -+++ libgcrypt-1.6.1/tests/keygen.c 2014-02-28 13:42:18.288831563 +0100 -@@ -215,11 +215,11 @@ check_rsa_keys (void) - - - if (verbose) -- show ("creating 512 bit RSA key with e=257\n"); -+ show ("creating 1024 bit RSA key with e=257\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" -- " (nbits 3:512)\n" -+ " (nbits 4:1024)\n" - " (rsa-use-e 3:257)\n" - " ))", 0, 1); - if (rc) -@@ -233,11 +233,11 @@ check_rsa_keys (void) - gcry_sexp_release (key); - - if (verbose) -- show ("creating 512 bit RSA key with default e\n"); -+ show ("creating 1024 bit RSA key with default e\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" -- " (nbits 3:512)\n" -+ " (nbits 4:1024)\n" - " (rsa-use-e 1:0)\n" - " ))", 0, 1); - if (rc) -@@ -307,12 +307,12 @@ check_dsa_keys (void) - } - - if (verbose) -- show ("creating 1536 bit DSA key\n"); -+ show ("creating 2048 bit DSA key\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (dsa\n" -- " (nbits 4:1536)\n" -- " (qbits 3:224)\n" -+ " (nbits 4:2048)\n" -+ " (qbits 3:256)\n" - " ))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gpg_strerror (rc)); diff --git a/libgcrypt-1.6.2-drbg.patch b/libgcrypt-1.6.2-drbg.patch deleted file mode 100644 index 306eb27..0000000 --- a/libgcrypt-1.6.2-drbg.patch +++ /dev/null @@ -1,2698 +0,0 @@ -diff -up libgcrypt-1.6.2/random/drbg.c.drbg libgcrypt-1.6.2/random/drbg.c ---- libgcrypt-1.6.2/random/drbg.c.drbg 2014-12-08 16:31:33.513992141 +0100 -+++ libgcrypt-1.6.2/random/drbg.c 2014-12-08 16:39:40.799012486 +0100 -@@ -0,0 +1,2335 @@ -+/* -+ * DRBG: Deterministic Random Bits Generator -+ * Based on NIST Recommended DRBG from NIST SP800-90A with the following -+ * properties: -+ * * CTR DRBG with DF with AES-128, AES-192, AES-256 cores -+ * * Hash DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores -+ * * HMAC DRBG with DF with SHA-1, SHA-256, SHA-384, SHA-512 cores -+ * * with and without prediction resistance -+ * -+ * Copyright Stephan Mueller , 2014 -+ * -+ * 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, and the entire permission notice in its entirety, -+ * including the disclaimer of warranties. -+ * 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. -+ * 3. The name of the author may not be used to endorse or promote -+ * products derived from this software without specific prior -+ * written permission. -+ * -+ * ALTERNATIVELY, this product may be distributed under the terms of -+ * LGPLv2+, in which case the provisions of the LGPL are -+ * required INSTEAD OF the above restrictions. (This clause is -+ * necessary due to a potential bad interaction between the LGPL and -+ * the restrictions contained in a BSD-style copyright.) -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE, ALL OF -+ * WHICH ARE HEREBY DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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 NOT ADVISED OF THE POSSIBILITY OF SUCH -+ * DAMAGE. -+ * -+ * -+ * gcry_control GCRYCTL_DRBG_REINIT -+ * ================================ -+ * This control request re-initializes the DRBG completely, i.e. the entire -+ * state of the DRBG is zeroized (with two exceptions listed in -+ * GCRYCTL_DRBG_SET_ENTROPY). -+ * -+ * The control request takes the following values which influences how the DRBG -+ * is re-initialized: -+ * * u32 flags: This variable specifies the DRBG type to be used for the -+ * next initialization. If set to 0, the previous DRBG type is -+ * used for the initialization. The DRBG type is an OR of the -+ * mandatory flags of the requested DRBG strength and DRBG -+ * cipher type. Optionally, the prediction resistance flag -+ * can be ORed into the flags variable. For example: -+ * - CTR-DRBG with AES-128 without prediction resistance: -+ * DRBG_CTRAES128 -+ * - HMAC-DRBG with SHA-512 with prediction resistance: -+ * DRBG_HMACSHA512 | DRBG_PREDICTION_RESIST -+ * * struct gcry_drbg_string *pers: personalization string to be used for -+ * initialization. -+ * The variable of flags is independent from the pers/perslen variables. If -+ * flags is set to 0 and perslen is set to 0, the current DRBG type is -+ * completely reset without using a personalization string. -+ * -+ * DRBG Usage -+ * ========== -+ * The SP 800-90A DRBG allows the user to specify a personalization string -+ * for initialization as well as an additional information string for each -+ * random number request. The following code fragments show how a caller -+ * uses the kernel crypto API to use the full functionality of the DRBG. -+ * -+ * Usage without any additional data -+ * --------------------------------- -+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); -+ * -+ * -+ * Usage with personalization string during initialization -+ * ------------------------------------------------------- -+ * struct gcry_drbg_string pers; -+ * char personalization[11] = "some-string"; -+ * -+ * gcry_drbg_string_fill(&pers, personalization, strlen(personalization)); -+ * // The reset completely re-initializes the DRBG with the provided -+ * // personalization string without changing the DRBG type -+ * ret = gcry_control(GCRYCTL_DRBG_REINIT, 0, &pers); -+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); -+ * -+ * -+ * Usage with additional information string during random number request -+ * --------------------------------------------------------------------- -+ * struct gcry_drbg_string addtl; -+ * char addtl_string[11] = "some-string"; -+ * -+ * gcry_drbg_string_fill(&addtl, addtl_string, strlen(addtl_string)); -+ * // The following call is a wrapper to gcry_randomize() and returns -+ * // the same error codes. -+ * gcry_randomize_drbg(outbuf, OUTLEN, GCRY_STRONG_RANDOM, &addtl); -+ * -+ * -+ * Usage with personalization and additional information strings -+ * ------------------------------------------------------------- -+ * Just mix both scenarios above. -+ * -+ * -+ * Switch the DRBG type to some other type -+ * --------------------------------------- -+ * // Switch to CTR DRBG AES-128 without prediction resistance -+ * ret = gcry_control(GCRYCTL_DRBG_REINIT, DRBG_NOPR_CTRAES128, NULL); -+ * gcry_randomize(outbuf, OUTLEN, GCRY_STRONG_RANDOM); -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#include "g10lib.h" -+#include "random.h" -+#include "rand-internal.h" -+#include "../cipher/bithelp.h" -+#include "ath.h" -+ -+/****************************************************************** -+ * Common data structures -+ ******************************************************************/ -+ -+struct gcry_drbg_state; -+ -+struct gcry_drbg_core -+{ -+ u32 flags; /* flags for the cipher */ -+ ushort statelen; /* maximum state length */ -+ ushort blocklen_bytes; /* block size of output in bytes */ -+ int backend_cipher; /* libgcrypt backend cipher */ -+}; -+ -+struct gcry_drbg_state_ops -+{ -+ gpg_err_code_t (*update) (struct gcry_drbg_state * drbg, -+ struct gcry_drbg_string * seed, int reseed); -+ gpg_err_code_t (*generate) (struct gcry_drbg_state * drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string * addtl); -+}; -+ -+/* DRBG test data */ -+struct gcry_drbg_test_data -+{ -+ struct gcry_drbg_string *testentropy; /* TEST PARAMETER: test entropy */ -+ int fail_seed_source:1; /* if set, the seed function will return an error */ -+}; -+ -+ -+struct gcry_drbg_state -+{ -+ unsigned char *V; /* internal state 10.1.1.1 1a) */ -+ unsigned char *C; /* hash: static value 10.1.1.1 1b) -+ * hmac / ctr: key */ -+ size_t reseed_ctr; /* Number of RNG requests since last reseed -- -+ * 10.1.1.1 1c) */ -+ unsigned char *scratchpad; /* some memory the DRBG can use for its -+ * operation -- allocated during init */ -+ int seeded:1; /* DRBG fully seeded? */ -+ int pr:1; /* Prediction resistance enabled? */ -+ int fips_primed:1; /* Continuous test primed? */ -+ unsigned char *prev; /* previous output value of gcry_drbg_blocklen -+ * for FIPS 140-2 continuous test */ -+ /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the -+ * process which did the initialization so that we can detect a fork. -+ * The volatile modifier is required so that the compiler does not -+ * optimize it away in case the getpid function is badly attributed. */ -+ pid_t seed_init_pid; -+ const struct gcry_drbg_state_ops *d_ops; -+ const struct gcry_drbg_core *core; -+ struct gcry_drbg_test_data *test_data; -+}; -+ -+enum gcry_drbg_prefixes -+{ -+ DRBG_PREFIX0 = 0x00, -+ DRBG_PREFIX1, -+ DRBG_PREFIX2, -+ DRBG_PREFIX3 -+}; -+ -+#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) -+ -+/*************************************************************** -+ * Backend cipher definitions available to DRBG -+ ***************************************************************/ -+ -+static const struct gcry_drbg_core gcry_drbg_cores[] = { -+ /* Hash DRBGs */ -+ {GCRY_DRBG_HASHSHA1, 55, 20, GCRY_MD_SHA1}, -+ {GCRY_DRBG_HASHSHA256, 55, 32, GCRY_MD_SHA256}, -+ {GCRY_DRBG_HASHSHA384, 111, 48, GCRY_MD_SHA384}, -+ {GCRY_DRBG_HASHSHA512, 111, 64, GCRY_MD_SHA512}, -+ /* HMAC DRBGs */ -+ {GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC, 20, 20, GCRY_MD_SHA1}, -+ {GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC, 32, 32, GCRY_MD_SHA256}, -+ {GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC, 48, 48, GCRY_MD_SHA384}, -+ {GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC, 64, 64, GCRY_MD_SHA512}, -+ /* block ciphers */ -+ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128, 32, 16, GCRY_CIPHER_AES128}, -+ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192, 40, 16, GCRY_CIPHER_AES192}, -+ {GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256, 48, 16, GCRY_CIPHER_AES256}, -+}; -+ -+static gpg_err_code_t gcry_drbg_sym (struct gcry_drbg_state *drbg, -+ const unsigned char *key, -+ unsigned char *outval, -+ const struct gcry_drbg_string *buf); -+static gpg_err_code_t gcry_drbg_hmac (struct gcry_drbg_state *drbg, -+ const unsigned char *key, -+ unsigned char *outval, -+ const struct gcry_drbg_string *buf); -+ -+/****************************************************************** -+ ****************************************************************** -+ ****************************************************************** -+ * Generic DRBG code -+ ****************************************************************** -+ ****************************************************************** -+ ******************************************************************/ -+ -+/****************************************************************** -+ * Generic helper functions -+ ******************************************************************/ -+ -+#if 0 -+#define dbg(x) do { log_debug x; } while(0) -+#else -+#define dbg(x) -+#endif -+ -+static inline ushort -+gcry_drbg_statelen (struct gcry_drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return drbg->core->statelen; -+ return 0; -+} -+ -+static inline ushort -+gcry_drbg_blocklen (struct gcry_drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return drbg->core->blocklen_bytes; -+ return 0; -+} -+ -+static inline ushort -+gcry_drbg_keylen (struct gcry_drbg_state *drbg) -+{ -+ if (drbg && drbg->core) -+ return (drbg->core->statelen - drbg->core->blocklen_bytes); -+ return 0; -+} -+ -+static inline size_t -+gcry_drbg_max_request_bytes (void) -+{ -+ /* SP800-90A requires the limit 2**19 bits, but we return bytes */ -+ return (1 << 16); -+} -+ -+static inline size_t -+gcry_drbg_max_addtl (void) -+{ -+ /* SP800-90A requires 2**35 bytes additional info str / pers str */ -+#ifdef __LP64__ -+ return (1UL << 35); -+#else -+ /* -+ * SP800-90A allows smaller maximum numbers to be returned -- we -+ * return SIZE_MAX - 1 to allow the verification of the enforcement -+ * of this value in gcry_drbg_healthcheck_sanity. -+ */ -+ return (SIZE_MAX - 1); -+#endif -+} -+ -+static inline size_t -+gcry_drbg_max_requests (void) -+{ -+ /* SP800-90A requires 2**48 maximum requests before reseeding */ -+#ifdef __LP64__ -+ return (1UL << 48); -+#else -+ return SIZE_MAX; -+#endif -+} -+ -+/* -+ * Return strength of DRBG according to SP800-90A section 8.4 -+ * -+ * flags: DRBG flags reference -+ * -+ * Return: normalized strength value or 32 as a default to counter -+ * programming errors -+ */ -+static inline unsigned short -+gcry_drbg_sec_strength (u32 flags) -+{ -+ if ((flags & GCRY_DRBG_HASHSHA1) || (flags & GCRY_DRBG_SYM128)) -+ return 16; -+ else if (flags & GCRY_DRBG_SYM192) -+ return 24; -+ else if ((flags & GCRY_DRBG_SYM256) || (flags & GCRY_DRBG_HASHSHA256) || -+ (flags & GCRY_DRBG_HASHSHA384) || (flags & GCRY_DRBG_HASHSHA512)) -+ return 32; -+ else -+ return 32; -+} -+ -+/* -+ * FIPS 140-2 continuous self test -+ * The test is performed on the result of one round of the output -+ * function. Thus, the function implicitly knows the size of the -+ * buffer. -+ * -+ * @drbg DRBG handle -+ * @buf output buffer of random data to be checked -+ * -+ * return: -+ * false on error -+ * true on success -+ */ -+static gpg_err_code_t -+gcry_drbg_fips_continuous_test (struct gcry_drbg_state *drbg, -+ const unsigned char *buf) -+{ -+ gpg_err_code_t ret = 0; -+ /* skip test if we test the overall system */ -+ if (drbg->test_data) -+ return 1; -+ /* only perform test in FIPS mode */ -+ if (0 == fips_mode ()) -+ return 1; -+ if (!drbg->fips_primed) -+ { -+ /* Priming of FIPS test */ -+ memcpy (drbg->prev, buf, gcry_drbg_blocklen (drbg)); -+ drbg->fips_primed = 1; -+ /* return false due to priming, i.e. another round is needed */ -+ return 0; -+ } -+ ret = memcmp (drbg->prev, buf, gcry_drbg_blocklen (drbg)); -+ memcpy (drbg->prev, buf, gcry_drbg_blocklen (drbg)); -+ /* the test shall pass when the two compared values are not equal */ -+ if (ret == 0) -+ fips_signal_error ("duplicate block returned by DRBG"); -+ -+ return ret != 0; -+} -+ -+/* -+ * Convert an integer into a byte representation of this integer. -+ * The byte representation is big-endian -+ * -+ * @val value to be converted -+ * @buf buffer holding the converted integer -- caller must ensure that -+ * buffer size is at least 32 bit -+ */ -+static inline void -+gcry_drbg_cpu_to_be32 (u32 val, unsigned char *buf) -+{ -+ struct s -+ { -+ u32 conv; -+ }; -+ struct s *conversion = (struct s *) buf; -+ -+ conversion->conv = be_bswap32 (val); -+} -+ -+static void -+gcry_drbg_add_buf (unsigned char *dst, size_t dstlen, -+ unsigned char *add, size_t addlen) -+{ -+ /* implied: dstlen > addlen */ -+ unsigned char *dstptr, *addptr; -+ unsigned int remainder = 0; -+ size_t len = addlen; -+ -+ dstptr = dst + (dstlen - 1); -+ addptr = add + (addlen - 1); -+ while (len) -+ { -+ remainder += *dstptr + *addptr; -+ *dstptr = remainder & 0xff; -+ remainder >>= 8; -+ len--; -+ dstptr--; -+ addptr--; -+ } -+ len = dstlen - addlen; -+ while (len && remainder > 0) -+ { -+ remainder = *dstptr + 1; -+ *dstptr = remainder & 0xff; -+ remainder >>= 8; -+ len--; -+ dstptr--; -+ } -+} -+ -+/* Helper variables for read_cb(). -+ * -+ * The _gcry_rnd*_gather_random interface does not allow to provide a -+ * data pointer. Thus we need to use a global variable for -+ * communication. However, the then required locking is anyway a good -+ * idea because it does not make sense to have several readers of (say -+ * /dev/random). It is easier to serve them one after the other. */ -+static unsigned char *read_cb_buffer; /* The buffer. */ -+static size_t read_cb_size; /* Size of the buffer. */ -+static size_t read_cb_len; /* Used length. */ -+ -+/* Callback for generating seed from kernel device. */ -+static void -+gcry_drbg_read_cb (const void *buffer, size_t length, -+ enum random_origins origin) -+{ -+ const unsigned char *p = buffer; -+ -+ (void) origin; -+ gcry_assert (read_cb_buffer); -+ -+ /* Note that we need to protect against gatherers returning more -+ * than the requested bytes (e.g. rndw32). */ -+ while (length-- && read_cb_len < read_cb_size) -+ read_cb_buffer[read_cb_len++] = *p++; -+} -+ -+static inline int -+gcry_drbg_get_entropy (struct gcry_drbg_state *drbg, unsigned char *buffer, -+ size_t len) -+{ -+ int rc = 0; -+ -+ /* Perform testing as defined in 11.3.2 */ -+ if (drbg->test_data && drbg->test_data->fail_seed_source) -+ return -1; -+ -+ read_cb_buffer = buffer; -+ read_cb_size = len; -+ read_cb_len = 0; -+#if USE_RNDLINUX -+ _gcry_rndlinux_gather_random (gcry_drbg_read_cb, 0, len, -+ -1); -+ read_cb_len = 0; -+ rc = _gcry_rndlinux_gather_random (gcry_drbg_read_cb, 0, len, -+ GCRY_STRONG_RANDOM); -+#elif USE_RNDUNIX -+ rc = _gcry_rndunix_gather_random (read_cb, 0, length, -+ GCRY_VERY_STRONG_RANDOM); -+#elif USE_RNDW32 -+ do -+ { -+ rc = _gcry_rndw32_gather_random (read_cb, 0, length, -+ GCRY_VERY_STRONG_RANDOM); -+ } -+ while (rc >= 0 && read_cb_len < read_cb_size); -+#else -+ rc = -1; -+#endif -+ return rc; -+} -+ -+/****************************************************************** -+ * CTR DRBG callback functions -+ ******************************************************************/ -+ -+/* BCC function for CTR DRBG as defined in 10.4.3 */ -+static gpg_err_code_t -+gcry_drbg_ctr_bcc (struct gcry_drbg_state *drbg, -+ unsigned char *out, const unsigned char *key, -+ struct gcry_drbg_string *in) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ struct gcry_drbg_string *curr = in; -+ size_t inpos = curr->len; -+ const unsigned char *pos = curr->buf; -+ struct gcry_drbg_string data; -+ -+ gcry_drbg_string_fill (&data, out, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.4.3 step 1 */ -+ memset (out, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.4.3 step 2 / 4 */ -+ while (inpos) -+ { -+ short cnt = 0; -+ /* 10.4.3 step 4.1 */ -+ for (cnt = 0; cnt < gcry_drbg_blocklen (drbg); cnt++) -+ { -+ out[cnt] ^= *pos; -+ pos++; -+ inpos--; -+ /* the following branch implements the linked list -+ * iteration. If we are at the end of the current data -+ * set, we have to start using the next data set if -+ * available -- the inpos value always points to the -+ * current byte and will be zero if we have processed -+ * the last byte of the last linked list member */ -+ if (0 == inpos) -+ { -+ curr = curr->next; -+ if (NULL != curr) -+ { -+ pos = curr->buf; -+ inpos = curr->len; -+ } -+ else -+ { -+ inpos = 0; -+ break; -+ } -+ } -+ } -+ /* 10.4.3 step 4.2 */ -+ ret = gcry_drbg_sym (drbg, key, out, &data); -+ if (ret) -+ return ret; -+ /* 10.4.3 step 2 */ -+ } -+ return 0; -+} -+ -+ -+/* -+ * scratchpad usage: gcry_drbg_ctr_update is interlinked with gcry_drbg_ctr_df -+ * (and gcry_drbg_ctr_bcc, but this function does not need any temporary buffers), -+ * the scratchpad is used as follows: -+ * gcry_drbg_ctr_update: -+ * temp -+ * start: drbg->scratchpad -+ * length: gcry_drbg_statelen(drbg) + gcry_drbg_blocklen(drbg) -+ * note: the cipher writing into this variable works -+ * blocklen-wise. Now, when the statelen is not a multiple -+ * of blocklen, the generateion loop below "spills over" -+ * by at most blocklen. Thus, we need to give sufficient -+ * memory. -+ * df_data -+ * start: drbg->scratchpad + -+ * gcry_drbg_statelen(drbg) + -+ * gcry_drbg_blocklen(drbg) -+ * length: gcry_drbg_statelen(drbg) -+ * -+ * gcry_drbg_ctr_df: -+ * pad -+ * start: df_data + gcry_drbg_statelen(drbg) -+ * length: gcry_drbg_blocklen(drbg) -+ * iv -+ * start: pad + gcry_drbg_blocklen(drbg) -+ * length: gcry_drbg_blocklen(drbg) -+ * temp -+ * start: iv + gcry_drbg_blocklen(drbg) -+ * length: gcry_drbg_satelen(drbg) + gcry_drbg_blocklen(drbg) -+ * note: temp is the buffer that the BCC function operates -+ * on. BCC operates blockwise. gcry_drbg_statelen(drbg) -+ * is sufficient when the DRBG state length is a multiple -+ * of the block size. For AES192 (and maybe other ciphers) -+ * this is not correct and the length for temp is -+ * insufficient (yes, that also means for such ciphers, -+ * the final output of all BCC rounds are truncated). -+ * Therefore, add gcry_drbg_blocklen(drbg) to cover all -+ * possibilities. -+ */ -+ -+/* Derivation Function for CTR DRBG as defined in 10.4.2 */ -+static gpg_err_code_t -+gcry_drbg_ctr_df (struct gcry_drbg_state *drbg, unsigned char *df_data, -+ size_t bytes_to_return, struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ unsigned char L_N[8]; -+ /* S3 is input */ -+ struct gcry_drbg_string S1, S2, S4, cipherin; -+ struct gcry_drbg_string *tempstr = addtl; -+ unsigned char *pad = df_data + gcry_drbg_statelen (drbg); -+ unsigned char *iv = pad + gcry_drbg_blocklen (drbg); -+ unsigned char *temp = iv + gcry_drbg_blocklen (drbg); -+ size_t padlen = 0; -+ unsigned int templen = 0; -+ /* 10.4.2 step 7 */ -+ unsigned int i = 0; -+ /* 10.4.2 step 8 */ -+ const unsigned char *K = (unsigned char *) -+ "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" -+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"; -+ unsigned char *X; -+ size_t generated_len = 0; -+ size_t inputlen = 0; -+ -+ memset (pad, 0, gcry_drbg_blocklen (drbg)); -+ memset (iv, 0, gcry_drbg_blocklen (drbg)); -+ memset (temp, 0, gcry_drbg_statelen (drbg)); -+ -+ /* 10.4.2 step 1 is implicit as we work byte-wise */ -+ -+ /* 10.4.2 step 2 */ -+ if ((512 / 8) < bytes_to_return) -+ return GPG_ERR_INV_ARG; -+ -+ /* 10.4.2 step 2 -- calculate the entire length of all input data */ -+ for (; NULL != tempstr; tempstr = tempstr->next) -+ inputlen += tempstr->len; -+ gcry_drbg_cpu_to_be32 (inputlen, &L_N[0]); -+ -+ /* 10.4.2 step 3 */ -+ gcry_drbg_cpu_to_be32 (bytes_to_return, &L_N[4]); -+ -+ /* 10.4.2 step 5: length is size of L_N, input_string, one byte, padding */ -+ padlen = (inputlen + sizeof (L_N) + 1) % (gcry_drbg_blocklen (drbg)); -+ /* wrap the padlen appropriately */ -+ if (padlen) -+ padlen = gcry_drbg_blocklen (drbg) - padlen; -+ /* pad / padlen contains the 0x80 byte and the following zero bytes, so -+ * add one for byte for 0x80 */ -+ padlen++; -+ pad[0] = 0x80; -+ -+ /* 10.4.2 step 4 -- first fill the linked list and then order it */ -+ gcry_drbg_string_fill (&S1, iv, gcry_drbg_blocklen (drbg)); -+ gcry_drbg_string_fill (&S2, L_N, sizeof (L_N)); -+ gcry_drbg_string_fill (&S4, pad, padlen); -+ S1.next = &S2; -+ S2.next = addtl; -+ -+ /* Splice in addtl between S2 and S4 -- we place S4 at the end of the -+ * input data chain. As this code is only triggered when addtl is not -+ * NULL, no NULL checks are necessary.*/ -+ tempstr = addtl; -+ while (tempstr->next) -+ tempstr = tempstr->next; -+ tempstr->next = &S4; -+ -+ /* 10.4.2 step 9 */ -+ while (templen < (gcry_drbg_keylen (drbg) + (gcry_drbg_blocklen (drbg)))) -+ { -+ /* 10.4.2 step 9.1 - the padding is implicit as the buffer -+ * holds zeros after allocation -- even the increment of i -+ * is irrelevant as the increment remains within length of i */ -+ gcry_drbg_cpu_to_be32 (i, iv); -+ /* 10.4.2 step 9.2 -- BCC and concatenation with temp */ -+ ret = gcry_drbg_ctr_bcc (drbg, temp + templen, K, &S1); -+ if (ret) -+ goto out; -+ /* 10.4.2 step 9.3 */ -+ i++; -+ templen += gcry_drbg_blocklen (drbg); -+ } -+ -+ /* 10.4.2 step 11 */ -+ /* implicit key len with seedlen - blocklen according to table 3 */ -+ X = temp + (gcry_drbg_keylen (drbg)); -+ gcry_drbg_string_fill (&cipherin, X, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.4.2 step 12: overwriting of outval */ -+ -+ /* 10.4.2 step 13 */ -+ while (generated_len < bytes_to_return) -+ { -+ short blocklen = 0; -+ /* 10.4.2 step 13.1 */ -+ /* the truncation of the key length is implicit as the key -+ * is only gcry_drbg_blocklen in size -- check for the implementation -+ * of the cipher function callback */ -+ ret = gcry_drbg_sym (drbg, temp, X, &cipherin); -+ if (ret) -+ goto out; -+ blocklen = (gcry_drbg_blocklen (drbg) < -+ (bytes_to_return - generated_len)) ? -+ gcry_drbg_blocklen (drbg) : (bytes_to_return - generated_len); -+ /* 10.4.2 step 13.2 and 14 */ -+ memcpy (df_data + generated_len, X, blocklen); -+ generated_len += blocklen; -+ } -+ -+ ret = 0; -+ -+out: -+ memset (iv, 0, gcry_drbg_blocklen (drbg)); -+ memset (temp, 0, gcry_drbg_statelen (drbg)); -+ memset (pad, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * update function of CTR DRBG as defined in 10.2.1.2 -+ * -+ * The reseed variable has an enhanced meaning compared to the update -+ * functions of the other DRBGs as follows: -+ * 0 => initial seed from initialization -+ * 1 => reseed via gcry_drbg_seed -+ * 2 => first invocation from gcry_drbg_ctr_update when addtl is present. In -+ * this case, the df_data scratchpad is not deleted so that it is -+ * available for another calls to prevent calling the DF function -+ * again. -+ * 3 => second invocation from gcry_drbg_ctr_update. When the update function -+ * was called with addtl, the df_data memory already contains the -+ * DFed addtl information and we do not need to call DF again. -+ */ -+static gpg_err_code_t -+gcry_drbg_ctr_update (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *addtl, int reseed) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ /* 10.2.1.2 step 1 */ -+ unsigned char *temp = drbg->scratchpad; -+ unsigned char *df_data = drbg->scratchpad + -+ gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); -+ unsigned char *temp_p, *df_data_p; /* pointer to iterate over buffers */ -+ unsigned int len = 0; -+ struct gcry_drbg_string cipherin; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (temp, 0, gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg)); -+ if (3 > reseed) -+ memset (df_data, 0, gcry_drbg_statelen (drbg)); -+ -+ /* 10.2.1.3.2 step 2 and 10.2.1.4.2 step 2 */ -+ /* TODO use reseed variable to avoid re-doing DF operation */ -+ (void) reseed; -+ if (addtl && 0 < addtl->len) -+ { -+ ret = -+ gcry_drbg_ctr_df (drbg, df_data, gcry_drbg_statelen (drbg), addtl); -+ if (ret) -+ goto out; -+ } -+ -+ gcry_drbg_string_fill (&cipherin, drbg->V, gcry_drbg_blocklen (drbg)); -+ /* 10.2.1.3.2 step 2 and 3 -- are already covered as we memset(0) -+ * all memory during initialization */ -+ while (len < (gcry_drbg_statelen (drbg))) -+ { -+ /* 10.2.1.2 step 2.1 */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); -+ /* 10.2.1.2 step 2.2 */ -+ /* using target of temp + len: 10.2.1.2 step 2.3 and 3 */ -+ ret = gcry_drbg_sym (drbg, drbg->C, temp + len, &cipherin); -+ if (ret) -+ goto out; -+ /* 10.2.1.2 step 2.3 and 3 */ -+ len += gcry_drbg_blocklen (drbg); -+ } -+ -+ /* 10.2.1.2 step 4 */ -+ temp_p = temp; -+ df_data_p = df_data; -+ for (len = 0; len < gcry_drbg_statelen (drbg); len++) -+ { -+ *temp_p ^= *df_data_p; -+ df_data_p++; -+ temp_p++; -+ } -+ -+ /* 10.2.1.2 step 5 */ -+ memcpy (drbg->C, temp, gcry_drbg_keylen (drbg)); -+ /* 10.2.1.2 step 6 */ -+ memcpy (drbg->V, temp + gcry_drbg_keylen (drbg), gcry_drbg_blocklen (drbg)); -+ ret = 0; -+ -+out: -+ memset (temp, 0, gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg)); -+ if (2 != reseed) -+ memset (df_data, 0, gcry_drbg_statelen (drbg)); -+ return ret; -+} -+ -+/* -+ * scratchpad use: gcry_drbg_ctr_update is called independently from -+ * gcry_drbg_ctr_extract_bytes. Therefore, the scratchpad is reused -+ */ -+/* Generate function of CTR DRBG as defined in 10.2.1.5.2 */ -+static gpg_err_code_t -+gcry_drbg_ctr_generate (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ struct gcry_drbg_string data; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.2.1.5.2 step 2 */ -+ if (addtl && 0 < addtl->len) -+ { -+ addtl->next = NULL; -+ ret = gcry_drbg_ctr_update (drbg, addtl, 2); -+ if (ret) -+ return ret; -+ } -+ -+ /* 10.2.1.5.2 step 4.1 */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); -+ gcry_drbg_string_fill (&data, drbg->V, gcry_drbg_blocklen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.2.1.5.2 step 4.2 */ -+ ret = gcry_drbg_sym (drbg, drbg->C, drbg->scratchpad, &data); -+ if (ret) -+ goto out; -+ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? -+ gcry_drbg_blocklen (drbg) : (buflen - len); -+ if (!gcry_drbg_fips_continuous_test (drbg, drbg->scratchpad)) -+ { -+ /* 10.2.1.5.2 step 6 */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); -+ continue; -+ } -+ /* 10.2.1.5.2 step 4.3 */ -+ memcpy (buf + len, drbg->scratchpad, outlen); -+ len += outlen; -+ /* 10.2.1.5.2 step 6 */ -+ if (len < buflen) -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_blocklen (drbg), &prefix, 1); -+ } -+ -+ /* 10.2.1.5.2 step 6 */ -+ if (addtl) -+ addtl->next = NULL; -+ ret = gcry_drbg_ctr_update (drbg, addtl, 3); -+ -+out: -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+static struct gcry_drbg_state_ops gcry_drbg_ctr_ops = { -+ gcry_drbg_ctr_update, -+ gcry_drbg_ctr_generate, -+}; -+ -+/****************************************************************** -+ * HMAC DRBG callback functions -+ ******************************************************************/ -+ -+static gpg_err_code_t -+gcry_drbg_hmac_update (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *seed, int reseed) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ int i = 0; -+ struct gcry_drbg_string seed1, seed2, cipherin; -+ -+ if (!reseed) -+ /* 10.1.2.3 step 2 already implicitly covered with -+ * the initial memset(0) of drbg->C */ -+ memset (drbg->V, 1, gcry_drbg_statelen (drbg)); -+ -+ /* build linked list which implements the concatenation and fill -+ * first part*/ -+ gcry_drbg_string_fill (&seed1, drbg->V, gcry_drbg_statelen (drbg)); -+ /* buffer will be filled in for loop below with one byte */ -+ gcry_drbg_string_fill (&seed2, NULL, 1); -+ seed1.next = &seed2; -+ /* seed may be NULL */ -+ seed2.next = seed; -+ -+ gcry_drbg_string_fill (&cipherin, drbg->V, gcry_drbg_statelen (drbg)); -+ /* we execute two rounds of V/K massaging */ -+ for (i = 2; 0 < i; i--) -+ { -+ /* first round uses 0x0, second 0x1 */ -+ unsigned char prefix = DRBG_PREFIX0; -+ if (1 == i) -+ prefix = DRBG_PREFIX1; -+ /* 10.1.2.2 step 1 and 4 -- concatenation and HMAC for key */ -+ seed2.buf = &prefix; -+ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->C, &seed1); -+ if (ret) -+ return ret; -+ -+ /* 10.1.2.2 step 2 and 5 -- HMAC for V */ -+ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->V, &cipherin); -+ if (ret) -+ return ret; -+ -+ /* 10.1.2.2 step 3 */ -+ if (!seed || 0 == seed->len) -+ return ret; -+ } -+ return 0; -+} -+ -+/* generate function of HMAC DRBG as defined in 10.1.2.5 */ -+static gpg_err_code_t -+gcry_drbg_hmac_generate (struct gcry_drbg_state *drbg, -+ unsigned char *buf, -+ unsigned int buflen, struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ struct gcry_drbg_string data; -+ -+ /* 10.1.2.5 step 2 */ -+ if (addtl && 0 < addtl->len) -+ { -+ addtl->next = NULL; -+ ret = gcry_drbg_hmac_update (drbg, addtl, 1); -+ if (ret) -+ return ret; -+ } -+ -+ gcry_drbg_string_fill (&data, drbg->V, gcry_drbg_statelen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.1.2.5 step 4.1 */ -+ ret = gcry_drbg_hmac (drbg, drbg->C, drbg->V, &data); -+ if (ret) -+ return ret; -+ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? -+ gcry_drbg_blocklen (drbg) : (buflen - len); -+ if (!gcry_drbg_fips_continuous_test (drbg, drbg->V)) -+ continue; -+ -+ /* 10.1.2.5 step 4.2 */ -+ memcpy (buf + len, drbg->V, outlen); -+ len += outlen; -+ } -+ -+ /* 10.1.2.5 step 6 */ -+ if (addtl) -+ addtl->next = NULL; -+ ret = gcry_drbg_hmac_update (drbg, addtl, 1); -+ -+ return ret; -+} -+ -+static struct gcry_drbg_state_ops gcry_drbg_hmac_ops = { -+ gcry_drbg_hmac_update, -+ gcry_drbg_hmac_generate, -+}; -+ -+/****************************************************************** -+ * Hash DRBG callback functions -+ ******************************************************************/ -+ -+/* -+ * scratchpad usage: as gcry_drbg_hash_update and gcry_drbg_hash_df are used -+ * interlinked, the scratchpad is used as follows: -+ * gcry_drbg_hash_update -+ * start: drbg->scratchpad -+ * length: gcry_drbg_statelen(drbg) -+ * gcry_drbg_hash_df: -+ * start: drbg->scratchpad + gcry_drbg_statelen(drbg) -+ * length: gcry_drbg_blocklen(drbg) -+ */ -+/* Derivation Function for Hash DRBG as defined in 10.4.1 */ -+static gpg_err_code_t -+gcry_drbg_hash_df (struct gcry_drbg_state *drbg, -+ unsigned char *outval, size_t outlen, -+ struct gcry_drbg_string *entropy) -+{ -+ gpg_err_code_t ret = 0; -+ size_t len = 0; -+ unsigned char input[5]; -+ unsigned char *tmp = drbg->scratchpad + gcry_drbg_statelen (drbg); -+ struct gcry_drbg_string data1; -+ -+ memset (tmp, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.4.1 step 3 */ -+ input[0] = 1; -+ gcry_drbg_cpu_to_be32 ((outlen * 8), &input[1]); -+ -+ /* 10.4.1 step 4.1 -- concatenation of data for input into hash */ -+ gcry_drbg_string_fill (&data1, input, 5); -+ data1.next = entropy; -+ -+ /* 10.4.1 step 4 */ -+ while (len < outlen) -+ { -+ short blocklen = 0; -+ /* 10.4.1 step 4.1 */ -+ ret = gcry_drbg_hmac (drbg, NULL, tmp, &data1); -+ if (ret) -+ goto out; -+ /* 10.4.1 step 4.2 */ -+ input[0]++; -+ blocklen = (gcry_drbg_blocklen (drbg) < (outlen - len)) ? -+ gcry_drbg_blocklen (drbg) : (outlen - len); -+ memcpy (outval + len, tmp, blocklen); -+ len += blocklen; -+ } -+ -+out: -+ memset (tmp, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* update function for Hash DRBG as defined in 10.1.1.2 / 10.1.1.3 */ -+static gpg_err_code_t -+gcry_drbg_hash_update (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *seed, int reseed) -+{ -+ gpg_err_code_t ret = 0; -+ struct gcry_drbg_string data1, data2; -+ unsigned char *V = drbg->scratchpad; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ memset (drbg->scratchpad, 0, gcry_drbg_statelen (drbg)); -+ if (!seed) -+ return GPG_ERR_INV_ARG; -+ -+ if (reseed) -+ { -+ /* 10.1.1.3 step 1: string length is concatenation of -+ * 1 byte, V and seed (which is concatenated entropy/addtl -+ * input) -+ */ -+ memcpy (V, drbg->V, gcry_drbg_statelen (drbg)); -+ gcry_drbg_string_fill (&data1, &prefix, 1); -+ gcry_drbg_string_fill (&data2, V, gcry_drbg_statelen (drbg)); -+ data1.next = &data2; -+ data2.next = seed; -+ } -+ else -+ { -+ gcry_drbg_string_fill (&data1, seed->buf, seed->len); -+ data1.next = seed->next; -+ } -+ -+ /* 10.1.1.2 / 10.1.1.3 step 2 and 3 */ -+ ret = gcry_drbg_hash_df (drbg, drbg->V, gcry_drbg_statelen (drbg), &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.2 / 10.1.1.3 step 4 -- concatenation */ -+ prefix = DRBG_PREFIX0; -+ gcry_drbg_string_fill (&data1, &prefix, 1); -+ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); -+ data1.next = &data2; -+ /* 10.1.1.2 / 10.1.1.3 step 4 -- df operation */ -+ ret = gcry_drbg_hash_df (drbg, drbg->C, gcry_drbg_statelen (drbg), &data1); -+ -+out: -+ memset (drbg->scratchpad, 0, gcry_drbg_statelen (drbg)); -+ return ret; -+} -+ -+/* processing of additional information string for Hash DRBG */ -+static gpg_err_code_t -+gcry_drbg_hash_process_addtl (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ struct gcry_drbg_string data1, data2; -+ struct gcry_drbg_string *data3; -+ unsigned char prefix = DRBG_PREFIX2; -+ -+ /* this is value w as per documentation */ -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.1.1.4 step 2 */ -+ if (!addtl || 0 == addtl->len) -+ return 0; -+ -+ /* 10.1.1.4 step 2a -- concatenation */ -+ gcry_drbg_string_fill (&data1, &prefix, 1); -+ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); -+ data3 = addtl; -+ data1.next = &data2; -+ data2.next = data3; -+ data3->next = NULL; -+ /* 10.1.1.4 step 2a -- cipher invocation */ -+ ret = gcry_drbg_hmac (drbg, NULL, drbg->scratchpad, &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.4 step 2b */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), -+ drbg->scratchpad, gcry_drbg_blocklen (drbg)); -+ -+out: -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * Hashgen defined in 10.1.1.4 -+ */ -+static gpg_err_code_t -+gcry_drbg_hash_hashgen (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int len = 0; -+ unsigned char *src = drbg->scratchpad; -+ unsigned char *dst = drbg->scratchpad + gcry_drbg_statelen (drbg); -+ struct gcry_drbg_string data; -+ unsigned char prefix = DRBG_PREFIX1; -+ -+ /* use the scratchpad as a lookaside buffer */ -+ memset (src, 0, gcry_drbg_statelen (drbg)); -+ memset (dst, 0, gcry_drbg_blocklen (drbg)); -+ -+ /* 10.1.1.4 step hashgen 2 */ -+ memcpy (src, drbg->V, gcry_drbg_statelen (drbg)); -+ -+ gcry_drbg_string_fill (&data, src, gcry_drbg_statelen (drbg)); -+ while (len < buflen) -+ { -+ unsigned int outlen = 0; -+ /* 10.1.1.4 step hashgen 4.1 */ -+ ret = gcry_drbg_hmac (drbg, NULL, dst, &data); -+ if (ret) -+ goto out; -+ outlen = (gcry_drbg_blocklen (drbg) < (buflen - len)) ? -+ gcry_drbg_blocklen (drbg) : (buflen - len); -+ if (!gcry_drbg_fips_continuous_test (drbg, dst)) -+ { -+ gcry_drbg_add_buf (src, gcry_drbg_statelen (drbg), &prefix, 1); -+ continue; -+ } -+ /* 10.1.1.4 step hashgen 4.2 */ -+ memcpy (buf + len, dst, outlen); -+ len += outlen; -+ /* 10.1.1.4 hashgen step 4.3 */ -+ if (len < buflen) -+ gcry_drbg_add_buf (src, gcry_drbg_statelen (drbg), &prefix, 1); -+ } -+ -+out: -+ memset (drbg->scratchpad, 0, -+ (gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg))); -+ return ret; -+} -+ -+/* generate function for Hash DRBG as defined in 10.1.1.4 */ -+static gpg_err_code_t -+gcry_drbg_hash_generate (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned char prefix = DRBG_PREFIX3; -+ struct gcry_drbg_string data1, data2; -+ union -+ { -+ unsigned char req[8]; -+ u64 req_int; -+ } u; -+ -+ /* -+ * scratchpad usage: gcry_drbg_hash_process_addtl uses the scratchpad, but -+ * fully completes before returning. Thus, we can reuse the scratchpad -+ */ -+ /* 10.1.1.4 step 2 */ -+ ret = gcry_drbg_hash_process_addtl (drbg, addtl); -+ if (ret) -+ return ret; -+ /* 10.1.1.4 step 3 -- invocation of the Hashgen function defined in -+ * 10.1.1.4 */ -+ ret = gcry_drbg_hash_hashgen (drbg, buf, buflen); -+ if (ret) -+ return ret; -+ -+ /* this is the value H as documented in 10.1.1.4 */ -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ /* 10.1.1.4 step 4 */ -+ gcry_drbg_string_fill (&data1, &prefix, 1); -+ gcry_drbg_string_fill (&data2, drbg->V, gcry_drbg_statelen (drbg)); -+ data1.next = &data2; -+ ret = gcry_drbg_hmac (drbg, NULL, drbg->scratchpad, &data1); -+ if (ret) -+ goto out; -+ -+ /* 10.1.1.4 step 5 */ -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), -+ drbg->scratchpad, gcry_drbg_blocklen (drbg)); -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), drbg->C, -+ gcry_drbg_statelen (drbg)); -+ u.req_int = be_bswap64 (drbg->reseed_ctr); -+ gcry_drbg_add_buf (drbg->V, gcry_drbg_statelen (drbg), u.req, -+ sizeof (u.req)); -+ -+out: -+ memset (drbg->scratchpad, 0, gcry_drbg_blocklen (drbg)); -+ return ret; -+} -+ -+/* -+ * scratchpad usage: as update and generate are used isolated, both -+ * can use the scratchpad -+ */ -+static struct gcry_drbg_state_ops gcry_drbg_hash_ops = { -+ gcry_drbg_hash_update, -+ gcry_drbg_hash_generate, -+}; -+ -+/****************************************************************** -+ * Functions common for DRBG implementations -+ ******************************************************************/ -+ -+/* -+ * Seeding or reseeding of the DRBG -+ * -+ * @drbg: DRBG state struct -+ * @pers: personalization / additional information buffer -+ * @reseed: 0 for initial seed process, 1 for reseeding -+ * -+ * return: -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+gcry_drbg_seed (struct gcry_drbg_state *drbg, struct gcry_drbg_string *pers, -+ int reseed) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned char *entropy = NULL; -+ size_t entropylen = 0; -+ struct gcry_drbg_string data1; -+ -+ /* 9.1 / 9.2 / 9.3.1 step 3 */ -+ if (pers && pers->len > (gcry_drbg_max_addtl ())) -+ { -+ dbg (("DRBG: personalization string too long %lu\n", pers->len)); -+ return GPG_ERR_INV_ARG; -+ } -+ if (drbg->test_data && drbg->test_data->testentropy) -+ { -+ gcry_drbg_string_fill (&data1, drbg->test_data->testentropy->buf, -+ drbg->test_data->testentropy->len); -+ dbg (("DRBG: using test entropy\n")); -+ } -+ else -+ { -+ /* Gather entropy equal to the security strength of the DRBG. -+ * With a derivation function, a nonce is required in addition -+ * to the entropy. A nonce must be at least 1/2 of the security -+ * strength of the DRBG in size. Thus, entropy * nonce is 3/2 -+ * of the strength. The consideration of a nonce is only -+ * applicable during initial seeding. */ -+ entropylen = gcry_drbg_sec_strength (drbg->core->flags); -+ if (!entropylen) -+ return GPG_ERR_GENERAL; -+ if (0 == reseed) -+ /* make sure we round up strength/2 in -+ * case it is not divisible by 2 */ -+ entropylen = ((entropylen + 1) / 2) * 3; -+ dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen)); -+ entropy = xcalloc_secure (1, entropylen); -+ if (!entropy) -+ return GPG_ERR_ENOMEM; -+ ret = gcry_drbg_get_entropy (drbg, entropy, entropylen); -+ if (ret) -+ goto out; -+ gcry_drbg_string_fill (&data1, entropy, entropylen); -+ } -+ -+ /* concatenation of entropy with personalization str / addtl input) -+ * the variable pers is directly handed by the caller, check its -+ * contents whether it is appropriate */ -+ if (pers && pers->buf && 0 < pers->len && NULL == pers->next) -+ { -+ data1.next = pers; -+ dbg (("DRBG: using personalization string\n")); -+ } -+ -+ ret = drbg->d_ops->update (drbg, &data1, reseed); -+ dbg (("DRBG: state updated with seed\n")); -+ if (ret) -+ goto out; -+ drbg->seeded = 1; -+ /* 10.1.1.2 / 10.1.1.3 step 5 */ -+ drbg->reseed_ctr = 1; -+ -+out: -+ xfree (entropy); -+ return ret; -+} -+ -+/************************************************************************* -+ * exported interfaces -+ *************************************************************************/ -+ -+/* -+ * DRBG generate function as required by SP800-90A - this function -+ * generates random numbers -+ * -+ * @drbg DRBG state handle -+ * @buf Buffer where to store the random numbers -- the buffer must already -+ * be pre-allocated by caller -+ * @buflen Length of output buffer - this value defines the number of random -+ * bytes pulled from DRBG -+ * @addtl Additional input that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * -+ * return: generated number of bytes -+ */ -+static gpg_err_code_t -+gcry_drbg_generate (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = GPG_ERR_INV_ARG; -+ -+ if (0 == buflen || !buf) -+ { -+ dbg (("DRBG: no buffer provided\n")); -+ return ret; -+ } -+ if (addtl && NULL == addtl->buf && 0 < addtl->len) -+ { -+ dbg (("DRBG: wrong format of additional information\n")); -+ return ret; -+ } -+ -+ /* 9.3.1 step 2 */ -+ if (buflen > (gcry_drbg_max_request_bytes ())) -+ { -+ dbg (("DRBG: requested random numbers too large %u\n", buflen)); -+ return ret; -+ } -+ /* 9.3.1 step 3 is implicit with the chosen DRBG */ -+ /* 9.3.1 step 4 */ -+ if (addtl && addtl->len > (gcry_drbg_max_addtl ())) -+ { -+ dbg (("DRBG: additional information string too long %lu\n", -+ addtl->len)); -+ return ret; -+ } -+ /* 9.3.1 step 5 is implicit with the chosen DRBG */ -+ /* 9.3.1 step 6 and 9 supplemented by 9.3.2 step c -- the spec is a -+ * bit convoluted here, we make it simpler */ -+ if ((gcry_drbg_max_requests ()) < drbg->reseed_ctr) -+ drbg->seeded = 0; -+ -+ if (drbg->pr || !drbg->seeded) -+ { -+ dbg (("DRBG: reseeding before generation (prediction resistance: %s, state %s)\n", drbg->pr ? "true" : "false", drbg->seeded ? "seeded" : "unseeded")); -+ /* 9.3.1 steps 7.1 through 7.3 */ -+ ret = gcry_drbg_seed (drbg, addtl, 1); -+ if (ret) -+ return ret; -+ /* 9.3.1 step 7.4 */ -+ addtl = NULL; -+ } -+ -+ if (addtl && addtl->buf) -+ { -+ dbg (("DRBG: using additional information string\n")); -+ } -+ -+ /* 9.3.1 step 8 and 10 */ -+ ret = drbg->d_ops->generate (drbg, buf, buflen, addtl); -+ -+ /* 10.1.1.4 step 6, 10.1.2.5 step 7, 10.2.1.5.2 step 7 */ -+ drbg->reseed_ctr++; -+ if (ret) -+ return ret; -+ -+ /* 11.3.3 -- re-perform self tests after some generated random -+ * numbers, the chosen value after which self test is performed -+ * is arbitrary, but it should be reasonable */ -+ /* Here we do not perform the self tests because of the following -+ * reasons: it is mathematically impossible that the initial self tests -+ * were successfully and the following are not. If the initial would -+ * pass and the following would not, the system integrity is violated. -+ * In this case, the entire system operation is questionable and it -+ * is unlikely that the integrity violation only affects to the -+ * correct operation of the DRBG. -+ */ -+#if 0 -+ if (drbg->reseed_ctr && !(drbg->reseed_ctr % 4096)) -+ { -+ dbg (("DRBG: start to perform self test\n")); -+ ret = gcry_drbg_healthcheck (); -+ if (ret) -+ { -+ log_fatal (("DRBG: self test failed\n")); -+ return ret; -+ } -+ else -+ { -+ dbg (("DRBG: self test successful\n")); -+ } -+ } -+#endif -+ -+ return ret; -+} -+ -+/* -+ * Wrapper around gcry_drbg_generate which can pull arbitrary long strings -+ * from the DRBG without hitting the maximum request limitation. -+ * -+ * Parameters: see gcry_drbg_generate -+ * Return codes: see gcry_drbg_generate -- if one gcry_drbg_generate request fails, -+ * the entire gcry_drbg_generate_long request fails -+ */ -+static gpg_err_code_t -+gcry_drbg_generate_long (struct gcry_drbg_state *drbg, -+ unsigned char *buf, unsigned int buflen, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ unsigned int slice = 0; -+ unsigned char *buf_p = buf; -+ unsigned len = 0; -+ do -+ { -+ unsigned int chunk = 0; -+ slice = ((buflen - len) / gcry_drbg_max_request_bytes ()); -+ chunk = slice ? gcry_drbg_max_request_bytes () : (buflen - len); -+ ret = gcry_drbg_generate (drbg, buf_p, chunk, addtl); -+ if (ret) -+ return ret; -+ buf_p += chunk; -+ len += chunk; -+ } -+ while (slice > 0 && (len < buflen)); -+ return ret; -+} -+ -+/* -+ * DRBG uninstantiate function as required by SP800-90A - this function -+ * frees all buffers and the DRBG handle -+ * -+ * @drbg DRBG state handle -+ * -+ * return -+ * 0 on success -+ */ -+static gpg_err_code_t -+gcry_drbg_uninstantiate (struct gcry_drbg_state *drbg) -+{ -+ if (!drbg) -+ return GPG_ERR_INV_ARG; -+ xfree (drbg->V); -+ drbg->V = NULL; -+ xfree (drbg->C); -+ drbg->C = NULL; -+ drbg->reseed_ctr = 0; -+ xfree (drbg->scratchpad); -+ drbg->scratchpad = NULL; -+ drbg->seeded = 0; -+ drbg->pr = 0; -+ drbg->fips_primed = 0; -+ xfree (drbg->prev); -+ drbg->prev = NULL; -+ drbg->seed_init_pid = 0; -+ return 0; -+} -+ -+/* -+ * DRBG instantiation function as required by SP800-90A - this function -+ * sets up the DRBG handle, performs the initial seeding and all sanity -+ * checks required by SP800-90A -+ * -+ * @drbg memory of state -- if NULL, new memory is allocated -+ * @pers Personalization string that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * @coreref reference to core -+ * @flags Flags defining the requested DRBG type and cipher type. The flags -+ * are defined in drbg.h and may be XORed. Beware, if you XOR multiple -+ * cipher types together, the code picks the core on a first come first -+ * serve basis as it iterates through the available cipher cores and -+ * uses the one with the first match. The minimum required flags are: -+ * cipher type flag -+ * -+ * return -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+gcry_drbg_instantiate (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *pers, int coreref, int pr) -+{ -+ gpg_err_code_t ret = GPG_ERR_ENOMEM; -+ unsigned int sb_size = 0; -+ -+ if (!drbg) -+ return GPG_ERR_INV_ARG; -+ -+ dbg (("DRBG: Initializing DRBG core %d with prediction resistance %s\n", -+ coreref, pr ? "enabled" : "disabled")); -+ drbg->core = &gcry_drbg_cores[coreref]; -+ drbg->pr = pr; -+ drbg->seeded = 0; -+ if (drbg->core->flags & GCRY_DRBG_HMAC) -+ drbg->d_ops = &gcry_drbg_hmac_ops; -+ else if (drbg->core->flags & GCRY_DRBG_HASH_MASK) -+ drbg->d_ops = &gcry_drbg_hash_ops; -+ else if (drbg->core->flags & GCRY_DRBG_CTR_MASK) -+ drbg->d_ops = &gcry_drbg_ctr_ops; -+ else -+ return GPG_ERR_GENERAL; -+ /* 9.1 step 1 is implicit with the selected DRBG type -- see -+ * gcry_drbg_sec_strength() */ -+ -+ /* 9.1 step 2 is implicit as caller can select prediction resistance -+ * and the flag is copied into drbg->flags -- -+ * all DRBG types support prediction resistance */ -+ -+ /* 9.1 step 4 is implicit in gcry_drbg_sec_strength */ -+ -+ /* no allocation of drbg as this is done by the kernel crypto API */ -+ drbg->V = xcalloc_secure (1, gcry_drbg_statelen (drbg)); -+ if (!drbg->V) -+ goto err; -+ drbg->C = xcalloc_secure (1, gcry_drbg_statelen (drbg)); -+ if (!drbg->C) -+ goto err; -+ drbg->prev = xcalloc_secure (1, gcry_drbg_blocklen (drbg)); -+ if (!drbg->prev) -+ goto err; -+ drbg->fips_primed = 0; -+ /* scratchpad is only generated for CTR and Hash */ -+ if (drbg->core->flags & GCRY_DRBG_HMAC) -+ sb_size = 0; -+ else if (drbg->core->flags & GCRY_DRBG_CTR_MASK) -+ sb_size = gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg) + /* temp */ -+ gcry_drbg_statelen (drbg) + /* df_data */ -+ gcry_drbg_blocklen (drbg) + /* pad */ -+ gcry_drbg_blocklen (drbg) + /* iv */ -+ gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); /* temp */ -+ else -+ sb_size = gcry_drbg_statelen (drbg) + gcry_drbg_blocklen (drbg); -+ -+ if (0 < sb_size) -+ { -+ drbg->scratchpad = xcalloc_secure (1, sb_size); -+ if (!drbg->scratchpad) -+ goto err; -+ } -+ dbg (("DRBG: state allocated with scratchpad size %u bytes\n", sb_size)); -+ -+ /* 9.1 step 6 through 11 */ -+ ret = gcry_drbg_seed (drbg, pers, 0); -+ if (ret) -+ goto err; -+ -+ dbg (("DRBG: core %d %s prediction resistance successfully initialized\n", -+ coreref, pr ? "with" : "without")); -+ return 0; -+ -+err: -+ gcry_drbg_uninstantiate (drbg); -+ return ret; -+} -+ -+/* -+ * DRBG reseed function as required by SP800-90A -+ * -+ * @drbg DRBG state handle -+ * @addtl Additional input that is mixed into state, may be NULL -- note -+ * the entropy is pulled by the DRBG internally unconditionally -+ * as defined in SP800-90A. The additional input is mixed into -+ * the state in addition to the pulled entropy. -+ * -+ * return -+ * 0 on success -+ * error value otherwise -+ */ -+static gpg_err_code_t -+gcry_drbg_reseed (struct gcry_drbg_state *drbg, -+ struct gcry_drbg_string *addtl) -+{ -+ gpg_err_code_t ret = 0; -+ ret = gcry_drbg_seed (drbg, addtl, 1); -+ return ret; -+} -+ -+/****************************************************************** -+ ****************************************************************** -+ ****************************************************************** -+ * libgcrypt integration code -+ ****************************************************************** -+ ****************************************************************** -+ ******************************************************************/ -+ -+/*************************************************************** -+ * libgcrypt backend functions to the RNG API code -+ ***************************************************************/ -+ -+/* global state variable holding the current instance of the DRBG -- the -+ * default DRBG type is defined in _gcry_gcry_drbg_init */ -+static struct gcry_drbg_state *gcry_drbg = NULL; -+ -+/* This is the lock we use to serialize access to this RNG. */ -+static ath_mutex_t drbg_lock; -+ -+static inline void -+gcry_drbg_lock (void) -+{ -+ int my_errno; -+ -+ my_errno = ath_mutex_lock (&drbg_lock); -+ if (my_errno) -+ log_fatal ("failed to acquire the RNG lock: %s\n", strerror (my_errno)); -+} -+ -+static inline void -+gcry_drbg_unlock (void) -+{ -+ int my_errno; -+ -+ my_errno = ath_mutex_unlock (&drbg_lock); -+ if (my_errno) -+ log_fatal ("failed to release the RNG lock: %s\n", strerror (my_errno)); -+} -+ -+/* Basic initialization is required to initialize mutexes and -+ do a few checks on the implementation. */ -+static void -+basic_initialization (void) -+{ -+ static int initialized; -+ int my_errno; -+ -+ if (initialized) -+ return; -+ initialized = 1; -+ -+ my_errno = ath_mutex_init (&drbg_lock); -+ if (my_errno) -+ log_fatal ("failed to create the RNG lock: %s\n", strerror (my_errno)); -+} -+ -+/****** helper functions where lock must be held by caller *****/ -+ -+/* Check whether given flags are known to point to an applicable DRBG */ -+static gpg_err_code_t -+gcry_drbg_algo_available (u32 flags, int *coreref) -+{ -+ int i = 0; -+ for (i = 0; ARRAY_SIZE (gcry_drbg_cores) > i; i++) -+ { -+ if ((gcry_drbg_cores[i].flags & GCRY_DRBG_CIPHER_MASK) == -+ (flags & GCRY_DRBG_CIPHER_MASK)) -+ { -+ *coreref = i; -+ return 0; -+ } -+ } -+ return GPG_ERR_GENERAL; -+} -+ -+static gpg_err_code_t -+_gcry_drbg_init_internal (u32 flags, struct gcry_drbg_string *pers) -+{ -+ gpg_err_code_t ret = 0; -+ static u32 oldflags = 0; -+ int coreref = 0; -+ int pr = 0; -+ -+ /* If a caller provides 0 as flags, use the flags of the previous -+ * initialization, otherwise use the current flags and remember them -+ * for the next invocation -+ */ -+ if (0 == flags) -+ flags = oldflags; -+ else -+ oldflags = flags; -+ -+ ret = gcry_drbg_algo_available (flags, &coreref); -+ if (ret) -+ return ret; -+ -+ if (NULL != gcry_drbg) -+ { -+ gcry_drbg_uninstantiate (gcry_drbg); -+ } -+ else -+ { -+ gcry_drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); -+ if (!gcry_drbg) -+ return GPG_ERR_ENOMEM; -+ } -+ if (flags & GCRY_DRBG_PREDICTION_RESIST) -+ pr = 1; -+ ret = gcry_drbg_instantiate (gcry_drbg, pers, coreref, pr); -+ if (ret) -+ fips_signal_error ("DRBG cannot be initialized"); -+ else -+ gcry_drbg->seed_init_pid = getpid (); -+ return ret; -+} -+ -+/************* calls available to common RNG code **************/ -+ -+/* -+ * Initialize one DRBG invoked by the libgcrypt API -+ */ -+void -+_gcry_drbg_init (int full) -+{ -+ (void) full; /* ignore for now */ -+ /* default DRBG */ -+ u32 flags = GCRY_DRBG_NOPR_HMACSHA256; -+ basic_initialization (); -+ gcry_drbg_lock (); -+ _gcry_drbg_init_internal (flags, NULL); -+ gcry_drbg_unlock (); -+} -+ -+/* -+ * Backend handler function for GCRYCTL_DRBG_REINIT -+ * -+ * Select a different DRBG type and initialize it. -+ * Function checks whether requested DRBG type exists and returns an error in -+ * case it does not. In case of an error, the previous instantiated DRBG is -+ * left untouched and alive. Thus, in case of an error, a DRBG is always -+ * available, even if it is not the chosen one. -+ * -+ * Re-initialization will be performed in any case regardless whether flags -+ * or personalization string are set. -+ * -+ * If flags == 0, do not change current DRBG -+ * If personalization string is NULL or its length is 0, re-initialize without -+ * personalization string -+ */ -+gpg_err_code_t -+_gcry_drbg_reinit (u32 flags, struct gcry_drbg_string *pers) -+{ -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ dbg (("DRBG: reinitialize internal DRBG state with flags %u\n", flags)); -+ gcry_drbg_lock (); -+ ret = _gcry_drbg_init_internal (flags, pers); -+ gcry_drbg_unlock (); -+ return ret; -+} -+ -+/* Try to close the FDs of the random gather module. This is -+ * currently only implemented for rndlinux. */ -+void -+_gcry_drbg_close_fds (void) -+{ -+#if USE_RNDLINUX -+ gcry_drbg_lock (); -+ _gcry_rndlinux_gather_random (NULL, 0, 0, 0); -+ gcry_drbg_unlock (); -+#endif -+} -+ -+/* Print some statistics about the RNG. */ -+void -+_gcry_drbg_dump_stats (void) -+{ -+ /* Not yet implemented. */ -+ /* Maybe dumping of reseed counter? */ -+} -+ -+/* This function returns true if no real RNG is available or the -+ * quality of the RNG has been degraded for test purposes. */ -+int -+_gcry_drbg_is_faked (void) -+{ -+ return 0; /* Faked random is not allowed. */ -+} -+ -+/* Add BUFLEN bytes from BUF to the internal random pool. QUALITY -+ * should be in the range of 0..100 to indicate the goodness of the -+ * entropy added, or -1 for goodness not known. */ -+gcry_error_t -+_gcry_drbg_add_bytes (const void *buf, size_t buflen, int quality) -+{ -+ gpg_err_code_t ret = 0; -+ struct gcry_drbg_string seed; -+ (void) quality; -+ if (NULL == gcry_drbg) -+ return GPG_ERR_GENERAL; -+ gcry_drbg_string_fill (&seed, (unsigned char *) buf, buflen); -+ gcry_drbg_lock (); -+ ret = gcry_drbg_reseed (gcry_drbg, &seed); -+ gcry_drbg_unlock (); -+ return ret; -+} -+ -+/* This function is to be used for all types of random numbers, including -+ * nonces -+ */ -+void -+_gcry_drbg_randomize (void *buffer, size_t length, -+ enum gcry_random_level level) -+{ -+ (void) level; -+ gcry_drbg_lock (); -+ if (NULL == gcry_drbg) -+ { -+ fips_signal_error ("DRBG is not initialized"); -+ goto bailout; -+ } -+ -+ /* As reseeding changes the entire state of the DRBG, including any -+ * key, either a re-init or a reseed is sufficient for a fork */ -+ if (gcry_drbg->seed_init_pid != getpid ()) -+ { -+ /* We are in a child of us. Perform a reseeding. */ -+ if (gcry_drbg_reseed (gcry_drbg, NULL)) -+ { -+ fips_signal_error ("reseeding upon fork failed"); -+ log_fatal ("severe error getting random\n"); -+ goto bailout; -+ } -+ gcry_drbg->seed_init_pid = getpid (); -+ } -+ /* potential integer overflow is covered by gcry_drbg_generate which -+ * ensures that length cannot overflow an unsigned int */ -+ if (0 < length) -+ { -+ if (!buffer) -+ goto bailout; -+ if (gcry_drbg_generate_long -+ (gcry_drbg, buffer, (unsigned int) length, NULL)) -+ log_fatal ("No random numbers generated\n"); -+ } -+ else -+ { -+ struct gcry_drbg_gen *data = (struct gcry_drbg_gen *) buffer; -+ /* catch NULL pointer */ -+ if (!data || !data->outbuf) -+ { -+ fips_signal_error ("No output buffer provided"); -+ goto bailout; -+ } -+ if (gcry_drbg_generate_long (gcry_drbg, data->outbuf, data->outlen, -+ data->addtl)) -+ log_fatal ("No random numbers generated\n"); -+ } -+bailout: -+ gcry_drbg_unlock (); -+ return; -+ -+} -+ -+/*************************************************************** -+ * Self-test code -+ ***************************************************************/ -+ -+/* -+ * Test vectors from -+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/drbgtestvectors.zip -+ */ -+struct gcry_drbg_test_vector gcry_drbg_test_pr[] = { -+ { -+ .flags = (GCRY_DRBG_PR_HASHSHA256), -+ .entropy = (unsigned char *) -+ "\x5d\xf2\x14\xbc\xf6\xb5\x4e\x0b\xf0\x0d\x6f\x2d" -+ "\xe2\x01\x66\x7b\xd0\xa4\x73\xa4\x21\xdd\xb0\xc0" -+ "\x51\x79\x09\xf4\xea\xa9\x08\xfa\xa6\x67\xe0\xe1" -+ "\xd1\x88\xa8\xad\xee\x69\x74\xb3\x55\x06\x9b\xf6", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xef\x48\x06\xa2\xc2\x45\xf1\x44\xfa\x34\x2c\xeb" -+ "\x8d\x78\x3c\x09\x8f\x34\x72\x20\xf2\xe7\xfd\x13" -+ "\x76\x0a\xf6\xdc\x3c\xf5\xc0\x15", -+ .entprb = (unsigned char *) -+ "\x4b\xbe\xe5\x24\xed\x6a\x2d\x0c\xdb\x73\x5e\x09" -+ "\xf9\xad\x67\x7c\x51\x47\x8b\x6b\x30\x2a\xc6\xde" -+ "\x76\xaa\x55\x04\x8b\x0a\x72\x95", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x3b\x14\x71\x99\xa1\xda\xa0\x42\xe6\xc8\x85\x32" -+ "\x70\x20\x32\x53\x9a\xbe\xd1\x1e\x15\xef\xfb\x4c" -+ "\x25\x6e\x19\x3a\xf0\xb9\xcb\xde\xf0\x3b\xc6\x18" -+ "\x4d\x85\x5a\x9b\xf1\xe3\xc2\x23\x03\x93\x08\xdb" -+ "\xa7\x07\x4b\x33\x78\x40\x4d\xeb\x24\xf5\x6e\x81" -+ "\x4a\x1b\x6e\xa3\x94\x52\x43\xb0\xaf\x2e\x21\xf4" -+ "\x42\x46\x8e\x90\xed\x34\x21\x75\xea\xda\x67\xb6" -+ "\xe4\xf6\xff\xc6\x31\x6c\x9a\x5a\xdb\xb3\x97\x13" -+ "\x09\xd3\x20\x98\x33\x2d\x6d\xd7\xb5\x6a\xa8\xa9" -+ "\x9a\x5b\xd6\x87\x52\xa1\x89\x2b\x4b\x9c\x64\x60" -+ "\x50\x47\xa3\x63\x81\x16\xaf\x19", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\xbe\x13\xdb\x2a\xe9\xa8\xfe\x09\x97\xe1\xce\x5d" -+ "\xe8\xbb\xc0\x7c\x4f\xcb\x62\x19\x3f\x0f\xd2\xad" -+ "\xa9\xd0\x1d\x59\x02\xc4\xff\x70", -+ .addtlb = (unsigned char *) -+ "\x6f\x96\x13\xe2\xa7\xf5\x6c\xfe\xdf\x66\xe3\x31" -+ "\x63\x76\xbf\x20\x27\x06\x49\xf1\xf3\x01\x77\x41" -+ "\x9f\xeb\xe4\x38\xfe\x67\x00\xcd", -+ .addtllen = 32, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = (GCRY_DRBG_PR_HMACSHA256), -+ .entropy = (unsigned char *) -+ "\x13\x54\x96\xfc\x1b\x7d\x28\xf3\x18\xc9\xa7\x89" -+ "\xb6\xb3\xc8\x72\xac\x00\xd4\x59\x36\x25\x05\xaf" -+ "\xa5\xdb\x96\xcb\x3c\x58\x46\x87\xa5\xaa\xbf\x20" -+ "\x3b\xfe\x23\x0e\xd1\xc7\x41\x0f\x3f\xc9\xb3\x67", -+ .entropylen = 48, -+ .entpra = (unsigned char *) -+ "\xe2\xbd\xb7\x48\x08\x06\xf3\xe1\x93\x3c\xac\x79" -+ "\xa7\x2b\x11\xda\xe3\x2e\xe1\x91\xa5\x02\x19\x57" -+ "\x20\x28\xad\xf2\x60\xd7\xcd\x45", -+ .entprb = (unsigned char *) -+ "\x8b\xd4\x69\xfc\xff\x59\x95\x95\xc6\x51\xde\x71" -+ "\x68\x5f\xfc\xf9\x4a\xab\xec\x5a\xcb\xbe\xd3\x66" -+ "\x1f\xfa\x74\xd3\xac\xa6\x74\x60", -+ .entprlen = 32, -+ .expected = (unsigned char *) -+ "\x1f\x9e\xaf\xe4\xd2\x46\xb7\x47\x41\x4c\x65\x99" -+ "\x01\xe9\x3b\xbb\x83\x0c\x0a\xb0\xc1\x3a\xe2\xb3" -+ "\x31\x4e\xeb\x93\x73\xee\x0b\x26\xc2\x63\xa5\x75" -+ "\x45\x99\xd4\x5c\x9f\xa1\xd4\x45\x87\x6b\x20\x61" -+ "\x40\xea\x78\xa5\x32\xdf\x9e\x66\x17\xaf\xb1\x88" -+ "\x9e\x2e\x23\xdd\xc1\xda\x13\x97\x88\xa5\xb6\x5e" -+ "\x90\x14\x4e\xef\x13\xab\x5c\xd9\x2c\x97\x9e\x7c" -+ "\xd7\xf8\xce\xea\x81\xf5\xcd\x71\x15\x49\x44\xce" -+ "\x83\xb6\x05\xfb\x7d\x30\xb5\x57\x2c\x31\x4f\xfc" -+ "\xfe\x80\xb6\xc0\x13\x0c\x5b\x9b\x2e\x8f\x3d\xfc" -+ "\xc2\xa3\x0c\x11\x1b\x80\x5f\xf3", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\x64\xb6\xfc\x60\xbc\x61\x76\x23\x6d\x3f\x4a\x0f" -+ "\xe1\xb4\xd5\x20\x9e\x70\xdd\x03\x53\x6d\xbf\xce" -+ "\xcd\x56\x80\xbc\xb8\x15\xc8\xaa", -+ .perslen = 32, -+ }, -+ { -+ .flags = (GCRY_DRBG_PR_CTRAES128), -+ .entropy = (unsigned char *) -+ "\x92\x89\x8f\x31\xfa\x1c\xff\x6d\x18\x2f\x26\x06" -+ "\x43\xdf\xf8\x18\xc2\xa4\xd9\x72\xc3\xb9\xb6\x97", -+ .entropylen = 24, -+ .entpra = (unsigned char *) -+ "\x20\x72\x8a\x06\xf8\x6f\x8d\xd4\x41\xe2\x72\xb7" -+ "\xc4\x2c\xe8\x10", -+ .entprb = (unsigned char *) -+ "\x3d\xb0\xf0\x94\xf3\x05\x50\x33\x17\x86\x3e\x22" -+ "\x08\xf7\xa5\x01", -+ .entprlen = 16, -+ .expected = (unsigned char *) -+ "\x5a\x35\x39\x87\x0f\x4d\x22\xa4\x09\x24\xee\x71" -+ "\xc9\x6f\xac\x72\x0a\xd6\xf0\x88\x82\xd0\x83\x28" -+ "\x73\xec\x3f\x93\xd8\xab\x45\x23\xf0\x7e\xac\x45" -+ "\x14\x5e\x93\x9f\xb1\xd6\x76\x43\x3d\xb6\xe8\x08" -+ "\x88\xf6\xda\x89\x08\x77\x42\xfe\x1a\xf4\x3f\xc4" -+ "\x23\xc5\x1f\x68", -+ .expectedlen = 64, -+ .addtla = (unsigned char *) -+ "\x1a\x40\xfa\xe3\xcc\x6c\x7c\xa0\xf8\xda\xba\x59" -+ "\x23\x6d\xad\x1d", -+ .addtlb = (unsigned char *) -+ "\x9f\x72\x76\x6c\xc7\x46\xe5\xed\x2e\x53\x20\x12" -+ "\xbc\x59\x31\x8c", -+ .addtllen = 16, -+ .pers = (unsigned char *) -+ "\xea\x65\xee\x60\x26\x4e\x7e\xb6\x0e\x82\x68\xc4" -+ "\x37\x3c\x5c\x0b", -+ .perslen = 16, -+ }, -+}; -+ -+struct gcry_drbg_test_vector gcry_drbg_test_nopr[] = { -+ { -+ .flags = GCRY_DRBG_NOPR_HASHSHA256, -+ .entropy = (unsigned char *) -+ "\x73\xd3\xfb\xa3\x94\x5f\x2b\x5f\xb9\x8f\xf6\x9c" -+ "\x8a\x93\x17\xae\x19\xc3\x4c\xc3\xd6\xca\xa3\x2d" -+ "\x16\xfc\x42\xd2\x2d\xd5\x6f\x56\xcc\x1d\x30\xff" -+ "\x9e\x06\x3e\x09\xce\x58\xe6\x9a\x35\xb3\xa6\x56", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\x71\x7b\x93\x46\x1a\x40\xaa\x35\xa4\xaa\xc5\xe7" -+ "\x6d\x5b\x5b\x8a\xa0\xdf\x39\x7d\xae\x71\x58\x5b" -+ "\x3c\x7c\xb4\xf0\x89\xfa\x4a\x8c\xa9\x5c\x54\xc0" -+ "\x40\xdf\xbc\xce\x26\x81\x34\xf8\xba\x7d\x1c\xe8" -+ "\xad\x21\xe0\x74\xcf\x48\x84\x30\x1f\xa1\xd5\x4f" -+ "\x81\x42\x2f\xf4\xdb\x0b\x23\xf8\x73\x27\xb8\x1d" -+ "\x42\xf8\x44\x58\xd8\x5b\x29\x27\x0a\xf8\x69\x59" -+ "\xb5\x78\x44\xeb\x9e\xe0\x68\x6f\x42\x9a\xb0\x5b" -+ "\xe0\x4e\xcb\x6a\xaa\xe2\xd2\xd5\x33\x25\x3e\xe0" -+ "\x6c\xc7\x6a\x07\xa5\x03\x83\x9f\xe2\x8b\xd1\x1c" -+ "\x70\xa8\x07\x59\x97\xeb\xf6\xbe", -+ .expectedlen = 128, -+ .addtla = (unsigned char *) -+ "\xf4\xd5\x98\x3d\xa8\xfc\xfa\x37\xb7\x54\x67\x73" -+ "\xc7\xc3\xdd\x47\x34\x71\x02\x5d\xc1\xa0\xd3\x10" -+ "\xc1\x8b\xbd\xf5\x66\x34\x6f\xdd", -+ .addtlb = (unsigned char *) -+ "\xf7\x9e\x6a\x56\x0e\x73\xe9\xd9\x7a\xd1\x69\xe0" -+ "\x6f\x8c\x55\x1c\x44\xd1\xce\x6f\x28\xcc\xa4\x4d" -+ "\xa8\xc0\x85\xd1\x5a\x0c\x59\x40", -+ .addtllen = 32, -+ .pers = NULL, -+ .perslen = 0, -+ }, -+ { -+ .flags = GCRY_DRBG_NOPR_HMACSHA256, -+ .entropy = (unsigned char *) -+ "\x8d\xf0\x13\xb4\xd1\x03\x52\x30\x73\x91\x7d\xdf" -+ "\x6a\x86\x97\x93\x05\x9e\x99\x43\xfc\x86\x54\x54" -+ "\x9e\x7a\xb2\x2f\x7c\x29\xf1\x22\xda\x26\x25\xaf" -+ "\x2d\xdd\x4a\xbc\xce\x3c\xf4\xfa\x46\x59\xd8\x4e", -+ .entropylen = 48, -+ .expected = (unsigned char *) -+ "\xb9\x1c\xba\x4c\xc8\x4f\xa2\x5d\xf8\x61\x0b\x81" -+ "\xb6\x41\x40\x27\x68\xa2\x09\x72\x34\x93\x2e\x37" -+ "\xd5\x90\xb1\x15\x4c\xbd\x23\xf9\x74\x52\xe3\x10" -+ "\xe2\x91\xc4\x51\x46\x14\x7f\x0d\xa2\xd8\x17\x61" -+ "\xfe\x90\xfb\xa6\x4f\x94\x41\x9c\x0f\x66\x2b\x28" -+ "\xc1\xed\x94\xda\x48\x7b\xb7\xe7\x3e\xec\x79\x8f" -+ "\xbc\xf9\x81\xb7\x91\xd1\xbe\x4f\x17\x7a\x89\x07" -+ "\xaa\x3c\x40\x16\x43\xa5\xb6\x2b\x87\xb8\x9d\x66" -+ "\xb3\xa6\x0e\x40\xd4\xa8\xe4\xe9\xd8\x2a\xf6\xd2" -+ "\x70\x0e\x6f\x53\x5c\xdb\x51\xf7\x5c\x32\x17\x29" -+ "\x10\x37\x41\x03\x0c\xcc\x3a\x56", -+ .expectedlen = 128, -+ .addtla = NULL, -+ .addtlb = NULL, -+ .addtllen = 0, -+ .pers = (unsigned char *) -+ "\xb5\x71\xe6\x6d\x7c\x33\x8b\xc0\x7b\x76\xad\x37" -+ "\x57\xbb\x2f\x94\x52\xbf\x7e\x07\x43\x7a\xe8\x58" -+ "\x1c\xe7\xbc\x7c\x3a\xc6\x51\xa9", -+ .perslen = 32, -+ }, -+ { -+ .flags = GCRY_DRBG_NOPR_CTRAES128, -+ .entropy = (unsigned char *) -+ "\xc0\x70\x1f\x92\x50\x75\x8f\xcd\xf2\xbe\x73\x98" -+ "\x80\xdb\x66\xeb\x14\x68\xb4\xa5\x87\x9c\x2d\xa6", -+ .entropylen = 24, -+ .expected = (unsigned char *) -+ "\x97\xc0\xc0\xe5\xa0\xcc\xf2\x4f\x33\x63\x48\x8a" -+ "\xdb\x13\x0a\x35\x89\xbf\x80\x65\x62\xee\x13\x95" -+ "\x7c\x33\xd3\x7d\xf4\x07\x77\x7a\x2b\x65\x0b\x5f" -+ "\x45\x5c\x13\xf1\x90\x77\x7f\xc5\x04\x3f\xcc\x1a" -+ "\x38\xf8\xcd\x1b\xbb\xd5\x57\xd1\x4a\x4c\x2e\x8a" -+ "\x2b\x49\x1e\x5c", -+ .expectedlen = 64, -+ .addtla = (unsigned char *) -+ "\xf9\x01\xf8\x16\x7a\x1d\xff\xde\x8e\x3c\x83\xe2" -+ "\x44\x85\xe7\xfe", -+ .addtlb = (unsigned char *) -+ "\x17\x1c\x09\x38\xc2\x38\x9f\x97\x87\x60\x55\xb4" -+ "\x82\x16\x62\x7f", -+ .addtllen = 16, -+ .pers = (unsigned char *) -+ "\x80\x08\xae\xe8\xe9\x69\x40\xc5\x08\x73\xc7\x9f" -+ "\x8e\xcf\xe0\x02", -+ .perslen = 16, -+ }, -+}; -+ -+ -+/* -+ * Tests implement the CAVS test approach as documented in -+ * http://csrc.nist.gov/groups/STM/cavp/documents/drbg/DRBGVS.pdf -+ */ -+ -+/* -+ * CAVS test -+ * -+ * This function is not static as it is needed for as a private API -+ * call for the CAVS test tool. -+ */ -+gpg_err_code_t -+gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, unsigned char *buf) -+{ -+ gpg_err_code_t ret = 0; -+ struct gcry_drbg_state *drbg = NULL; -+ struct gcry_drbg_test_data test_data; -+ struct gcry_drbg_string addtl, pers, testentropy; -+ int coreref = 0; -+ int pr = 0; -+ -+ ret = gcry_drbg_algo_available (test->flags, &coreref); -+ if (ret) -+ goto outbuf; -+ -+ drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); -+ if (!drbg) -+ { -+ ret = GPG_ERR_ENOMEM; -+ goto outbuf; -+ } -+ -+ if (test->flags & GCRY_DRBG_PREDICTION_RESIST) -+ pr = 1; -+ -+ test_data.testentropy = &testentropy; -+ gcry_drbg_string_fill (&testentropy, test->entropy, test->entropylen); -+ drbg->test_data = &test_data; -+ gcry_drbg_string_fill (&pers, test->pers, test->perslen); -+ ret = gcry_drbg_instantiate (drbg, &pers, coreref, pr); -+ if (ret) -+ goto outbuf; -+ -+ gcry_drbg_string_fill (&addtl, test->addtla, test->addtllen); -+ if (test->entpra) -+ { -+ gcry_drbg_string_fill (&testentropy, test->entpra, test->entprlen); -+ drbg->test_data = &test_data; -+ } -+ gcry_drbg_generate_long (drbg, buf, test->expectedlen, &addtl); -+ -+ gcry_drbg_string_fill (&addtl, test->addtlb, test->addtllen); -+ if (test->entprb) -+ { -+ gcry_drbg_string_fill (&testentropy, test->entprb, test->entprlen); -+ drbg->test_data = &test_data; -+ } -+ gcry_drbg_generate_long (drbg, buf, test->expectedlen, &addtl); -+ gcry_drbg_uninstantiate (drbg); -+ -+outbuf: -+ xfree (drbg); -+ return ret; -+} -+ -+/* -+ * Invoke the CAVS test and perform the final check whether the -+ * calculated random value matches the expected one. -+ * -+ * This function is not static as it is needed for as a private API -+ * call for the CAVS test tool. -+ */ -+gpg_err_code_t -+gcry_drbg_healthcheck_one (struct gcry_drbg_test_vector * test) -+{ -+ gpg_err_code_t ret = GPG_ERR_ENOMEM; -+ unsigned char *buf = xcalloc_secure (1, test->expectedlen); -+ if (!buf) -+ return GPG_ERR_ENOMEM; -+ -+ ret = gcry_drbg_cavs_test (test, buf); -+ ret = memcmp (test->expected, buf, test->expectedlen); -+ -+ xfree (buf); -+ return ret; -+} -+ -+/* -+ * Tests as defined in 11.3.2 in addition to the cipher tests: testing -+ * of the error handling. -+ * -+ * Note, testing the reseed counter is not done as an automatic reseeding -+ * is performed in gcry_drbg_generate when the reseed counter is too large. -+ */ -+static gpg_err_code_t -+gcry_drbg_healthcheck_sanity (struct gcry_drbg_test_vector *test) -+{ -+ unsigned int len = 0; -+ struct gcry_drbg_state *drbg = NULL; -+ gpg_err_code_t ret = GPG_ERR_GENERAL; -+ gpg_err_code_t tmpret = GPG_ERR_GENERAL; -+ struct gcry_drbg_test_data test_data; -+ struct gcry_drbg_string addtl, testentropy; -+ int coreref = 0; -+ unsigned char *buf = NULL; -+ size_t max_addtllen, max_request_bytes; -+ -+ /* only perform test in FIPS mode */ -+ if (0 == fips_mode ()) -+ return 0; -+ -+ buf = xcalloc_secure (1, test->expectedlen); -+ if (!buf) -+ return GPG_ERR_ENOMEM; -+ tmpret = gcry_drbg_algo_available (test->flags, &coreref); -+ if (tmpret) -+ goto outbuf; -+ drbg = xcalloc_secure (1, sizeof (struct gcry_drbg_state)); -+ if (!drbg) -+ goto outbuf; -+ -+ /* if the following tests fail, it is likely that there is a buffer -+ * overflow and we get a SIGSEV */ -+ ret = gcry_drbg_instantiate (drbg, NULL, coreref, 1); -+ if (ret) -+ goto outbuf; -+ max_addtllen = gcry_drbg_max_addtl (); -+ max_request_bytes = gcry_drbg_max_request_bytes (); -+ /* overflow addtllen with additonal info string */ -+ gcry_drbg_string_fill (&addtl, test->addtla, (max_addtllen + 1)); -+ len = gcry_drbg_generate (drbg, buf, test->expectedlen, &addtl); -+ if (len) -+ goto outdrbg; -+ -+ /* overflow max_bits */ -+ len = gcry_drbg_generate (drbg, buf, (max_request_bytes + 1), NULL); -+ if (len) -+ goto outdrbg; -+ gcry_drbg_uninstantiate (drbg); -+ -+ /* test failing entropy source as defined in 11.3.2 */ -+ test_data.testentropy = NULL; -+ test_data.fail_seed_source = 1; -+ drbg->test_data = &test_data; -+ tmpret = gcry_drbg_instantiate (drbg, NULL, coreref, 0); -+ if (!tmpret) -+ goto outdrbg; -+ test_data.fail_seed_source = 0; -+ -+ test_data.testentropy = &testentropy; -+ gcry_drbg_string_fill (&testentropy, test->entropy, test->entropylen); -+ /* overflow max addtllen with personalization string */ -+ tmpret = gcry_drbg_instantiate (drbg, &addtl, coreref, 0); -+ if (!tmpret) -+ goto outdrbg; -+ -+ dbg (("DRBG: Sanity tests for failure code paths successfully completed\n")); -+ ret = 0; -+ -+outdrbg: -+ gcry_drbg_uninstantiate (drbg); -+outbuf: -+ xfree (buf); -+ xfree (drbg); -+ return ret; -+} -+ -+/* -+ * DRBG Healthcheck function as required in SP800-90A -+ * -+ * return: -+ * 0 on success (all tests pass) -+ * >0 on error (return code indicate the number of failures) -+ */ -+static int -+gcry_drbg_healthcheck (void) -+{ -+ int ret = 0; -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[0]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[1]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_nopr[2]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[0]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[1]); -+ ret += gcry_drbg_healthcheck_one (&gcry_drbg_test_pr[2]); -+ ret += gcry_drbg_healthcheck_sanity (&gcry_drbg_test_nopr[0]); -+ return ret; -+} -+ -+/* Run the self-tests. */ -+gcry_error_t -+_gcry_drbg_selftest (selftest_report_func_t report) -+{ -+ gcry_err_code_t ec; -+ const char *errtxt = NULL; -+ gcry_drbg_lock (); -+ if (0 != gcry_drbg_healthcheck ()) -+ errtxt = "RNG output does not match known value"; -+ gcry_drbg_unlock (); -+ if (report && errtxt) -+ report ("random", 0, "KAT", errtxt); -+ ec = errtxt ? GPG_ERR_SELFTEST_FAILED : 0; -+ return gpg_error (ec); -+} -+ -+/*************************************************************** -+ * Cipher invocations requested by DRBG -+ ***************************************************************/ -+ -+static gpg_err_code_t -+gcry_drbg_hmac (struct gcry_drbg_state *drbg, const unsigned char *key, -+ unsigned char *outval, const struct gcry_drbg_string *buf) -+{ -+ gpg_error_t err; -+ gcry_md_hd_t hd; -+ -+ if (key) -+ { -+ err = -+ _gcry_md_open (&hd, drbg->core->backend_cipher, GCRY_MD_FLAG_HMAC); -+ if (err) -+ return err; -+ err = _gcry_md_setkey (hd, key, gcry_drbg_statelen (drbg)); -+ if (err) -+ return err; -+ } -+ else -+ { -+ err = _gcry_md_open (&hd, drbg->core->backend_cipher, 0); -+ if (err) -+ return err; -+ } -+ for (; NULL != buf; buf = buf->next) -+ _gcry_md_write (hd, buf->buf, buf->len); -+ _gcry_md_final (hd); -+ memcpy (outval, _gcry_md_read (hd, drbg->core->backend_cipher), -+ gcry_drbg_blocklen (drbg)); -+ _gcry_md_close (hd); -+ return 0; -+} -+ -+static gpg_err_code_t -+gcry_drbg_sym (struct gcry_drbg_state *drbg, const unsigned char *key, -+ unsigned char *outval, const struct gcry_drbg_string *buf) -+{ -+ gpg_error_t err; -+ gcry_cipher_hd_t hd; -+ -+ if (gcry_drbg_blocklen (drbg) != -+ _gcry_cipher_get_algo_blklen (drbg->core->backend_cipher)) -+ return -GPG_ERR_NO_ERROR; -+ if (gcry_drbg_blocklen (drbg) < buf->len) -+ return -GPG_ERR_NO_ERROR; -+ err = -+ _gcry_cipher_open (&hd, drbg->core->backend_cipher, GCRY_CIPHER_MODE_ECB, -+ 0); -+ if (err) -+ return err; -+ err = _gcry_cipher_setkey (hd, key, gcry_drbg_keylen (drbg)); -+ if (err) -+ { -+ _gcry_cipher_close (hd); -+ return err; -+ } -+ /* in is only component */ -+ _gcry_cipher_encrypt (hd, outval, gcry_drbg_blocklen (drbg), buf->buf, -+ buf->len); -+ _gcry_cipher_close (hd); -+ return 0; -+} -diff -up libgcrypt-1.6.2/random/Makefile.am.drbg libgcrypt-1.6.2/random/Makefile.am ---- libgcrypt-1.6.2/random/Makefile.am.drbg 2014-08-18 08:46:51.000000000 +0200 -+++ libgcrypt-1.6.2/random/Makefile.am 2014-12-08 16:31:33.513992141 +0100 -@@ -35,6 +35,7 @@ random.c random.h \ - rand-internal.h \ - random-csprng.c \ - random-fips.c \ -+drbg.c \ - random-system.c \ - rndhw.c - -diff -up libgcrypt-1.6.2/random/Makefile.in.drbg libgcrypt-1.6.2/random/Makefile.in ---- libgcrypt-1.6.2/random/Makefile.in.drbg 2014-08-21 15:14:08.000000000 +0200 -+++ libgcrypt-1.6.2/random/Makefile.in 2014-12-08 16:31:33.514992163 +0100 -@@ -92,11 +92,11 @@ CONFIG_CLEAN_VPATH_FILES = - LTLIBRARIES = $(noinst_LTLIBRARIES) - am__DEPENDENCIES_1 = - am__librandom_la_SOURCES_DIST = random.c random.h rand-internal.h \ -- random-csprng.c random-fips.c random-system.c rndhw.c \ -+ random-csprng.c random-fips.c drbg.c random-system.c rndhw.c \ - random-daemon.c - @USE_RANDOM_DAEMON_TRUE@am__objects_1 = random-daemon.lo - am_librandom_la_OBJECTS = random.lo random-csprng.lo random-fips.lo \ -- random-system.lo rndhw.lo $(am__objects_1) -+ drbg.lo random-system.lo rndhw.lo $(am__objects_1) - librandom_la_OBJECTS = $(am_librandom_la_OBJECTS) - AM_V_lt = $(am__v_lt_@AM_V@) - am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) -@@ -310,7 +310,7 @@ GCRYPT_MODULES = @GCRYPT_RANDOM@ - librandom_la_DEPENDENCIES = $(GCRYPT_MODULES) - librandom_la_LIBADD = $(GCRYPT_MODULES) - librandom_la_SOURCES = random.c random.h rand-internal.h \ -- random-csprng.c random-fips.c random-system.c rndhw.c \ -+ random-csprng.c random-fips.c drbg.c random-system.c rndhw.c \ - $(am__append_1) - EXTRA_librandom_la_SOURCES = \ - rndlinux.c \ -@@ -374,6 +374,7 @@ distclean-compile: - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-csprng.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-daemon.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-fips.Plo@am__quote@ -+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/drbg.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random-system.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Plo@am__quote@ - @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rndegd.Plo@am__quote@ -diff -up libgcrypt-1.6.2/random/rand-internal.h.drbg libgcrypt-1.6.2/random/rand-internal.h ---- libgcrypt-1.6.2/random/rand-internal.h.drbg 2014-08-18 08:46:51.000000000 +0200 -+++ libgcrypt-1.6.2/random/rand-internal.h 2014-12-08 16:31:33.514992163 +0100 -@@ -88,6 +88,15 @@ gcry_err_code_t _gcry_rngfips_run_extern - char *buffer, size_t buflen); - void _gcry_rngfips_deinit_external_test (void *context); - -+/* drbg-gcry.h */ -+void _gcry_drbg_init(int full); -+void _gcry_drbg_close_fds(void); -+void _gcry_drbg_dump_stats(void); -+int _gcry_drbg_is_faked (void); -+gcry_error_t _gcry_drbg_add_bytes (const void *buf, size_t buflen, int quality); -+void _gcry_drbg_randomize (void *buffer, size_t length, -+ enum gcry_random_level level); -+gcry_error_t _gcry_drbg_selftest (selftest_report_func_t report); - - /*-- random-system.c --*/ - void _gcry_rngsystem_initialize (int full); -diff -up libgcrypt-1.6.2/random/random.c.drbg libgcrypt-1.6.2/random/random.c ---- libgcrypt-1.6.2/random/random.c.drbg 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/random/random.c 2014-12-08 16:31:33.514992163 +0100 -@@ -153,11 +153,11 @@ _gcry_random_initialize (int full) - } - - if (fips_mode ()) -- _gcry_rngfips_initialize (full); -+ _gcry_drbg_init(full); - else if (rng_types.standard) - _gcry_rngcsprng_initialize (full); - else if (rng_types.fips) -- _gcry_rngfips_initialize (full); -+ _gcry_drbg_init(full); - else if (rng_types.system) - _gcry_rngsystem_initialize (full); - else -@@ -174,11 +174,11 @@ _gcry_random_close_fds (void) - the entropy gatherer. */ - - if (fips_mode ()) -- _gcry_rngfips_close_fds (); -+ _gcry_drbg_close_fds (); - else if (rng_types.standard) - _gcry_rngcsprng_close_fds (); - else if (rng_types.fips) -- _gcry_rngfips_close_fds (); -+ _gcry_drbg_close_fds (); - else if (rng_types.system) - _gcry_rngsystem_close_fds (); - else -@@ -212,7 +212,7 @@ void - _gcry_random_dump_stats (void) - { - if (fips_mode ()) -- _gcry_rngfips_dump_stats (); -+ _gcry_drbg_dump_stats (); - else - _gcry_rngcsprng_dump_stats (); - } -@@ -271,7 +271,7 @@ int - _gcry_random_is_faked (void) - { - if (fips_mode ()) -- return _gcry_rngfips_is_faked (); -+ return _gcry_drbg_is_faked (); - else - return _gcry_rngcsprng_is_faked (); - } -@@ -301,11 +301,11 @@ static void - do_randomize (void *buffer, size_t length, enum gcry_random_level level) - { - if (fips_mode ()) -- _gcry_rngfips_randomize (buffer, length, level); -+ _gcry_drbg_randomize (buffer, length, level); - else if (rng_types.standard) - _gcry_rngcsprng_randomize (buffer, length, level); - else if (rng_types.fips) -- _gcry_rngfips_randomize (buffer, length, level); -+ _gcry_drbg_randomize (buffer, length, level); - else if (rng_types.system) - _gcry_rngsystem_randomize (buffer, length, level); - else /* default */ -@@ -437,7 +437,7 @@ _gcry_create_nonce (void *buffer, size_t - nonce generator which is seeded by the RNG actual in use. */ - if (fips_mode ()) - { -- _gcry_rngfips_create_nonce (buffer, length); -+ _gcry_drbg_randomize (buffer, length, GCRY_WEAK_RANDOM); - return; - } - -@@ -514,7 +514,7 @@ gpg_error_t - _gcry_random_selftest (selftest_report_func_t report) - { - if (fips_mode ()) -- return _gcry_rngfips_selftest (report); -+ return _gcry_drbg_selftest (report); - else - return 0; /* No selftests yet. */ - } -@@ -530,6 +530,7 @@ _gcry_random_init_external_test (void ** - const void *seed, size_t seedlen, - const void *dt, size_t dtlen) - { -+ return GPG_ERR_NOT_SUPPORTED; - (void)flags; - if (fips_mode ()) - return _gcry_rngfips_init_external_test (r_context, flags, key, keylen, -@@ -544,6 +545,7 @@ _gcry_random_init_external_test (void ** - gcry_err_code_t - _gcry_random_run_external_test (void *context, char *buffer, size_t buflen) - { -+ return GPG_ERR_NOT_SUPPORTED; - if (fips_mode ()) - return _gcry_rngfips_run_external_test (context, buffer, buflen); - else -@@ -554,6 +556,7 @@ _gcry_random_run_external_test (void *co - void - _gcry_random_deinit_external_test (void *context) - { -+ return; - if (fips_mode ()) - _gcry_rngfips_deinit_external_test (context); - } -diff -up libgcrypt-1.6.2/random/random.h.drbg libgcrypt-1.6.2/random/random.h ---- libgcrypt-1.6.2/random/random.h.drbg 2014-08-18 08:46:51.000000000 +0200 -+++ libgcrypt-1.6.2/random/random.h 2014-12-08 16:31:33.514992163 +0100 -@@ -54,7 +54,29 @@ gcry_err_code_t _gcry_random_run_externa - char *buffer, size_t buflen); - void _gcry_random_deinit_external_test (void *context); - -+/*-- drbg.c --*/ -+gpg_err_code_t _gcry_drbg_reinit (u32 flags, struct gcry_drbg_string *pers); -+/* private interfaces for testing of DRBG */ -+struct gcry_drbg_test_vector -+{ -+ u32 flags; -+ unsigned char *entropy; -+ size_t entropylen; -+ unsigned char *entpra; -+ unsigned char *entprb; -+ size_t entprlen; -+ unsigned char *addtla; -+ unsigned char *addtlb; -+ size_t addtllen; -+ unsigned char *pers; -+ size_t perslen; -+ unsigned char *expected; -+ size_t expectedlen; -+}; - -+gpg_err_code_t gcry_drbg_cavs_test (struct gcry_drbg_test_vector *test, -+ unsigned char *buf); -+gpg_err_code_t gcry_drbg_healthcheck_one (struct gcry_drbg_test_vector *test); - /*-- rndegd.c --*/ - gpg_error_t _gcry_rndegd_set_socket_name (const char *name); - -diff -up libgcrypt-1.6.2/src/gcrypt.h.in.drbg libgcrypt-1.6.2/src/gcrypt.h.in ---- libgcrypt-1.6.2/src/gcrypt.h.in.drbg 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/src/gcrypt.h.in 2014-12-08 16:31:33.515992186 +0100 -@@ -329,7 +329,9 @@ enum gcry_ctl_cmds - GCRYCTL_SET_CCM_LENGTHS = 69, - GCRYCTL_CLOSE_RANDOM_DEVICE = 70, - GCRYCTL_INACTIVATE_FIPS_FLAG = 71, -- GCRYCTL_REACTIVATE_FIPS_FLAG = 72 -+ GCRYCTL_REACTIVATE_FIPS_FLAG = 72, -+ GCRYCTL_DRBG_REINIT = 74 -+ /* Note: 75 is used internally */ - }; - - /* Perform various operations defined by CMD. */ -@@ -1668,6 +1670,110 @@ int gcry_is_secure (const void *a) _GCRY - /* Return true if Libgcrypt is in FIPS mode. */ - #define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0) - -+/* DRBG input data structure for DRBG generate with additional information -+ * string */ -+struct gcry_drbg_gen { -+ unsigned char *outbuf; /* output buffer for random numbers */ -+ unsigned int outlen; /* size of output buffer */ -+ struct gcry_drbg_string *addtl; /* input buffer for -+ * additional information string */ -+}; -+ -+/* -+ * Concatenation Helper and string operation helper -+ * -+ * SP800-90A requires the concatenation of different data. To avoid copying -+ * buffers around or allocate additional memory, the following data structure -+ * is used to point to the original memory with its size. In addition, it -+ * is used to build a linked list. The linked list defines the concatenation -+ * of individual buffers. The order of memory block referenced in that -+ * linked list determines the order of concatenation. -+ */ -+/* DRBG string definition */ -+struct gcry_drbg_string { -+ const unsigned char *buf; -+ size_t len; -+ struct gcry_drbg_string *next; -+}; -+ -+#define gcry_drbg_string_fill(s, b, l) \ -+do { \ -+ (s)->buf = (b); \ -+ (s)->len = (l); \ -+ (s)->next = NULL; \ -+} while (0) -+ -+/* this is a wrapper function for users of libgcrypt */ -+#define gcry_randomize_drbg(ob, ol, lvl, add) \ -+do { \ -+ struct gcry_drbg_gen genbuf; \ -+ genbuf.outbuf = (unsigned char *)(ob); \ -+ genbuf.outlen = (ol); \ -+ genbuf.addtl = (add); \ -+ gcry_randomize(&genbuf, 0, (lvl)); \ -+} while (0) -+ -+/* -+ * DRBG flags bitmasks -+ * -+ * 31 (B) 28 19 (A) 0 -+ * +-+-+-+--------+---+-----------+-----+ -+ * |~|~|u|~~~~~~~~| 3 | 2 | 1 | -+ * +-+-+-+--------+- -+-----------+-----+ -+ * ctl flg| |drbg use selection flags -+ * -+ */ -+ -+/* internal state control flags (B) */ -+#define GCRY_DRBG_PREDICTION_RESIST ((u_int32_t)1<<28) -+ -+/* CTR type modifiers (A.1)*/ -+#define GCRY_DRBG_CTRAES ((u_int32_t)1<<0) -+#define GCRY_DRBG_CTRSERPENT ((u_int32_t)1<<1) -+#define GCRY_DRBG_CTRTWOFISH ((u_int32_t)1<<2) -+#define GCRY_DRBG_CTR_MASK (GCRY_DRBG_CTRAES | GCRY_DRBG_CTRSERPENT | GCRY_DRBG_CTRTWOFISH) -+ -+/* HASH type modifiers (A.2)*/ -+#define GCRY_DRBG_HASHSHA1 ((u_int32_t)1<<4) -+#define GCRY_DRBG_HASHSHA224 ((u_int32_t)1<<5) -+#define GCRY_DRBG_HASHSHA256 ((u_int32_t)1<<6) -+#define GCRY_DRBG_HASHSHA384 ((u_int32_t)1<<7) -+#define GCRY_DRBG_HASHSHA512 ((u_int32_t)1<<8) -+#define GCRY_DRBG_HASH_MASK (GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HASHSHA224 | \ -+ GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HASHSHA384 | \ -+ GCRY_DRBG_HASHSHA512) -+/* type modifiers (A.3)*/ -+#define GCRY_DRBG_HMAC ((u_int32_t)1<<12) -+#define GCRY_DRBG_SYM128 ((u_int32_t)1<<13) -+#define GCRY_DRBG_SYM192 ((u_int32_t)1<<14) -+#define GCRY_DRBG_SYM256 ((u_int32_t)1<<15) -+#define GCRY_DRBG_TYPE_MASK (GCRY_DRBG_HMAC | GCRY_DRBG_SYM128 | GCRY_DRBG_SYM192 | \ -+ GCRY_DRBG_SYM256) -+#define GCRY_DRBG_CIPHER_MASK (GCRY_DRBG_CTR_MASK | GCRY_DRBG_HASH_MASK | GCRY_DRBG_TYPE_MASK) -+ -+#define GCRY_DRBG_PR_CTRAES128 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128) -+#define GCRY_DRBG_PR_CTRAES192 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192) -+#define GCRY_DRBG_PR_CTRAES256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256) -+#define GCRY_DRBG_NOPR_CTRAES128 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM128) -+#define GCRY_DRBG_NOPR_CTRAES192 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM192) -+#define GCRY_DRBG_NOPR_CTRAES256 (GCRY_DRBG_CTRAES | GCRY_DRBG_SYM256) -+#define GCRY_DRBG_PR_HASHSHA1 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA1) -+#define GCRY_DRBG_PR_HASHSHA256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA256) -+#define GCRY_DRBG_PR_HASHSHA384 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA384) -+#define GCRY_DRBG_PR_HASHSHA512 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA512) -+#define GCRY_DRBG_NOPR_HASHSHA1 (GCRY_DRBG_HASHSHA1) -+#define GCRY_DRBG_NOPR_HASHSHA256 (GCRY_DRBG_HASHSHA256) -+#define GCRY_DRBG_NOPR_HASHSHA384 (GCRY_DRBG_HASHSHA384) -+#define GCRY_DRBG_NOPR_HASHSHA512 (GCRY_DRBG_HASHSHA512) -+#define GCRY_DRBG_PR_HMACSHA1 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_PR_HMACSHA256 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_PR_HMACSHA384 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_PR_HMACSHA512 (GCRY_DRBG_PREDICTION_RESIST | GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_NOPR_HMACSHA1 (GCRY_DRBG_HASHSHA1 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_NOPR_HMACSHA256 (GCRY_DRBG_HASHSHA256 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_NOPR_HMACSHA384 (GCRY_DRBG_HASHSHA384 | GCRY_DRBG_HMAC) -+#define GCRY_DRBG_NOPR_HMACSHA512 (GCRY_DRBG_HASHSHA512 | GCRY_DRBG_HMAC) -+#define DRBG_NOPR_HMACSHA512 GCRY_DRBG_NOPR_HMACSHA512 /* deprecated leftover */ - - #if 0 /* (Keep Emacsens' auto-indent happy.) */ - { -diff -up libgcrypt-1.6.2/src/global.c.drbg libgcrypt-1.6.2/src/global.c ---- libgcrypt-1.6.2/src/global.c.drbg 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/src/global.c 2014-12-08 16:31:33.515992186 +0100 -@@ -680,6 +680,28 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - rc = GPG_ERR_NOT_IMPLEMENTED; - break; - -+ case GCRYCTL_DRBG_REINIT: -+ { -+ u32 flags = va_arg (arg_ptr, u32); -+ struct gcry_drbg_string *pers = va_arg (arg_ptr, -+ struct gcry_drbg_string *); -+ rc = _gcry_drbg_reinit(flags, pers); -+ } -+ break; -+ -+ case 75: -+ { -+ struct gcry_drbg_test_vector *test = -+ va_arg (arg_ptr, struct gcry_drbg_test_vector *); -+ unsigned char *buf = va_arg (arg_ptr, unsigned char *); -+ -+ if (buf) -+ rc = gcry_drbg_cavs_test (test, buf); -+ else -+ rc = gcry_drbg_healthcheck_one (test); -+ } -+ break; -+ - default: - _gcry_set_preferred_rng_type (0); - rc = GPG_ERR_INV_OP; diff --git a/libgcrypt-1.6.2-fips-reqs.patch b/libgcrypt-1.6.2-fips-reqs.patch deleted file mode 100644 index 4fa5f33..0000000 --- a/libgcrypt-1.6.2-fips-reqs.patch +++ /dev/null @@ -1,345 +0,0 @@ -diff -up libgcrypt-1.6.2/cipher/dsa.c.fips-reqs libgcrypt-1.6.2/cipher/dsa.c ---- libgcrypt-1.6.2/cipher/dsa.c.fips-reqs 2014-12-08 17:15:07.198102721 +0100 -+++ libgcrypt-1.6.2/cipher/dsa.c 2014-12-08 17:16:59.636645610 +0100 -@@ -66,42 +66,86 @@ static const char *dsa_names[] = - }; - - --/* A sample 1024 bit DSA key used for the selftests. */ -+/* A sample 2048 bit DSA key used for the selftests. */ - static const char sample_secret_key[] = - "(private-key" - " (dsa" --" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" --" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" --" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" --" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)" --" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)" --" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" --" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" --" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" --" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)" --" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" --" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" --" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" --" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)" --" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))"; --/* A sample 1024 bit DSA key used for the selftests (public only). */ -+" (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" -+" 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" -+" 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" -+" 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" -+" 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" -+" eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" -+" 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" -+" 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" -+" 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" -+" 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" -+" 2c8d7469db02e24d592394a7dba069e9#)" -+" (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" -+" 7441a0a5#)" -+" (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" -+" 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" -+" ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" -+" 0df242b75b414df372121e53a553f222f836b000f016485b" -+" 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" -+" 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" -+" 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" -+" ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" -+" 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" -+" 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" -+" 45f322f82e4e85ca3ab85591b3c2a966#)" -+" (y #2452f3ccbe9ed5ca7dc74c602b99226e8f2fab38e7d7ddfb" -+" 75539b17155e9fcfd1aba564eb8535d812c9c2dcf9728444" -+" 1bc482243624c7f457580c1c38a57c46c457392470edb52c" -+" b5a6e03fe6287bb6f49a42a2065a054f030839df1fd3149c" -+" 4ca0531dd8ca8aaa9cc7337193387348336118224545e88c" -+" 80ffd8765d74360333ccab9972779b6525a65bdd0d10c675" -+" c109bbd3e5be4d72ef6eba6e438d5226237db888379c5fcc" -+" 47a3847ff63711baed6d03afe81e694a413b680bd38ab490" -+" 3f8370a707ef551d4941026d9579d691de8edaa16105eb9d" -+" ba3c2f4c1bec508275aa0207e251b5eccb286a4b01d449d3" -+" 0acb673717a0d2fb3b50c893f7dab14f#)" -+" (x #0c4b3089d1b862cb3c436491f0915470c52796e3acbee800" -+" ec55f6cc#)))"; -+/* A sample 2048 bit DSA key used for the selftests (public only). */ - static const char sample_public_key[] = - "(public-key" - " (dsa" --" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" --" 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" --" CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" --" 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)" --" (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)" --" (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" --" AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" --" B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" --" 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)" --" (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" --" A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" --" 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" --" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))"; -- -+" (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" -+" 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" -+" 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" -+" 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" -+" 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" -+" eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" -+" 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" -+" 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" -+" 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" -+" 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" -+" 2c8d7469db02e24d592394a7dba069e9#)" -+" (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" -+" 7441a0a5#)" -+" (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" -+" 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" -+" ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" -+" 0df242b75b414df372121e53a553f222f836b000f016485b" -+" 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" -+" 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" -+" 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" -+" ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" -+" 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" -+" 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" -+" 45f322f82e4e85ca3ab85591b3c2a966#)" -+" (y #2452f3ccbe9ed5ca7dc74c602b99226e8f2fab38e7d7ddfb" -+" 75539b17155e9fcfd1aba564eb8535d812c9c2dcf9728444" -+" 1bc482243624c7f457580c1c38a57c46c457392470edb52c" -+" b5a6e03fe6287bb6f49a42a2065a054f030839df1fd3149c" -+" 4ca0531dd8ca8aaa9cc7337193387348336118224545e88c" -+" 80ffd8765d74360333ccab9972779b6525a65bdd0d10c675" -+" c109bbd3e5be4d72ef6eba6e438d5226237db888379c5fcc" -+" 47a3847ff63711baed6d03afe81e694a413b680bd38ab490" -+" 3f8370a707ef551d4941026d9579d691de8edaa16105eb9d" -+" ba3c2f4c1bec508275aa0207e251b5eccb286a4b01d449d3" -+" 0acb673717a0d2fb3b50c893f7dab14f#)))"; - - - -@@ -1164,14 +1208,14 @@ dsa_get_nbits (gcry_sexp_t parms) - */ - - static const char * --selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) -+selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey) - { - static const char sample_data[] = - "(data (flags raw)" -- " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))"; -+ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4f1e2d3c4b5a6978879605142#))"; - static const char sample_data_bad[] = - "(data (flags raw)" -- " (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))"; -+ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d401e2d3c4b5a6978879605142#))"; - - const char *errtxt = NULL; - gcry_error_t err; -@@ -1247,7 +1291,7 @@ selftests_dsa (selftest_report_func_t re - } - - what = "sign"; -- errtxt = selftest_sign_1024 (pkey, skey); -+ errtxt = selftest_sign (pkey, skey); - if (errtxt) - goto failed; - -diff -up libgcrypt-1.6.2/cipher/rsa.c.fips-reqs libgcrypt-1.6.2/cipher/rsa.c ---- libgcrypt-1.6.2/cipher/rsa.c.fips-reqs 2014-12-08 17:15:07.218103174 +0100 -+++ libgcrypt-1.6.2/cipher/rsa.c 2014-12-08 17:20:24.666282521 +0100 -@@ -62,33 +62,57 @@ static const char *rsa_names[] = - }; - - --/* A sample 1024 bit RSA key used for the selftests. */ -+/* A sample 2048 bit RSA key used for the selftests. */ - static const char sample_secret_key[] = - "(private-key" - " (rsa" --" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" --" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" --" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" --" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)" -+" (n #00c9d56d9d90db43d602ed9688138ab2bf6ea10610b27837a714a8ffdd00" -+" ddb493a045cc9690edada9ddc4d6ca0cf0ed4f725e21499a1812158f905a" -+" dbb63399a3e6b4f0c4972126bbe3baf2ffa072da89638e8b3e089d922abe" -+" 16e14315fc57c71f0911671ca996d18b3e8093c159d06d39f2ac95cc1075" -+" e93124d143af68524be716d749656f26c086adc0070ac1e12f8785863bdc" -+" 5a99bee9f9b9e98227510415ab060e765a288d92bdc5b57ba8df4e47a2c1" -+" e752bf47f762e03a6f4d6a4d4ed4b95969fab214c1eee62f95cd9472aee4" -+" db189ac4cd70bdee3116b74965ac40190eb56d83f136bb082f2e4e9262a4" -+" ff50db2045a2eb167af2d528c1fd4e0371#)" - " (e #010001#)" --" (d #046129f2489d71579be0a75fe029bd6cdb574ebf57ea8a5b0fda942cab943b11" --" 7d7bb95e5d28875e0f9fc5fcc06a72f6d502464dabded78ef6b716177b83d5bd" --" c543dc5d3fed932e59f5897e92e6f58a0f33424106a3b6fa2cbf877510e4ac21" --" c3ee47851e97d12996222ac3566d4ccb0b83d164074abf7de655fc2446da1781#)" --" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" --" fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)" --" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" --" 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)" --" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" --" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))"; --/* A sample 1024 bit RSA key used for the selftests (public only). */ -+" (d #03b1e24a94e50ab21f8619701ec97679be2cf8f733c9331d9e2974dba721" -+" 27e5def480290e78a769f96b19d28397a284868fb614ca9b1fb3a0d7efed" -+" df41451204ce71aceba659f6ed15964ebb317712364e1cfaf2fded77d658" -+" 8561acc49c97c2d7efe75f1534b35bd4f6561e1f468b45590db34553d4d0" -+" c2cb4d806b74e1b2c52740462538865d9792b0aefbbf7b9827f4b3badcb3" -+" 5adab638266a2d2fb8422a7a19142e08848e56af77a66c39b2afafa2e15b" -+" 1a7e4ed1f2c7ed350678c0465d86472af97371b13ef5058662f835ef9087" -+" f6cca8281bbf1b6b155c737b33d9e443350df85e7cc3b507231fb839f41f" -+" 02c654b29017f35d69007c70e13ba0e5#)" -+" (p #00ccbe7b096906ee45bf884738a8f817e5b6ba6755e3e8058bb8e253d68e" -+" ef2ce74f4af74e268d850b3fecc31cd4ebec6ac8722a257dfda67796f01e" -+" cd2857f83730756bbdd47b0c87c56c8740a5bb272c78c9745a545b0b306f" -+" 444afa71e4216166f9ee65de7c04d7fda9155b7fe27aba698672a6068d9b" -+" 9055609e4c5da9b655#)" -+" (q #00fc5c6e16ce1f037bcdf7b372b28f1672b856aef7cd67d84e7d07afd543" -+" 26c335be438f4e2f1c434e6bd2b2ec526d97522bcc5c3a6bf414c674da66" -+" 381c7a3f842fe3f95ab865694606a33779b2a15b58ed5ea75f8c6566bbd1" -+" 2436e637a73d49778a8c34d86929f34d5822b05124b640a886590ab7ba5c" -+" 97da57e836da7a9cad#)" -+" (u #2396c191175e0a83d2dc7b69b2591d3358523f18c709501cb9a1bb4ca238" -+" 404c9a8efe9c9092d0719f899950911f348b745311114a70e2f730d88c80" -+" e1cc9ff163171a7d67294ccb4e747be03e9e2ff4678fecb95c001e7ea27b" -+" 92c96f4ce40ef94863cd50225dbfb69d01336af450be86984fca3f3afacf" -+" 0740c4aaadaebebf#)))"; -+/* A sample 2048 bit RSA key used for the selftests (public only). */ - static const char sample_public_key[] = - "(public-key" - " (rsa" --" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" --" 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" --" ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" --" 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)" -+" (n #00c9d56d9d90db43d602ed9688138ab2bf6ea10610b27837a714a8ffdd00" -+" ddb493a045cc9690edada9ddc4d6ca0cf0ed4f725e21499a1812158f905a" -+" dbb63399a3e6b4f0c4972126bbe3baf2ffa072da89638e8b3e089d922abe" -+" 16e14315fc57c71f0911671ca996d18b3e8093c159d06d39f2ac95cc1075" -+" e93124d143af68524be716d749656f26c086adc0070ac1e12f8785863bdc" -+" 5a99bee9f9b9e98227510415ab060e765a288d92bdc5b57ba8df4e47a2c1" -+" e752bf47f762e03a6f4d6a4d4ed4b95969fab214c1eee62f95cd9472aee4" -+" db189ac4cd70bdee3116b74965ac40190eb56d83f136bb082f2e4e9262a4" -+" ff50db2045a2eb167af2d528c1fd4e0371#)" - " (e #010001#)))"; - - -@@ -1610,20 +1634,35 @@ compute_keygrip (gcry_md_hd_t md, gcry_s - */ - - static const char * --selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) -+selftest_sign (gcry_sexp_t pkey, gcry_sexp_t skey) - { - static const char sample_data[] = - "(data (flags pkcs1)" -- " (hash sha1 #11223344556677889900aabbccddeeff10203040#))"; -+ " (hash sha256 #11223344556677889900aabbccddeeffa0b0c0d0102030405060708090a1b1c1#))"; - static const char sample_data_bad[] = - "(data (flags pkcs1)" -- " (hash sha1 #11223344556677889900aabbccddeeff80203040#))"; -+ " (hash sha256 #11223344556677889900aabbccddeeffa0b0c0d0102030405060708091a1b1c1#))"; -+ static const char signature_ka[] = -+ "(sig-val \n" -+ " (rsa \n" -+ " (s #0B12D55738B099D401C81BEEDA54E045B4B7D9CDA5A8769E9C484F696A58912A" -+ "1E5DE7E5A2D181DA15A5C254D802AB75F1056E27406850AC7BE310BC32D2CED8" -+ "6697FE84508F7EFFF4D147C52E955A0873EF2F52ED71F2FC9C3C12D4045CB643" -+ "70158378E1494D8FBAD2248B9B64233D2CC2C1932B0531E539DEB07434B76D3B" -+ "6959E8A37E33B234C0C8C2C8FB1D00939239C9C491B2EBEED77BF952B597E11B" -+ "D4ED0C103D2B88BC78B4E505CF9D8D08B585CE3688D4FBE83ED58D1E1341AC4D" -+ "7C5EFF3CBC565CC7AE61C2F568426763A5239D31C1FFFD366984901679A343C4" -+ "01BB778BBA5E533B7875BA658A19AA9E56170F4A28E4322BF1621175FB06463E#)\n" -+ " )\n" -+ " )\n"; - - const char *errtxt = NULL; - gcry_error_t err; - gcry_sexp_t data = NULL; - gcry_sexp_t data_bad = NULL; - gcry_sexp_t sig = NULL; -+ char buf[1024]; -+ size_t len; - - err = sexp_sscan (&data, NULL, sample_data, strlen (sample_data)); - if (!err) -@@ -1641,6 +1680,12 @@ selftest_sign_1024 (gcry_sexp_t pkey, gc - errtxt = "signing failed"; - goto leave; - } -+ len = sexp_sprint (sig, GCRYSEXP_FMT_ADVANCED, buf, sizeof(buf)); -+ if (len != sizeof (signature_ka) - 1 || memcmp (buf, signature_ka, len) != 0) -+ { -+ errtxt = "signature KAT failed"; -+ goto leave; -+ } - err = _gcry_pk_verify (sig, data, pkey); - if (err) - { -@@ -1697,11 +1742,11 @@ extract_a_from_sexp (gcry_sexp_t encr_da - - - static const char * --selftest_encr_1024 (gcry_sexp_t pkey, gcry_sexp_t skey) -+selftest_encr (gcry_sexp_t pkey, gcry_sexp_t skey) - { - const char *errtxt = NULL; - gcry_error_t err; -- const unsigned int nbits = 1000; /* Encrypt 1000 random bits. */ -+ const unsigned int nbits = 2000; /* Encrypt 2000 random bits. */ - gcry_mpi_t plaintext = NULL; - gcry_sexp_t plain = NULL; - gcry_sexp_t encr = NULL; -@@ -1822,12 +1867,12 @@ selftests_rsa (selftest_report_func_t re - } - - what = "sign"; -- errtxt = selftest_sign_1024 (pkey, skey); -+ errtxt = selftest_sign (pkey, skey); - if (errtxt) - goto failed; - - what = "encrypt"; -- errtxt = selftest_encr_1024 (pkey, skey); -+ errtxt = selftest_encr (pkey, skey); - if (errtxt) - goto failed; - -diff -up libgcrypt-1.6.2/random/drbg.c.fips-reqs libgcrypt-1.6.2/random/drbg.c -diff -up libgcrypt-1.6.2/src/visibility.c.fips-reqs libgcrypt-1.6.2/src/visibility.c ---- libgcrypt-1.6.2/src/visibility.c.fips-reqs 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/src/visibility.c 2014-12-08 17:23:06.530943221 +0100 -@@ -1259,6 +1259,8 @@ gcry_kdf_derive (const void *passphrase, - unsigned long iterations, - size_t keysize, void *keybuffer) - { -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); - return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, - salt, saltlen, iterations, - keysize, keybuffer)); -@@ -1314,6 +1316,13 @@ void - gcry_mpi_randomize (gcry_mpi_t w, - unsigned int nbits, enum gcry_random_level level) - { -+ if (!fips_is_operational ()) -+ { -+ (void)fips_not_operational (); -+ fips_signal_fatal_error ("called in non-operational state"); -+ fips_noreturn (); -+ } -+ - _gcry_mpi_randomize (w, nbits, level); - } - -@@ -1339,6 +1348,8 @@ gcry_prime_generate (gcry_mpi_t *prime, - gcry_random_level_t random_level, - unsigned int flags) - { -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); - return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits, - factors, cb_func, cb_arg, - random_level, flags)); diff --git a/libgcrypt-1.6.2-fips-test.patch b/libgcrypt-1.6.2-fips-test.patch deleted file mode 100644 index b21d4a1..0000000 --- a/libgcrypt-1.6.2-fips-test.patch +++ /dev/null @@ -1,18 +0,0 @@ -diff -up libgcrypt-1.6.2/tests/basic.c.fips-test libgcrypt-1.6.2/tests/basic.c ---- libgcrypt-1.6.2/tests/basic.c.fips-test 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/tests/basic.c 2014-12-08 16:54:07.767619682 +0100 -@@ -582,6 +582,14 @@ check_ctr_cipher (void) - if (!tv[i].algo) - continue; - -+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ tv[i].algo); -+ continue; -+ } -+ - err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); - if (!err) - err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); diff --git a/libgcrypt-1.6.3-aliasing.patch b/libgcrypt-1.6.3-aliasing.patch deleted file mode 100644 index 9282944..0000000 --- a/libgcrypt-1.6.3-aliasing.patch +++ /dev/null @@ -1,177 +0,0 @@ -diff -up libgcrypt-1.6.3/cipher/bufhelp.h.aliasing libgcrypt-1.6.3/cipher/bufhelp.h ---- libgcrypt-1.6.3/cipher/bufhelp.h.aliasing 2015-02-27 10:54:03.000000000 +0100 -+++ libgcrypt-1.6.3/cipher/bufhelp.h 2015-03-13 15:03:43.301749751 +0100 -@@ -80,7 +80,7 @@ do_bytes: - for (; len; len--) - *dst++ = *src++; - #endif /*__GNUC__ >= 4 && (__x86_64__ || __i386__)*/ --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - /* Optimized function for buffer xoring */ -@@ -117,7 +117,7 @@ do_bytes: - /* Handle tail. */ - for (; len; len--) - *dst++ = *src1++ ^ *src2++; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - /* Optimized function for buffer xoring with two destination buffers. Used -@@ -155,7 +155,7 @@ do_bytes: - /* Handle tail. */ - for (; len; len--) - *dst1++ = (*dst2++ ^= *src++); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - /* Optimized function for combined buffer xoring and copying. Used by mainly -@@ -208,7 +208,7 @@ do_bytes: - *dst_xor++ = *srcdst_cpy ^ *src_xor++; - *srcdst_cpy++ = temp; - } --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - /* Optimized function for combined buffer xoring and copying. Used by mainly -@@ -234,7 +234,7 @@ buf_eq_const(const void *_a, const void - diff -= !!(a[i] - b[i]); - - return !diff; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - - #ifndef BUFHELP_FAST_UNALIGNED_ACCESS -@@ -246,14 +246,14 @@ static inline u32 buf_get_be32(const voi - const byte *in = _buf; - return ((u32)in[0] << 24) | ((u32)in[1] << 16) | \ - ((u32)in[2] << 8) | (u32)in[3]; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline u32 buf_get_le32(const void *_buf) - { - const byte *in = _buf; - return ((u32)in[3] << 24) | ((u32)in[2] << 16) | \ - ((u32)in[1] << 8) | (u32)in[0]; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_be32(void *_buf, u32 val) - { -@@ -262,7 +262,7 @@ static inline void buf_put_be32(void *_b - out[1] = val >> 16; - out[2] = val >> 8; - out[3] = val; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_le32(void *_buf, u32 val) - { -@@ -271,7 +271,7 @@ static inline void buf_put_le32(void *_b - out[2] = val >> 16; - out[1] = val >> 8; - out[0] = val; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - #ifdef HAVE_U64_TYPEDEF - /* Functions for loading and storing unaligned u64 values of different -@@ -283,7 +283,7 @@ static inline u64 buf_get_be64(const voi - ((u64)in[2] << 40) | ((u64)in[3] << 32) | \ - ((u64)in[4] << 24) | ((u64)in[5] << 16) | \ - ((u64)in[6] << 8) | (u64)in[7]; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline u64 buf_get_le64(const void *_buf) - { -@@ -292,7 +292,7 @@ static inline u64 buf_get_le64(const voi - ((u64)in[5] << 40) | ((u64)in[4] << 32) | \ - ((u64)in[3] << 24) | ((u64)in[2] << 16) | \ - ((u64)in[1] << 8) | (u64)in[0]; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_be64(void *_buf, u64 val) - { -@@ -305,7 +305,7 @@ static inline void buf_put_be64(void *_b - out[5] = val >> 16; - out[6] = val >> 8; - out[7] = val; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_le64(void *_buf, u64 val) - { -@@ -318,7 +318,7 @@ static inline void buf_put_le64(void *_b - out[2] = val >> 16; - out[1] = val >> 8; - out[0] = val; --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - #endif /*HAVE_U64_TYPEDEF*/ - - #else /*BUFHELP_FAST_UNALIGNED_ACCESS*/ -@@ -328,24 +328,24 @@ static inline void buf_put_le64(void *_b - static inline u32 buf_get_be32(const void *_buf) - { - return be_bswap32(*(const u32 *)_buf); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline u32 buf_get_le32(const void *_buf) - { - return le_bswap32(*(const u32 *)_buf); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_be32(void *_buf, u32 val) - { - u32 *out = _buf; - *out = be_bswap32(val); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_le32(void *_buf, u32 val) - { - u32 *out = _buf; - *out = le_bswap32(val); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - #ifdef HAVE_U64_TYPEDEF - /* Functions for loading and storing unaligned u64 values of different -@@ -353,24 +353,24 @@ static inline void buf_put_le32(void *_b - static inline u64 buf_get_be64(const void *_buf) - { - return be_bswap64(*(const u64 *)_buf); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline u64 buf_get_le64(const void *_buf) - { - return le_bswap64(*(const u64 *)_buf); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_be64(void *_buf, u64 val) - { - u64 *out = _buf; - *out = be_bswap64(val); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - - static inline void buf_put_le64(void *_buf, u64 val) - { - u64 *out = _buf; - *out = le_bswap64(val); --} -+} __attribute__ ((optimize("no-strict-aliasing"))) - #endif /*HAVE_U64_TYPEDEF*/ - - #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ diff --git a/libgcrypt-1.6.3-rsa-fips-keygen.patch b/libgcrypt-1.6.3-rsa-fips-keygen.patch deleted file mode 100644 index a229039..0000000 --- a/libgcrypt-1.6.3-rsa-fips-keygen.patch +++ /dev/null @@ -1,382 +0,0 @@ -Add FIPS 186-4 compliant RSA probable prime key generator. - -Signed-off-by: Tomáš Mráz - -diff -up libgcrypt-1.6.3/cipher/primegen.c.fips-keygen libgcrypt-1.6.3/cipher/primegen.c ---- libgcrypt-1.6.3/cipher/primegen.c.fips-keygen 2015-03-06 16:38:56.698052602 +0100 -+++ libgcrypt-1.6.3/cipher/primegen.c 2015-03-06 16:45:45.848193024 +0100 -@@ -1199,6 +1199,25 @@ _gcry_prime_check (gcry_mpi_t x, unsigne - return GPG_ERR_NO_PRIME; - } - -+/* Check whether the number X is prime according to FIPS 186-4 table C.2. */ -+gcry_err_code_t -+_gcry_fips186_4_prime_check (gcry_mpi_t x, unsigned int bits) -+{ -+ gcry_err_code_t ec = GPG_ERR_NO_ERROR; -+ -+ switch (mpi_cmp_ui (x, 2)) -+ { -+ case 0: return ec; /* 2 is a prime */ -+ case -1: return GPG_ERR_NO_PRIME; /* Only numbers > 1 are primes. */ -+ } -+ -+ /* We use 5 or 4 rounds as specified in table C.2 */ -+ if (! check_prime (x, mpi_const (MPI_C_TWO), bits > 1024 ? 4 : 5, NULL, NULL)) -+ ec = GPG_ERR_NO_PRIME; -+ -+ return ec; -+} -+ - /* Find a generator for PRIME where the factorization of (prime-1) is - in the NULL terminated array FACTORS. Return the generator as a - newly allocated MPI in R_G. If START_G is not NULL, use this as s -diff -up libgcrypt-1.6.3/cipher/rsa.c.fips-keygen libgcrypt-1.6.3/cipher/rsa.c ---- libgcrypt-1.6.3/cipher/rsa.c.fips-keygen 2015-03-06 16:38:56.661052411 +0100 -+++ libgcrypt-1.6.3/cipher/rsa.c 2015-03-06 16:38:56.699052607 +0100 -@@ -339,6 +339,279 @@ generate_std (RSA_secret_key *sk, unsign - } - - -+/**************** -+ * Generate a key pair with a key of size NBITS. -+ * USE_E = 0 let Libcgrypt decide what exponent to use. -+ * = 1 request the use of a "secure" exponent; this is required by some -+ * specification to be 65537. -+ * > 2 Use this public exponent. If the given exponent -+ * is not odd one is internally added to it. -+ * TESTPARMS: If set, do not generate but test whether the p,q is probably prime -+ * Returns key with zeroes to not break code calling this function. -+ * TRANSIENT_KEY: If true, generate the primes using the standard RNG. -+ * Returns: 2 structures filled with all needed values -+ */ -+static gpg_err_code_t -+generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, -+ gcry_sexp_t testparms, int transient_key) -+{ -+ gcry_mpi_t p, q; /* the two primes */ -+ gcry_mpi_t d; /* the private key */ -+ gcry_mpi_t u; -+ gcry_mpi_t p1, q1; -+ gcry_mpi_t n; /* the public key */ -+ gcry_mpi_t e; /* the exponent */ -+ gcry_mpi_t g; -+ gcry_mpi_t minp; -+ gcry_mpi_t diff, mindiff; -+ gcry_random_level_t random_level; -+ unsigned int pbits = nbits/2; -+ unsigned int i; -+ int pqswitch; -+ gpg_err_code_t ec = GPG_ERR_NO_PRIME; -+ -+ if (nbits < 1024 || (nbits & 0x1FF)) -+ return GPG_ERR_INV_VALUE; -+ if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072) -+ return GPG_ERR_INV_VALUE; -+ -+ /* The random quality depends on the transient_key flag. */ -+ random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM; -+ -+ if (testparms) -+ { -+ /* Parameters to derive the key are given. */ -+ /* Note that we explicitly need to setup the values of tbl -+ because some compilers (e.g. OpenWatcom, IRIX) don't allow -+ to initialize a structure with automatic variables. */ -+ struct { const char *name; gcry_mpi_t *value; } tbl[] = { -+ { "e" }, -+ { "p" }, -+ { "q" }, -+ { NULL } -+ }; -+ int idx; -+ gcry_sexp_t oneparm; -+ -+ tbl[0].value = &e; -+ tbl[1].value = &p; -+ tbl[2].value = &q; -+ -+ for (idx=0; tbl[idx].name; idx++) -+ { -+ oneparm = sexp_find_token (testparms, tbl[idx].name, 0); -+ if (oneparm) -+ { -+ *tbl[idx].value = sexp_nth_mpi (oneparm, 1, -+ GCRYMPI_FMT_USG); -+ sexp_release (oneparm); -+ } -+ } -+ for (idx=0; tbl[idx].name; idx++) -+ if (!*tbl[idx].value) -+ break; -+ if (tbl[idx].name) -+ { -+ /* At least one parameter is missing. */ -+ for (idx=0; tbl[idx].name; idx++) -+ _gcry_mpi_release (*tbl[idx].value); -+ return GPG_ERR_MISSING_VALUE; -+ } -+ } -+ else -+ { -+ if (use_e < 65537) -+ use_e = 65537; /* This is the smallest value allowed by FIPS */ -+ -+ e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB ); -+ -+ use_e |= 1; /* make sure this is odd */ -+ mpi_set_ui (e, use_e); -+ -+ p = mpi_snew (pbits); -+ q = mpi_snew (pbits); -+ } -+ -+ n = mpi_new (nbits); -+ d = mpi_snew (nbits); -+ u = mpi_snew (nbits); -+ -+ /* prepare approximate minimum p and q */ -+ minp = mpi_new (pbits); -+ mpi_set_ui (minp, 0xB504F334); -+ mpi_lshift (minp, minp, pbits - 32); -+ -+ /* prepare minimum p and q difference */ -+ diff = mpi_new (pbits); -+ mindiff = mpi_new (pbits - 99); -+ mpi_set_ui (mindiff, 1); -+ mpi_lshift (mindiff, mindiff, pbits - 100); -+ -+ p1 = mpi_snew (pbits); -+ q1 = mpi_snew (pbits); -+ g = mpi_snew (pbits); -+ -+retry: -+ /* generate p and q */ -+ for (i = 0; i < 5 * pbits; i++) -+ { -+ ploop: -+ if (!testparms) -+ { -+ _gcry_mpi_randomize (p, pbits, random_level); -+ } -+ if (mpi_cmp (p, minp) < 0) -+ { -+ if (testparms) goto err; -+ goto ploop; -+ } -+ -+ mpi_sub_ui (p1, p, 1); -+ if (mpi_gcd (g, p1, e)) -+ { -+ if (_gcry_fips186_4_prime_check (p, pbits) != GPG_ERR_NO_ERROR) -+ { -+ /* not a prime */ -+ if (testparms) goto err; -+ } -+ else -+ break; -+ } -+ else if (testparms) goto err; -+ } -+ if (i >= 5 * pbits) -+ goto err; -+ -+ for (i = 0; i < 5 * pbits; i++) -+ { -+ qloop: -+ if (!testparms) -+ { -+ _gcry_mpi_randomize (q, pbits, random_level); -+ } -+ if (mpi_cmp (q, minp) < 0) -+ { -+ if (testparms) goto err; -+ goto qloop; -+ } -+ if (mpi_cmp (p, q) > 0) -+ { -+ pqswitch = 1; -+ mpi_sub (diff, p, q); -+ } -+ else -+ { -+ pqswitch = 0; -+ mpi_sub (diff, q, p); -+ } -+ if (mpi_cmp (diff, mindiff) < 0) -+ { -+ if (testparms) goto err; -+ goto qloop; -+ } -+ -+ mpi_sub_ui (q1, q, 1); -+ if (mpi_gcd (g, q1, e)) -+ { -+ if (_gcry_fips186_4_prime_check (q, pbits) != GPG_ERR_NO_ERROR) -+ { -+ /* not a prime */ -+ if (testparms) goto err; -+ } -+ else -+ break; -+ } -+ else if (testparms) goto err; -+ } -+ if (i >= 5 * pbits) -+ goto err; -+ -+ if (testparms) -+ { -+ mpi_clear (p); -+ mpi_clear (q); -+ } -+ else -+ { -+ gcry_mpi_t f; -+ -+ if (pqswitch) -+ { -+ gcry_mpi_t tmp; -+ -+ tmp = p; -+ p = q; -+ q = tmp; -+ } -+ -+ f = mpi_snew (nbits); -+ -+ /* calculate the modulus */ -+ mpi_mul(n, p, q); -+ -+ /* calculate the secret key d = e^1 mod phi */ -+ mpi_gcd (g, p1, q1); -+ mpi_fdiv_q (f, p1, g); -+ mpi_mul (f, f, q1); -+ -+ mpi_invm (d, e, f); -+ -+ _gcry_mpi_release (f); -+ -+ if (mpi_get_nbits (d) < pbits) goto retry; -+ -+ /* calculate the inverse of p and q (used for chinese remainder theorem)*/ -+ mpi_invm(u, p, q ); -+ } -+ -+ ec = 0; -+ -+ if( DBG_CIPHER ) -+ { -+ log_mpidump(" p= ", p ); -+ log_mpidump(" q= ", q ); -+ log_mpidump(" n= ", n ); -+ log_mpidump(" e= ", e ); -+ log_mpidump(" d= ", d ); -+ log_mpidump(" u= ", u ); -+ } -+ -+err: -+ -+ _gcry_mpi_release (p1); -+ _gcry_mpi_release (q1); -+ _gcry_mpi_release (g); -+ _gcry_mpi_release (minp); -+ _gcry_mpi_release (mindiff); -+ _gcry_mpi_release (diff); -+ -+ sk->n = n; -+ sk->e = e; -+ sk->p = p; -+ sk->q = q; -+ sk->d = d; -+ sk->u = u; -+ -+ /* Now we can test our keys. */ -+ if (ec || (!testparms && test_keys (sk, nbits - 64))) -+ { -+ _gcry_mpi_release (sk->n); sk->n = NULL; -+ _gcry_mpi_release (sk->e); sk->e = NULL; -+ _gcry_mpi_release (sk->p); sk->p = NULL; -+ _gcry_mpi_release (sk->q); sk->q = NULL; -+ _gcry_mpi_release (sk->d); sk->d = NULL; -+ _gcry_mpi_release (sk->u); sk->u = NULL; -+ if (!ec) -+ { -+ fips_signal_error ("self-test after key generation failed"); -+ return GPG_ERR_SELFTEST_FAILED; -+ } -+ } -+ -+ return ec; -+} -+ -+ - /* Helper for generate_x931. */ - static gcry_mpi_t - gen_x931_parm_xp (unsigned int nbits) -@@ -799,7 +1072,7 @@ rsa_generate (const gcry_sexp_t genparms - } - } - -- if (deriveparms || (flags & PUBKEY_FLAG_USE_X931) || fips_mode ()) -+ if (deriveparms || (flags & PUBKEY_FLAG_USE_X931)) - { - int swapped; - ec = generate_x931 (&sk, nbits, evalue, deriveparms, &swapped); -@@ -819,9 +1092,14 @@ rsa_generate (const gcry_sexp_t genparms - sexp_release (l1); - } - } -+ deriveparms = (genparms? -+ sexp_find_token (genparms, "test-parms", 0) : NULL); - /* Generate. */ -- ec = generate_std (&sk, nbits, evalue, -- !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); -+ if (deriveparms || fips_mode()) -+ ec = generate_fips (&sk, nbits, evalue, deriveparms, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); -+ else -+ ec = generate_std (&sk, nbits, evalue, !!(flags & PUBKEY_FLAG_TRANSIENT_KEY)); -+ sexp_release (deriveparms); - } - - if (!ec) -diff -up libgcrypt-1.6.3/src/g10lib.h.fips-keygen libgcrypt-1.6.3/src/g10lib.h ---- libgcrypt-1.6.3/src/g10lib.h.fips-keygen 2015-02-23 11:55:58.000000000 +0100 -+++ libgcrypt-1.6.3/src/g10lib.h 2015-03-06 16:38:56.699052607 +0100 -@@ -259,6 +259,9 @@ gpg_err_code_t _gcry_generate_fips186_3_ - int *r_counter, - void **r_seed, size_t *r_seedlen, int *r_hashalgo); - -+gpg_err_code_t _gcry_fips186_4_prime_check -+ (const gcry_mpi_t x, unsigned int bits); -+ - - /* Replacements of missing functions (missing-string.c). */ - #ifndef HAVE_STPCPY -diff -up libgcrypt-1.6.3/tests/keygen.c.fips-keygen libgcrypt-1.6.3/tests/keygen.c ---- libgcrypt-1.6.3/tests/keygen.c.fips-keygen 2015-03-06 16:38:56.661052411 +0100 -+++ libgcrypt-1.6.3/tests/keygen.c 2015-03-06 16:38:56.699052607 +0100 -@@ -215,12 +215,12 @@ check_rsa_keys (void) - - - if (verbose) -- show ("creating 1024 bit RSA key with e=257\n"); -+ show ("creating 1024 bit RSA key with e=65539\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" - " (nbits 4:1024)\n" -- " (rsa-use-e 3:257)\n" -+ " (rsa-use-e 5:65539)\n" - " ))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gpg_strerror (rc)); -@@ -229,7 +229,7 @@ check_rsa_keys (void) - if (rc) - die ("error generating RSA key: %s\n", gpg_strerror (rc)); - -- check_generated_rsa_key (key, 257); -+ check_generated_rsa_key (key, 65539); - gcry_sexp_release (key); - - if (verbose) diff --git a/libgcrypt-1.6.5-leak.patch b/libgcrypt-1.6.5-leak.patch deleted file mode 100644 index df51187..0000000 --- a/libgcrypt-1.6.5-leak.patch +++ /dev/null @@ -1,27 +0,0 @@ -diff -up libgcrypt-1.6.5/cipher/primegen.c.leak libgcrypt-1.6.5/cipher/primegen.c ---- libgcrypt-1.6.5/cipher/primegen.c.leak 2016-07-21 11:06:32.783421204 +0200 -+++ libgcrypt-1.6.5/cipher/primegen.c 2016-07-21 11:06:32.789421337 +0200 -@@ -1208,10 +1208,7 @@ _gcry_prime_group_generator (gcry_mpi_t - gcry_mpi_t prime, gcry_mpi_t *factors, - gcry_mpi_t start_g) - { -- gcry_mpi_t tmp = mpi_new (0); -- gcry_mpi_t b = mpi_new (0); -- gcry_mpi_t pmin1 = mpi_new (0); -- gcry_mpi_t g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); -+ gcry_mpi_t tmp, b, pmin1, g; - int first = 1; - int i, n; - -@@ -1224,6 +1221,11 @@ _gcry_prime_group_generator (gcry_mpi_t - if (n < 2) - return GPG_ERR_INV_ARG; - -+ tmp = mpi_new (0); -+ b = mpi_new (0); -+ pmin1 = mpi_new (0); -+ g = start_g? mpi_copy (start_g) : mpi_set_ui (NULL, 3); -+ - /* Extra sanity check - usually disabled. */ - /* mpi_set (tmp, factors[0]); */ - /* for(i = 1; i < n; i++) */ diff --git a/libgcrypt-1.7.3-aliasing.patch b/libgcrypt-1.7.3-aliasing.patch new file mode 100644 index 0000000..5fa3b9b --- /dev/null +++ b/libgcrypt-1.7.3-aliasing.patch @@ -0,0 +1,24 @@ +diff -up libgcrypt-1.7.3/cipher/bufhelp.h.aliasing libgcrypt-1.7.3/cipher/bufhelp.h +--- libgcrypt-1.7.3/cipher/bufhelp.h.aliasing 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.7.3/cipher/bufhelp.h 2016-11-22 17:00:13.065692916 +0100 +@@ -35,6 +35,11 @@ + # define BUFHELP_FAST_UNALIGNED_ACCESS 1 + #endif + ++#if _GCRY_GCC_VERSION >= 40400 ++# pragma GCC push_options ++# pragma GCC optimize ("no-strict-aliasing") ++#endif ++ + + #ifdef BUFHELP_FAST_UNALIGNED_ACCESS + /* Define type with one-byte alignment on architectures with fast unaligned +@@ -429,4 +434,8 @@ static inline void buf_put_le64(void *_b + + #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ + ++#if _GCRY_GCC_VERSION >= 40400 ++# pragma GCC pop_options ++#endif ++ + #endif /*GCRYPT_BUFHELP_H*/ diff --git a/libgcrypt-1.7.3-ecc-test-fix.patch b/libgcrypt-1.7.3-ecc-test-fix.patch new file mode 100644 index 0000000..229d9f1 --- /dev/null +++ b/libgcrypt-1.7.3-ecc-test-fix.patch @@ -0,0 +1,158 @@ +diff -up libgcrypt-1.7.3/tests/basic.c.eccfix libgcrypt-1.7.3/tests/basic.c +--- libgcrypt-1.7.3/tests/basic.c.eccfix 2016-04-15 09:42:06.000000000 +0200 ++++ libgcrypt-1.7.3/tests/basic.c 2016-11-22 18:43:19.732897206 +0100 +@@ -8506,6 +8506,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex + /* */ "000102030405060708090A0B0C0D0E0F#))", + 0 + }, ++#if 0 + { 256, + "(data (flags gost)\n" + " (value #00112233445566778899AABBCCDDEEFF" +@@ -8530,6 +8531,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex + /* */ "000102030405060708090A0B0C0D0E0F#))", + 0 + }, ++#endif + { 0, NULL } + }; + +@@ -9136,6 +9138,7 @@ check_pubkey (void) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } + }, ++#if 0 + { /* GOST R 34.10-2001/2012 test 256 bit. */ + GCRY_PK_ECDSA, FLAG_SIGN, + { +@@ -9187,6 +9190,7 @@ check_pubkey (void) + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } + }, ++#endif + { /* secp256k1 test 256 bit. */ + GCRY_PK_ECDSA, FLAG_SIGN, + { +diff -up libgcrypt-1.7.3/tests/benchmark.c.eccfix libgcrypt-1.7.3/tests/benchmark.c +--- libgcrypt-1.7.3/tests/benchmark.c.eccfix 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/tests/benchmark.c 2016-11-22 16:21:00.109004197 +0100 +@@ -1412,8 +1412,7 @@ ecc_bench (int iterations, int print_hea + { + #if USE_ECC + gpg_error_t err; +- const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", +- "gost256", "gost512" }; ++ const char *p_sizes[] = { "224", "256", "384", "521", "Ed25519" }; + int testno; + + if (print_header) +diff -up libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix libgcrypt-1.7.3/tests/dsa-rfc6979.c +--- libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix 2016-02-18 09:38:03.000000000 +0100 ++++ libgcrypt-1.7.3/tests/dsa-rfc6979.c 2016-11-22 16:22:11.804674008 +0100 +@@ -210,16 +210,6 @@ check_dsa_rfc6979 (void) + " ))" + }, + { +- "ECDSA, 192 bits (prime field)", +- "(private-key" +- " (ecdsa" +- " (curve \"NIST P-192\")" +- " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" +- " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" +- " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" +- " ))" +- }, +- { + "ECDSA, 224 bits (prime field)", + "(private-key" + " (ecdsa" +@@ -443,89 +433,6 @@ check_dsa_rfc6979 (void) + "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1" + }, + { +- "ECDSA, 192 bits (prime field)", +- "With SHA-1, message = \"sample\"", +- "sha1", "sample", +- "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", +- "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", +- "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-224, message = \"sample\"", +- "sha224", "sample", +- "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8", +- "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", +- "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-256, message = \"sample\"", +- "sha256", "sample", +- "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", +- "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", +- "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-384, message = \"sample\"", +- "sha384", "sample", +- "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311", +- "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", +- "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-512, message = \"sample\"", +- "sha512", "sample", +- "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", +- "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", +- "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-1, message = \"test\"", +- "sha1", "test", +- "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", +- "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", +- "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-224, message = \"test\"", +- "sha224", "test", +- "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE", +- "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", +- "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-256, message = \"test\"", +- "sha256", "test", +- "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", +- "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", +- "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-384, message = \"test\"", +- "sha384", "test", +- "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693", +- "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", +- "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A" +- }, +- { +- "ECDSA, 192 bits (prime field)", +- "With SHA-512, message = \"test\"", +- "sha512", "test", +- "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", +- "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", +- "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290" +- }, +- +- +- +- { + "ECDSA, 224 bits (prime field)", + "With SHA-1, message = \"sample\"", + "sha1", "sample", diff --git a/libgcrypt-1.6.2-fips-cavs.patch b/libgcrypt-1.7.3-fips-cavs.patch similarity index 89% rename from libgcrypt-1.6.2-fips-cavs.patch rename to libgcrypt-1.7.3-fips-cavs.patch index 52067b0..42d028e 100644 --- a/libgcrypt-1.6.2-fips-cavs.patch +++ b/libgcrypt-1.7.3-fips-cavs.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.5.3/tests/cavs_driver.pl.cavs libgcrypt-1.5.3/tests/cavs_driver.pl ---- libgcrypt-1.5.3/tests/cavs_driver.pl.cavs 2013-05-22 18:02:55.000000000 +0200 -+++ libgcrypt-1.5.3/tests/cavs_driver.pl 2014-10-21 09:38:34.250691408 +0200 +diff -up libgcrypt-1.7.3/tests/cavs_driver.pl.cavs libgcrypt-1.7.3/tests/cavs_driver.pl +--- libgcrypt-1.7.3/tests/cavs_driver.pl.cavs 2013-03-15 20:25:38.000000000 +0100 ++++ libgcrypt-1.7.3/tests/cavs_driver.pl 2016-11-22 17:29:06.067553077 +0100 @@ -1,9 +1,11 @@ #!/usr/bin/env perl # @@ -862,9 +862,9 @@ diff -up libgcrypt-1.5.3/tests/cavs_driver.pl.cavs libgcrypt-1.5.3/tests/cavs_dr } else { die "Invalid interface option given"; } -diff -up libgcrypt-1.5.3/tests/cavs_tests.sh.cavs libgcrypt-1.5.3/tests/cavs_tests.sh ---- libgcrypt-1.5.3/tests/cavs_tests.sh.cavs 2013-05-22 18:02:55.000000000 +0200 -+++ libgcrypt-1.5.3/tests/cavs_tests.sh 2014-09-26 17:45:38.434674884 +0200 +diff -up libgcrypt-1.7.3/tests/cavs_tests.sh.cavs libgcrypt-1.7.3/tests/cavs_tests.sh +--- libgcrypt-1.7.3/tests/cavs_tests.sh.cavs 2013-03-15 20:25:38.000000000 +0100 ++++ libgcrypt-1.7.3/tests/cavs_tests.sh 2016-11-22 17:29:06.067553077 +0100 @@ -55,7 +55,7 @@ function run_one_test () { [ -d "$respdir" ] || mkdir "$respdir" [ -f "$rspfile" ] && rm "$rspfile" @@ -874,10 +874,10 @@ diff -up libgcrypt-1.5.3/tests/cavs_tests.sh.cavs libgcrypt-1.5.3/tests/cavs_tes dflag="-D" fi -diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c ---- libgcrypt-1.5.3/tests/fipsdrv.c.cavs 2013-07-25 11:10:04.000000000 +0200 -+++ libgcrypt-1.5.3/tests/fipsdrv.c 2014-10-21 09:30:30.796777225 +0200 -@@ -893,6 +893,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) +diff -up libgcrypt-1.7.3/tests/fipsdrv.c.cavs libgcrypt-1.7.3/tests/fipsdrv.c +--- libgcrypt-1.7.3/tests/fipsdrv.c.cavs 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/tests/fipsdrv.c 2016-11-22 17:33:15.468330859 +0100 +@@ -892,6 +892,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); p = buf; @@ -887,77 +887,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) p += 2; -@@ -1346,6 +1349,69 @@ run_rsa_derive (const void *data, size_t - } - - -+/* Generate RSA key using the S-expression in (DATA,DATALEN). This -+ S-expression is used directly as input to gcry_pk_genkey. The -+ result is printed to stdout with one parameter per line in hex -+ format and in this order: e, p, q, n, d. */ -+static void -+run_rsa_keygen (const void *data, size_t datalen, int test) -+{ -+ gpg_error_t err; -+ gcry_sexp_t s_keyspec, s_key, s_top, l1; -+ gcry_mpi_t mpi; -+ const char *parmlist; -+ int idx; -+ -+ if (!datalen) -+ err = gpg_error (GPG_ERR_NO_DATA); -+ else -+ err = gcry_sexp_new (&s_keyspec, data, datalen, 1); -+ if (err) -+ die ("gcry_sexp_new failed for RSA key generation: %s\n", -+ gpg_strerror (err)); -+ -+ err = gcry_pk_genkey (&s_key, s_keyspec); -+ -+ gcry_sexp_release (s_keyspec); -+ -+ if (test) { -+ if (err) -+ printf("F\n"); -+ else { -+ gcry_sexp_release (s_key); -+ printf("P\n"); -+ } -+ return; -+ } -+ -+ if (err) -+ die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); -+ -+ parmlist = "epqnd"; -+ -+ /* Parse and print the parameters. */ -+ l1 = gcry_sexp_find_token (s_key, "private-key", 0); -+ s_top = gcry_sexp_find_token (l1, "rsa", 0); -+ gcry_sexp_release (l1); -+ if (!s_top) -+ die ("private-key part not found in result\n"); -+ -+ for (idx=0; parmlist[idx]; idx++) -+ { -+ l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1); -+ mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); -+ gcry_sexp_release (l1); -+ if (!mpi) -+ die ("parameter %c missing in private-key\n", parmlist[idx]); -+ print_mpi_line (mpi, 1); -+ gcry_mpi_release (mpi); -+ } -+ -+ gcry_sexp_release (s_top); -+ gcry_sexp_release (s_key); -+} -+ -+ - - static size_t - compute_tag_length (size_t n) -@@ -1675,14 +1741,14 @@ run_rsa_verify (const void *data, size_t +@@ -1765,14 +1768,14 @@ run_rsa_verify (const void *data, size_t /* Generate a DSA key of size KEYSIZE and return the complete S-expression. */ static gcry_sexp_t @@ -975,7 +905,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c if (err) die ("gcry_sexp_build failed for DSA key generation: %s\n", gpg_strerror (err)); -@@ -1700,7 +1766,7 @@ dsa_gen (int keysize) +@@ -1790,7 +1793,7 @@ dsa_gen (int keysize) /* Generate a DSA key of size KEYSIZE and return the complete S-expression. */ static gcry_sexp_t @@ -984,7 +914,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c { gpg_error_t err; gcry_sexp_t keyspec, key; -@@ -1709,10 +1775,11 @@ dsa_gen_with_seed (int keysize, const vo +@@ -1799,10 +1802,11 @@ dsa_gen_with_seed (int keysize, const vo "(genkey" " (dsa" " (nbits %d)" @@ -998,7 +928,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c if (err) die ("gcry_sexp_build failed for DSA key generation: %s\n", gpg_strerror (err)); -@@ -1720,6 +1787,37 @@ dsa_gen_with_seed (int keysize, const vo +@@ -1810,6 +1814,37 @@ dsa_gen_with_seed (int keysize, const vo err = gcry_pk_genkey (&key, keyspec); if (err) die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); @@ -1036,7 +966,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c gcry_sexp_release (keyspec); -@@ -1732,7 +1830,7 @@ dsa_gen_with_seed (int keysize, const vo +@@ -1849,7 +1884,7 @@ ecdsa_gen_key (const char *curve) with one parameter per line in hex format using this order: p, q, g, seed, counter, h. */ static void @@ -1045,7 +975,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c { gcry_sexp_t l1, l2; gcry_mpi_t mpi; -@@ -1768,6 +1866,9 @@ print_dsa_domain_parameters (gcry_sexp_t +@@ -1885,6 +1920,9 @@ print_dsa_domain_parameters (gcry_sexp_t } gcry_sexp_release (l1); @@ -1055,7 +985,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c /* Extract the seed values. */ l1 = gcry_sexp_find_token (key, "misc-key-info", 0); if (!l1) -@@ -1819,38 +1920,106 @@ print_dsa_domain_parameters (gcry_sexp_t +@@ -1976,38 +2014,106 @@ print_ecdsa_dq (gcry_sexp_t key) } @@ -1172,7 +1102,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c fp = fopen (filename, "wb"); if (!fp) -@@ -1863,6 +2032,53 @@ run_dsa_gen (int keysize, const char *fi +@@ -2020,6 +2126,53 @@ run_dsa_gen (int keysize, const char *fi } @@ -1226,7 +1156,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c /* Sign DATA of length DATALEN using the key taken from the S-expression encoded KEYFILE. */ -@@ -1872,11 +2088,16 @@ run_dsa_sign (const void *data, size_t d +@@ -2029,11 +2182,16 @@ run_dsa_sign (const void *data, size_t d { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; @@ -1234,19 +1164,19 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c + char hash[128]; gcry_mpi_t tmpmpi; + int algo; ++ ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); - err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); -+ + gcry_md_hash_buffer (algo, hash, data, datalen); + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, + gcry_md_get_algo_dlen(algo), NULL); if (!err) { err = gcry_sexp_build (&s_data, NULL, -@@ -1887,8 +2108,6 @@ run_dsa_sign (const void *data, size_t d +@@ -2044,8 +2202,6 @@ run_dsa_sign (const void *data, size_t d die ("gcry_sexp_build failed for DSA data input: %s\n", gpg_strerror (err)); @@ -1255,7 +1185,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c err = gcry_pk_sign (&s_sig, s_data, s_key); if (err) { -@@ -1964,13 +2183,18 @@ run_dsa_verify (const void *data, size_t +@@ -2121,13 +2277,18 @@ run_dsa_verify (const void *data, size_t { gpg_error_t err; gcry_sexp_t s_data, s_key, s_sig; @@ -1263,11 +1193,11 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c + char hash[128]; gcry_mpi_t tmpmpi; + int algo; -+ -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); - gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); ++ s_key = read_sexp_from_file (keyfile); ++ algo = dsa_hash_from_key(s_key); ++ + gcry_md_hash_buffer (algo, hash, data, datalen); /* Note that we can't simply use %b with HASH to build the S-expression, because that might yield a negative value. */ @@ -1277,7 +1207,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c if (!err) { err = gcry_sexp_build (&s_data, NULL, -@@ -1981,7 +2205,6 @@ run_dsa_verify (const void *data, size_t +@@ -2138,7 +2299,6 @@ run_dsa_verify (const void *data, size_t die ("gcry_sexp_build failed for DSA data input: %s\n", gpg_strerror (err)); @@ -1285,24 +1215,24 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c s_sig = read_sexp_from_file (sigfile); err = gcry_pk_verify (s_sig, s_data, s_key); -@@ -2014,7 +2237,7 @@ usage (int show_help) - "Run a crypto operation using hex encoded input and output.\n" +@@ -2304,7 +2464,7 @@ usage (int show_help) "MODE:\n" " encrypt, decrypt, digest, random, hmac-sha,\n" -- " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" -+ " rsa-{derive,gen,sign,verify}, dsa-{pq-gen,g-gen,gen,sign,verify}\n" + " rsa-{derive,gen,sign,verify},\n" +- " dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" ++ " dsa-{pq-gen,g-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" "OPTIONS:\n" " --verbose Print additional information\n" " --binary Input and output is in binary form\n" -@@ -2024,6 +2247,7 @@ usage (int show_help) - " --dt DT Use the hex encoded DT for the RNG\n" +@@ -2315,6 +2475,7 @@ usage (int show_help) " --algo NAME Use algorithm NAME\n" + " --curve NAME Select ECC curve spec NAME\n" " --keysize N Use a keysize of N bits\n" + " --qize N Use a DSA q parameter size of N bits\n" " --signature NAME Take signature from file NAME\n" " --chunk N Read in chunks of N bytes (implies --binary)\n" " --pkcs1 Use PKCS#1 encoding\n" -@@ -2050,6 +2274,7 @@ main (int argc, char **argv) +@@ -2344,6 +2505,7 @@ main (int argc, char **argv) const char *dt_string = NULL; const char *algo_string = NULL; const char *keysize_string = NULL; @@ -1310,7 +1240,7 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c const char *signature_string = NULL; FILE *input; void *data; -@@ -2143,6 +2368,14 @@ main (int argc, char **argv) +@@ -2437,6 +2599,14 @@ main (int argc, char **argv) keysize_string = *argv; argc--; argv++; } @@ -1325,36 +1255,16 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c else if (!strcmp (*argv, "--signature")) { argc--; argv++; -@@ -2406,6 +2639,18 @@ main (int argc, char **argv) - die ("no data available (do not use --chunk)\n"); - run_rsa_derive (data, datalen); - } -+ else if (!strcmp (mode_string, "rsa-keygen")) -+ { -+ if (!data) -+ die ("no data available (do not use --chunk)\n"); -+ run_rsa_keygen (data, datalen, 0); -+ } -+ else if (!strcmp (mode_string, "rsa-keygen-kat")) -+ { -+ if (!data) -+ die ("no data available (do not use --chunk)\n"); -+ run_rsa_keygen (data, datalen, 1); -+ } - else if (!strcmp (mode_string, "rsa-gen")) - { - int keysize; -@@ -2463,23 +2708,49 @@ main (int argc, char **argv) +@@ -2792,23 +2962,49 @@ main (int argc, char **argv) } else if (!strcmp (mode_string, "dsa-pqg-gen")) { - int keysize; + int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); ++ ++ keysize = keysize_string? atoi (keysize_string) : 0; ++ if (keysize < 1024 || keysize > 3072) ++ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); + qsize = qsize_string? atoi (qsize_string) : 0; + if (qsize < 160 || qsize > 256) + die ("invalid qsize specified; needs to be 160 .. 256\n"); @@ -1363,10 +1273,11 @@ diff -up libgcrypt-1.5.3/tests/fipsdrv.c.cavs libgcrypt-1.5.3/tests/fipsdrv.c + else if (!strcmp (mode_string, "dsa-g-gen")) + { + int keysize, qsize; -+ -+ keysize = keysize_string? atoi (keysize_string) : 0; -+ if (keysize < 1024 || keysize > 3072) -+ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); +- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); + qsize = qsize_string? atoi (qsize_string) : 0; + if (qsize < 160 || qsize > 256) + die ("invalid qsize specified; needs to be 160 .. 256\n"); diff --git a/libgcrypt-1.7.3-fips-cfgrandom.patch b/libgcrypt-1.7.3-fips-cfgrandom.patch new file mode 100644 index 0000000..c9786e4 --- /dev/null +++ b/libgcrypt-1.7.3-fips-cfgrandom.patch @@ -0,0 +1,104 @@ +diff -up libgcrypt-1.7.3/random/random-drbg.c.cfgrandom libgcrypt-1.7.3/random/random-drbg.c +--- libgcrypt-1.7.3/random/random-drbg.c.cfgrandom 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.7.3/random/random-drbg.c 2016-11-22 15:54:02.227319203 +0100 +@@ -627,8 +627,13 @@ drbg_get_entropy (drbg_state_t drbg, uns + read_cb_size = len; + read_cb_len = 0; + #if USE_RNDLINUX ++ /* First read from /etc/gcrypt/rngseed if available */ ++ _gcry_rndlinux_gather_random (drbg_read_cb, 0, len, ++ -1); ++ read_cb_len = 0; ++ /* then use /dev/urandom. */ + rc = _gcry_rndlinux_gather_random (drbg_read_cb, 0, len, +- GCRY_VERY_STRONG_RANDOM); ++ GCRY_STRONG_RANDOM); + #elif USE_RNDUNIX + rc = _gcry_rndunix_gather_random (drbg_read_cb, 0, len, + GCRY_VERY_STRONG_RANDOM); +diff -up libgcrypt-1.7.3/random/rndlinux.c.cfgrandom libgcrypt-1.7.3/random/rndlinux.c +--- libgcrypt-1.7.3/random/rndlinux.c.cfgrandom 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/random/rndlinux.c 2016-11-22 15:45:19.921141761 +0100 +@@ -40,7 +40,9 @@ + #include "g10lib.h" + #include "rand-internal.h" + +-static int open_device (const char *name, int retry); ++#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed" ++ ++static int open_device (const char *name, int retry, int fatal); + + + static int +@@ -63,7 +65,7 @@ set_cloexec_flag (int fd) + * a fatal error but retries until it is able to reopen the device. + */ + static int +-open_device (const char *name, int retry) ++open_device (const char *name, int retry, int fatal) + { + int fd; + +@@ -71,6 +73,8 @@ open_device (const char *name, int retry + _gcry_random_progress ("open_dev_random", 'X', 1, 0); + again: + fd = open (name, O_RDONLY); ++ if (fd == -1 && !fatal) ++ return fd; + if (fd == -1 && retry) + { + struct timeval tv; +@@ -115,6 +119,7 @@ _gcry_rndlinux_gather_random (void (*add + { + static int fd_urandom = -1; + static int fd_random = -1; ++ static int fd_configured = -1; + static unsigned char ever_opened; + int fd; + int n; +@@ -138,6 +143,11 @@ _gcry_rndlinux_gather_random (void (*add + close (fd_urandom); + fd_urandom = -1; + } ++ if (fd_configured != -1) ++ { ++ close (fd_configured); ++ fd_configured = -1; ++ } + return 0; + } + +@@ -165,20 +175,30 @@ _gcry_rndlinux_gather_random (void (*add + that we always require the device to be existent but want a more + graceful behaviour if the rarely needed close operation has been + used and the device needs to be re-opened later. */ ++ ++ if (level == -1) ++ { ++ if (fd_configured == -1) ++ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0, 0 ); ++ fd = fd_configured; ++ if (fd == -1) ++ return -1; ++ } ++ + if (level >= 2) + { + if (fd_random == -1) + { +- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1)); ++ fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); + ever_opened |= 1; + } + fd = fd_random; + } +- else ++ else if (level != -1) + { + if (fd_urandom == -1) + { +- fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); ++ fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1); + ever_opened |= 2; + } + fd = fd_urandom; diff --git a/libgcrypt-1.7.3-fips-reqs.patch b/libgcrypt-1.7.3-fips-reqs.patch new file mode 100644 index 0000000..ef7f765 --- /dev/null +++ b/libgcrypt-1.7.3-fips-reqs.patch @@ -0,0 +1,35 @@ +diff -up libgcrypt-1.7.3/src/visibility.c.fips-reqs libgcrypt-1.7.3/src/visibility.c +--- libgcrypt-1.7.3/src/visibility.c.fips-reqs 2016-03-23 12:59:34.000000000 +0100 ++++ libgcrypt-1.7.3/src/visibility.c 2016-11-22 16:29:36.992042480 +0100 +@@ -1288,6 +1288,8 @@ gcry_kdf_derive (const void *passphrase, + unsigned long iterations, + size_t keysize, void *keybuffer) + { ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); + return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, + salt, saltlen, iterations, + keysize, keybuffer)); +@@ -1343,6 +1345,13 @@ void + gcry_mpi_randomize (gcry_mpi_t w, + unsigned int nbits, enum gcry_random_level level) + { ++ if (!fips_is_operational ()) ++ { ++ (void)fips_not_operational (); ++ fips_signal_fatal_error ("called in non-operational state"); ++ fips_noreturn (); ++ } ++ + _gcry_mpi_randomize (w, nbits, level); + } + +@@ -1368,6 +1377,8 @@ gcry_prime_generate (gcry_mpi_t *prime, + gcry_random_level_t random_level, + unsigned int flags) + { ++ if (!fips_is_operational ()) ++ return gpg_error (fips_not_operational ()); + return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits, + factors, cb_func, cb_arg, + random_level, flags)); diff --git a/libgcrypt-1.7.3-tests.patch b/libgcrypt-1.7.3-tests.patch new file mode 100644 index 0000000..f1b461c --- /dev/null +++ b/libgcrypt-1.7.3-tests.patch @@ -0,0 +1,115 @@ +diff -up libgcrypt-1.7.3/cipher/dsa.c.tests libgcrypt-1.7.3/cipher/dsa.c +--- libgcrypt-1.7.3/cipher/dsa.c.tests 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.7.3/cipher/dsa.c 2016-11-22 15:33:48.813026002 +0100 +@@ -457,11 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen); +- else +- ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, ++ else if (!domain->p || !domain->q) ++ ec = _gcry_generate_fips186_3_prime (nbits, qbits, ++ initial_seed.seed, ++ initial_seed.seedlen, + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen, NULL); ++ else ++ { ++ /* Domain parameters p and q are given; use them. */ ++ prime_p = mpi_copy (domain->p); ++ prime_q = mpi_copy (domain->q); ++ gcry_assert (mpi_get_nbits (prime_p) == nbits); ++ gcry_assert (mpi_get_nbits (prime_q) == qbits); ++ ec = 0; ++ } + sexp_release (initial_seed.sexp); + if (ec) + goto leave; +@@ -855,13 +866,12 @@ dsa_generate (const gcry_sexp_t genparms + sexp_release (l1); + sexp_release (domainsexp); + +- /* Check that all domain parameters are available. */ +- if (!domain.p || !domain.q || !domain.g) ++ /* Check that p and q domain parameters are available. */ ++ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) + { + _gcry_mpi_release (domain.p); + _gcry_mpi_release (domain.q); + _gcry_mpi_release (domain.g); +- sexp_release (deriveparms); + return GPG_ERR_MISSING_VALUE; + } + +diff -up libgcrypt-1.7.3/cipher/rsa.c.tests libgcrypt-1.7.3/cipher/rsa.c +--- libgcrypt-1.7.3/cipher/rsa.c.tests 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/cipher/rsa.c 2016-11-22 15:25:05.426838229 +0100 +@@ -696,7 +696,7 @@ generate_x931 (RSA_secret_key *sk, unsig + + *swapped = 0; + +- if (e_value == 1) /* Alias for a secure value. */ ++ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ + e_value = 65537; + + /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ +diff -up libgcrypt-1.7.3/tests/keygen.c.tests libgcrypt-1.7.3/tests/keygen.c +--- libgcrypt-1.7.3/tests/keygen.c.tests 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.7.3/tests/keygen.c 2016-11-22 15:25:33.178484464 +0100 +@@ -257,11 +257,11 @@ check_rsa_keys (void) + + + if (verbose) +- show ("creating 512 bit RSA key with e=257\n"); ++ show ("creating 1024 bit RSA key with e=257\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" +- " (nbits 3:512)\n" ++ " (nbits 4:1024)\n" + " (rsa-use-e 3:257)\n" + " ))", 0, 1); + if (rc) +@@ -282,11 +282,11 @@ check_rsa_keys (void) + gcry_sexp_release (key); + + if (verbose) +- show ("creating 512 bit RSA key with default e\n"); ++ show ("creating 1024 bit RSA key with default e\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" +- " (nbits 3:512)\n" ++ " (nbits 4:1024)\n" + " (rsa-use-e 1:0)\n" + " ))", 0, 1); + if (rc) +@@ -366,12 +366,12 @@ check_dsa_keys (void) + } + + if (verbose) +- show ("creating 1536 bit DSA key\n"); ++ show ("creating 2048 bit DSA key\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (dsa\n" +- " (nbits 4:1536)\n" +- " (qbits 3:224)\n" ++ " (nbits 4:2048)\n" ++ " (qbits 3:256)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); +diff -up libgcrypt-1.7.3/tests/pubkey.c.tests libgcrypt-1.7.3/tests/pubkey.c +--- libgcrypt-1.7.3/tests/pubkey.c.tests 2016-07-14 11:19:17.000000000 +0200 ++++ libgcrypt-1.7.3/tests/pubkey.c 2016-11-22 18:40:23.220813982 +0100 +@@ -651,7 +651,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ + " (use-fips186)" + " (transient-key)" + " (derive-parms" +- " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", ++ " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", + 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); diff --git a/libgcrypt-1.6.1-use-poll.patch b/libgcrypt-1.7.3-use-poll.patch similarity index 77% rename from libgcrypt-1.6.1-use-poll.patch rename to libgcrypt-1.7.3-use-poll.patch index 2fcaebf..16b7164 100644 --- a/libgcrypt-1.6.1-use-poll.patch +++ b/libgcrypt-1.7.3-use-poll.patch @@ -1,15 +1,15 @@ -diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndlinux.c ---- libgcrypt-1.6.1/random/rndlinux.c.use-poll 2014-02-28 15:17:55.294433915 +0100 -+++ libgcrypt-1.6.1/random/rndlinux.c 2014-02-28 15:34:52.505945274 +0100 +diff -up libgcrypt-1.7.3/random/rndlinux.c.use-poll libgcrypt-1.7.3/random/rndlinux.c +--- libgcrypt-1.7.3/random/rndlinux.c.use-poll 2016-11-22 16:05:05.114761069 +0100 ++++ libgcrypt-1.7.3/random/rndlinux.c 2016-11-22 16:16:05.373139721 +0100 @@ -32,6 +32,7 @@ #include #include #include +#include - #include "types.h" - #include "g10lib.h" - #include "rand-internal.h" -@@ -199,9 +200,11 @@ _gcry_rndlinux_gather_random (void (*add + #if defined(__linux__) && defined(HAVE_SYSCALL) + # include + #endif +@@ -211,9 +212,11 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) { @@ -23,7 +23,7 @@ diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndli /* If we collected some bytes update the progress indicator. We do this always and not just if the select timed out because -@@ -215,33 +218,18 @@ _gcry_rndlinux_gather_random (void (*add +@@ -227,33 +230,19 @@ _gcry_rndlinux_gather_random (void (*add any_need_entropy = 1; } @@ -35,7 +35,14 @@ diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndli -#ifdef FD_SETSIZE - if (fd < FD_SETSIZE) -#endif -- { ++ if ( !(rc=poll(&pfd, 1, delay)) ) ++ { ++ any_need_entropy = 1; ++ delay = 3000; /* Use 3 seconds henceforth. */ ++ continue; ++ } ++ else if( rc == -1 ) + { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = delay; @@ -54,13 +61,6 @@ diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndli - we have ever blocked. */ - continue; - } -+ if ( !(rc=poll(&pfd, 1, delay)) ) -+ { -+ delay = 3000; /* Use 3 seconds henceforth. */ -+ continue; -+ } -+ else if( rc == -1 ) -+ { + log_error ("poll() error: %s\n", strerror(errno)); + if (!delay) + delay = 1000; /* Use 1 second if we encounter an error before @@ -68,4 +68,4 @@ diff -up libgcrypt-1.6.1/random/rndlinux.c.use-poll libgcrypt-1.6.1/random/rndli + continue; } - do + /* If we have a modern Linux kernel and we want to read from the diff --git a/libgcrypt.spec b/libgcrypt.spec index 590cabc..cd1628a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.6.6 +Version: 1.7.3 Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -15,36 +15,29 @@ Source3: hobble-libgcrypt Source4: ecc-curves.c Source5: curves.c Source6: t-mpi-point.c +Source7: ecc-gost.c # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump Patch2: libgcrypt-1.6.2-use-fipscheck.patch -# fix tests in the FIPS mode, fix the FIPS-186-3 DSA keygen -Patch5: libgcrypt-1.6.1-tests.patch +# fix tests in the FIPS mode, allow CAVS testing of DSA keygen +Patch5: libgcrypt-1.7.3-tests.patch # add configurable source of RNG seed and seed by default # from /dev/urandom in the FIPS mode -Patch6: libgcrypt-1.6.1-fips-cfgrandom.patch +Patch6: libgcrypt-1.7.3-fips-cfgrandom.patch # update the CAVS tests -Patch7: libgcrypt-1.6.2-fips-cavs.patch -# fix for memory leaks and other errors found by Coverity scan -Patch9: libgcrypt-1.6.5-leak.patch +Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness -Patch11: libgcrypt-1.6.1-use-poll.patch +Patch11: libgcrypt-1.7.3-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC -Patch14: libgcrypt-1.6.1-ecc-test-fix.patch -# Replace the FIPS RNG with DRBG -Patch15: libgcrypt-1.6.2-drbg.patch +Patch14: libgcrypt-1.7.3-ecc-test-fix.patch # Run the FIPS mode initialization in the shared library constructor Patch18: libgcrypt-1.6.2-fips-ctor.patch -# Make it possible to run the test suite in the FIPS mode -Patch19: libgcrypt-1.6.2-fips-test.patch -# Make the FIPS RSA keygen to be FIPS 186-4 compliant -Patch20: libgcrypt-1.6.3-rsa-fips-keygen.patch -# update the selftests for new FIPS requirements -Patch22: libgcrypt-1.6.2-fips-reqs.patch +# Block some operations if in FIPS non-operational state +Patch22: libgcrypt-1.7.3-fips-reqs.patch # do not use strict aliasing for bufhelp functions -Patch23: libgcrypt-1.6.3-aliasing.patch +Patch23: libgcrypt-1.7.3-aliasing.patch # use only urandom if /dev/random cannot be opened Patch24: libgcrypt-1.6.3-urandom-only.patch @@ -86,19 +79,15 @@ applications using libgcrypt. %patch5 -p1 -b .tests %patch6 -p1 -b .cfgrandom %patch7 -p1 -b .cavs -%patch9 -p1 -b .leak %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix -%patch15 -p1 -b .drbg %patch18 -p1 -b .fips-ctor -%patch19 -p1 -b .fips-test -%patch20 -p1 -b .fips-keygen %patch22 -p1 -b .fips-reqs %patch23 -p1 -b .aliasing %patch24 -p1 -b .urandom-only -cp %{SOURCE4} cipher/ +cp %{SOURCE4} %{SOURCE7} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ %build @@ -208,6 +197,9 @@ exit 0 %license COPYING %changelog +* Wed Nov 23 2016 Tomáš Mráz 1.7.3-1 +- new upstream version 1.7.3 + * Wed Aug 17 2016 Tomáš Mráz 1.6.6-1 - new upstream version with important security fix (CVE-2016-6316) diff --git a/sources b/sources index 4a375a0..e714a44 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -67edcc4715a8c239eac70a931e49660d libgcrypt-1.6.6-hobbled.tar.xz +8ed4255c512e382eba465330c2a939dc libgcrypt-1.7.3-hobbled.tar.xz diff --git a/t-mpi-point.c b/t-mpi-point.c index 2c977c5..b1b8b2c 100644 --- a/t-mpi-point.c +++ b/t-mpi-point.c @@ -57,8 +57,20 @@ static struct const char *a, *b; /* The coefficients. */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ + const char *h; /* Cofactor. */ } test_curve[] = { + { + "NIST P-224", + "0xffffffffffffffffffffffffffffffff000000000000000000000001", + "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", + "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", + "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , + + "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", + "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", + "0x01" + }, { "NIST P-256", "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", @@ -67,7 +79,8 @@ static struct "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5" + "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", + "0x01" }, { "NIST P-384", @@ -83,7 +96,8 @@ static struct "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f" + "0a60b1ce1d7e819d7a431d7c90ea0e5f", + "0x01" }, { "NIST P-521", @@ -99,18 +113,20 @@ static struct "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650" + "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", + "0x01" }, { "Ed25519", "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "-0x01", - "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", + "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC", + "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3", "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658" + "0x6666666666666666666666666666666666666666666666666666666666666658", + "0x08" }, - { NULL, NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, NULL, NULL } }; /* A sample public key for NIST P-256. */ @@ -414,28 +430,18 @@ context_alloc (void) gcry_mpi_release (a); gcry_ctx_release (ctx); - p = gcry_mpi_set_ui (NULL, 0); + p = NULL; a = gcry_mpi_set_ui (NULL, 0); + err = ec_p_new (&ctx, p, a); if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) fail ("ec_p_new: bad parameter detection failed (1)\n"); - gcry_mpi_set_ui (p, 1); - err = ec_p_new (&ctx, p, a); - if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (2)\n"); - - gcry_mpi_release (p); - p = NULL; - err = ec_p_new (&ctx, p, a); - if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (3)\n"); - gcry_mpi_release (a); a = NULL; err = ec_p_new (&ctx, p, a); if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (4)\n"); + fail ("ec_p_new: bad parameter detection failed (2)\n"); } @@ -523,6 +529,17 @@ context_param (void) show ("checking standard curves\n"); for (idx=0; test_curve[idx].desc; idx++) { + /* P-192 and Ed25519 are not supported in fips mode */ + if (gcry_fips_mode_active()) + { + if (!strcmp(test_curve[idx].desc, "NIST P-192") + || !strcmp(test_curve[idx].desc, "Ed25519")) + { + show("skipping %s in fips mode\n", test_curve[idx].desc ); + continue; + } + } + gcry_ctx_release (ctx); err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc); if (err) @@ -546,6 +563,8 @@ context_param (void) if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y, test_curve[idx].desc, ctx)) continue; + if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx)) + continue; } @@ -616,6 +635,10 @@ context_param (void) gcry_sexp_release (sexp); } + /* Skipping Ed25519 if in FIPS mode (it isn't supported) */ + if (gcry_fips_mode_active()) + goto cleanup; + show ("checking sample public key (Ed25519)\n"); q = hex2mpi (sample_ed25519_q); gcry_sexp_release (keyparam); @@ -703,6 +726,7 @@ context_param (void) } + cleanup: gcry_ctx_release (ctx); gcry_sexp_release (keyparam); } @@ -804,6 +828,14 @@ basic_ec_math (void) } +/* This is the same as basic_ec_math but uses more advanced + features. */ +static void +basic_ec_math_simplified (void) +{ +} + + /* Check the math used with Twisted Edwards curves. */ static void twistededwards_math (void) @@ -963,7 +995,14 @@ main (int argc, char **argv) context_alloc (); context_param (); basic_ec_math (); - twistededwards_math (); + + /* The tests are for P-192 and ed25519 which are not supported in + FIPS mode. */ + if (!gcry_fips_mode_active()) + { + basic_ec_math_simplified (); + twistededwards_math (); + } show ("All tests completed. Errors: %d\n", error_count); return error_count ? 1 : 0; From 0aa4874598546c34af8ee10cd792e601bb67199b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 16 Dec 2016 16:12:33 +0100 Subject: [PATCH 092/214] new upstream version 1.7.5 --- .gitignore | 1 + libgcrypt.spec | 5 ++++- sources | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index cb05f79..7be4383 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.6.5-hobbled.tar.xz /libgcrypt-1.6.6-hobbled.tar.xz /libgcrypt-1.7.3-hobbled.tar.xz +/libgcrypt-1.7.5-hobbled.tar.xz diff --git a/libgcrypt.spec b/libgcrypt.spec index cd1628a..b4487b2 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.7.3 +Version: 1.7.5 Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -197,6 +197,9 @@ exit 0 %license COPYING %changelog +* Fri Dec 16 2016 Tomáš Mráz 1.7.5-1 +- new upstream version 1.7.5 + * Wed Nov 23 2016 Tomáš Mráz 1.7.3-1 - new upstream version 1.7.3 diff --git a/sources b/sources index e714a44..93082e7 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -8ed4255c512e382eba465330c2a939dc libgcrypt-1.7.3-hobbled.tar.xz +SHA512 (libgcrypt-1.7.5-hobbled.tar.xz) = 687a4d01e02d8a92faeec6e9e9a3dbd32e71df9da83c2f1d69c2d8a625ce572d1ee1f025f4b5563b294f450849d65ce3da31a9e9f9cd47438da3b558e6e15c77 From 1c953f2503ffde8ca5d8cc000b464adf0baa6f61 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 30 Jan 2017 18:05:13 +0100 Subject: [PATCH 093/214] new upstream version 1.7.6 --- .gitignore | 1 + ...ll.patch => libgcrypt-1.7.6-use-poll.patch | 34 +++++++++---------- libgcrypt.spec | 7 ++-- sources | 2 +- 4 files changed, 24 insertions(+), 20 deletions(-) rename libgcrypt-1.7.3-use-poll.patch => libgcrypt-1.7.6-use-poll.patch (79%) diff --git a/.gitignore b/.gitignore index 7be4383..3aa8d24 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.6.6-hobbled.tar.xz /libgcrypt-1.7.3-hobbled.tar.xz /libgcrypt-1.7.5-hobbled.tar.xz +/libgcrypt-1.7.6-hobbled.tar.xz diff --git a/libgcrypt-1.7.3-use-poll.patch b/libgcrypt-1.7.6-use-poll.patch similarity index 79% rename from libgcrypt-1.7.3-use-poll.patch rename to libgcrypt-1.7.6-use-poll.patch index 16b7164..4ec20ce 100644 --- a/libgcrypt-1.7.3-use-poll.patch +++ b/libgcrypt-1.7.6-use-poll.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.7.3/random/rndlinux.c.use-poll libgcrypt-1.7.3/random/rndlinux.c ---- libgcrypt-1.7.3/random/rndlinux.c.use-poll 2016-11-22 16:05:05.114761069 +0100 -+++ libgcrypt-1.7.3/random/rndlinux.c 2016-11-22 16:16:05.373139721 +0100 +diff -up libgcrypt-1.7.6/random/rndlinux.c.use-poll libgcrypt-1.7.6/random/rndlinux.c +--- libgcrypt-1.7.6/random/rndlinux.c.use-poll 2017-01-30 14:20:13.665662981 +0100 ++++ libgcrypt-1.7.6/random/rndlinux.c 2017-01-30 14:27:45.957027214 +0100 @@ -32,6 +32,7 @@ #include #include @@ -9,7 +9,7 @@ diff -up libgcrypt-1.7.3/random/rndlinux.c.use-poll libgcrypt-1.7.3/random/rndli #if defined(__linux__) && defined(HAVE_SYSCALL) # include #endif -@@ -211,9 +212,11 @@ _gcry_rndlinux_gather_random (void (*add +@@ -211,9 +212,8 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) { @@ -17,13 +17,10 @@ diff -up libgcrypt-1.7.3/random/rndlinux.c.use-poll libgcrypt-1.7.3/random/rndli - struct timeval tv; int rc; + struct pollfd pfd; -+ -+ pfd.fd = fd; -+ pfd.events = POLLIN; - /* If we collected some bytes update the progress indicator. We - do this always and not just if the select timed out because -@@ -227,33 +230,19 @@ _gcry_rndlinux_gather_random (void (*add + /* If we have a modern Linux kernel and we want to read from the + * the non-blocking /dev/urandom, we first try to use the new +@@ -269,33 +269,22 @@ _gcry_rndlinux_gather_random (void (*add any_need_entropy = 1; } @@ -35,13 +32,10 @@ diff -up libgcrypt-1.7.3/random/rndlinux.c.use-poll libgcrypt-1.7.3/random/rndli -#ifdef FD_SETSIZE - if (fd < FD_SETSIZE) -#endif ++ pfd.fd = fd; ++ pfd.events = POLLIN; ++ + if ( !(rc=poll(&pfd, 1, delay)) ) -+ { -+ any_need_entropy = 1; -+ delay = 3000; /* Use 3 seconds henceforth. */ -+ continue; -+ } -+ else if( rc == -1 ) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); @@ -61,6 +55,12 @@ diff -up libgcrypt-1.7.3/random/rndlinux.c.use-poll libgcrypt-1.7.3/random/rndli - we have ever blocked. */ - continue; - } ++ any_need_entropy = 1; ++ delay = 3000; /* Use 3 seconds henceforth. */ ++ continue; ++ } ++ else if( rc == -1 ) ++ { + log_error ("poll() error: %s\n", strerror(errno)); + if (!delay) + delay = 1000; /* Use 1 second if we encounter an error before @@ -68,4 +68,4 @@ diff -up libgcrypt-1.7.3/random/rndlinux.c.use-poll libgcrypt-1.7.3/random/rndli + continue; } - /* If we have a modern Linux kernel and we want to read from the + /* Read from the device. */ diff --git a/libgcrypt.spec b/libgcrypt.spec index b4487b2..068e1ba 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.7.5 +Version: 1.7.6 Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -27,7 +27,7 @@ Patch6: libgcrypt-1.7.3-fips-cfgrandom.patch # update the CAVS tests Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness -Patch11: libgcrypt-1.7.3-use-poll.patch +Patch11: libgcrypt-1.7.6-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC @@ -197,6 +197,9 @@ exit 0 %license COPYING %changelog +* Mon Jan 30 2017 Tomáš Mráz 1.7.6-1 +- new upstream version 1.7.6 + * Fri Dec 16 2016 Tomáš Mráz 1.7.5-1 - new upstream version 1.7.5 diff --git a/sources b/sources index 93082e7..e4f2850 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.7.5-hobbled.tar.xz) = 687a4d01e02d8a92faeec6e9e9a3dbd32e71df9da83c2f1d69c2d8a625ce572d1ee1f025f4b5563b294f450849d65ce3da31a9e9f9cd47438da3b558e6e15c77 +SHA512 (libgcrypt-1.7.6-hobbled.tar.xz) = 4aa981f4b270e480324dc3b021781c0b01a0f1fc5950654ccd379d47acbb791a2df612f212191ecac50c39a7ba83cc62de9a9271c663aad6d49721de14ecced5 From 396c70cd7ad79ee8d8bd672f4fbc3cc4f04fb8d7 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 10 Feb 2017 18:41:27 +0000 Subject: [PATCH 094/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 068e1ba..c237db6 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.7.6 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -197,6 +197,9 @@ exit 0 %license COPYING %changelog +* Fri Feb 10 2017 Fedora Release Engineering - 1.7.6-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + * Mon Jan 30 2017 Tomáš Mráz 1.7.6-1 - new upstream version 1.7.6 From 0a0dd316660ca7be58caf98845a843ac4a3d049a Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 2 Jun 2017 15:58:46 +0200 Subject: [PATCH 095/214] new upstream version 1.7.7 GOST is now enabled --- .gitignore | 1 + ecc-curves.c | 109 +++++++++++++++++++++++++++++ ecc-gost.c | 56 --------------- hobble-libgcrypt | 1 - libgcrypt-1.7.3-ecc-test-fix.patch | 42 +---------- libgcrypt.spec | 11 +-- sources | 2 +- 7 files changed, 121 insertions(+), 101 deletions(-) delete mode 100644 ecc-gost.c diff --git a/.gitignore b/.gitignore index 3aa8d24..b032213 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.7.3-hobbled.tar.xz /libgcrypt-1.7.5-hobbled.tar.xz /libgcrypt-1.7.6-hobbled.tar.xz +/libgcrypt-1.7.7-hobbled.tar.xz diff --git a/ecc-curves.c b/ecc-curves.c index a971e0a..1720778 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -60,6 +60,18 @@ static const struct { "NIST P-521", "1.3.132.0.35" }, { "NIST P-521", "nistp521" }, /* rfc5656. */ + { "GOST2001-test", "1.2.643.2.2.35.0" }, + { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" }, + { "GOST2001-CryptoPro-B", "1.2.643.2.2.35.2" }, + { "GOST2001-CryptoPro-C", "1.2.643.2.2.35.3" }, + { "GOST2001-CryptoPro-A", "GOST2001-CryptoPro-XchA" }, + { "GOST2001-CryptoPro-C", "GOST2001-CryptoPro-XchB" }, + { "GOST2001-CryptoPro-A", "1.2.643.2.2.36.0" }, + { "GOST2001-CryptoPro-C", "1.2.643.2.2.36.1" }, + + { "GOST2012-tc26-A", "1.2.643.7.1.2.1.2.1" }, + { "GOST2012-tc26-B", "1.2.643.7.1.2.1.2.2" }, + { "secp256k1", "1.3.132.0.10" }, { NULL, NULL} @@ -178,6 +190,103 @@ static const ecc_domain_parms_t domain_parms[] = "0x01" }, + { + "GOST2001-test", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0x8000000000000000000000000000000000000000000000000000000000000431", + "0x0000000000000000000000000000000000000000000000000000000000000007", + "0x5fbff498aa938ce739b8e022fbafef40563f6e6a3472fc2a514c0ce9dae23b7e", + "0x8000000000000000000000000000000150fe8a1892976154c59cfc193accf5b3", + + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8", + "0x01" + }, + { + "GOST2001-CryptoPro-A", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97", + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd94", + "0x00000000000000000000000000000000000000000000000000000000000000a6", + "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14", + "0x01" + }, + { + "GOST2001-CryptoPro-B", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0x8000000000000000000000000000000000000000000000000000000000000c99", + "0x8000000000000000000000000000000000000000000000000000000000000c96", + "0x3e1af419a269a5f866a7d3c25c3df80ae979259373ff2b182f49d4ce7e1bbc8b", + "0x800000000000000000000000000000015f700cfff1a624e5e497161bcc8a198f", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc", + "0x01" + }, + { + "GOST2001-CryptoPro-C", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d759b", + "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d7598", + "0x000000000000000000000000000000000000000000000000000000000000805a", + "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67", + "0x01" + }, + { + "GOST2012-test", 511, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" + "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373", + "0x0000000000000000000000000000000000000000000000000000000000000007", + "0x1cff0806a31116da29d8cfa54e57eb748bc5f377e49400fdd788b649eca1ac4" + "361834013b2ad7322480a89ca58e0cf74bc9e540c2add6897fad0a3084f302adc", + "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" + "a82f2d7ecb1dbac719905c5eecc423f1d86e25edbe23c595d644aaf187e6e6df", + + "0x24d19cc64572ee30f396bf6ebbfd7a6c5213b3b3d7057cc825f91093a68cd762" + "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a", + "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2" + "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e", + "0x01" + }, + { + "GOST2012-tc26-A", 512, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc4", + "0xe8c2505dedfc86ddc1bd0b2b6667f1da34b82574761cb0e879bd081cfd0b6265" + "ee3cb090f30d27614cb4574010da90dd862ef9d4ebee4761503190785a71c760", + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "27e69532f48d89116ff22b8d4e0560609b4b38abfad2b85dcacdb1411f10b275", + "0x0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000003", + "0x7503cfe87a836ae3a61b8816e25450e6ce5e1c93acf1abc1778064fdcbefa921" + "df1626be4fd036e93d75e6a50e3a41e98028fe5fc235f5b889a589cb5215f2a4", + "0x01" + }, + { + "GOST2012-tc26-B", 512, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0x8000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000006f", + "0x8000000000000000000000000000000000000000000000000000000000000000" + "000000000000000000000000000000000000000000000000000000000000006c", + "0x687d1b459dc841457e3e06cf6f5e2517b97c7d614af138bcbf85dc806c4b289f" + "3e965d2db1416d217f8b276fad1ab69c50f78bee1fa3106efb8ccbc7c5140116", + "0x8000000000000000000000000000000000000000000000000000000000000001" + "49a1ec142565a545acfdb77bd9d40cfa8b996712101bea0ec6346c54374f25bd", + "0x0000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000000002", + "0x1a8f7eda389b094c2c071e3647a8940f3c123b697578c213be6dd9e6c8ec7335" + "dcb228fd1edf4a39152cbcaaf8c0398828041055f94ceeec7e21340780fe41bd", + "0x01" + }, + { "secp256k1", 256, 0, MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, diff --git a/ecc-gost.c b/ecc-gost.c deleted file mode 100644 index 75a2a93..0000000 --- a/ecc-gost.c +++ /dev/null @@ -1,56 +0,0 @@ -/* ecc-gots.c - Elliptic Curve GOST signatures - * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. - * Copyright (C) 2013 Dmitry Eremin-Solenikov - * - * This file is part of Libgcrypt. - * - * Libgcrypt 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. - * - * Libgcrypt 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 program; if not, see . - */ - -#include -#include -#include -#include -#include - -#include "g10lib.h" -#include "mpi.h" -#include "cipher.h" -#include "context.h" -#include "ec-context.h" -#include "ecc-common.h" -#include "pubkey-internal.h" - - -/* Compute an GOST R 34.10-01/-12 signature. - * Return the signature struct (r,s) from the message hash. The caller - * must have allocated R and S. - */ -gpg_err_code_t -_gcry_ecc_gost_sign (gcry_mpi_t input, ECC_secret_key *skey, - gcry_mpi_t r, gcry_mpi_t s) -{ - return GPG_ERR_UNSUPPORTED_ALGORITHM; -} - - -/* Verify a GOST R 34.10-01/-12 signature. - * Check if R and S verifies INPUT. - */ -gpg_err_code_t -_gcry_ecc_gost_verify (gcry_mpi_t input, ECC_public_key *pkey, - gcry_mpi_t r, gcry_mpi_t s) -{ - return GPG_ERR_UNSUPPORTED_ALGORITHM; -} diff --git a/hobble-libgcrypt b/hobble-libgcrypt index 81bda0f..cc53cc1 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -7,6 +7,5 @@ set -e -x # EC: ????????? ??/??/2015 rm -f cipher/ecc-curves.c -rm -f cipher/ecc-gost.c rm -f tests/curves.c rm -f tests/t-mpi-point.c diff --git a/libgcrypt-1.7.3-ecc-test-fix.patch b/libgcrypt-1.7.3-ecc-test-fix.patch index 229d9f1..8ce7aa9 100644 --- a/libgcrypt-1.7.3-ecc-test-fix.patch +++ b/libgcrypt-1.7.3-ecc-test-fix.patch @@ -1,51 +1,15 @@ -diff -up libgcrypt-1.7.3/tests/basic.c.eccfix libgcrypt-1.7.3/tests/basic.c ---- libgcrypt-1.7.3/tests/basic.c.eccfix 2016-04-15 09:42:06.000000000 +0200 -+++ libgcrypt-1.7.3/tests/basic.c 2016-11-22 18:43:19.732897206 +0100 -@@ -8506,6 +8506,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex - /* */ "000102030405060708090A0B0C0D0E0F#))", - 0 - }, -+#if 0 - { 256, - "(data (flags gost)\n" - " (value #00112233445566778899AABBCCDDEEFF" -@@ -8530,6 +8531,7 @@ check_pubkey_sign_ecdsa (int n, gcry_sex - /* */ "000102030405060708090A0B0C0D0E0F#))", - 0 - }, -+#endif - { 0, NULL } - }; - -@@ -9136,6 +9138,7 @@ check_pubkey (void) - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } - }, -+#if 0 - { /* GOST R 34.10-2001/2012 test 256 bit. */ - GCRY_PK_ECDSA, FLAG_SIGN, - { -@@ -9187,6 +9190,7 @@ check_pubkey (void) - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" - "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" } - }, -+#endif - { /* secp256k1 test 256 bit. */ - GCRY_PK_ECDSA, FLAG_SIGN, - { diff -up libgcrypt-1.7.3/tests/benchmark.c.eccfix libgcrypt-1.7.3/tests/benchmark.c --- libgcrypt-1.7.3/tests/benchmark.c.eccfix 2016-07-14 11:19:17.000000000 +0200 +++ libgcrypt-1.7.3/tests/benchmark.c 2016-11-22 16:21:00.109004197 +0100 -@@ -1412,8 +1412,7 @@ ecc_bench (int iterations, int print_hea +@@ -1412,7 +1412,7 @@ ecc_bench (int iterations, int print_hea { #if USE_ECC gpg_error_t err; - const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", -- "gost256", "gost512" }; -+ const char *p_sizes[] = { "224", "256", "384", "521", "Ed25519" }; ++ const char *p_sizes[] = { "224", "256", "384", "521", "Ed25519", + "gost256", "gost512" }; int testno; - if (print_header) diff -up libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix libgcrypt-1.7.3/tests/dsa-rfc6979.c --- libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix 2016-02-18 09:38:03.000000000 +0100 +++ libgcrypt-1.7.3/tests/dsa-rfc6979.c 2016-11-22 16:22:11.804674008 +0100 diff --git a/libgcrypt.spec b/libgcrypt.spec index c237db6..e66edf1 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.7.6 -Release: 2%{?dist} +Version: 1.7.7 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -15,7 +15,6 @@ Source3: hobble-libgcrypt Source4: ecc-curves.c Source5: curves.c Source6: t-mpi-point.c -Source7: ecc-gost.c # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump Patch2: libgcrypt-1.6.2-use-fipscheck.patch @@ -87,7 +86,7 @@ applications using libgcrypt. %patch23 -p1 -b .aliasing %patch24 -p1 -b .urandom-only -cp %{SOURCE4} %{SOURCE7} cipher/ +cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ %build @@ -197,6 +196,10 @@ exit 0 %license COPYING %changelog +* Fri Jun 2 2017 Tomáš Mráz 1.7.7-1 +- new upstream version 1.7.7 +- GOST is now enabled + * Fri Feb 10 2017 Fedora Release Engineering - 1.7.6-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild diff --git a/sources b/sources index e4f2850..a46e20b 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.7.6-hobbled.tar.xz) = 4aa981f4b270e480324dc3b021781c0b01a0f1fc5950654ccd379d47acbb791a2df612f212191ecac50c39a7ba83cc62de9a9271c663aad6d49721de14ecced5 +SHA512 (libgcrypt-1.7.7-hobbled.tar.xz) = 4e75594b8911581ce04f2594a5860644f07c69b4f28f7a2e20fd0476933ecd0159d3331bdbf5e61bffafddacdeebe4a7aa0f0d306e09ae6cf481e6a452359b98 From 2aa8a11e2c2962844e4081c2f1994975d1b96aed Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Fri, 2 Jun 2017 16:05:40 +0200 Subject: [PATCH 096/214] We now have 14 EC curves supported. --- curves.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/curves.c b/curves.c index f27346d..545c03e 100644 --- a/curves.c +++ b/curves.c @@ -29,7 +29,7 @@ #include "../src/gcrypt-int.h" /* Number of curves defined in ../cipger/ecc.c */ -#define N_CURVES 7 +#define N_CURVES 14 /* A real world sample public key. */ static char const sample_key_1[] = From 0b4ad5ed6969454ffc69b0101def610fa76a922a Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 29 Jun 2017 11:17:10 +0200 Subject: [PATCH 097/214] new upstream version 1.7.8 --- .gitignore | 1 + libgcrypt.spec | 5 ++++- sources | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index b032213..782e573 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.7.5-hobbled.tar.xz /libgcrypt-1.7.6-hobbled.tar.xz /libgcrypt-1.7.7-hobbled.tar.xz +/libgcrypt-1.7.8-hobbled.tar.xz diff --git a/libgcrypt.spec b/libgcrypt.spec index e66edf1..f36f19d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.7.7 +Version: 1.7.8 Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -196,6 +196,9 @@ exit 0 %license COPYING %changelog +* Thu Jun 29 2017 Tomáš Mráz 1.7.8-1 +- new upstream version 1.7.8 + * Fri Jun 2 2017 Tomáš Mráz 1.7.7-1 - new upstream version 1.7.7 - GOST is now enabled diff --git a/sources b/sources index a46e20b..33c4cb4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.7.7-hobbled.tar.xz) = 4e75594b8911581ce04f2594a5860644f07c69b4f28f7a2e20fd0476933ecd0159d3331bdbf5e61bffafddacdeebe4a7aa0f0d306e09ae6cf481e6a452359b98 +SHA512 (libgcrypt-1.7.8-hobbled.tar.xz) = 19c13ebdbd24657a9694702f91f045f5fb91b7b68eb4361a6abbb0c1bb90403cf8657d650cf97f9fd61d7ed571682181b34d35777d634187bfd0a78b2857efe1 From 73dab95fa742de8507915e3d0f9adc2dd65a25cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C3=A1draig=20Brady?= Date: Sat, 15 Jul 2017 21:12:09 -0700 Subject: [PATCH 098/214] make compilation valid independent of configure options I.E. ensure the package still compiles even without the --enable-hmac-binary-check configure option being specified --- libgcrypt-1.6.2-use-fipscheck.patch | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libgcrypt-1.6.2-use-fipscheck.patch b/libgcrypt-1.6.2-use-fipscheck.patch index 26f31b6..26af6bf 100644 --- a/libgcrypt-1.6.2-use-fipscheck.patch +++ b/libgcrypt-1.6.2-use-fipscheck.patch @@ -1,10 +1,11 @@ diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c --- libgcrypt-1.6.2/src/fips.c.use-fipscheck 2014-08-21 14:50:39.000000000 +0200 +++ libgcrypt-1.6.2/src/fips.c 2014-09-26 11:42:20.999588282 +0200 -@@ -578,23 +578,48 @@ run_random_selftests (void) +@@ -578,23 +578,50 @@ run_random_selftests (void) return !!err; } ++#ifdef ENABLE_HMAC_BINARY_CHECK +static int +get_library_path(const char *libname, const char *symbolname, char *path, size_t pathlen) +{ @@ -29,6 +30,7 @@ diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c + + return rv; +} ++#endif + /* Run an integrity check on the binary. Returns 0 on success. */ static int @@ -55,7 +57,7 @@ diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c key, strlen (key)); if (dlen < 0) err = gpg_error_from_syserror (); -@@ -602,7 +627,7 @@ check_binary_integrity (void) +@@ -602,7 +629,7 @@ check_binary_integrity (void) err = gpg_error (GPG_ERR_INTERNAL); else { @@ -64,7 +66,7 @@ diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c if (!fname) err = gpg_error_from_syserror (); else -@@ -611,7 +636,7 @@ check_binary_integrity (void) +@@ -611,7 +638,7 @@ check_binary_integrity (void) char *p; /* Prefix the basename with a dot. */ From 7518a93c42978b693a2b36798218e4c7b8b9ab8f Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 26 Jul 2017 18:52:56 +0000 Subject: [PATCH 099/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index f36f19d..82de040 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.7.8 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -196,6 +196,9 @@ exit 0 %license COPYING %changelog +* Wed Jul 26 2017 Fedora Release Engineering - 1.7.8-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild + * Thu Jun 29 2017 Tomáš Mráz 1.7.8-1 - new upstream version 1.7.8 From 2f0819346c15d844bd3f7345e1548e724148776d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 3 Aug 2017 01:29:36 +0000 Subject: [PATCH 100/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 82de040..ec79a86 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.7.8 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -196,6 +196,9 @@ exit 0 %license COPYING %changelog +* Thu Aug 03 2017 Fedora Release Engineering - 1.7.8-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild + * Wed Jul 26 2017 Fedora Release Engineering - 1.7.8-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Mass_Rebuild From 0c8865f0b9937dd7c6d741b814f6c2c03f0ddd0b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 16 Aug 2017 10:55:16 +0200 Subject: [PATCH 101/214] new upstream version 1.8.0 --- curves.c | 37 ++---- libgcrypt-1.6.3-urandom-only.patch | 29 ----- libgcrypt-1.7.3-aliasing.patch | 24 ---- libgcrypt-1.7.3-fips-cfgrandom.patch | 104 ---------------- ...tests.patch => libgcrypt-1.8.0-tests.patch | 44 +++---- ...ll.patch => libgcrypt-1.8.0-use-poll.patch | 22 ++-- libgcrypt.spec | 29 ++--- random.conf | 4 + t-mpi-point.c | 114 +++++------------- 9 files changed, 92 insertions(+), 315 deletions(-) delete mode 100644 libgcrypt-1.6.3-urandom-only.patch delete mode 100644 libgcrypt-1.7.3-aliasing.patch delete mode 100644 libgcrypt-1.7.3-fips-cfgrandom.patch rename libgcrypt-1.7.3-tests.patch => libgcrypt-1.8.0-tests.patch (72%) rename libgcrypt-1.7.6-use-poll.patch => libgcrypt-1.8.0-use-poll.patch (76%) create mode 100644 random.conf diff --git a/curves.c b/curves.c index 545c03e..b68e0e2 100644 --- a/curves.c +++ b/curves.c @@ -28,6 +28,10 @@ #include "../src/gcrypt-int.h" + +#define PGM "curves" +#include "t-common.h" + /* Number of curves defined in ../cipger/ecc.c */ #define N_CURVES 14 @@ -48,31 +52,6 @@ static char const sample_key_1[] = static char const sample_key_1_curve[] = "NIST P-256"; static unsigned int sample_key_1_nbits = 256; -/* Program option flags. */ -static int verbose; -static int error_count; - -static void -fail (const char *format, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - error_count++; -} - -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - exit (1); -} static void @@ -145,8 +124,6 @@ check_get_params (void) int main (int argc, char **argv) { - int debug = 0; - if (argc > 1 && !strcmp (argv[1], "--verbose")) verbose = 1; else if (argc > 1 && !strcmp (argv[1], "--debug")) @@ -155,10 +132,10 @@ main (int argc, char **argv) if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); - gcry_control (GCRYCTL_DISABLE_SECMEM, 0); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + xgcry_control (GCRYCTL_DISABLE_SECMEM, 0); + xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); if (debug) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); list_curves (); check_matching (); check_get_params (); diff --git a/libgcrypt-1.6.3-urandom-only.patch b/libgcrypt-1.6.3-urandom-only.patch deleted file mode 100644 index cf0901d..0000000 --- a/libgcrypt-1.6.3-urandom-only.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff -up libgcrypt-1.6.3/random/random-csprng.c.urandom-only libgcrypt-1.6.3/random/random-csprng.c ---- libgcrypt-1.6.3/random/random-csprng.c.urandom-only 2015-02-27 10:54:03.000000000 +0100 -+++ libgcrypt-1.6.3/random/random-csprng.c 2015-03-20 08:29:27.513113519 +0100 -@@ -1125,8 +1125,7 @@ getfnc_gather_random (void))(void (*)(co - enum random_origins, size_t, int); - - #if USE_RNDLINUX -- if ( !access (NAME_OF_DEV_RANDOM, R_OK) -- && !access (NAME_OF_DEV_URANDOM, R_OK)) -+ if (!access (NAME_OF_DEV_URANDOM, R_OK)) - { - fnc = _gcry_rndlinux_gather_random; - return fnc; -diff -up libgcrypt-1.6.3/random/rndlinux.c.urandom-only libgcrypt-1.6.3/random/rndlinux.c ---- libgcrypt-1.6.3/random/rndlinux.c.urandom-only 2015-03-20 08:36:13.472098269 +0100 -+++ libgcrypt-1.6.3/random/rndlinux.c 2015-03-20 08:36:43.765097131 +0100 -@@ -178,7 +178,11 @@ _gcry_rndlinux_gather_random (void (*add - { - if (fd_random == -1) - { -- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); -+ /* We try to open /dev/random first but in case the open fails -+ we gracefully retry with /dev/urandom. */ -+ fd_random = open_device (NAME_OF_DEV_RANDOM, 0, 0); -+ if (fd_random == -1) -+ fd_random = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 1), 1); - ever_opened |= 1; - } - fd = fd_random; diff --git a/libgcrypt-1.7.3-aliasing.patch b/libgcrypt-1.7.3-aliasing.patch deleted file mode 100644 index 5fa3b9b..0000000 --- a/libgcrypt-1.7.3-aliasing.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff -up libgcrypt-1.7.3/cipher/bufhelp.h.aliasing libgcrypt-1.7.3/cipher/bufhelp.h ---- libgcrypt-1.7.3/cipher/bufhelp.h.aliasing 2016-04-07 17:30:08.000000000 +0200 -+++ libgcrypt-1.7.3/cipher/bufhelp.h 2016-11-22 17:00:13.065692916 +0100 -@@ -35,6 +35,11 @@ - # define BUFHELP_FAST_UNALIGNED_ACCESS 1 - #endif - -+#if _GCRY_GCC_VERSION >= 40400 -+# pragma GCC push_options -+# pragma GCC optimize ("no-strict-aliasing") -+#endif -+ - - #ifdef BUFHELP_FAST_UNALIGNED_ACCESS - /* Define type with one-byte alignment on architectures with fast unaligned -@@ -429,4 +434,8 @@ static inline void buf_put_le64(void *_b - - #endif /*BUFHELP_FAST_UNALIGNED_ACCESS*/ - -+#if _GCRY_GCC_VERSION >= 40400 -+# pragma GCC pop_options -+#endif -+ - #endif /*GCRYPT_BUFHELP_H*/ diff --git a/libgcrypt-1.7.3-fips-cfgrandom.patch b/libgcrypt-1.7.3-fips-cfgrandom.patch deleted file mode 100644 index c9786e4..0000000 --- a/libgcrypt-1.7.3-fips-cfgrandom.patch +++ /dev/null @@ -1,104 +0,0 @@ -diff -up libgcrypt-1.7.3/random/random-drbg.c.cfgrandom libgcrypt-1.7.3/random/random-drbg.c ---- libgcrypt-1.7.3/random/random-drbg.c.cfgrandom 2016-04-07 17:30:08.000000000 +0200 -+++ libgcrypt-1.7.3/random/random-drbg.c 2016-11-22 15:54:02.227319203 +0100 -@@ -627,8 +627,13 @@ drbg_get_entropy (drbg_state_t drbg, uns - read_cb_size = len; - read_cb_len = 0; - #if USE_RNDLINUX -+ /* First read from /etc/gcrypt/rngseed if available */ -+ _gcry_rndlinux_gather_random (drbg_read_cb, 0, len, -+ -1); -+ read_cb_len = 0; -+ /* then use /dev/urandom. */ - rc = _gcry_rndlinux_gather_random (drbg_read_cb, 0, len, -- GCRY_VERY_STRONG_RANDOM); -+ GCRY_STRONG_RANDOM); - #elif USE_RNDUNIX - rc = _gcry_rndunix_gather_random (drbg_read_cb, 0, len, - GCRY_VERY_STRONG_RANDOM); -diff -up libgcrypt-1.7.3/random/rndlinux.c.cfgrandom libgcrypt-1.7.3/random/rndlinux.c ---- libgcrypt-1.7.3/random/rndlinux.c.cfgrandom 2016-07-14 11:19:17.000000000 +0200 -+++ libgcrypt-1.7.3/random/rndlinux.c 2016-11-22 15:45:19.921141761 +0100 -@@ -40,7 +40,9 @@ - #include "g10lib.h" - #include "rand-internal.h" - --static int open_device (const char *name, int retry); -+#define NAME_OF_CFG_RNGSEED "/etc/gcrypt/rngseed" -+ -+static int open_device (const char *name, int retry, int fatal); - - - static int -@@ -63,7 +65,7 @@ set_cloexec_flag (int fd) - * a fatal error but retries until it is able to reopen the device. - */ - static int --open_device (const char *name, int retry) -+open_device (const char *name, int retry, int fatal) - { - int fd; - -@@ -71,6 +73,8 @@ open_device (const char *name, int retry - _gcry_random_progress ("open_dev_random", 'X', 1, 0); - again: - fd = open (name, O_RDONLY); -+ if (fd == -1 && !fatal) -+ return fd; - if (fd == -1 && retry) - { - struct timeval tv; -@@ -115,6 +119,7 @@ _gcry_rndlinux_gather_random (void (*add - { - static int fd_urandom = -1; - static int fd_random = -1; -+ static int fd_configured = -1; - static unsigned char ever_opened; - int fd; - int n; -@@ -138,6 +143,11 @@ _gcry_rndlinux_gather_random (void (*add - close (fd_urandom); - fd_urandom = -1; - } -+ if (fd_configured != -1) -+ { -+ close (fd_configured); -+ fd_configured = -1; -+ } - return 0; - } - -@@ -165,20 +175,30 @@ _gcry_rndlinux_gather_random (void (*add - that we always require the device to be existent but want a more - graceful behaviour if the rarely needed close operation has been - used and the device needs to be re-opened later. */ -+ -+ if (level == -1) -+ { -+ if (fd_configured == -1) -+ fd_configured = open_device ( NAME_OF_CFG_RNGSEED, 0, 0 ); -+ fd = fd_configured; -+ if (fd == -1) -+ return -1; -+ } -+ - if (level >= 2) - { - if (fd_random == -1) - { -- fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1)); -+ fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1), 1); - ever_opened |= 1; - } - fd = fd_random; - } -- else -+ else if (level != -1) - { - if (fd_urandom == -1) - { -- fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); -+ fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2), 1); - ever_opened |= 2; - } - fd = fd_urandom; diff --git a/libgcrypt-1.7.3-tests.patch b/libgcrypt-1.8.0-tests.patch similarity index 72% rename from libgcrypt-1.7.3-tests.patch rename to libgcrypt-1.8.0-tests.patch index f1b461c..f3dfe96 100644 --- a/libgcrypt-1.7.3-tests.patch +++ b/libgcrypt-1.8.0-tests.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.7.3/cipher/dsa.c.tests libgcrypt-1.7.3/cipher/dsa.c ---- libgcrypt-1.7.3/cipher/dsa.c.tests 2016-04-07 17:30:08.000000000 +0200 -+++ libgcrypt-1.7.3/cipher/dsa.c 2016-11-22 15:33:48.813026002 +0100 +diff -up libgcrypt-1.8.0/cipher/dsa.c.tests libgcrypt-1.8.0/cipher/dsa.c +--- libgcrypt-1.8.0/cipher/dsa.c.tests 2016-04-07 17:30:08.000000000 +0200 ++++ libgcrypt-1.8.0/cipher/dsa.c 2017-08-15 15:10:39.551600227 +0200 @@ -457,11 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un &prime_q, &prime_p, r_counter, @@ -42,9 +42,9 @@ diff -up libgcrypt-1.7.3/cipher/dsa.c.tests libgcrypt-1.7.3/cipher/dsa.c return GPG_ERR_MISSING_VALUE; } -diff -up libgcrypt-1.7.3/cipher/rsa.c.tests libgcrypt-1.7.3/cipher/rsa.c ---- libgcrypt-1.7.3/cipher/rsa.c.tests 2016-07-14 11:19:17.000000000 +0200 -+++ libgcrypt-1.7.3/cipher/rsa.c 2016-11-22 15:25:05.426838229 +0100 +diff -up libgcrypt-1.8.0/cipher/rsa.c.tests libgcrypt-1.8.0/cipher/rsa.c +--- libgcrypt-1.8.0/cipher/rsa.c.tests 2017-07-06 10:21:36.000000000 +0200 ++++ libgcrypt-1.8.0/cipher/rsa.c 2017-08-15 15:10:39.551600227 +0200 @@ -696,7 +696,7 @@ generate_x931 (RSA_secret_key *sk, unsig *swapped = 0; @@ -54,15 +54,15 @@ diff -up libgcrypt-1.7.3/cipher/rsa.c.tests libgcrypt-1.7.3/cipher/rsa.c e_value = 65537; /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ -diff -up libgcrypt-1.7.3/tests/keygen.c.tests libgcrypt-1.7.3/tests/keygen.c ---- libgcrypt-1.7.3/tests/keygen.c.tests 2016-04-07 17:30:08.000000000 +0200 -+++ libgcrypt-1.7.3/tests/keygen.c 2016-11-22 15:25:33.178484464 +0100 -@@ -257,11 +257,11 @@ check_rsa_keys (void) +diff -up libgcrypt-1.8.0/tests/keygen.c.tests libgcrypt-1.8.0/tests/keygen.c +--- libgcrypt-1.8.0/tests/keygen.c.tests 2017-08-15 15:10:39.551600227 +0200 ++++ libgcrypt-1.8.0/tests/keygen.c 2017-08-15 15:16:05.433176171 +0200 +@@ -200,11 +200,11 @@ check_rsa_keys (void) if (verbose) -- show ("creating 512 bit RSA key with e=257\n"); -+ show ("creating 1024 bit RSA key with e=257\n"); +- info ("creating 512 bit RSA key with e=257\n"); ++ info ("creating 1024 bit RSA key with e=257\n"); rc = gcry_sexp_new (&keyparm, "(genkey\n" " (rsa\n" @@ -71,12 +71,12 @@ diff -up libgcrypt-1.7.3/tests/keygen.c.tests libgcrypt-1.7.3/tests/keygen.c " (rsa-use-e 3:257)\n" " ))", 0, 1); if (rc) -@@ -282,11 +282,11 @@ check_rsa_keys (void) +@@ -225,11 +225,11 @@ check_rsa_keys (void) gcry_sexp_release (key); if (verbose) -- show ("creating 512 bit RSA key with default e\n"); -+ show ("creating 1024 bit RSA key with default e\n"); +- info ("creating 512 bit RSA key with default e\n"); ++ info ("creating 1024 bit RSA key with default e\n"); rc = gcry_sexp_new (&keyparm, "(genkey\n" " (rsa\n" @@ -85,12 +85,12 @@ diff -up libgcrypt-1.7.3/tests/keygen.c.tests libgcrypt-1.7.3/tests/keygen.c " (rsa-use-e 1:0)\n" " ))", 0, 1); if (rc) -@@ -366,12 +366,12 @@ check_dsa_keys (void) +@@ -309,12 +309,12 @@ check_dsa_keys (void) } if (verbose) -- show ("creating 1536 bit DSA key\n"); -+ show ("creating 2048 bit DSA key\n"); +- info ("creating 1536 bit DSA key\n"); ++ info ("creating 2048 bit DSA key\n"); rc = gcry_sexp_new (&keyparm, "(genkey\n" " (dsa\n" @@ -101,10 +101,10 @@ diff -up libgcrypt-1.7.3/tests/keygen.c.tests libgcrypt-1.7.3/tests/keygen.c " ))", 0, 1); if (rc) die ("error creating S-expression: %s\n", gpg_strerror (rc)); -diff -up libgcrypt-1.7.3/tests/pubkey.c.tests libgcrypt-1.7.3/tests/pubkey.c ---- libgcrypt-1.7.3/tests/pubkey.c.tests 2016-07-14 11:19:17.000000000 +0200 -+++ libgcrypt-1.7.3/tests/pubkey.c 2016-11-22 18:40:23.220813982 +0100 -@@ -651,7 +651,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ +diff -up libgcrypt-1.8.0/tests/pubkey.c.tests libgcrypt-1.8.0/tests/pubkey.c +--- libgcrypt-1.8.0/tests/pubkey.c.tests 2017-01-18 15:24:25.000000000 +0100 ++++ libgcrypt-1.8.0/tests/pubkey.c 2017-08-15 15:10:39.552600207 +0200 +@@ -595,7 +595,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ " (use-fips186)" " (transient-key)" " (derive-parms" diff --git a/libgcrypt-1.7.6-use-poll.patch b/libgcrypt-1.8.0-use-poll.patch similarity index 76% rename from libgcrypt-1.7.6-use-poll.patch rename to libgcrypt-1.8.0-use-poll.patch index 4ec20ce..07df8dd 100644 --- a/libgcrypt-1.7.6-use-poll.patch +++ b/libgcrypt-1.8.0-use-poll.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.7.6/random/rndlinux.c.use-poll libgcrypt-1.7.6/random/rndlinux.c ---- libgcrypt-1.7.6/random/rndlinux.c.use-poll 2017-01-30 14:20:13.665662981 +0100 -+++ libgcrypt-1.7.6/random/rndlinux.c 2017-01-30 14:27:45.957027214 +0100 +diff -up libgcrypt-1.8.0/random/rndlinux.c.use-poll libgcrypt-1.8.0/random/rndlinux.c +--- libgcrypt-1.8.0/random/rndlinux.c.use-poll 2017-06-24 13:34:29.000000000 +0200 ++++ libgcrypt-1.8.0/random/rndlinux.c 2017-08-15 15:37:37.604629377 +0200 @@ -32,6 +32,7 @@ #include #include @@ -9,7 +9,7 @@ diff -up libgcrypt-1.7.6/random/rndlinux.c.use-poll libgcrypt-1.7.6/random/rndli #if defined(__linux__) && defined(HAVE_SYSCALL) # include #endif -@@ -211,9 +212,8 @@ _gcry_rndlinux_gather_random (void (*add +@@ -216,9 +217,8 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) { @@ -20,7 +20,7 @@ diff -up libgcrypt-1.7.6/random/rndlinux.c.use-poll libgcrypt-1.7.6/random/rndli /* If we have a modern Linux kernel and we want to read from the * the non-blocking /dev/urandom, we first try to use the new -@@ -269,33 +269,22 @@ _gcry_rndlinux_gather_random (void (*add +@@ -276,36 +276,25 @@ _gcry_rndlinux_gather_random (void (*add any_need_entropy = 1; } @@ -35,13 +35,19 @@ diff -up libgcrypt-1.7.6/random/rndlinux.c.use-poll libgcrypt-1.7.6/random/rndli + pfd.fd = fd; + pfd.events = POLLIN; + -+ if ( !(rc=poll(&pfd, 1, delay)) ) ++ _gcry_pre_syscall (); ++ rc = poll(&pfd, 1, delay); ++ _gcry_post_syscall (); ++ if (!rc) { - FD_ZERO(&rfds); - FD_SET(fd, &rfds); - tv.tv_sec = delay; - tv.tv_usec = delay? 0 : 100000; -- if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) ) +- _gcry_pre_syscall (); +- rc = select (fd+1, &rfds, NULL, NULL, &tv); +- _gcry_post_syscall (); +- if (!rc) - { - any_need_entropy = 1; - delay = 3; /* Use 3 seconds henceforth. */ @@ -68,4 +74,4 @@ diff -up libgcrypt-1.7.6/random/rndlinux.c.use-poll libgcrypt-1.7.6/random/rndli + continue; } - /* Read from the device. */ + do diff --git a/libgcrypt.spec b/libgcrypt.spec index ec79a86..d38e9b8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,32 +1,30 @@ Name: libgcrypt -Version: 1.7.8 -Release: 3%{?dist} +Version: 1.8.0 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with # the hobble-libgcrypt script. # (We replace it with RH approved ECC in Source4-5) -#Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 -#Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig +#Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2 +#Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2.sig Source2: wk@g10code.com Source3: hobble-libgcrypt # Approved ECC support (from 1.6.1) Source4: ecc-curves.c Source5: curves.c Source6: t-mpi-point.c +Source7: random.conf # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump Patch2: libgcrypt-1.6.2-use-fipscheck.patch # fix tests in the FIPS mode, allow CAVS testing of DSA keygen -Patch5: libgcrypt-1.7.3-tests.patch -# add configurable source of RNG seed and seed by default -# from /dev/urandom in the FIPS mode -Patch6: libgcrypt-1.7.3-fips-cfgrandom.patch +Patch5: libgcrypt-1.8.0-tests.patch # update the CAVS tests Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness -Patch11: libgcrypt-1.7.6-use-poll.patch +Patch11: libgcrypt-1.8.0-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC @@ -35,10 +33,6 @@ Patch14: libgcrypt-1.7.3-ecc-test-fix.patch Patch18: libgcrypt-1.6.2-fips-ctor.patch # Block some operations if in FIPS non-operational state Patch22: libgcrypt-1.7.3-fips-reqs.patch -# do not use strict aliasing for bufhelp functions -Patch23: libgcrypt-1.7.3-aliasing.patch -# use only urandom if /dev/random cannot be opened -Patch24: libgcrypt-1.6.3-urandom-only.patch %define gcrylibdir %{_libdir} @@ -76,15 +70,13 @@ applications using libgcrypt. %{SOURCE3} %patch2 -p1 -b .use-fipscheck %patch5 -p1 -b .tests -%patch6 -p1 -b .cfgrandom %patch7 -p1 -b .cavs %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix %patch18 -p1 -b .fips-ctor %patch22 -p1 -b .fips-reqs -%patch23 -p1 -b .aliasing -%patch24 -p1 -b .urandom-only +#%patch23 -p1 -b .aliasing cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -155,6 +147,7 @@ popd # Create /etc/gcrypt (hardwired, not dependent on the configure invocation) so # that _someone_ owns it. mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt +install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %post -p /sbin/ldconfig @@ -174,6 +167,7 @@ exit 0 %files %defattr(-,root,root,-) %dir /etc/gcrypt +%config(noreplace) /etc/gcrypt/random.conf %{gcrylibdir}/libgcrypt.so.* %{gcrylibdir}/.libgcrypt.so.*.hmac %{!?_licensedir:%global license %%doc} @@ -196,6 +190,9 @@ exit 0 %license COPYING %changelog +* Wed Aug 16 2017 Tomáš Mráz 1.8.0-1 +- new upstream version 1.8.0 + * Thu Aug 03 2017 Fedora Release Engineering - 1.7.8-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_27_Binutils_Mass_Rebuild diff --git a/random.conf b/random.conf new file mode 100644 index 0000000..6041bcd --- /dev/null +++ b/random.conf @@ -0,0 +1,4 @@ +# use only /dev/urandom - see https://www.2uo.de/myths-about-urandom/ +only-urandom +# Keep jitter entropy generator enabled (should do no harm) +#disable-jent diff --git a/t-mpi-point.c b/t-mpi-point.c index b1b8b2c..3a67d8f 100644 --- a/t-mpi-point.c +++ b/t-mpi-point.c @@ -26,29 +26,8 @@ #include #include -#include "../src/gcrypt-int.h" - #define PGM "t-mpi-point" - -static const char *wherestr; -static int verbose; -static int debug; -static int error_count; - - -#define my_isascii(c) (!((c) & 0x80)) -#define digitp(p) (*(p) >= '0' && *(p) <= '9') -#define hexdigitp(a) (digitp (a) \ - || (*(a) >= 'A' && *(a) <= 'F') \ - || (*(a) >= 'a' && *(a) <= 'f')) -#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ - *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) -#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) -#define xmalloc(a) gcry_xmalloc ((a)) -#define xcalloc(a,b) gcry_xcalloc ((a),(b)) -#define xfree(a) gcry_free ((a)) -#define pass() do { ; } while (0) - +#include "t-common.h" static struct { @@ -155,50 +134,6 @@ static const char sample_ed25519_d[] = "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"; -static void -show (const char *format, ...) -{ - va_list arg_ptr; - - if (!verbose) - return; - fprintf (stderr, "%s: ", PGM); - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); -} - -static void -fail (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", PGM); - if (wherestr) - fprintf (stderr, "%s: ", wherestr); - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - error_count++; -} - -static void -die (const char *format, ...) -{ - va_list arg_ptr; - - fflush (stdout); - fprintf (stderr, "%s: ", PGM); - if (wherestr) - fprintf (stderr, "%s: ", wherestr); - va_start (arg_ptr, format); - vfprintf (stderr, format, arg_ptr); - va_end (arg_ptr); - exit (1); -} - - static void print_mpi_2 (const char *text, const char *text2, gcry_mpi_t a) { @@ -310,7 +245,7 @@ hex2mpiopa (const char *string) die ("hex2mpiopa '%s' failed: parser error\n", string); val = gcry_mpi_set_opaque (NULL, buffer, buflen*8); if (!buffer) - die ("hex2mpiopa '%s' failed: set_opaque error%s\n", string); + die ("hex2mpiopa '%s' failed: set_opaque error\n", string); return val; } @@ -360,11 +295,11 @@ ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a) static void set_get_point (void) { - gcry_mpi_point_t point; + gcry_mpi_point_t point, point2; gcry_mpi_t x, y, z; wherestr = "set_get_point"; - show ("checking point setting functions\n"); + info ("checking point setting functions\n"); point = gcry_mpi_point_new (0); x = gcry_mpi_set_ui (NULL, 17); @@ -404,7 +339,22 @@ set_get_point (void) || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) fail ("point_snatch_set/point_get failed\n"); + point2 = gcry_mpi_point_copy (point); + + gcry_mpi_point_get (x, y, z, point2); + if (gcry_mpi_cmp_ui (x, 17) + || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) + fail ("point_copy failed (1)\n"); + gcry_mpi_point_release (point); + + gcry_mpi_point_get (x, y, z, point2); + if (gcry_mpi_cmp_ui (x, 17) + || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) + fail ("point_copy failed (2)\n"); + + gcry_mpi_point_release (point2); + gcry_mpi_release (x); gcry_mpi_release (y); gcry_mpi_release (z); @@ -419,7 +369,7 @@ context_alloc (void) gcry_mpi_t p, a; wherestr = "context_alloc"; - show ("checking context functions\n"); + info ("checking context functions\n"); p = gcry_mpi_set_ui (NULL, 1); a = gcry_mpi_set_ui (NULL, 1); @@ -526,7 +476,7 @@ context_param (void) wherestr = "context_param"; - show ("checking standard curves\n"); + info ("checking standard curves\n"); for (idx=0; test_curve[idx].desc; idx++) { /* P-192 and Ed25519 are not supported in fips mode */ @@ -535,7 +485,7 @@ context_param (void) if (!strcmp(test_curve[idx].desc, "NIST P-192") || !strcmp(test_curve[idx].desc, "Ed25519")) { - show("skipping %s in fips mode\n", test_curve[idx].desc ); + info ("skipping %s in fips mode\n", test_curve[idx].desc ); continue; } } @@ -568,7 +518,7 @@ context_param (void) } - show ("checking sample public key (nistp256)\n"); + info ("checking sample public key (nistp256)\n"); q = hex2mpi (sample_p256_q); err = gcry_sexp_build (&keyparam, NULL, "(public-key(ecc(curve %s)(q %m)))", @@ -639,7 +589,7 @@ context_param (void) if (gcry_fips_mode_active()) goto cleanup; - show ("checking sample public key (Ed25519)\n"); + info ("checking sample public key (Ed25519)\n"); q = hex2mpi (sample_ed25519_q); gcry_sexp_release (keyparam); err = gcry_sexp_build (&keyparam, NULL, @@ -761,7 +711,7 @@ basic_ec_math (void) gcry_mpi_t x, y, z; wherestr = "basic_ec_math"; - show ("checking basic math functions for EC\n"); + info ("checking basic math functions for EC\n"); P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); @@ -847,7 +797,7 @@ twistededwards_math (void) gcry_mpi_t w, a, x, y, z, p, n, b, I; wherestr = "twistededwards_math"; - show ("checking basic Twisted Edwards math\n"); + info ("checking basic Twisted Edwards math\n"); err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519"); if (err) @@ -881,7 +831,7 @@ twistededwards_math (void) /* Check: p % 4 == 1 */ gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR); if (gcry_mpi_cmp_ui (w, 1)) - fail ("failed assertion: p % 4 == 1\n"); + fail ("failed assertion: p %% 4 == 1\n"); /* Check: 2^{n-1} mod n == 1 */ gcry_mpi_sub_ui (a, n, 1); @@ -985,11 +935,11 @@ main (int argc, char **argv) if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); - gcry_control (GCRYCTL_DISABLE_SECMEM, 0); - gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + xgcry_control (GCRYCTL_DISABLE_SECMEM, 0); + xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); if (debug) - gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); - gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); set_get_point (); context_alloc (); @@ -1004,6 +954,6 @@ main (int argc, char **argv) twistededwards_math (); } - show ("All tests completed. Errors: %d\n", error_count); + info ("All tests completed. Errors: %d\n", error_count); return error_count ? 1 : 0; } From 64437a1a3c548a2735a13314de707726488323f9 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 16 Aug 2017 11:36:51 +0200 Subject: [PATCH 102/214] new upstream version 1.8.0 --- .gitignore | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 782e573..d65cb65 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.7.6-hobbled.tar.xz /libgcrypt-1.7.7-hobbled.tar.xz /libgcrypt-1.7.8-hobbled.tar.xz +/libgcrypt-1.8.0-hobbled.tar.xz diff --git a/sources b/sources index 33c4cb4..57bd8e0 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.7.8-hobbled.tar.xz) = 19c13ebdbd24657a9694702f91f045f5fb91b7b68eb4361a6abbb0c1bb90403cf8657d650cf97f9fd61d7ed571682181b34d35777d634187bfd0a78b2857efe1 +SHA512 (libgcrypt-1.8.0-hobbled.tar.xz) = 6ee60b53935dfe261cc5ebf620551e2a2ea0083a273f84c949f213e3a6baf61807bbfa2a76c09b21dfc4116fba3a9e315335a4228e28f371e99e1542be9c9c40 From 6c13b08816b206b3ff2bab09fe55157cb3417fd1 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 16 Aug 2017 15:15:51 +0200 Subject: [PATCH 103/214] Fix the t-secmem on PPC64 --- libgcrypt-1.8.0-build.patch | 34 ++++++++++++++++++++++++++++++++++ libgcrypt.spec | 4 +++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.8.0-build.patch diff --git a/libgcrypt-1.8.0-build.patch b/libgcrypt-1.8.0-build.patch new file mode 100644 index 0000000..02d8821 --- /dev/null +++ b/libgcrypt-1.8.0-build.patch @@ -0,0 +1,34 @@ +diff -up libgcrypt-1.8.0/tests/t-secmem.c.build libgcrypt-1.8.0/tests/t-secmem.c +--- libgcrypt-1.8.0/tests/t-secmem.c.build 2017-01-18 15:24:25.000000000 +0100 ++++ libgcrypt-1.8.0/tests/t-secmem.c 2017-08-16 15:12:48.948224849 +0200 +@@ -25,6 +25,7 @@ + #include + #include + #include ++#include + + #define PGM "t-secmem" + +@@ -37,17 +38,21 @@ test_secmem (void) + { + void *a[28]; + void *b; ++ long oversize; + int i; + + memset (a, 0, sizeof a); + ++ oversize = sysconf (_SC_PAGESIZE); ++ oversize = oversize <= 16384 ? 2048 : oversize - (16384 - 2048); ++ + /* Allocating 28*512=14k should work in the default 16k pool even + * with extrem alignment requirements. */ + for (i=0; i < DIM(a); i++) + a[i] = gcry_xmalloc_secure (512); + + /* Allocating another 2k should fail for the default 16k pool. */ +- b = gcry_malloc_secure (2048); ++ b = gcry_malloc_secure (oversize); + if (b) + fail ("allocation did not fail as expected\n"); + diff --git a/libgcrypt.spec b/libgcrypt.spec index d38e9b8..91a71c9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -33,6 +33,8 @@ Patch14: libgcrypt-1.7.3-ecc-test-fix.patch Patch18: libgcrypt-1.6.2-fips-ctor.patch # Block some operations if in FIPS non-operational state Patch22: libgcrypt-1.7.3-fips-reqs.patch +# Fix the t-secmem on PPC64 +Patch23: libgcrypt-1.8.0-build.patch %define gcrylibdir %{_libdir} @@ -76,7 +78,7 @@ applications using libgcrypt. %patch14 -p1 -b .eccfix %patch18 -p1 -b .fips-ctor %patch22 -p1 -b .fips-reqs -#%patch23 -p1 -b .aliasing +%patch23 -p1 -b .build cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ From 66671a43b4ea40f8cf7f2e9b198fd293a8484ad7 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 5 Sep 2017 14:35:26 +0200 Subject: [PATCH 104/214] new upstream version 1.8.1 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 91a71c9..229a6a8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.8.0 +Version: 1.8.1 Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -192,6 +192,9 @@ exit 0 %license COPYING %changelog +* Tue Sep 5 2017 Tomáš Mráz 1.8.1-1 +- new upstream version 1.8.1 + * Wed Aug 16 2017 Tomáš Mráz 1.8.0-1 - new upstream version 1.8.0 From 32333cbd3a282a196c13a193ed0d2483c204b3b5 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 5 Sep 2017 14:47:03 +0200 Subject: [PATCH 105/214] new upstream version 1.8.1 --- .gitignore | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d65cb65..c1202bb 100644 --- a/.gitignore +++ b/.gitignore @@ -16,3 +16,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.7.7-hobbled.tar.xz /libgcrypt-1.7.8-hobbled.tar.xz /libgcrypt-1.8.0-hobbled.tar.xz +/libgcrypt-1.8.1-hobbled.tar.xz diff --git a/sources b/sources index 57bd8e0..c36a315 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.8.0-hobbled.tar.xz) = 6ee60b53935dfe261cc5ebf620551e2a2ea0083a273f84c949f213e3a6baf61807bbfa2a76c09b21dfc4116fba3a9e315335a4228e28f371e99e1542be9c9c40 +SHA512 (libgcrypt-1.8.1-hobbled.tar.xz) = d9c2119e4a43fa4d0e5b55fbd128965a9dc153fd2ad36fcda4c205d409380aa7361dcfec1e5a1279060d8db94b4e9970cf4b97b12299506d014813a100fff4e1 From f1706aee3290a6147757c0a42dfc0c57a957f2da Mon Sep 17 00:00:00 2001 From: Bruno Goncalves Date: Fri, 29 Sep 2017 09:06:32 +0200 Subject: [PATCH 106/214] Add CI tests using the standard test interface --- tests/smoke-test/Makefile | 71 +++++++++++++++++++++++++++++++++++++ tests/smoke-test/PURPOSE | 3 ++ tests/smoke-test/runtest.sh | 71 +++++++++++++++++++++++++++++++++++++ tests/tests.yml | 21 +++++++++++ 4 files changed, 166 insertions(+) create mode 100644 tests/smoke-test/Makefile create mode 100644 tests/smoke-test/PURPOSE create mode 100755 tests/smoke-test/runtest.sh create mode 100644 tests/tests.yml diff --git a/tests/smoke-test/Makefile b/tests/smoke-test/Makefile new file mode 100644 index 0000000..22dfe9b --- /dev/null +++ b/tests/smoke-test/Makefile @@ -0,0 +1,71 @@ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Makefile of /CoreOS/libgcrypt/smoke-test +# Description: Test calls upstream test suite. +# Author: Ondrej Moris +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2010 Red Hat, Inc. All rights reserved. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +export TEST=/CoreOS/libgcrypt/smoke-test +export TESTVERSION=1.0 + +BUILT_FILES= + +FILES=$(METADATA) runtest.sh Makefile PURPOSE + +.PHONY: all install download clean + +run: $(FILES) build + ./runtest.sh + +build: $(BUILT_FILES) + chmod a+x runtest.sh + +clean: + rm -f *~ $(BUILT_FILES) + + +include /usr/share/rhts/lib/rhts-make.include + +$(METADATA): Makefile + @echo "Owner: Ondrej Moris " > $(METADATA) + @echo "Name: $(TEST)" >> $(METADATA) + @echo "TestVersion: $(TESTVERSION)" >> $(METADATA) + @echo "Path: $(TEST_DIR)" >> $(METADATA) + @echo "Description: Test calls upstream test suite." >> $(METADATA) + @echo "Type: Sanity" >> $(METADATA) + @echo "TestTime: 15m" >> $(METADATA) + @echo "RunFor: libgcrypt" >> $(METADATA) + @echo "Requires: libgcrypt" >> $(METADATA) + @echo "Requires: nfs-utils" >> $(METADATA) + @echo "Requires: rpm-build" >> $(METADATA) + @echo "Requires: gawk" >> $(METADATA) + @echo "Requires: gcc-c++ fipscheck" >> $(METADATA) + @echo "Requires: libgpg-error-devel yum-utils wget" >> $(METADATA) + @echo "Requires: pkgconfig texinfo libselinux-utils" >> $(METADATA) + @echo "Releases: -RHEL3 -RHEL4" >> $(METADATA) + @echo "Priority: Normal" >> $(METADATA) + @echo "Architectures: i386 x86_64 s390x ia64" >> $(METADATA) + @echo "License: GPLv2" >> $(METADATA) + @echo "Confidential: no" >> $(METADATA) + @echo "Destructive: no" >> $(METADATA) + + rhts-lint $(METADATA) diff --git a/tests/smoke-test/PURPOSE b/tests/smoke-test/PURPOSE new file mode 100644 index 0000000..5df6ca9 --- /dev/null +++ b/tests/smoke-test/PURPOSE @@ -0,0 +1,3 @@ +PURPOSE of /CoreOS/libgcrypt/Sanity/smoke-test +Description: Test calls upstream test suite. +Author: Ondrej Moris diff --git a/tests/smoke-test/runtest.sh b/tests/smoke-test/runtest.sh new file mode 100755 index 0000000..dd1803d --- /dev/null +++ b/tests/smoke-test/runtest.sh @@ -0,0 +1,71 @@ +#!/bin/bash +# vim: dict=/usr/share/beakerlib/dictionary.vim cpt=.,w,b,u,t,i,k +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# runtest.sh of /CoreOS/libgcrypt/smoke-test +# Description: Test calls upstream test suite. +# Author: Ondrej Moris +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# +# Copyright (c) 2010 Red Hat, Inc. All rights reserved. +# +# This copyrighted material is made available to anyone wishing +# to use, modify, copy, or redistribute it subject to the terms +# and conditions of the GNU General Public License version 2. +# +# This program 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public +# License along with this program; if not, write to the Free +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02110-1301, USA. +# +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# Include rhts environment +#. /usr/bin/rhts-environment.sh +. /usr/share/beakerlib/beakerlib.sh + +PACKAGE="libgcrypt" + +rlJournalStart + + rlPhaseStartSetup + TmpDir=`mktemp -d` + rlAssertRpm $PACKAGE + rlFileBackup --clean "/etc/gcrypt/fips_enabled" + rlRun "pushd $TmpDir" 0 + rlFetchSrcForInstalled $PACKAGE + rlRun "rpm -ihv `ls *.rpm`" 0 + if grep '1' /proc/sys/crypto/fips_enabled; then + rlRun "echo '1' > /etc/gcrypt/fips_enabled" 0 + fi + rlPhaseEnd + + rlPhaseStartTest + TOPDIR=`rpm --eval %_topdir` + rlRun "pushd $TOPDIR" 0 + rlRun "rm -rf BUILD/libgcrypt-*" 0-255 + rlRun "rpmbuild -vv -bc SPECS/libgcrypt.spec" 0 + rlRun "pushd BUILD/libgcrypt-*" 0 + rlRun "fipshmac src/.libs/libgcrypt.so.??" 0 + rlRun "make check > $TmpDir/make_check.out" 0 + rlRun "popd" 0 + rlRun "popd" 0 + rlRun "grep \"All [0-9]\+ tests passed\" $TmpDir/make_check.out" 0 \ + "All tests passed" + rlRun "cat $TmpDir/make_check.out" 0 + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "popd" 0 + rlRun "rm -r $TmpDir" 0 + rlFileRestore + rlPhaseEnd + +rlJournalPrintText +rlJournalEnd diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..8c1d16c --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,21 @@ +- hosts: localhost + tags: + - classic + - container + roles: + - role: standard-test-beakerlib + tests: + - smoke-test + required_packages: + - fipscheck + - gawk + - gcc-c++ + - libgcrypt + - libgpg-error-devel + - libselinux-utils + - nfs-utils + - pkgconfig + - rpm-build + - texinfo + - wget + - yum-utils From e16cfed1d68392a0917e8a0ce3014567dc033edf Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 4 Dec 2017 09:53:29 +0100 Subject: [PATCH 107/214] do not try to open /dev/urandom if getrandom() works (#1380866) --- libgcrypt-1.8.1-getrandom.patch | 39 +++++++++++++++++++++++++++++++++ libgcrypt.spec | 8 ++++++- 2 files changed, 46 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.8.1-getrandom.patch diff --git a/libgcrypt-1.8.1-getrandom.patch b/libgcrypt-1.8.1-getrandom.patch new file mode 100644 index 0000000..c343ae6 --- /dev/null +++ b/libgcrypt-1.8.1-getrandom.patch @@ -0,0 +1,39 @@ +diff -up libgcrypt-1.8.1/random/rndlinux.c.getrandom libgcrypt-1.8.1/random/rndlinux.c +--- libgcrypt-1.8.1/random/rndlinux.c.getrandom 2017-09-05 14:34:28.003872675 +0200 ++++ libgcrypt-1.8.1/random/rndlinux.c 2017-12-04 09:48:38.704845838 +0100 +@@ -35,6 +35,7 @@ + #include + #if defined(__linux__) && defined(HAVE_SYSCALL) + # include ++# include + #endif + + #include "types.h" +@@ -204,6 +205,16 @@ _gcry_rndlinux_gather_random (void (*add + { + if (fd_urandom == -1) + { ++#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) ++ long ret; ++ ++ _gcry_pre_syscall (); ++ ret = syscall (__NR_getrandom, ++ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); ++ _gcry_post_syscall (); ++ if (ret == -1 && errno == ENOSYS) ++ /* The syscall is not supported - fallback to /dev/urandom. */ ++#endif + fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); + ever_opened |= 2; + } +@@ -246,9 +257,7 @@ _gcry_rndlinux_gather_random (void (*add + _gcry_post_syscall (); + } + while (ret == -1 && errno == EINTR); +- if (ret == -1 && errno == ENOSYS) +- ; /* The syscall is not supported - fallback to /dev/urandom. */ +- else ++ if (1) + { /* The syscall is supported. Some sanity checks. */ + if (ret == -1) + log_fatal ("unexpected error from getrandom: %s\n", diff --git a/libgcrypt.spec b/libgcrypt.spec index 229a6a8..d6639df 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.1 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -35,6 +35,8 @@ Patch18: libgcrypt-1.6.2-fips-ctor.patch Patch22: libgcrypt-1.7.3-fips-reqs.patch # Fix the t-secmem on PPC64 Patch23: libgcrypt-1.8.0-build.patch +# Do not try to open /dev/urandom if getrandom() works +Patch24: libgcrypt-1.8.1-getrandom.patch %define gcrylibdir %{_libdir} @@ -79,6 +81,7 @@ applications using libgcrypt. %patch18 -p1 -b .fips-ctor %patch22 -p1 -b .fips-reqs %patch23 -p1 -b .build +%patch24 -p1 -b .getrandom cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -192,6 +195,9 @@ exit 0 %license COPYING %changelog +* Mon Dec 4 2017 Tomáš Mráz 1.8.1-2 +- do not try to open /dev/urandom if getrandom() works (#1380866) + * Tue Sep 5 2017 Tomáš Mráz 1.8.1-1 - new upstream version 1.8.1 From ed535bbc523714d062a3a5949e7924ff3f7cd403 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 5 Dec 2017 11:54:01 +0100 Subject: [PATCH 108/214] do not try to access() /dev/urandom either if getrandom() works --- libgcrypt-1.8.1-getrandom.patch | 37 +++++++++++++++++++++++++++++++++ libgcrypt.spec | 5 ++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/libgcrypt-1.8.1-getrandom.patch b/libgcrypt-1.8.1-getrandom.patch index c343ae6..470acd3 100644 --- a/libgcrypt-1.8.1-getrandom.patch +++ b/libgcrypt-1.8.1-getrandom.patch @@ -1,3 +1,40 @@ +diff -up libgcrypt-1.8.1/random/random-csprng.c.getrandom libgcrypt-1.8.1/random/random-csprng.c +--- libgcrypt-1.8.1/random/random-csprng.c.getrandom 2017-08-27 09:05:36.000000000 +0200 ++++ libgcrypt-1.8.1/random/random-csprng.c 2017-12-05 11:49:06.609801947 +0100 +@@ -55,6 +55,10 @@ + #ifdef __MINGW32__ + #include + #endif ++#if defined(__linux__) && defined(HAVE_SYSCALL) ++# include ++# include ++#endif + #include "g10lib.h" + #include "random.h" + #include "rand-internal.h" +@@ -1116,6 +1120,22 @@ getfnc_gather_random (void))(void (*)(co + enum random_origins, size_t, int); + + #if USE_RNDLINUX ++#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) ++ long ret; ++ char buffer[1]; ++ ++ _gcry_pre_syscall (); ++ ret = syscall (__NR_getrandom, ++ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); ++ gcry_post_syscall (); ++ if (ret != -1 || errno != ENOSYS) ++ { ++ fnc = _gcry_rndlinux_gather_random; ++ return fnc; ++ } ++ else ++ /* The syscall is not supported - fallback to /dev/urandom. */ ++#endif + if ( !access (NAME_OF_DEV_RANDOM, R_OK) + && !access (NAME_OF_DEV_URANDOM, R_OK)) + { diff -up libgcrypt-1.8.1/random/rndlinux.c.getrandom libgcrypt-1.8.1/random/rndlinux.c --- libgcrypt-1.8.1/random/rndlinux.c.getrandom 2017-09-05 14:34:28.003872675 +0200 +++ libgcrypt-1.8.1/random/rndlinux.c 2017-12-04 09:48:38.704845838 +0100 diff --git a/libgcrypt.spec b/libgcrypt.spec index d6639df..822aeba 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.1 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -195,6 +195,9 @@ exit 0 %license COPYING %changelog +* Tue Dec 5 2017 Tomáš Mráz 1.8.1-3 +- do not try to access() /dev/urandom either if getrandom() works + * Mon Dec 4 2017 Tomáš Mráz 1.8.1-2 - do not try to open /dev/urandom if getrandom() works (#1380866) From ea4d1dc728b3debbe2c74b144e140ff00f228085 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 6 Dec 2017 09:04:48 +0100 Subject: [PATCH 109/214] Typo in the getrandom patch. --- libgcrypt-1.8.1-getrandom.patch | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgcrypt-1.8.1-getrandom.patch b/libgcrypt-1.8.1-getrandom.patch index 470acd3..ea3b1ef 100644 --- a/libgcrypt-1.8.1-getrandom.patch +++ b/libgcrypt-1.8.1-getrandom.patch @@ -23,7 +23,7 @@ diff -up libgcrypt-1.8.1/random/random-csprng.c.getrandom libgcrypt-1.8.1/random + _gcry_pre_syscall (); + ret = syscall (__NR_getrandom, + (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ gcry_post_syscall (); ++ _gcry_post_syscall (); + if (ret != -1 || errno != ENOSYS) + { + fnc = _gcry_rndlinux_gather_random; From ff389a60e814213933732dca655ec8e0752e39ea Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 21 Dec 2017 11:31:50 +0100 Subject: [PATCH 110/214] new upstream version 1.8.2 --- .gitignore | 1 + libgcrypt-1.8.0-build.patch | 34 ---------------------------------- libgcrypt.spec | 10 +++++----- sources | 2 +- 4 files changed, 7 insertions(+), 40 deletions(-) delete mode 100644 libgcrypt-1.8.0-build.patch diff --git a/.gitignore b/.gitignore index c1202bb..e3596b3 100644 --- a/.gitignore +++ b/.gitignore @@ -17,3 +17,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.7.8-hobbled.tar.xz /libgcrypt-1.8.0-hobbled.tar.xz /libgcrypt-1.8.1-hobbled.tar.xz +/libgcrypt-1.8.2-hobbled.tar.xz diff --git a/libgcrypt-1.8.0-build.patch b/libgcrypt-1.8.0-build.patch deleted file mode 100644 index 02d8821..0000000 --- a/libgcrypt-1.8.0-build.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff -up libgcrypt-1.8.0/tests/t-secmem.c.build libgcrypt-1.8.0/tests/t-secmem.c ---- libgcrypt-1.8.0/tests/t-secmem.c.build 2017-01-18 15:24:25.000000000 +0100 -+++ libgcrypt-1.8.0/tests/t-secmem.c 2017-08-16 15:12:48.948224849 +0200 -@@ -25,6 +25,7 @@ - #include - #include - #include -+#include - - #define PGM "t-secmem" - -@@ -37,17 +38,21 @@ test_secmem (void) - { - void *a[28]; - void *b; -+ long oversize; - int i; - - memset (a, 0, sizeof a); - -+ oversize = sysconf (_SC_PAGESIZE); -+ oversize = oversize <= 16384 ? 2048 : oversize - (16384 - 2048); -+ - /* Allocating 28*512=14k should work in the default 16k pool even - * with extrem alignment requirements. */ - for (i=0; i < DIM(a); i++) - a[i] = gcry_xmalloc_secure (512); - - /* Allocating another 2k should fail for the default 16k pool. */ -- b = gcry_malloc_secure (2048); -+ b = gcry_malloc_secure (oversize); - if (b) - fail ("allocation did not fail as expected\n"); - diff --git a/libgcrypt.spec b/libgcrypt.spec index 822aeba..25a1fce 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.8.1 -Release: 3%{?dist} +Version: 1.8.2 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -33,8 +33,6 @@ Patch14: libgcrypt-1.7.3-ecc-test-fix.patch Patch18: libgcrypt-1.6.2-fips-ctor.patch # Block some operations if in FIPS non-operational state Patch22: libgcrypt-1.7.3-fips-reqs.patch -# Fix the t-secmem on PPC64 -Patch23: libgcrypt-1.8.0-build.patch # Do not try to open /dev/urandom if getrandom() works Patch24: libgcrypt-1.8.1-getrandom.patch @@ -80,7 +78,6 @@ applications using libgcrypt. %patch14 -p1 -b .eccfix %patch18 -p1 -b .fips-ctor %patch22 -p1 -b .fips-reqs -%patch23 -p1 -b .build %patch24 -p1 -b .getrandom cp %{SOURCE4} cipher/ @@ -195,6 +192,9 @@ exit 0 %license COPYING %changelog +* Thu Dec 21 2017 Tomáš Mráz 1.8.2-1 +- new upstream version 1.8.2 + * Tue Dec 5 2017 Tomáš Mráz 1.8.1-3 - do not try to access() /dev/urandom either if getrandom() works diff --git a/sources b/sources index c36a315..43e7786 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.8.1-hobbled.tar.xz) = d9c2119e4a43fa4d0e5b55fbd128965a9dc153fd2ad36fcda4c205d409380aa7361dcfec1e5a1279060d8db94b4e9970cf4b97b12299506d014813a100fff4e1 +SHA512 (libgcrypt-1.8.2-hobbled.tar.xz) = a44a5fc1205e9d9eaaabd07be1a079a5a1d59c729cd13310e9bbd30da0c24ad98c40e23ea8a2db22c43aca818745e95004e51f6eb1d63ae4e259506aeecfb692 From e4efa24217b8586def20b1970b649f408928e839 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 6 Feb 2018 16:37:17 +0100 Subject: [PATCH 111/214] fix behavior when getrandom syscall is not present (#1542453) --- libgcrypt-1.8.1-getrandom.patch | 13 +++++++++++-- libgcrypt.spec | 5 ++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/libgcrypt-1.8.1-getrandom.patch b/libgcrypt-1.8.1-getrandom.patch index ea3b1ef..d323b20 100644 --- a/libgcrypt-1.8.1-getrandom.patch +++ b/libgcrypt-1.8.1-getrandom.patch @@ -1,6 +1,6 @@ diff -up libgcrypt-1.8.1/random/random-csprng.c.getrandom libgcrypt-1.8.1/random/random-csprng.c --- libgcrypt-1.8.1/random/random-csprng.c.getrandom 2017-08-27 09:05:36.000000000 +0200 -+++ libgcrypt-1.8.1/random/random-csprng.c 2017-12-05 11:49:06.609801947 +0100 ++++ libgcrypt-1.8.1/random/random-csprng.c 2017-12-06 09:04:27.824175303 +0100 @@ -55,6 +55,10 @@ #ifdef __MINGW32__ #include @@ -37,7 +37,7 @@ diff -up libgcrypt-1.8.1/random/random-csprng.c.getrandom libgcrypt-1.8.1/random { diff -up libgcrypt-1.8.1/random/rndlinux.c.getrandom libgcrypt-1.8.1/random/rndlinux.c --- libgcrypt-1.8.1/random/rndlinux.c.getrandom 2017-09-05 14:34:28.003872675 +0200 -+++ libgcrypt-1.8.1/random/rndlinux.c 2017-12-04 09:48:38.704845838 +0100 ++++ libgcrypt-1.8.1/random/rndlinux.c 2018-02-06 16:31:56.047481806 +0100 @@ -35,6 +35,7 @@ #include #if defined(__linux__) && defined(HAVE_SYSCALL) @@ -63,6 +63,15 @@ diff -up libgcrypt-1.8.1/random/rndlinux.c.getrandom libgcrypt-1.8.1/random/rndl fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); ever_opened |= 2; } +@@ -230,7 +241,7 @@ _gcry_rndlinux_gather_random (void (*add + * syscall and not a new device and thus we are not able to use + * select(2) to have a timeout. */ + #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) +- if (fd == fd_urandom) ++ if (fd == -1) + { + long ret; + size_t nbytes; @@ -246,9 +257,7 @@ _gcry_rndlinux_gather_random (void (*add _gcry_post_syscall (); } diff --git a/libgcrypt.spec b/libgcrypt.spec index 25a1fce..9465cfd 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.2 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -192,6 +192,9 @@ exit 0 %license COPYING %changelog +* Tue Feb 6 2018 Tomáš Mráz 1.8.2-2 +- fix behavior when getrandom syscall is not present (#1542453) + * Thu Dec 21 2017 Tomáš Mráz 1.8.2-1 - new upstream version 1.8.2 From 088a628978336000badffa7a89067be59a2c97f3 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 21 Feb 2018 15:08:25 +0100 Subject: [PATCH 112/214] Add gcc to BuildRequires --- libgcrypt.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index 9465cfd..17e6433 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -43,6 +43,7 @@ Patch24: libgcrypt-1.8.1-getrandom.patch # are in the devel subpackage. License: LGPLv2+ Summary: A general-purpose cryptography library +BuildRequires: gcc BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig BuildRequires: fipscheck # This is needed only when patching the .texi doc. From 297f7867bf1cbaf23494494072b780ecbc667086 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 14 Jun 2018 16:33:23 +0200 Subject: [PATCH 113/214] new upstream version 1.8.3 --- .gitignore | 1 + libgcrypt.spec | 9 +- sources | 2 +- t-mpi-point.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 274 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index e3596b3..fc81043 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.0-hobbled.tar.xz /libgcrypt-1.8.1-hobbled.tar.xz /libgcrypt-1.8.2-hobbled.tar.xz +/libgcrypt-1.8.3-hobbled.tar.xz diff --git a/libgcrypt.spec b/libgcrypt.spec index 17e6433..cd6f445 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.8.2 -Release: 2%{?dist} +Version: 1.8.3 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -11,7 +11,7 @@ Source0: libgcrypt-%{version}-hobbled.tar.xz #Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2.sig Source2: wk@g10code.com Source3: hobble-libgcrypt -# Approved ECC support (from 1.6.1) +# Approved ECC support Source4: ecc-curves.c Source5: curves.c Source6: t-mpi-point.c @@ -193,6 +193,9 @@ exit 0 %license COPYING %changelog +* Thu Jun 14 2018 Tomáš Mráz 1.8.3-1 +- new upstream version 1.8.3 + * Tue Feb 6 2018 Tomáš Mráz 1.8.2-2 - fix behavior when getrandom syscall is not present (#1542453) diff --git a/sources b/sources index 43e7786..365d656 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.8.2-hobbled.tar.xz) = a44a5fc1205e9d9eaaabd07be1a079a5a1d59c729cd13310e9bbd30da0c24ad98c40e23ea8a2db22c43aca818745e95004e51f6eb1d63ae4e259506aeecfb692 +SHA512 (libgcrypt-1.8.3-hobbled.tar.xz) = 6981367a138e03375d7ccf44e2dacb5c96f0ebadf34c2734f95cf3b94a7d7b206a2864304abfbcc3acf0055cc83491fd68d065af33487fefa73f550954a99613 diff --git a/t-mpi-point.c b/t-mpi-point.c index 3a67d8f..b12a8ba 100644 --- a/t-mpi-point.c +++ b/t-mpi-point.c @@ -923,6 +923,271 @@ twistededwards_math (void) } +/* Check the point on curve function. */ +static void +point_on_curve (void) +{ + static struct { + const char *curve; + int oncurve; /* Point below is on the curve. */ + const char *qx; + const char *qy; + } t[] = { + { + "NIST P-256", 0, + "015B4F6775D68D4D2E2192C6B8027FC5A3D49957E453CB251155AA3FF5D3EC9974", + "4BC4C87B57A25E1056831208AB5B8F091142F891E9FF19F1E090B030DF1087B3" + }, { + "NIST P-256", 0, + "D22C316E7EBE7B293BD66808E000806F0754398A5D72A4F9BBC21C26EAC0A651", + "3C8DB80CC3CDE5E530D040536E6A58AAB41C33FA70B30896943513FF3690132D" + }, { + "NIST P-256", 0, + "0130F7E7BC52854CA493A0DE87DC4AB3B4343758F2B634F15B10D70DBC0A5A5291", + "86F9CA73C25CE86D54CB21C181AECBB52A5971334FF5040F76CAE9845ED46023" + }, { + "NIST P-256", 1, + "14957B602C7849F28858C7407696F014BC091D6D68C449560B7A38147D6E6A9B", + "A8E09EFEECFE00C797A0848F38B61992D30C61FAB13021E88C8BD3545B3A6C63" + }, { + "NIST P-256", 0, + "923DE4957241DD97780841C76294DB0D4F5DC04C3045081174764D2D32AD2D53", + "01B4B1A2027C02F0F520A3B01E4CE3C668BF481346A74499C5D1044A53E210B600" + }, { + "NIST P-256", 1, + "9021DFAB8B4DAEAADA634AAA26D6E5FFDF8C0476FF5CA31606C870A1B933FB36", + "9AFC65EEB24E46C7B75712EF29A981CB09FAC56E2B81D3ED024748CCAB1CB77E" + }, { + "NIST P-256", 0, + "011529F0B26DE5E0EB2DA4BFB6C149C802CB52EE479DD666553286928A4005E990", + "0EBC63DB2104884456DC0AA81A3F4E99D93B7AE2CD4B1489655EA9BE6289CF9E" + }, { + "NIST P-256", 1, + "216EC5DE8CA989199D31F0DFCD381DCC9270A0785365EC3E34CA347C070A87BE", + "87A88897BA763509ECC1DBE28D9D37F6F4E70E3B99B1CD3C0B934D4190968A6D" + }, { + "NIST P-256", 1, + "7ABAA44ACBC6016FDB52A6F45F6178E65CBFC35F9920D99149CA9999612CE945", + "88F7684BDCDA31EAFB6CAD859F8AB29B5D921D7DB2B34DF7E40CE36235F45B63" + }, { + "NIST P-256", 0, + "E765B4272D211DD0064189B55421FB76BB3A7756364A6CB1627FAED848157A84", + "C13171CFFB243E06B203F0996BBDD16F52292AD11F2DA81106E9C2FD87F4FA0F" + }, { + "NIST P-256", 0, + "EE4999DFC3A1871EE7A592BE26A09BEC9D9B561613EE9EFB6ED42F17985C9CDC", + "8399E967338A7A618336AF70DA67D9CAC1C19267809652F5C5183C8B129E0902" + }, { + "NIST P-256", 0, + "F755D0CF2642A2C7FBACCC8E9E442B8B047A99C6E052B2FA5AB0544B36B4D51C", + "AA080F17657B6565D9A4D94BD260B54D92FEE8DC4A78C4FC9C19209933AF39B0" + } , { + "NIST P-384", 0, + "CBFC7DBEBF15BEAD682549757F9BBA0E3F67669DF13FCE0EBE8024B725B38B00" + "83EC46A8F2FF3203C5C7F8C7E722A5EF", + "0548FE281BEAB18FD1AB86F59B0CA524479A4A81373C83B78AFFD801FAC75922" + "96470753DCF46173C9AA4A8A4C2FBE51" + }, { + "NIST P-384", 0, + "1DC8E054A883DB81EAEDE6C487B26816C927B8196780525A6CA8F675D2557752" + "02CE06CCBE705EA8A38AA2894D4BEEE6", + "010191050E867AFAA96A199FE9C591CF8B853D81486786DA889124881FB39D2F" + "8E0875F4C4BB1E3D0F8535C7A52306FB82" + }, { + "NIST P-384", 1, + "2539FC368CE1D5E464B6C0FBB12D557B712327DB086975255AD7D17F7E7E4F23" + "D719ED4116E2CC907AEB92CF22331A60", + "8843FDBA742CB64323E49CEBE8DD74908CFC9C3AA0015662DFBB7219E92CF32E" + "9FC63F61EF19DE9B3CEA98D163ABF254" + }, { + "NIST P-384", 0, + "0B786DACF400D43575394349EDD9F9CD145FC7EF737A3C5F69B253BE7639DB24" + "EC2F0CA62FF1F90B6515DE356EC2A404", + "225D6B2939CC7F7133F43353946A682C68DAC6BB75EE9CF6BD9A1609FA915692" + "72F4D3A87E88529754E109BB9B61B03B" + }, { + "NIST P-384", 0, + "76C660C9F58CF2051F9F8B06049694AB6FE418009DE6F0A0833BC690CEC06CC2" + "9A440AD51C94CF5BC28817C8C6E2D302", + "012974E5D9E55304ED294AB6C7A3C65B663E67ABC5E6F6C0F6498B519F2F6CA1" + "8306976291F3ADC0B5ABA42DED376EA9A5" + }, { + "NIST P-384", 0, + "23D758B1EDB8E12E9E707C53C131A19D9464B20EE05C99766F5ABDF9F906AD03" + "B958BF28B022E54E320672C4BAD4EEC0", + "01E9E72870C88F4C82A5AB3CC8A3398E8F006BF3EC05FFBB1EFF8AEE88020FEA" + "9E558E9F58ED1D324C9DCBCB4E8F2A5970" + }, { + "NIST P-384", 0, + "D062B96D5A10F715ACF361F99262ABF0F7693A8BB60ECB1DF459CF95750E4293" + "18BCB9FC60499D009F949298F3F9F47B", + "9089C6328E4B39A73D7EE6FAE1A77E48CE354B83BBCE432082C32C8FD6784B86" + "CFE9C552E2E720F5DA5806503D3784CD" + }, { + "NIST P-384", 0, + "2A951D4D6EB35C43D94866280D37365B82441BC84D62CBFF3365CAB1FD0A3E20" + "823CA8F84D2BBF4EA687885437DE7839", + "01CC7D762AFE613F7B5568BC516568A421159C40599E8D52DE10E8F9488931E1" + "69F3656C322DE45C4A70DC6DB9A661E599" + }, { + "NIST P-384", 1, + "A4BAEE6CDAF3AEB69032B3FBA811707C54F5753670DA5173D891547E8CBAEEF3" + "89B92C9A55573A596123415FBFA26991", + "3241EA716583C11C71BB30AF6C5E3A6637956F17ADBBE641BAB52E8539F9FC7B" + "F3B04F46DBFFE08151E0F0950CC70081" + }, { + "NIST P-384", 0, + "5C0E18B0DE3261BCBCFC7B702C2D75CF481336BFBADF420BADC616235C1966AB" + "4C0F876575DDEC1BDB3F3F04061C9AE4", + "E90C78550D1C922F1D8161D8C9C0576E29BD09CA665376FA887D13FA8DF48352" + "D7BBEEFB803F6CC8FC7895E47F348D33" + }, { + "NIST P-384", 1, + "2015864CD50F0A1A50E6401F44191665C19E4AD4B4903EA9EB464E95D1070E36" + "F1D8325E45734D5A0FDD103F4DF6F83E", + "5FB3E9A5C59DD5C5262A8176CB7032A00AE33AED08485884A3E5D68D9EEB990B" + "F26E8D87EC175577E782AD51A6A12C02" + }, { + "NIST P-384", 1, + "56EBF5310EEF5A5D8D001F570A18625383ECD4882B3FC738A69874E7C9D8F89C" + "187BECA23369DFD6C15CC0DA0629958F", + "C1230B349FB662CB762563DB8F9FCB32D5CCA16120681C474D67D279CCA6F6DB" + "73DE6AA96140B5C457B7486E06D318CE" + }, { + "NIST P-521", 0, + "01E4D82EE5CD6DA37080252295EFA273BBBA6952012D0120EAF131E73F1E5024" + "36E3324624471040030E1C345D65490ECEE9B64E03B15B6C7EB69A39C618BAFEED70", + "03EE3A3C88A6933B7B16016BE4CC4E3BF5EA0625CB3DB2604CDCBBD02CABBC90" + "8904D9DB42998F6C5101D4D4318ACFC9643C9CD641F636D1810ED86F1840EA74F3C0" + }, { + "NIST P-521", 0, + "01F3DFCB5433387B6B2E3F74177F4F3D7300F05E1AD49DE112630E27B1C8A437" + "1E742CB020E0039B5477FC897D17332034F9660B3066764EFF5FB440EB8856E782E3", + "02D337616C9D202DC5E290C486F5855CBD6A8470AE62CA96245834CF49257D8D" + "96D4041B15007650DEE668C00DDBF749054256C571F60980AC74D0DBCA7FB96C2F48" + }, { + "NIST P-521", 1, + "822A846606DC9E96452CAC373567A8B57D9ACA15B177F75DD7EF10C635F52CE4" + "EF6ABEEDB90D3F48F50A0C9015A95C955A25C45DE8413DE3BF899B6B1E62CF7CB8", + "0102771B5F3EC8C36838CEC04DCBC28AD1E38C37DAB0EA89B5EE92D21F7A35CE" + "ABC8B155EDC70154D6DFA2E77EC1D8C4A3406A6BD0ECF8F1EE2AC33A02464CB70C97" + }, { + "NIST P-521", 0, + "F733D48467912D1FFE46CF442F27FDD218D190E7B8A829D822DA3B6BAF9B987E" + "5B4BCCE34499248F59EEAF74F63ED15FF73F243C6FC3FD5E5842F6A3BA34C2022D", + "0281AAAD1B7EEBABEB6EC67932CB7E95717AFA3B4CF7A2DB151CD537C419C3A5" + "156ED9160758190B47696CDC15E81BBAD12975283907A571604DB23F702AEA4B38FF" + }, { + "NIST P-521", 0, + "03B1B274175AAEB5907152E5114CCAEADA28A7ADD4A2B1831C3D8302E8596489" + "E2C98B9B8D0CAE98C03BB11E28CE66D4736449758AF58BAFE40EF5A5FA22C9A43117", + "94C5951F81D544E959EDFC5DC1D5F42FE427871D4FB91A43A0B4A6BEA6B35B9E" + "BC5FB444C70BE4FD47B4ED16704F8C86EF019FC47C7FF2271F8B0DDEA9E2D3BCDD" + }, { + "NIST P-521", 1, + "F2248C318055DE37CD706D4FCAF7E7D96737A4A7B6B8067A66DCD58B6B8DFC55" + "90ECE67F6AA67F9C51B57E7B023075F2F42909BF47361CB6881C10F55FB7215B56", + "0162F735CE6A2ADA54CAF96A12D6888C02DE0A74638CF34CE39DABBACA4D651B" + "7E6ED1A65B551B36BAE7BE474BB6E6905ED0E33C7BA2021885027C7C6E40C5613004" + }, { + "NIST P-521", 0, + "9F08E97FEADCF0A391CA1EA4D97B5FE62D3B164593E12027EB967BD6E1FA841A" + "9831158DF164BCAD0BF3ADA96127745E25F349BDDD52EEA1654892B35960C9C023", + "AE2A25F5440F258AFACA6925C4C9F7AEAD3CB67153C4FACB31AC33F58B43A78C" + "B14F682FF726CEE2A6B6F6B481AEEB29A9B3150F02D1CFB764672BA8294C477291" + }, { + "NIST P-521", 0, + "01047B52014748C904980716953206A93F0D01B34CA94A997407FA93FE304F86" + "17BB6E402B2BB8B434C2671ECE953ABE7BADB75713CD9DF950943A33A9A19ACCDABE", + "7433533F098037DEA616337986887D01C5CC8DEC3DC1FDB9CDF7287EF27CC125" + "54FCF3A5E212DF9DAD9F8A3A7173B23FC6E15930704F3AEE1B074BDDB0ED6823E4" + }, { + "NIST P-521", 0, + "01C2A9EBF51592FE6589F618EAADA1697D9B2EC7CE5D48C9E80FC597642B23F1" + "F0EBE953449762BD3F094F57791D9850AFE98BBDA9872BE399B7BDD617860076BB03", + "0B822E27692F63DB8E12C59BB3CCA172B9BBF613CAE5F9D1474186E45E8B26FF" + "962084E1C6BE74821EDBB60941A3B75516F603719563433383812BFEA89EC14B89" + }, { + "NIST P-521", 0, + "99390F342C3F0D46E80C5B65C61E8AA8ACA0B6D4E1352404586364A05D8398E9" + "2BC71A644E8663F0A9B87D0B3ACAEE32F2AB9B321317AD23059D045EBAB91C5D93", + "82FCF93AE4467EB57766F2B150E736636727E7282500CD482DA70D153D195F2B" + "DF9B96D689A0DC1BB9137B41557A33F202F1B71840544CBEFF03072E77E4BB6F0B" + }, { + "NIST P-521", 1, + "018E48E80594FF5496D8CC7DF8A19D6AA18805A4EF4490038AED6A1E9AA18056" + "D0244A97DCF6D132C6804E3F4F369922119544B4C057D783C848FB798B48730A382C", + "01AF510B4F5E1C40BC9C110216D35E7C6D7A2BEE52914FC98258676288449901" + "F27A07EE91DF2D5D79259712906C3E18A990CBF35BCAC41A952820CE2BA8D0220080" + }, { + "NIST P-521", 1, + "ADCEF3539B4BC831DC0AFD173137A4426152058AFBAE06A17FCB89F4DB6E48B5" + "335CB88F8E4DB475A1E390E5656072F06605BFB84CBF9795B7992ECA04A8E10CA1", + "01BCB985AFD6404B9EDA49B6190AAA346BF7D5909CA440C0F7E505C62FAC8635" + "31D3EB7B2AC4DD4F4404E4B12E9D6D3C596179587F3724B1EFFF684CFDB4B21826B9" + } + }; + gpg_error_t err; + int tidx; + const char *lastcurve = NULL; + gcry_ctx_t ctx = NULL; + gcry_mpi_t qx = NULL; + gcry_mpi_t qy = NULL; + gcry_mpi_point_t Q; + int oncurve; + + wherestr = "point_on_curve"; + for (tidx=0; tidx < DIM (t); tidx++) + { + if (!t[tidx].curve) + { + if (!lastcurve || !ctx) + die ("invalid test vectors at idx %d\n", tidx); + } + else if (!ctx || !lastcurve || strcmp (t[tidx].curve, lastcurve)) + { + lastcurve = t[tidx].curve; + gcry_ctx_release (ctx); + err = gcry_mpi_ec_new (&ctx, NULL, lastcurve); + if (err) + die ("error creating context for curve %s at idx %d: %s\n", + lastcurve, tidx, gpg_strerror (err)); + + info ("checking points on curve %s\n", lastcurve); + } + + gcry_mpi_release (qx); + gcry_mpi_release (qy); + qx = hex2mpi (t[tidx].qx); + qy = hex2mpi (t[tidx].qy); + + Q = gcry_mpi_point_set (NULL, qx, qy, GCRYMPI_CONST_ONE); + if (!Q) + die ("gcry_mpi_point_set(Q) failed at idx %d\n", tidx); + + oncurve = gcry_mpi_ec_curve_point (Q, ctx); + + if (t[tidx].oncurve && !oncurve) + { + fail ("point expected on curve but not identified as such (i=%d):\n", + tidx); + print_point (" Q", Q); + } + else if (!t[tidx].oncurve && oncurve) + { + fail ("point not expected on curve but identified as such (i=%d):\n", + tidx); + print_point (" Q", Q); + } + gcry_mpi_point_release (Q); + } + + gcry_mpi_release (qx); + gcry_mpi_release (qy); + gcry_ctx_release (ctx); +} + + int main (int argc, char **argv) { @@ -945,6 +1210,7 @@ main (int argc, char **argv) context_alloc (); context_param (); basic_ec_math (); + point_on_curve (); /* The tests are for P-192 and ed25519 which are not supported in FIPS mode. */ From 040115104fd18335bb4f54936f2f30702aac07c1 Mon Sep 17 00:00:00 2001 From: Bruno Goncalves Date: Fri, 15 Jun 2018 10:46:49 +0200 Subject: [PATCH 114/214] remove yum-utils dependency from test --- tests/smoke-test/Makefile | 4 ++-- tests/tests.yml | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/smoke-test/Makefile b/tests/smoke-test/Makefile index 22dfe9b..0e0dda3 100644 --- a/tests/smoke-test/Makefile +++ b/tests/smoke-test/Makefile @@ -59,11 +59,11 @@ $(METADATA): Makefile @echo "Requires: rpm-build" >> $(METADATA) @echo "Requires: gawk" >> $(METADATA) @echo "Requires: gcc-c++ fipscheck" >> $(METADATA) - @echo "Requires: libgpg-error-devel yum-utils wget" >> $(METADATA) + @echo "Requires: libgpg-error-devel wget" >> $(METADATA) @echo "Requires: pkgconfig texinfo libselinux-utils" >> $(METADATA) @echo "Releases: -RHEL3 -RHEL4" >> $(METADATA) @echo "Priority: Normal" >> $(METADATA) - @echo "Architectures: i386 x86_64 s390x ia64" >> $(METADATA) + @echo "Architectures: i386 x86_64 s390x ia64" >> $(METADATA) @echo "License: GPLv2" >> $(METADATA) @echo "Confidential: no" >> $(METADATA) @echo "Destructive: no" >> $(METADATA) diff --git a/tests/tests.yml b/tests/tests.yml index 8c1d16c..dd115e9 100644 --- a/tests/tests.yml +++ b/tests/tests.yml @@ -18,4 +18,3 @@ - rpm-build - texinfo - wget - - yum-utils From 1aa209e7a1416c992e8e5d5add868153d31f10b3 Mon Sep 17 00:00:00 2001 From: Jason Tibbitts Date: Tue, 10 Jul 2018 01:39:53 -0500 Subject: [PATCH 115/214] Remove needless use of %defattr --- libgcrypt.spec | 2 -- 1 file changed, 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index cd6f445..8e9b677 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -168,7 +168,6 @@ fi exit 0 %files -%defattr(-,root,root,-) %dir /etc/gcrypt %config(noreplace) /etc/gcrypt/random.conf %{gcrylibdir}/libgcrypt.so.* @@ -178,7 +177,6 @@ exit 0 %doc AUTHORS NEWS THANKS %files devel -%defattr(-,root,root,-) %{_bindir}/%{name}-config %{_bindir}/dumpsexp %{_bindir}/hmac256 From 6b6d4b0dbd4948a48c6c854fdfe283347d3643e8 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 12 Jul 2018 15:45:03 +0200 Subject: [PATCH 116/214] Improve situation with libgcrypt blocking when getting kernel entropy on boot make only_urandom a default in non-presence of configuration file run the full FIPS selftests only when the library is called from application --- libgcrypt-1.6.2-fips-ctor.patch | 74 ----- libgcrypt-1.8.3-fips-ctor.patch | 253 ++++++++++++++++++ ...m.patch => libgcrypt-1.8.3-getrandom.patch | 40 ++- libgcrypt.spec | 11 +- 4 files changed, 289 insertions(+), 89 deletions(-) delete mode 100644 libgcrypt-1.6.2-fips-ctor.patch create mode 100644 libgcrypt-1.8.3-fips-ctor.patch rename libgcrypt-1.8.1-getrandom.patch => libgcrypt-1.8.3-getrandom.patch (62%) diff --git a/libgcrypt-1.6.2-fips-ctor.patch b/libgcrypt-1.6.2-fips-ctor.patch deleted file mode 100644 index fe3ec60..0000000 --- a/libgcrypt-1.6.2-fips-ctor.patch +++ /dev/null @@ -1,74 +0,0 @@ -diff -up libgcrypt-1.6.2/cipher/md.c.fips-ctor libgcrypt-1.6.2/cipher/md.c ---- libgcrypt-1.6.2/cipher/md.c.fips-ctor 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/cipher/md.c 2015-02-25 13:57:21.175704866 +0100 -@@ -413,11 +413,8 @@ md_enable (gcry_md_hd_t hd, int algorith - - if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) - { -- _gcry_inactivate_fips_mode ("MD5 used"); - if (_gcry_enforced_fips_mode () ) - { -- /* We should never get to here because we do not register -- MD5 in enforced fips mode. But better throw an error. */ - err = GPG_ERR_DIGEST_ALGO; - } - } -diff -up libgcrypt-1.6.2/src/global.c.fips-ctor libgcrypt-1.6.2/src/global.c ---- libgcrypt-1.6.2/src/global.c.fips-ctor 2015-02-25 13:57:21.174704842 +0100 -+++ libgcrypt-1.6.2/src/global.c 2015-02-25 14:03:07.066864208 +0100 -@@ -132,6 +132,36 @@ global_init (void) - } - - -+#ifndef FIPS_MODULE_PATH -+#define FIPS_MODULE_PATH "/etc/system-fips" -+#endif -+ -+void __attribute__ ((constructor)) _gcry_global_constructor (void) -+{ -+ int rv; -+ -+ rv = access (FIPS_MODULE_PATH, F_OK); -+ if (rv < 0 && errno != ENOENT) -+ rv = 0; -+ -+ if (!rv) -+ { -+ int no_secmem_save; -+ -+ /* it should be always 0 at this point but let's keep on the safe side */ -+ no_secmem_save = no_secure_memory; -+ no_secure_memory = 1; -+ /* force selftests */ -+ global_init (); -+ if (fips_mode ()) -+ _gcry_random_initialize (1); -+ _gcry_fips_run_selftests (0); -+ if (!fips_mode()) -+ _gcry_random_close_fds (); -+ no_secure_memory = no_secmem_save; -+ } -+} -+ - /* This function is called by the macro fips_is_operational and makes - sure that the minimal initialization has been done. This is far - from a perfect solution and hides problems with an improper -@@ -542,8 +572,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - - case GCRYCTL_FIPS_MODE_P: - if (fips_mode () -- && !_gcry_is_fips_mode_inactive () -- && !no_secure_memory) -+ && !_gcry_is_fips_mode_inactive ()) - rc = GPG_ERR_GENERAL; /* Used as TRUE value */ - break; - -@@ -635,7 +664,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - break; - - case GCRYCTL_SET_ENFORCED_FIPS_FLAG: -- if (!any_init_done) -+ if (fips_mode ()) - { - /* Not yet initialized at all. Set the enforced fips mode flag */ - _gcry_set_preferred_rng_type (0); diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch new file mode 100644 index 0000000..47c07c4 --- /dev/null +++ b/libgcrypt-1.8.3-fips-ctor.patch @@ -0,0 +1,253 @@ +diff -up libgcrypt-1.8.3/cipher/md.c.fips-ctor libgcrypt-1.8.3/cipher/md.c +--- libgcrypt-1.8.3/cipher/md.c.fips-ctor 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.3/cipher/md.c 2018-07-12 13:02:49.599423390 +0200 +@@ -411,11 +411,8 @@ md_enable (gcry_md_hd_t hd, int algorith + + if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) + { +- _gcry_inactivate_fips_mode ("MD5 used"); + if (_gcry_enforced_fips_mode () ) + { +- /* We should never get to here because we do not register +- MD5 in enforced fips mode. But better throw an error. */ + err = GPG_ERR_DIGEST_ALGO; + } + } +diff -up libgcrypt-1.8.3/src/fips.c.fips-ctor libgcrypt-1.8.3/src/fips.c +--- libgcrypt-1.8.3/src/fips.c.fips-ctor 2018-07-12 13:02:49.589423158 +0200 ++++ libgcrypt-1.8.3/src/fips.c 2018-07-12 13:08:45.955663998 +0200 +@@ -91,6 +91,31 @@ static void fips_new_state (enum module_ + + + ++/* Initialize the FSM lock - this function may only ++ be called once and is intended to be run from the library ++ constructor */ ++void ++_gcry_initialize_fsm_lock (void) ++{ ++ gpg_error_t err; ++ /* Intitialize the lock to protect the FSM. */ ++ err = gpgrt_lock_init (&fsm_lock); ++ if (err) ++ { ++ /* If that fails we can't do anything but abort the ++ process. We need to use log_info so that the FSM won't ++ get involved. */ ++ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", ++ gpg_strerror (err)); ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " ++ "creating FSM lock failed: %s - abort", ++ gpg_strerror (err)); ++#endif /*HAVE_SYSLOG*/ ++ abort (); ++ } ++} ++ + /* Check whether the OS is in FIPS mode and record that in a module + local variable. If FORCE is passed as true, fips mode will be + enabled anyway. Note: This function is not thread-safe and should +@@ -100,7 +125,6 @@ void + _gcry_initialize_fips_mode (int force) + { + static int done; +- gpg_error_t err; + + /* Make sure we are not accidentally called twice. */ + if (done) +@@ -179,24 +203,6 @@ _gcry_initialize_fips_mode (int force) + /* Yes, we are in FIPS mode. */ + FILE *fp; + +- /* Intitialize the lock to protect the FSM. */ +- err = gpgrt_lock_init (&fsm_lock); +- if (err) +- { +- /* If that fails we can't do anything but abort the +- process. We need to use log_info so that the FSM won't +- get involved. */ +- log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", +- gpg_strerror (err)); +-#ifdef HAVE_SYSLOG +- syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " +- "creating FSM lock failed: %s - abort", +- gpg_strerror (err)); +-#endif /*HAVE_SYSLOG*/ +- abort (); +- } +- +- + /* If the FIPS force files exists, is readable and has a number + != 0 on its first line, we enable the enforced fips mode. */ + fp = fopen (FIPS_FORCE_FILE, "r"); +@@ -359,16 +365,20 @@ _gcry_fips_is_operational (void) + { + int result; + +- if (!fips_mode ()) ++ lock_fsm (); ++ if (current_state == STATE_POWERON && !fips_mode ()) ++ /* If we are at this point in POWERON state it means the FIPS ++ module installation was not completed. (/etc/system-fips ++ is not present.) */ + result = 1; + else + { +- lock_fsm (); +- if (current_state == STATE_INIT) ++ if (current_state == STATE_INIT || current_state == STATE_SELFTEST) + { +- /* If we are still in the INIT state, we need to run the +- selftests so that the FSM can eventually get into +- operational state. Given that we would need a 2-phase ++ /* If we are still in the INIT (or SELFTEST) state, ++ we need to run (or finish) the selftests so ++ that the FSM can eventually get into operational ++ state. Given that we would need a 2-phase + initialization of libgcrypt, but that has traditionally + not been enforced, we use this on demand self-test + checking. Note that Proper applications would do the +@@ -384,9 +394,11 @@ _gcry_fips_is_operational (void) + lock_fsm (); + } + +- result = (current_state == STATE_OPERATIONAL); +- unlock_fsm (); ++ result = (current_state == STATE_OPERATIONAL) || !fips_mode (); ++ /* We always run the selftests but ignore the result ++ in non-FIPS mode. */ + } ++ unlock_fsm (); + return result; + } + +@@ -709,9 +721,25 @@ _gcry_fips_run_selftests (int extended) + { + enum module_states result = STATE_ERROR; + gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; ++ int in_poweron; + +- if (fips_mode ()) +- fips_new_state (STATE_SELFTEST); ++ lock_fsm (); ++ in_poweron = (current_state == STATE_POWERON); ++ unlock_fsm (); ++ ++ fips_new_state (STATE_SELFTEST); ++ ++ /* We first check the integrity of the binary. ++ If run from the constructor we are in POWERON state, ++ we return and finish the remaining selftests before ++ real use of the library. It will be in the POWERON ++ state meanwhile. */ ++ if (in_poweron) ++ if (check_binary_integrity ()) ++ goto leave; ++ ++ if (in_poweron) ++ return 0; + + if (run_cipher_selftests (extended)) + goto leave; +@@ -730,18 +758,12 @@ _gcry_fips_run_selftests (int extended) + if (run_pubkey_selftests (extended)) + goto leave; + +- /* Now check the integrity of the binary. We do this this after +- having checked the HMAC code. */ +- if (check_binary_integrity ()) +- goto leave; +- + /* All selftests passed. */ + result = STATE_OPERATIONAL; + ec = 0; + + leave: +- if (fips_mode ()) +- fips_new_state (result); ++ fips_new_state (result); + + return ec; + } +@@ -797,6 +819,7 @@ fips_new_state (enum module_states new_s + { + case STATE_POWERON: + if (new_state == STATE_INIT ++ || new_state == STATE_SELFTEST + || new_state == STATE_ERROR + || new_state == STATE_FATALERROR) + ok = 1; +@@ -811,6 +834,8 @@ fips_new_state (enum module_states new_s + + case STATE_SELFTEST: + if (new_state == STATE_OPERATIONAL ++ || new_state == STATE_INIT ++ || new_state == STATE_SELFTEST + || new_state == STATE_ERROR + || new_state == STATE_FATALERROR) + ok = 1; +diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c +--- libgcrypt-1.8.3/src/global.c.fips-ctor 2017-11-23 19:25:58.000000000 +0100 ++++ libgcrypt-1.8.3/src/global.c 2018-07-12 13:02:49.599423390 +0200 +@@ -141,6 +141,29 @@ global_init (void) + } + + ++#ifndef FIPS_MODULE_PATH ++#define FIPS_MODULE_PATH "/etc/system-fips" ++#endif ++ ++void __attribute__ ((constructor)) _gcry_global_constructor (void) ++{ ++ int rv; ++ ++ /* We always need the FSM lock to be functional. */ ++ _gcry_initialize_fsm_lock (); ++ ++ rv = access (FIPS_MODULE_PATH, F_OK); ++ if (rv < 0 && errno != ENOENT) ++ rv = 0; ++ ++ if (!rv) ++ { ++ /* We run the integrity check at this point. The remaining ++ selftests are run before use of the library by application. */ ++ _gcry_fips_run_selftests (0); ++ } ++} ++ + /* This function is called by the macro fips_is_operational and makes + sure that the minimal initialization has been done. This is far + from a perfect solution and hides problems with an improper +@@ -671,8 +694,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, + + case GCRYCTL_FIPS_MODE_P: + if (fips_mode () +- && !_gcry_is_fips_mode_inactive () +- && !no_secure_memory) ++ && !_gcry_is_fips_mode_inactive ()) + rc = GPG_ERR_GENERAL; /* Used as TRUE value */ + break; + +@@ -749,7 +771,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, + break; + + case GCRYCTL_SET_ENFORCED_FIPS_FLAG: +- if (!any_init_done) ++ if (fips_mode ()) + { + /* Not yet initialized at all. Set the enforced fips mode flag */ + _gcry_set_preferred_rng_type (0); +diff -up libgcrypt-1.8.3/src/g10lib.h.fips-ctor libgcrypt-1.8.3/src/g10lib.h +--- libgcrypt-1.8.3/src/g10lib.h.fips-ctor 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.3/src/g10lib.h 2018-07-12 13:02:49.600423413 +0200 +@@ -422,6 +422,8 @@ gpg_err_code_t _gcry_sexp_vextract_param + + /*-- fips.c --*/ + ++void _gcry_initialize_fsm_lock (void); ++ + void _gcry_initialize_fips_mode (int force); + + int _gcry_fips_mode (void); diff --git a/libgcrypt-1.8.1-getrandom.patch b/libgcrypt-1.8.3-getrandom.patch similarity index 62% rename from libgcrypt-1.8.1-getrandom.patch rename to libgcrypt-1.8.3-getrandom.patch index d323b20..7428dfb 100644 --- a/libgcrypt-1.8.1-getrandom.patch +++ b/libgcrypt-1.8.3-getrandom.patch @@ -1,6 +1,20 @@ -diff -up libgcrypt-1.8.1/random/random-csprng.c.getrandom libgcrypt-1.8.1/random/random-csprng.c ---- libgcrypt-1.8.1/random/random-csprng.c.getrandom 2017-08-27 09:05:36.000000000 +0200 -+++ libgcrypt-1.8.1/random/random-csprng.c 2017-12-06 09:04:27.824175303 +0100 +diff -up libgcrypt-1.8.3/random/random.c.getrandom libgcrypt-1.8.3/random/random.c +--- libgcrypt-1.8.3/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.3/random/random.c 2018-07-10 15:38:34.303855808 +0200 +@@ -110,8 +110,8 @@ _gcry_random_read_conf (void) + unsigned int result = 0; + + fp = fopen (fname, "r"); +- if (!fp) +- return result; ++ if (!fp) /* We make only_urandom the default. */ ++ return RANDOM_CONF_ONLY_URANDOM; + + for (;;) + { +diff -up libgcrypt-1.8.3/random/random-csprng.c.getrandom libgcrypt-1.8.3/random/random-csprng.c +--- libgcrypt-1.8.3/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.3/random/random-csprng.c 2018-06-14 16:31:04.731179208 +0200 @@ -55,6 +55,10 @@ #ifdef __MINGW32__ #include @@ -35,9 +49,9 @@ diff -up libgcrypt-1.8.1/random/random-csprng.c.getrandom libgcrypt-1.8.1/random if ( !access (NAME_OF_DEV_RANDOM, R_OK) && !access (NAME_OF_DEV_URANDOM, R_OK)) { -diff -up libgcrypt-1.8.1/random/rndlinux.c.getrandom libgcrypt-1.8.1/random/rndlinux.c ---- libgcrypt-1.8.1/random/rndlinux.c.getrandom 2017-09-05 14:34:28.003872675 +0200 -+++ libgcrypt-1.8.1/random/rndlinux.c 2018-02-06 16:31:56.047481806 +0100 +diff -up libgcrypt-1.8.3/random/rndlinux.c.getrandom libgcrypt-1.8.3/random/rndlinux.c +--- libgcrypt-1.8.3/random/rndlinux.c.getrandom 2018-06-14 16:31:04.722178971 +0200 ++++ libgcrypt-1.8.3/random/rndlinux.c 2018-07-10 15:55:03.301075155 +0200 @@ -35,6 +35,7 @@ #include #if defined(__linux__) && defined(HAVE_SYSCALL) @@ -46,7 +60,7 @@ diff -up libgcrypt-1.8.1/random/rndlinux.c.getrandom libgcrypt-1.8.1/random/rndl #endif #include "types.h" -@@ -204,6 +205,16 @@ _gcry_rndlinux_gather_random (void (*add +@@ -204,6 +205,18 @@ _gcry_rndlinux_gather_random (void (*add { if (fd_urandom == -1) { @@ -57,22 +71,24 @@ diff -up libgcrypt-1.8.1/random/rndlinux.c.getrandom libgcrypt-1.8.1/random/rndl + ret = syscall (__NR_getrandom, + (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); + _gcry_post_syscall (); -+ if (ret == -1 && errno == ENOSYS) -+ /* The syscall is not supported - fallback to /dev/urandom. */ ++ if (ret > -1 || errno == EAGAIN || errno == EINTR) ++ fd_urandom = -2; ++ else ++ /* The syscall is not supported - fallback to /dev/urandom. */ +#endif fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); ever_opened |= 2; } -@@ -230,7 +241,7 @@ _gcry_rndlinux_gather_random (void (*add +@@ -230,7 +243,7 @@ _gcry_rndlinux_gather_random (void (*add * syscall and not a new device and thus we are not able to use * select(2) to have a timeout. */ #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) - if (fd == fd_urandom) -+ if (fd == -1) ++ if (fd == -2) { long ret; size_t nbytes; -@@ -246,9 +257,7 @@ _gcry_rndlinux_gather_random (void (*add +@@ -246,9 +259,7 @@ _gcry_rndlinux_gather_random (void (*add _gcry_post_syscall (); } while (ret == -1 && errno == EINTR); diff --git a/libgcrypt.spec b/libgcrypt.spec index 8e9b677..f6bf893 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.3 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -30,11 +30,11 @@ Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC Patch14: libgcrypt-1.7.3-ecc-test-fix.patch # Run the FIPS mode initialization in the shared library constructor -Patch18: libgcrypt-1.6.2-fips-ctor.patch +Patch18: libgcrypt-1.8.3-fips-ctor.patch # Block some operations if in FIPS non-operational state Patch22: libgcrypt-1.7.3-fips-reqs.patch # Do not try to open /dev/urandom if getrandom() works -Patch24: libgcrypt-1.8.1-getrandom.patch +Patch24: libgcrypt-1.8.3-getrandom.patch %define gcrylibdir %{_libdir} @@ -191,6 +191,11 @@ exit 0 %license COPYING %changelog +* Thu Jul 12 2018 Tomáš Mráz 1.8.3-2 +- make only_urandom a default in non-presence of configuration file +- run the full FIPS selftests only when the library is called from + application + * Thu Jun 14 2018 Tomáš Mráz 1.8.3-1 - new upstream version 1.8.3 From 66ba0d50ee99da5c8fea8b5193b88380bce46389 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 13 Jul 2018 08:08:04 +0000 Subject: [PATCH 117/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index f6bf893..079c08b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.3 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -191,6 +191,9 @@ exit 0 %license COPYING %changelog +* Fri Jul 13 2018 Fedora Release Engineering - 1.8.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild + * Thu Jul 12 2018 Tomáš Mráz 1.8.3-2 - make only_urandom a default in non-presence of configuration file - run the full FIPS selftests only when the library is called from From 911a1f29551783508de8aceb33a3cc987d5d5623 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 17 Jul 2018 19:16:47 +0200 Subject: [PATCH 118/214] Modify comment in the fips-ctor patch to reflect the patched situation. --- libgcrypt-1.8.3-fips-ctor.patch | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch index 47c07c4..e04201f 100644 --- a/libgcrypt-1.8.3-fips-ctor.patch +++ b/libgcrypt-1.8.3-fips-ctor.patch @@ -1,6 +1,6 @@ diff -up libgcrypt-1.8.3/cipher/md.c.fips-ctor libgcrypt-1.8.3/cipher/md.c --- libgcrypt-1.8.3/cipher/md.c.fips-ctor 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/cipher/md.c 2018-07-12 13:02:49.599423390 +0200 ++++ libgcrypt-1.8.3/cipher/md.c 2018-07-12 13:24:54.088403006 +0200 @@ -411,11 +411,8 @@ md_enable (gcry_md_hd_t hd, int algorith if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) @@ -14,8 +14,8 @@ diff -up libgcrypt-1.8.3/cipher/md.c.fips-ctor libgcrypt-1.8.3/cipher/md.c } } diff -up libgcrypt-1.8.3/src/fips.c.fips-ctor libgcrypt-1.8.3/src/fips.c ---- libgcrypt-1.8.3/src/fips.c.fips-ctor 2018-07-12 13:02:49.589423158 +0200 -+++ libgcrypt-1.8.3/src/fips.c 2018-07-12 13:08:45.955663998 +0200 +--- libgcrypt-1.8.3/src/fips.c.fips-ctor 2018-07-12 13:24:54.075402698 +0200 ++++ libgcrypt-1.8.3/src/fips.c 2018-07-12 13:24:54.088403006 +0200 @@ -91,6 +91,31 @@ static void fips_new_state (enum module_ @@ -189,7 +189,7 @@ diff -up libgcrypt-1.8.3/src/fips.c.fips-ctor libgcrypt-1.8.3/src/fips.c ok = 1; diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c --- libgcrypt-1.8.3/src/global.c.fips-ctor 2017-11-23 19:25:58.000000000 +0100 -+++ libgcrypt-1.8.3/src/global.c 2018-07-12 13:02:49.599423390 +0200 ++++ libgcrypt-1.8.3/src/global.c 2018-07-17 19:15:43.933827112 +0200 @@ -141,6 +141,29 @@ global_init (void) } @@ -230,18 +230,21 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c rc = GPG_ERR_GENERAL; /* Used as TRUE value */ break; -@@ -749,7 +771,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, +@@ -749,9 +771,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, break; case GCRYCTL_SET_ENFORCED_FIPS_FLAG: - if (!any_init_done) + if (fips_mode ()) { - /* Not yet initialized at all. Set the enforced fips mode flag */ +- /* Not yet initialized at all. Set the enforced fips mode flag */ ++ /* We are in FIPS mode, we can set the enforced fips mode flag. */ _gcry_set_preferred_rng_type (0); + _gcry_set_enforced_fips_mode (); + } diff -up libgcrypt-1.8.3/src/g10lib.h.fips-ctor libgcrypt-1.8.3/src/g10lib.h --- libgcrypt-1.8.3/src/g10lib.h.fips-ctor 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/src/g10lib.h 2018-07-12 13:02:49.600423413 +0200 ++++ libgcrypt-1.8.3/src/g10lib.h 2018-07-12 13:24:54.089403030 +0200 @@ -422,6 +422,8 @@ gpg_err_code_t _gcry_sexp_vextract_param /*-- fips.c --*/ From abc0e95a20066736dffcbf8b30c2635b68c47130 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 20 Nov 2018 16:22:10 +0100 Subject: [PATCH 119/214] new upstream version 1.8.4 --- .gitignore | 1 + ecc-curves.c | 2 +- libgcrypt-1.8.3-getrandom.patch | 101 ------------- libgcrypt-1.8.4-getrandom.patch | 134 ++++++++++++++++++ ...ll.patch => libgcrypt-1.8.4-use-poll.patch | 14 +- libgcrypt.spec | 11 +- sources | 2 +- 7 files changed, 151 insertions(+), 114 deletions(-) delete mode 100644 libgcrypt-1.8.3-getrandom.patch create mode 100644 libgcrypt-1.8.4-getrandom.patch rename libgcrypt-1.8.0-use-poll.patch => libgcrypt-1.8.4-use-poll.patch (80%) diff --git a/.gitignore b/.gitignore index fc81043..d698df1 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.1-hobbled.tar.xz /libgcrypt-1.8.2-hobbled.tar.xz /libgcrypt-1.8.3-hobbled.tar.xz +/libgcrypt-1.8.4-hobbled.tar.xz diff --git a/ecc-curves.c b/ecc-curves.c index 1720778..7378bae 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -1057,7 +1057,7 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) if (!strcmp (name, "q.x") && ec->Q && ec->Q->x) return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x); if (!strcmp (name, "q.y") && ec->Q && ec->Q->y) - return mpi_is_const (ec->G->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y); + return mpi_is_const (ec->Q->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y); /* If the base point has been requested, return it in standard encoding. */ diff --git a/libgcrypt-1.8.3-getrandom.patch b/libgcrypt-1.8.3-getrandom.patch deleted file mode 100644 index 7428dfb..0000000 --- a/libgcrypt-1.8.3-getrandom.patch +++ /dev/null @@ -1,101 +0,0 @@ -diff -up libgcrypt-1.8.3/random/random.c.getrandom libgcrypt-1.8.3/random/random.c ---- libgcrypt-1.8.3/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/random/random.c 2018-07-10 15:38:34.303855808 +0200 -@@ -110,8 +110,8 @@ _gcry_random_read_conf (void) - unsigned int result = 0; - - fp = fopen (fname, "r"); -- if (!fp) -- return result; -+ if (!fp) /* We make only_urandom the default. */ -+ return RANDOM_CONF_ONLY_URANDOM; - - for (;;) - { -diff -up libgcrypt-1.8.3/random/random-csprng.c.getrandom libgcrypt-1.8.3/random/random-csprng.c ---- libgcrypt-1.8.3/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/random/random-csprng.c 2018-06-14 16:31:04.731179208 +0200 -@@ -55,6 +55,10 @@ - #ifdef __MINGW32__ - #include - #endif -+#if defined(__linux__) && defined(HAVE_SYSCALL) -+# include -+# include -+#endif - #include "g10lib.h" - #include "random.h" - #include "rand-internal.h" -@@ -1116,6 +1120,22 @@ getfnc_gather_random (void))(void (*)(co - enum random_origins, size_t, int); - - #if USE_RNDLINUX -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ long ret; -+ char buffer[1]; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret != -1 || errno != ENOSYS) -+ { -+ fnc = _gcry_rndlinux_gather_random; -+ return fnc; -+ } -+ else -+ /* The syscall is not supported - fallback to /dev/urandom. */ -+#endif - if ( !access (NAME_OF_DEV_RANDOM, R_OK) - && !access (NAME_OF_DEV_URANDOM, R_OK)) - { -diff -up libgcrypt-1.8.3/random/rndlinux.c.getrandom libgcrypt-1.8.3/random/rndlinux.c ---- libgcrypt-1.8.3/random/rndlinux.c.getrandom 2018-06-14 16:31:04.722178971 +0200 -+++ libgcrypt-1.8.3/random/rndlinux.c 2018-07-10 15:55:03.301075155 +0200 -@@ -35,6 +35,7 @@ - #include - #if defined(__linux__) && defined(HAVE_SYSCALL) - # include -+# include - #endif - - #include "types.h" -@@ -204,6 +205,18 @@ _gcry_rndlinux_gather_random (void (*add - { - if (fd_urandom == -1) - { -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ long ret; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret > -1 || errno == EAGAIN || errno == EINTR) -+ fd_urandom = -2; -+ else -+ /* The syscall is not supported - fallback to /dev/urandom. */ -+#endif - fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2)); - ever_opened |= 2; - } -@@ -230,7 +243,7 @@ _gcry_rndlinux_gather_random (void (*add - * syscall and not a new device and thus we are not able to use - * select(2) to have a timeout. */ - #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -- if (fd == fd_urandom) -+ if (fd == -2) - { - long ret; - size_t nbytes; -@@ -246,9 +259,7 @@ _gcry_rndlinux_gather_random (void (*add - _gcry_post_syscall (); - } - while (ret == -1 && errno == EINTR); -- if (ret == -1 && errno == ENOSYS) -- ; /* The syscall is not supported - fallback to /dev/urandom. */ -- else -+ if (1) - { /* The syscall is supported. Some sanity checks. */ - if (ret == -1) - log_fatal ("unexpected error from getrandom: %s\n", diff --git a/libgcrypt-1.8.4-getrandom.patch b/libgcrypt-1.8.4-getrandom.patch new file mode 100644 index 0000000..a2fb7b9 --- /dev/null +++ b/libgcrypt-1.8.4-getrandom.patch @@ -0,0 +1,134 @@ +diff -up libgcrypt-1.8.4/random/random.c.getrandom libgcrypt-1.8.4/random/random.c +--- libgcrypt-1.8.4/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/random/random.c 2018-11-20 15:52:41.738708554 +0100 +@@ -110,8 +110,8 @@ _gcry_random_read_conf (void) + unsigned int result = 0; + + fp = fopen (fname, "r"); +- if (!fp) +- return result; ++ if (!fp) /* We make only_urandom the default. */ ++ return RANDOM_CONF_ONLY_URANDOM; + + for (;;) + { +diff -up libgcrypt-1.8.4/random/random-csprng.c.getrandom libgcrypt-1.8.4/random/random-csprng.c +--- libgcrypt-1.8.4/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/random/random-csprng.c 2018-11-20 15:52:41.738708554 +0100 +@@ -55,6 +55,10 @@ + #ifdef __MINGW32__ + #include + #endif ++#if defined(__linux__) && defined(HAVE_SYSCALL) ++# include ++# include ++#endif + #include "g10lib.h" + #include "random.h" + #include "rand-internal.h" +@@ -1116,6 +1120,22 @@ getfnc_gather_random (void))(void (*)(co + enum random_origins, size_t, int); + + #if USE_RNDLINUX ++#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) ++ long ret; ++ char buffer[1]; ++ ++ _gcry_pre_syscall (); ++ ret = syscall (__NR_getrandom, ++ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); ++ _gcry_post_syscall (); ++ if (ret != -1 || errno != ENOSYS) ++ { ++ fnc = _gcry_rndlinux_gather_random; ++ return fnc; ++ } ++ else ++ /* The syscall is not supported - fallback to /dev/urandom. */ ++#endif + if ( !access (NAME_OF_DEV_RANDOM, R_OK) + && !access (NAME_OF_DEV_URANDOM, R_OK)) + { +diff -up libgcrypt-1.8.4/random/rndlinux.c.getrandom libgcrypt-1.8.4/random/rndlinux.c +--- libgcrypt-1.8.4/random/rndlinux.c.getrandom 2018-11-20 15:52:41.731708393 +0100 ++++ libgcrypt-1.8.4/random/rndlinux.c 2018-11-20 16:06:45.431207374 +0100 +@@ -35,6 +35,7 @@ + #include + #if defined(__linux__) && defined(HAVE_SYSCALL) + # include ++# include + #endif + + #include "types.h" +@@ -147,12 +148,12 @@ _gcry_rndlinux_gather_random (void (*add + if (!add) + { + /* Special mode to close the descriptors. */ +- if (fd_random != -1) ++ if (fd_random >= 0) + { + close (fd_random); + fd_random = -1; + } +- if (fd_urandom != -1) ++ if (fd_urandom >= 0) + { + close (fd_urandom); + fd_urandom = -1; +@@ -166,12 +167,12 @@ _gcry_rndlinux_gather_random (void (*add + apid = getpid (); + if (my_pid != apid) + { +- if (fd_random != -1) ++ if (fd_random >= 0) + { + close (fd_random); + fd_random = -1; + } +- if (fd_urandom != -1) ++ if (fd_urandom >= 0) + { + close (fd_urandom); + fd_urandom = -1; +@@ -216,6 +217,22 @@ _gcry_rndlinux_gather_random (void (*add + that we always require the device to be existent but want a more + graceful behaviour if the rarely needed close operation has been + used and the device needs to be re-opened later. */ ++#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) ++ if (fd_urandom != -2) ++ { ++ long ret; ++ ++ _gcry_pre_syscall (); ++ ret = syscall (__NR_getrandom, ++ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); ++ _gcry_post_syscall (); ++ if (ret > -1 || errno == EAGAIN || errno == EINTR) ++ { ++ fd_urandom = -2; ++ fd_random = -2; ++ } ++ } ++#endif + if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom) + { + if (fd_random == -1) +@@ -255,6 +272,7 @@ _gcry_rndlinux_gather_random (void (*add + * syscall and not a new device and thus we are not able to use + * select(2) to have a timeout. */ + #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) ++ if (fd == -2) + { + long ret; + size_t nbytes; +@@ -270,9 +288,7 @@ _gcry_rndlinux_gather_random (void (*add + _gcry_post_syscall (); + } + while (ret == -1 && errno == EINTR); +- if (ret == -1 && errno == ENOSYS) +- ; /* The syscall is not supported - fallback to pulling from fd. */ +- else ++ if (1) + { /* The syscall is supported. Some sanity checks. */ + if (ret == -1) + log_fatal ("unexpected error from getrandom: %s\n", diff --git a/libgcrypt-1.8.0-use-poll.patch b/libgcrypt-1.8.4-use-poll.patch similarity index 80% rename from libgcrypt-1.8.0-use-poll.patch rename to libgcrypt-1.8.4-use-poll.patch index 07df8dd..b96c6ce 100644 --- a/libgcrypt-1.8.0-use-poll.patch +++ b/libgcrypt-1.8.4-use-poll.patch @@ -1,6 +1,6 @@ -diff -up libgcrypt-1.8.0/random/rndlinux.c.use-poll libgcrypt-1.8.0/random/rndlinux.c ---- libgcrypt-1.8.0/random/rndlinux.c.use-poll 2017-06-24 13:34:29.000000000 +0200 -+++ libgcrypt-1.8.0/random/rndlinux.c 2017-08-15 15:37:37.604629377 +0200 +diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndlinux.c +--- libgcrypt-1.8.4/random/rndlinux.c.use-poll 2018-10-26 13:50:20.000000000 +0200 ++++ libgcrypt-1.8.4/random/rndlinux.c 2018-11-20 15:51:56.760669058 +0100 @@ -32,6 +32,7 @@ #include #include @@ -9,7 +9,7 @@ diff -up libgcrypt-1.8.0/random/rndlinux.c.use-poll libgcrypt-1.8.0/random/rndli #if defined(__linux__) && defined(HAVE_SYSCALL) # include #endif -@@ -216,9 +217,8 @@ _gcry_rndlinux_gather_random (void (*add +@@ -241,9 +242,8 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) { @@ -18,9 +18,9 @@ diff -up libgcrypt-1.8.0/random/rndlinux.c.use-poll libgcrypt-1.8.0/random/rndli int rc; + struct pollfd pfd; - /* If we have a modern Linux kernel and we want to read from the - * the non-blocking /dev/urandom, we first try to use the new -@@ -276,36 +276,25 @@ _gcry_rndlinux_gather_random (void (*add + /* If we have a modern Linux kernel, we first try to use the new + * getrandom syscall. That call guarantees that the kernel's +@@ -300,36 +300,25 @@ _gcry_rndlinux_gather_random (void (*add any_need_entropy = 1; } diff --git a/libgcrypt.spec b/libgcrypt.spec index 079c08b..8940376 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.8.3 -Release: 3%{?dist} +Version: 1.8.4 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -24,7 +24,7 @@ Patch5: libgcrypt-1.8.0-tests.patch # update the CAVS tests Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness -Patch11: libgcrypt-1.8.0-use-poll.patch +Patch11: libgcrypt-1.8.4-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch # fix tests to work with approved ECC @@ -34,7 +34,7 @@ Patch18: libgcrypt-1.8.3-fips-ctor.patch # Block some operations if in FIPS non-operational state Patch22: libgcrypt-1.7.3-fips-reqs.patch # Do not try to open /dev/urandom if getrandom() works -Patch24: libgcrypt-1.8.3-getrandom.patch +Patch24: libgcrypt-1.8.4-getrandom.patch %define gcrylibdir %{_libdir} @@ -191,6 +191,9 @@ exit 0 %license COPYING %changelog +* Tue Nov 20 2018 Tomáš Mráz 1.8.4-1 +- new upstream version 1.8.4 + * Fri Jul 13 2018 Fedora Release Engineering - 1.8.3-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_29_Mass_Rebuild diff --git a/sources b/sources index 365d656..465ff20 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.8.3-hobbled.tar.xz) = 6981367a138e03375d7ccf44e2dacb5c96f0ebadf34c2734f95cf3b94a7d7b206a2864304abfbcc3acf0055cc83491fd68d065af33487fefa73f550954a99613 +SHA512 (libgcrypt-1.8.4-hobbled.tar.xz) = 9f124d84a401f6b63faabe46b983e157573a20064e9652fe47b4d18b58d580eab9458a47eb24694b26e8e8e7e8c82002f354f075a0fc7037e61fb4ab0eafdf19 From 736889c2463f4e7641ac68cf798b94ddcba44015 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Tue, 22 Jan 2019 18:39:43 +0100 Subject: [PATCH 120/214] Remove obsolete ldconfig scriptlets References: https://fedoraproject.org/wiki/Changes/RemoveObsoleteScriptlets Signed-off-by: Igor Gnatenko --- libgcrypt.spec | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 8940376..536095d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -152,9 +152,7 @@ popd mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig +%ldconfig_scriptlets %post devel [ -f %{_infodir}/gcrypt.info.gz ] && \ From 2aacaf900fbd115d3ef51b3118350797c4c0dd3e Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Sun, 27 Jan 2019 19:05:26 +0100 Subject: [PATCH 121/214] Remove obsolete scriptlets References: https://fedoraproject.org/wiki/Changes/RemoveObsoleteScriptlets Signed-off-by: Igor Gnatenko --- libgcrypt.spec | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 536095d..ab3ccad 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -54,8 +54,6 @@ Group: System Environment/Libraries Summary: Development files for the %{name} package License: LGPLv2+ and GPLv2+ Group: Development/Libraries -Requires(pre): /sbin/install-info -Requires(post): /sbin/install-info Requires: libgpg-error-devel Requires: %{name} = %{version}-%{release} @@ -154,17 +152,6 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %ldconfig_scriptlets -%post devel -[ -f %{_infodir}/gcrypt.info.gz ] && \ - /sbin/install-info %{_infodir}/gcrypt.info.gz %{_infodir}/dir -exit 0 - -%preun devel -if [ $1 = 0 -a -f %{_infodir}/gcrypt.info.gz ]; then - /sbin/install-info --delete %{_infodir}/gcrypt.info.gz %{_infodir}/dir -fi -exit 0 - %files %dir /etc/gcrypt %config(noreplace) /etc/gcrypt/random.conf From 31f411aab3735e8fa7750ecc05411affc1200dd2 Mon Sep 17 00:00:00 2001 From: Igor Gnatenko Date: Mon, 28 Jan 2019 20:17:51 +0100 Subject: [PATCH 122/214] Remove obsolete Group tag References: https://fedoraproject.org/wiki/Changes/Remove_Group_Tag --- libgcrypt.spec | 2 -- 1 file changed, 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index ab3ccad..38a47df 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -48,12 +48,10 @@ BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig BuildRequires: fipscheck # This is needed only when patching the .texi doc. BuildRequires: texinfo -Group: System Environment/Libraries %package devel Summary: Development files for the %{name} package License: LGPLv2+ and GPLv2+ -Group: Development/Libraries Requires: libgpg-error-devel Requires: %{name} = %{version}-%{release} From 1bdd0f0858c6c21f50461229d4d9d17badb89a8d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 1 Feb 2019 07:11:04 +0000 Subject: [PATCH 123/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 38a47df..266a693 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.4 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -174,6 +174,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Fri Feb 01 2019 Fedora Release Engineering - 1.8.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild + * Tue Nov 20 2018 Tomáš Mráz 1.8.4-1 - new upstream version 1.8.4 From 3b24cd465f60aa16f7b7a99757cd2b453c9416ae Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 12 Feb 2019 14:37:45 +0100 Subject: [PATCH 124/214] fix the build tests to pass in the FIPS mode --- libgcrypt-1.8.0-tests.patch | 115 ----------------- libgcrypt-1.8.4-fips-keygen.patch | 65 ++++++++++ libgcrypt-1.8.4-tests-fipsmode.patch | 184 +++++++++++++++++++++++++++ libgcrypt.spec | 14 +- 4 files changed, 259 insertions(+), 119 deletions(-) delete mode 100644 libgcrypt-1.8.0-tests.patch create mode 100644 libgcrypt-1.8.4-fips-keygen.patch create mode 100644 libgcrypt-1.8.4-tests-fipsmode.patch diff --git a/libgcrypt-1.8.0-tests.patch b/libgcrypt-1.8.0-tests.patch deleted file mode 100644 index f3dfe96..0000000 --- a/libgcrypt-1.8.0-tests.patch +++ /dev/null @@ -1,115 +0,0 @@ -diff -up libgcrypt-1.8.0/cipher/dsa.c.tests libgcrypt-1.8.0/cipher/dsa.c ---- libgcrypt-1.8.0/cipher/dsa.c.tests 2016-04-07 17:30:08.000000000 +0200 -+++ libgcrypt-1.8.0/cipher/dsa.c 2017-08-15 15:10:39.551600227 +0200 -@@ -457,11 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -- else -- ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, -+ else if (!domain->p || !domain->q) -+ ec = _gcry_generate_fips186_3_prime (nbits, qbits, -+ initial_seed.seed, -+ initial_seed.seedlen, - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen, NULL); -+ else -+ { -+ /* Domain parameters p and q are given; use them. */ -+ prime_p = mpi_copy (domain->p); -+ prime_q = mpi_copy (domain->q); -+ gcry_assert (mpi_get_nbits (prime_p) == nbits); -+ gcry_assert (mpi_get_nbits (prime_q) == qbits); -+ ec = 0; -+ } - sexp_release (initial_seed.sexp); - if (ec) - goto leave; -@@ -855,13 +866,12 @@ dsa_generate (const gcry_sexp_t genparms - sexp_release (l1); - sexp_release (domainsexp); - -- /* Check that all domain parameters are available. */ -- if (!domain.p || !domain.q || !domain.g) -+ /* Check that p and q domain parameters are available. */ -+ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) - { - _gcry_mpi_release (domain.p); - _gcry_mpi_release (domain.q); - _gcry_mpi_release (domain.g); -- sexp_release (deriveparms); - return GPG_ERR_MISSING_VALUE; - } - -diff -up libgcrypt-1.8.0/cipher/rsa.c.tests libgcrypt-1.8.0/cipher/rsa.c ---- libgcrypt-1.8.0/cipher/rsa.c.tests 2017-07-06 10:21:36.000000000 +0200 -+++ libgcrypt-1.8.0/cipher/rsa.c 2017-08-15 15:10:39.551600227 +0200 -@@ -696,7 +696,7 @@ generate_x931 (RSA_secret_key *sk, unsig - - *swapped = 0; - -- if (e_value == 1) /* Alias for a secure value. */ -+ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ - e_value = 65537; - - /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ -diff -up libgcrypt-1.8.0/tests/keygen.c.tests libgcrypt-1.8.0/tests/keygen.c ---- libgcrypt-1.8.0/tests/keygen.c.tests 2017-08-15 15:10:39.551600227 +0200 -+++ libgcrypt-1.8.0/tests/keygen.c 2017-08-15 15:16:05.433176171 +0200 -@@ -200,11 +200,11 @@ check_rsa_keys (void) - - - if (verbose) -- info ("creating 512 bit RSA key with e=257\n"); -+ info ("creating 1024 bit RSA key with e=257\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" -- " (nbits 3:512)\n" -+ " (nbits 4:1024)\n" - " (rsa-use-e 3:257)\n" - " ))", 0, 1); - if (rc) -@@ -225,11 +225,11 @@ check_rsa_keys (void) - gcry_sexp_release (key); - - if (verbose) -- info ("creating 512 bit RSA key with default e\n"); -+ info ("creating 1024 bit RSA key with default e\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (rsa\n" -- " (nbits 3:512)\n" -+ " (nbits 4:1024)\n" - " (rsa-use-e 1:0)\n" - " ))", 0, 1); - if (rc) -@@ -309,12 +309,12 @@ check_dsa_keys (void) - } - - if (verbose) -- info ("creating 1536 bit DSA key\n"); -+ info ("creating 2048 bit DSA key\n"); - rc = gcry_sexp_new (&keyparm, - "(genkey\n" - " (dsa\n" -- " (nbits 4:1536)\n" -- " (qbits 3:224)\n" -+ " (nbits 4:2048)\n" -+ " (qbits 3:256)\n" - " ))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gpg_strerror (rc)); -diff -up libgcrypt-1.8.0/tests/pubkey.c.tests libgcrypt-1.8.0/tests/pubkey.c ---- libgcrypt-1.8.0/tests/pubkey.c.tests 2017-01-18 15:24:25.000000000 +0100 -+++ libgcrypt-1.8.0/tests/pubkey.c 2017-08-15 15:10:39.552600207 +0200 -@@ -595,7 +595,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ - " (use-fips186)" - " (transient-key)" - " (derive-parms" -- " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", -+ " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", - 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); diff --git a/libgcrypt-1.8.4-fips-keygen.patch b/libgcrypt-1.8.4-fips-keygen.patch new file mode 100644 index 0000000..9d3a647 --- /dev/null +++ b/libgcrypt-1.8.4-fips-keygen.patch @@ -0,0 +1,65 @@ +diff -up libgcrypt-1.8.4/cipher/dsa.c.fips-keygen libgcrypt-1.8.4/cipher/dsa.c +--- libgcrypt-1.8.4/cipher/dsa.c.fips-keygen 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/cipher/dsa.c 2019-02-12 14:29:25.629513989 +0100 +@@ -457,11 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen); +- else +- ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, ++ else if (!domain->p || !domain->q) ++ ec = _gcry_generate_fips186_3_prime (nbits, qbits, ++ initial_seed.seed, ++ initial_seed.seedlen, + &prime_q, &prime_p, + r_counter, + r_seed, r_seedlen, NULL); ++ else ++ { ++ /* Domain parameters p and q are given; use them. */ ++ prime_p = mpi_copy (domain->p); ++ prime_q = mpi_copy (domain->q); ++ gcry_assert (mpi_get_nbits (prime_p) == nbits); ++ gcry_assert (mpi_get_nbits (prime_q) == qbits); ++ ec = 0; ++ } + sexp_release (initial_seed.sexp); + if (ec) + goto leave; +@@ -855,13 +866,12 @@ dsa_generate (const gcry_sexp_t genparms + sexp_release (l1); + sexp_release (domainsexp); + +- /* Check that all domain parameters are available. */ +- if (!domain.p || !domain.q || !domain.g) ++ /* Check that p and q domain parameters are available. */ ++ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) + { + _gcry_mpi_release (domain.p); + _gcry_mpi_release (domain.q); + _gcry_mpi_release (domain.g); +- sexp_release (deriveparms); + return GPG_ERR_MISSING_VALUE; + } + +diff -up libgcrypt-1.8.4/cipher/rsa.c.fips-keygen libgcrypt-1.8.4/cipher/rsa.c +--- libgcrypt-1.8.4/cipher/rsa.c.fips-keygen 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/cipher/rsa.c 2019-02-12 14:29:25.630513971 +0100 +@@ -389,7 +389,7 @@ generate_fips (RSA_secret_key *sk, unsig + + if (nbits < 1024 || (nbits & 0x1FF)) + return GPG_ERR_INV_VALUE; +- if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072) ++ if (fips_mode() && nbits < 2048) + return GPG_ERR_INV_VALUE; + + /* The random quality depends on the transient_key flag. */ +@@ -696,7 +696,7 @@ generate_x931 (RSA_secret_key *sk, unsig + + *swapped = 0; + +- if (e_value == 1) /* Alias for a secure value. */ ++ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ + e_value = 65537; + + /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ diff --git a/libgcrypt-1.8.4-tests-fipsmode.patch b/libgcrypt-1.8.4-tests-fipsmode.patch new file mode 100644 index 0000000..1442a0b --- /dev/null +++ b/libgcrypt-1.8.4-tests-fipsmode.patch @@ -0,0 +1,184 @@ +diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basic.c +--- libgcrypt-1.8.4/tests/basic.c.tests-fipsmode 2018-04-17 17:29:40.000000000 +0200 ++++ libgcrypt-1.8.4/tests/basic.c 2019-02-12 13:30:48.935791024 +0100 +@@ -6964,7 +6964,7 @@ check_ciphers (void) + check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0); + if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN) + check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0); +- if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) ++ if (!in_fips_mode && gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) + check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0); + if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN) + check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0); +@@ -7010,11 +7010,17 @@ check_cipher_modes(void) + check_cfb_cipher (); + check_ofb_cipher (); + check_ccm_cipher (); +- check_gcm_cipher (); +- check_poly1305_cipher (); +- check_ocb_cipher (); ++ if (!in_fips_mode) ++ { ++ check_gcm_cipher (); ++ check_poly1305_cipher (); ++ check_ocb_cipher (); ++ } + check_xts_cipher (); +- check_gost28147_cipher (); ++ if (!in_fips_mode) ++ { ++ check_gost28147_cipher (); ++ } + check_stream_cipher (); + check_stream_cipher_large_block (); + +@@ -10001,7 +10007,7 @@ check_mac (void) + show_mac_not_available (algos[i].algo); + continue; + } +- if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode) ++ if ((algos[i].algo == GCRY_MAC_GMAC_AES || gcry_mac_test_algo (algos[i].algo)) && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", +@@ -11095,8 +11101,6 @@ main (int argc, char **argv) + /* If we are in fips mode do some more tests. */ + gcry_md_hd_t md; + +- /* First trigger a self-test. */ +- xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("not in operational state after self-test\n"); + +@@ -11121,15 +11125,6 @@ main (int argc, char **argv) + gcry_md_close (md); + if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("expected error state but still in operational state\n"); +- else +- { +- /* Now run a self-test and to get back into +- operational state. */ +- xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); +- if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) +- fail ("did not reach operational after error " +- "and self-test\n"); +- } + } + } + +diff -up libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode libgcrypt-1.8.4/tests/benchmark.c +--- libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode 2019-02-12 11:31:44.859603883 +0100 ++++ libgcrypt-1.8.4/tests/benchmark.c 2019-02-12 14:10:40.271999352 +0100 +@@ -872,8 +872,10 @@ cipher_bench ( const char *algoname ) + || (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM)) + continue; + +- if (modes[modeidx].req_blocksize > 0 +- && blklen != modes[modeidx].req_blocksize) ++ if ((modes[modeidx].req_blocksize > 0 ++ && blklen != modes[modeidx].req_blocksize) ++ || (in_fips_mode ++ && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM)) + { + printf (" %7s %7s", "-", "-" ); + continue; +diff -up libgcrypt-1.8.4/tests/bench-slope.c.tests-fipsmode libgcrypt-1.8.4/tests/bench-slope.c +--- libgcrypt-1.8.4/tests/bench-slope.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/tests/bench-slope.c 2019-02-12 14:14:33.618763325 +0100 +@@ -1338,7 +1338,7 @@ cipher_bench_one (int algo, struct bench + return; + + /* GCM has restrictions for block-size */ +- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) ++ if (mode.mode == GCRY_CIPHER_MODE_GCM && (gcry_fips_mode_active () || blklen != GCRY_GCM_BLOCK_LEN)) + return; + + /* XTS has restrictions for block-size */ +diff -up libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode libgcrypt-1.8.4/tests/pubkey.c +--- libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/tests/pubkey.c 2019-02-12 13:52:25.658746415 +0100 +@@ -504,15 +504,30 @@ get_dsa_key_with_domain_new (gcry_sexp_t + rc = gcry_sexp_new + (&key_spec, + "(genkey (dsa (transient-key)(domain" +- "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" +- "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" +- "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" +- "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" +- "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" +- "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" +- "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" +- "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" +- "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" ++ " (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" ++ " 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" ++ " 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" ++ " 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" ++ " 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" ++ " eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" ++ " 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" ++ " 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" ++ " 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" ++ " 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" ++ " 2c8d7469db02e24d592394a7dba069e9#)" ++ " (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" ++ " 7441a0a5#)" ++ " (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" ++ " 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" ++ " ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" ++ " 0df242b75b414df372121e53a553f222f836b000f016485b" ++ " 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" ++ " 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" ++ " 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" ++ " ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" ++ " 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" ++ " 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" ++ " 45f322f82e4e85ca3ab85591b3c2a966#)" + ")))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); +@@ -595,7 +610,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ + " (use-fips186)" + " (transient-key)" + " (derive-parms" +- " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", ++ " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", + 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); +diff -up libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode libgcrypt-1.8.4/tests/t-cv25519.c +--- libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/tests/t-cv25519.c 2019-02-12 14:02:35.935705390 +0100 +@@ -560,6 +560,9 @@ main (int argc, char **argv) + xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); ++ /* Curve25519 isn't supported in fips mode */ ++ if (gcry_fips_mode_active()) ++ return 77; + + start_timer (); + check_cv25519 (); +diff -up libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode libgcrypt-1.8.4/tests/t-secmem.c +--- libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode 2017-11-23 19:19:54.000000000 +0100 ++++ libgcrypt-1.8.4/tests/t-secmem.c 2019-02-12 11:51:02.462190538 +0100 +@@ -174,7 +174,8 @@ main (int argc, char **argv) + xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + xgcry_control (GCRYCTL_INIT_SECMEM, pool_size, 0); +- gcry_set_outofcore_handler (outofcore_handler, NULL); ++ if (!gcry_fips_mode_active ()) ++ gcry_set_outofcore_handler (outofcore_handler, NULL); + xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + /* Libgcrypt prints a warning when the first overflow is allocated; +@@ -184,7 +185,8 @@ main (int argc, char **argv) + + + test_secmem (); +- test_secmem_overflow (); ++ if (!gcry_fips_mode_active ()) ++ test_secmem_overflow (); + /* FIXME: We need to improve the tests, for example by registering + * our own log handler and comparing the output of + * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */ diff --git a/libgcrypt.spec b/libgcrypt.spec index 266a693..e8e5676 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.4 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -19,8 +19,10 @@ Source7: random.conf # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump Patch2: libgcrypt-1.6.2-use-fipscheck.patch -# fix tests in the FIPS mode, allow CAVS testing of DSA keygen -Patch5: libgcrypt-1.8.0-tests.patch +# modify FIPS RSA and DSA keygen to comply with requirements +Patch5: libgcrypt-1.8.4-fips-keygen.patch +# fix the tests to work correctly in the FIPS mode +Patch6: libgcrypt-1.8.4-tests-fipsmode.patch # update the CAVS tests Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness @@ -68,7 +70,8 @@ applications using libgcrypt. %setup -q %{SOURCE3} %patch2 -p1 -b .use-fipscheck -%patch5 -p1 -b .tests +%patch5 -p1 -b .fips-keygen +%patch6 -p1 -b .tests-fipsmode %patch7 -p1 -b .cavs %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt @@ -174,6 +177,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Feb 12 2019 Tomáš Mráz 1.8.4-3 +- fix the build tests to pass in the FIPS mode + * Fri Feb 01 2019 Fedora Release Engineering - 1.8.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_30_Mass_Rebuild From 24a8b93dca7895d6b1166a17bc6e7fa9046ad6a6 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 25 Jul 2019 13:18:59 +0000 Subject: [PATCH 125/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index e8e5676..b43d612 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.4 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -177,6 +177,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Jul 25 2019 Fedora Release Engineering - 1.8.4-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild + * Tue Feb 12 2019 Tomáš Mráz 1.8.4-3 - fix the build tests to pass in the FIPS mode From 402a3b5f2eed746bea996c5743c99bec9bbc3487 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 3 Sep 2019 14:12:27 +0200 Subject: [PATCH 126/214] new upstream version 1.8.5 add CMAC selftest for FIPS POST add continuous FIPS entropy test disable non-approved FIPS hashes in the enforced FIPS mode --- .gitignore | 1 + libgcrypt-1.8.3-cmac-selftest.patch | 322 ++++++++++++++++++++++++++ libgcrypt-1.8.3-fips-enttest.patch | 113 +++++++++ libgcrypt-1.8.3-md-fips-enforce.patch | 12 + libgcrypt.spec | 21 +- sources | 2 +- 6 files changed, 468 insertions(+), 3 deletions(-) create mode 100644 libgcrypt-1.8.3-cmac-selftest.patch create mode 100644 libgcrypt-1.8.3-fips-enttest.patch create mode 100644 libgcrypt-1.8.3-md-fips-enforce.patch diff --git a/.gitignore b/.gitignore index d698df1..e510ea5 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.2-hobbled.tar.xz /libgcrypt-1.8.3-hobbled.tar.xz /libgcrypt-1.8.4-hobbled.tar.xz +/libgcrypt-1.8.5-hobbled.tar.xz diff --git a/libgcrypt-1.8.3-cmac-selftest.patch b/libgcrypt-1.8.3-cmac-selftest.patch new file mode 100644 index 0000000..d480092 --- /dev/null +++ b/libgcrypt-1.8.3-cmac-selftest.patch @@ -0,0 +1,322 @@ +diff -up libgcrypt-1.8.3/cipher/cipher-cmac.c.cmac-selftest libgcrypt-1.8.3/cipher/cipher-cmac.c +--- libgcrypt-1.8.3/cipher/cipher-cmac.c.cmac-selftest 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.3/cipher/cipher-cmac.c 2019-05-31 17:33:35.594407152 +0200 +@@ -251,3 +251,246 @@ _gcry_cipher_cmac_set_subkeys (gcry_ciph + + return GPG_ERR_NO_ERROR; + } ++ ++/* CMAC selftests. ++ * Copyright (C) 2008 Free Software Foundation, Inc. ++ * Copyright (C) 2019 Red Hat, Inc. ++ */ ++ ++ ++ ++/* Check one MAC with MAC ALGO using the regular MAC ++ * API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key ++ * and (EXPECT,EXPECTLEN) the expected result. If TRUNC is set, the ++ * EXPECTLEN may be less than the digest length. Returns NULL on ++ * success or a string describing the failure. */ ++static const char * ++check_one (int algo, ++ const void *data, size_t datalen, ++ const void *key, size_t keylen, ++ const void *expect, size_t expectlen) ++{ ++ gcry_mac_hd_t hd; ++ unsigned char mac[512]; /* hardcoded to avoid allocation */ ++ size_t macoutlen = expectlen; ++ ++/* printf ("MAC algo %d\n", algo); */ ++ if (_gcry_mac_get_algo_maclen (algo) != expectlen || ++ expectlen > sizeof (mac)) ++ return "invalid tests data"; ++ if (_gcry_mac_open (&hd, algo, 0, NULL)) ++ return "gcry_mac_open failed"; ++ if (_gcry_mac_setkey (hd, key, keylen)) ++ { ++ _gcry_mac_close (hd); ++ return "gcry_md_setkey failed"; ++ } ++ if (_gcry_mac_write (hd, data, datalen)) ++ { ++ _gcry_mac_close (hd); ++ return "gcry_mac_write failed"; ++ } ++ if (_gcry_mac_read (hd, mac, &macoutlen)) ++ { ++ _gcry_mac_close (hd); ++ return "gcry_mac_read failed"; ++ } ++ _gcry_mac_close (hd); ++ if (macoutlen != expectlen || memcmp (mac, expect, expectlen)) ++ { ++/* int i; */ ++ ++/* fputs (" {", stdout); */ ++/* for (i=0; i < expectlen-1; i++) */ ++/* { */ ++/* if (i && !(i % 8)) */ ++/* fputs ("\n ", stdout); */ ++/* printf (" 0x%02x,", mac[i]); */ ++/* } */ ++/* printf (" 0x%02x } },\n", mac[i]); */ ++ ++ return "does not match"; ++ } ++ return NULL; ++} ++ ++ ++static gpg_err_code_t ++selftests_cmac_tdes (int extended, selftest_report_func_t report) ++{ ++ const char *what; ++ const char *errtxt; ++ ++ what = "Basic TDES"; ++ errtxt = check_one (GCRY_MAC_CMAC_3DES, ++ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" ++ "\xae\x2d\x8a\x57", 20, ++ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" ++ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, ++ "\x74\x3d\xdb\xe0\xce\x2d\xc2\xed", 8); ++ if (errtxt) ++ goto failed; ++ ++ if (extended) ++ { ++ what = "Extended TDES #1"; ++ errtxt = check_one (GCRY_MAC_CMAC_3DES, ++ "", 0, ++ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" ++ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, ++ "\xb7\xa6\x88\xe1\x22\xff\xaf\x95", 8); ++ if (errtxt) ++ goto failed; ++ ++ what = "Extended TDES #2"; ++ errtxt = check_one (GCRY_MAC_CMAC_3DES, ++ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96", 8, ++ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" ++ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, ++ "\x8e\x8f\x29\x31\x36\x28\x37\x97", 8); ++ if (errtxt) ++ goto failed; ++ ++ what = "Extended TDES #3"; ++ errtxt = check_one (GCRY_MAC_CMAC_3DES, ++ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" ++ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 32, ++ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" ++ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, ++ "\x33\xe6\xb1\x09\x24\x00\xea\xe5", 8); ++ if (errtxt) ++ goto failed; ++ } ++ ++ return 0; /* Succeeded. */ ++ ++ failed: ++ if (report) ++ report ("cmac", GCRY_MAC_CMAC_3DES, what, errtxt); ++ return GPG_ERR_SELFTEST_FAILED; ++} ++ ++ ++ ++static gpg_err_code_t ++selftests_cmac_aes (int extended, selftest_report_func_t report) ++{ ++ const char *what; ++ const char *errtxt; ++ ++ what = "Basic AES128"; ++ errtxt = check_one (GCRY_MAC_CMAC_AES, ++ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" ++ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" ++ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, ++ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, ++ "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27", 16); ++ if (errtxt) ++ goto failed; ++ ++ what = "Basic AES192"; ++ errtxt = check_one (GCRY_MAC_CMAC_AES, ++ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" ++ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" ++ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, ++ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" ++ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, ++ "\x8a\x1d\xe5\xbe\x2e\xb3\x1a\xad\x08\x9a\x82\xe6\xee\x90\x8b\x0e", 16); ++ if (errtxt) ++ goto failed; ++ ++ what = "Basic AES256"; ++ errtxt = check_one (GCRY_MAC_CMAC_AES, ++ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" ++ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" ++ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, ++ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" ++ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, ++ "\xaa\xf3\xd8\xf1\xde\x56\x40\xc2\x32\xf5\xb1\x69\xb9\xc9\x11\xe6", 16); ++ if (errtxt) ++ goto failed; ++ if (extended) ++ { ++ what = "Extended AES #1"; ++ errtxt = check_one (GCRY_MAC_CMAC_AES, ++ "", 0, ++ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, ++ "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46", 16); ++ if (errtxt) ++ goto failed; ++ ++ what = "Extended AES #2"; ++ errtxt = check_one (GCRY_MAC_CMAC_AES, ++ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, ++ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" ++ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, ++ "\x9e\x99\xa7\xbf\x31\xe7\x10\x90\x06\x62\xf6\x5e\x61\x7c\x51\x84", 16); ++ if (errtxt) ++ goto failed; ++ ++ what = "Extended AES #3"; ++ errtxt = check_one (GCRY_MAC_CMAC_AES, ++ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" ++ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" ++ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" ++ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 64, ++ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" ++ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, ++ "\xe1\x99\x21\x90\x54\x9f\x6e\xd5\x69\x6a\x2c\x05\x6c\x31\x54\x10", 16 ); ++ if (errtxt) ++ goto failed; ++ } ++ ++ return 0; /* Succeeded. */ ++ ++ failed: ++ if (report) ++ report ("cmac", GCRY_MAC_CMAC_AES, what, errtxt); ++ return GPG_ERR_SELFTEST_FAILED; ++} ++ ++ ++/* Run a full self-test for ALGO and return 0 on success. */ ++static gpg_err_code_t ++run_cmac_selftests (int algo, int extended, selftest_report_func_t report) ++{ ++ gpg_err_code_t ec; ++ ++ switch (algo) ++ { ++ case GCRY_MAC_CMAC_3DES: ++ ec = selftests_cmac_tdes (extended, report); ++ break; ++ case GCRY_MAC_CMAC_AES: ++ ec = selftests_cmac_aes (extended, report); ++ break; ++ ++ default: ++ ec = GPG_ERR_MAC_ALGO; ++ break; ++ } ++ return ec; ++} ++ ++ ++ ++ ++/* Run the selftests for CMAC with CMAC algorithm ALGO with optional ++ reporting function REPORT. */ ++gpg_error_t ++_gcry_cmac_selftest (int algo, int extended, selftest_report_func_t report) ++{ ++ gcry_err_code_t ec = 0; ++ ++ if (!_gcry_mac_algo_info( algo, GCRYCTL_TEST_ALGO, NULL, NULL )) ++ { ++ ec = run_cmac_selftests (algo, extended, report); ++ } ++ else ++ { ++ ec = GPG_ERR_MAC_ALGO; ++ if (report) ++ report ("mac", algo, "module", "algorithm not available"); ++ } ++ return gpg_error (ec); ++} +diff -up libgcrypt-1.8.3/src/cipher-proto.h.cmac-selftest libgcrypt-1.8.3/src/cipher-proto.h +--- libgcrypt-1.8.3/src/cipher-proto.h.cmac-selftest 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.3/src/cipher-proto.h 2019-05-31 17:29:34.574588234 +0200 +@@ -256,6 +256,8 @@ gcry_error_t _gcry_pk_selftest (int algo + selftest_report_func_t report); + gcry_error_t _gcry_hmac_selftest (int algo, int extended, + selftest_report_func_t report); ++gcry_error_t _gcry_cmac_selftest (int algo, int extended, ++ selftest_report_func_t report); + + gcry_error_t _gcry_random_selftest (selftest_report_func_t report); + +diff -up libgcrypt-1.8.3/src/fips.c.cmac-selftest libgcrypt-1.8.3/src/fips.c +--- libgcrypt-1.8.3/src/fips.c.cmac-selftest 2018-11-01 15:40:36.051865535 +0100 ++++ libgcrypt-1.8.3/src/fips.c 2019-05-31 17:31:20.157756640 +0200 +@@ -521,29 +521,32 @@ run_digest_selftests (int extended) + + /* Run self-tests for all HMAC algorithms. Return 0 on success. */ + static int +-run_hmac_selftests (int extended) ++run_mac_selftests (int extended) + { +- static int algos[] = ++ static int algos[][2] = + { +- GCRY_MD_SHA1, +- GCRY_MD_SHA224, +- GCRY_MD_SHA256, +- GCRY_MD_SHA384, +- GCRY_MD_SHA512, +- GCRY_MD_SHA3_224, +- GCRY_MD_SHA3_256, +- GCRY_MD_SHA3_384, +- GCRY_MD_SHA3_512, +- 0 ++ { GCRY_MD_SHA1, 0 }, ++ { GCRY_MD_SHA224, 0 }, ++ { GCRY_MD_SHA256, 0 }, ++ { GCRY_MD_SHA384, 0 }, ++ { GCRY_MD_SHA512, 0 }, ++ { GCRY_MD_SHA3_224, 0 }, ++ { GCRY_MD_SHA3_256, 0 }, ++ { GCRY_MD_SHA3_384, 0 }, ++ { GCRY_MD_SHA3_512, 0 }, ++ { GCRY_MAC_CMAC_3DES, 1 }, ++ { GCRY_MAC_CMAC_AES, 1 }, ++ { 0, 0 } + }; + int idx; + gpg_error_t err; + int anyerr = 0; + +- for (idx=0; algos[idx]; idx++) ++ for (idx=0; algos[idx][0]; idx++) + { +- err = _gcry_hmac_selftest (algos[idx], extended, reporter); +- reporter ("hmac", algos[idx], NULL, ++ err = algos[idx][1] ? _gcry_cmac_selftest (algos[idx][0], extended, reporter) : ++ _gcry_hmac_selftest (algos[idx][0], extended, reporter); ++ reporter (algos[idx][1] ? "cmac" : "hmac", algos[idx][0], NULL, + err? gpg_strerror (err):NULL); + if (err) + anyerr = 1; +@@ -747,7 +750,7 @@ _gcry_fips_run_selftests (int extended) + if (run_digest_selftests (extended)) + goto leave; + +- if (run_hmac_selftests (extended)) ++ if (run_mac_selftests (extended)) + goto leave; + + /* Run random tests before the pubkey tests because the latter diff --git a/libgcrypt-1.8.3-fips-enttest.patch b/libgcrypt-1.8.3-fips-enttest.patch new file mode 100644 index 0000000..b6b09ba --- /dev/null +++ b/libgcrypt-1.8.3-fips-enttest.patch @@ -0,0 +1,113 @@ +diff -up libgcrypt-1.8.3/random/random-drbg.c.fips-enttest libgcrypt-1.8.3/random/random-drbg.c +--- libgcrypt-1.8.3/random/random-drbg.c.fips-enttest 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.3/random/random-drbg.c 2019-06-24 10:04:23.219547141 +0200 +@@ -317,6 +317,7 @@ struct drbg_state_s + unsigned char *ctr_null; /* CTR mode zero buffer */ + int seeded:1; /* DRBG fully seeded? */ + int pr:1; /* Prediction resistance enabled? */ ++ int ent_primed:1; /* Previous entropy data primed? */ + /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the + * process which did the initialization so that we can detect a fork. + * The volatile modifier is required so that the compiler does not +@@ -324,6 +325,7 @@ struct drbg_state_s + pid_t seed_init_pid; + const struct drbg_state_ops_s *d_ops; + const struct drbg_core_s *core; ++ unsigned char ent_hash[64]; /* Hash of previous entropy data */ + struct drbg_test_data_s *test_data; + }; + +@@ -610,11 +612,13 @@ drbg_get_entropy (drbg_state_t drbg, uns + size_t len) + { + int rc = 0; ++ unsigned char newhash[64]; + + /* Perform testing as defined in 11.3.2 */ + if (drbg->test_data && drbg->test_data->fail_seed_source) + return -1; + ++redo: + read_cb_buffer = buffer; + read_cb_size = len; + read_cb_len = 0; +@@ -634,6 +638,27 @@ drbg_get_entropy (drbg_state_t drbg, uns + #else + rc = -1; + #endif ++ ++ /* to avoid storing the actual entropy obtained for indefinite ++ time, we just store the SHA-512 hash of the entropy gathered ++ */ ++ _gcry_md_hash_buffer (GCRY_MD_SHA512, newhash, buffer, len); ++ ++ if (!drbg->ent_primed) ++ { ++ memcpy (drbg->ent_hash, newhash, sizeof (drbg->ent_hash)); ++ drbg->ent_primed = 1; ++ goto redo; ++ } ++ ++ if (memcmp (newhash, drbg->ent_hash, sizeof (drbg->ent_hash)) == 0) ++ { ++ fips_signal_error ("Entropy source failed the continuous test"); ++ return -1; /* continuous entropy test failed */ ++ } ++ ++ memcpy (drbg->ent_hash, newhash, sizeof (drbg->ent_hash)); ++ + return rc; + } + +@@ -1341,26 +1366,38 @@ drbg_seed (drbg_state_t drbg, drbg_strin + } + else + { ++ int nonce = 0; + /* Gather entropy equal to the security strength of the DRBG. + * With a derivation function, a nonce is required in addition + * to the entropy. A nonce must be at least 1/2 of the security + * strength of the DRBG in size. Thus, entropy * nonce is 3/2 + * of the strength. The consideration of a nonce is only +- * applicable during initial seeding. */ ++ * applicable during initial seeding. ++ * To avoid pulling different length of data from entropy ++ * source, we use 2 * strength for initial seeding. */ + entropylen = drbg_sec_strength (drbg->core->flags); + if (!entropylen) + return GPG_ERR_GENERAL; + if (0 == reseed) +- /* make sure we round up strength/2 in +- * case it is not divisible by 2 */ +- entropylen = ((entropylen + 1) / 2) * 3; ++ { ++ nonce = 1; ++ } + dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen)); +- entropy = xcalloc_secure (1, entropylen); ++ entropy = xcalloc_secure (nonce + 1, entropylen); + if (!entropy) + return GPG_ERR_ENOMEM; + ret = drbg_get_entropy (drbg, entropy, entropylen); + if (ret) + goto out; ++ if (nonce) ++ { ++ ret = drbg_get_entropy (drbg, entropy + entropylen, entropylen); ++ if (ret) ++ goto out; ++ /* make sure we round up strength/2 in ++ * case it is not divisible by 2 */ ++ entropylen = 2 * entropylen; ++ } + drbg_string_fill (&data1, entropy, entropylen); + } + +@@ -1597,6 +1634,7 @@ drbg_instantiate (drbg_state_t drbg, + drbg->core = &drbg_cores[coreref]; + drbg->pr = pr; + drbg->seeded = 0; ++ drbg->ent_primed = 0; + if (drbg->core->flags & DRBG_HMAC) + drbg->d_ops = &drbg_hmac_ops; + else if (drbg->core->flags & DRBG_HASH_MASK) diff --git a/libgcrypt-1.8.3-md-fips-enforce.patch b/libgcrypt-1.8.3-md-fips-enforce.patch new file mode 100644 index 0000000..d040bfb --- /dev/null +++ b/libgcrypt-1.8.3-md-fips-enforce.patch @@ -0,0 +1,12 @@ +diff -up libgcrypt-1.8.3/cipher/md.c.fips-enforce libgcrypt-1.8.3/cipher/md.c +--- libgcrypt-1.8.3/cipher/md.c.fips-enforce 2018-11-01 15:40:36.051865535 +0100 ++++ libgcrypt-1.8.3/cipher/md.c 2019-06-03 11:50:21.435401753 +0200 +@@ -409,7 +409,7 @@ md_enable (gcry_md_hd_t hd, int algorith + } + + +- if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) ++ if (!err && !spec->flags.fips && fips_mode ()) + { + if (_gcry_enforced_fips_mode () ) + { diff --git a/libgcrypt.spec b/libgcrypt.spec index b43d612..7abc068 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.8.4 -Release: 4%{?dist} +Version: 1.8.5 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -37,6 +37,12 @@ Patch18: libgcrypt-1.8.3-fips-ctor.patch Patch22: libgcrypt-1.7.3-fips-reqs.patch # Do not try to open /dev/urandom if getrandom() works Patch24: libgcrypt-1.8.4-getrandom.patch +# CMAC selftest for FIPS POST +Patch25: libgcrypt-1.8.3-cmac-selftest.patch +# Continuous FIPS entropy test +Patch26: libgcrypt-1.8.3-fips-enttest.patch +# Disable non-approved FIPS hashes in the enforced FIPS mode +Patch27: libgcrypt-1.8.3-md-fips-enforce.patch %define gcrylibdir %{_libdir} @@ -56,6 +62,7 @@ Summary: Development files for the %{name} package License: LGPLv2+ and GPLv2+ Requires: libgpg-error-devel Requires: %{name} = %{version}-%{release} +Requires: pkgconfig %description Libgcrypt is a general purpose crypto library based on the code used @@ -79,6 +86,9 @@ applications using libgcrypt. %patch18 -p1 -b .fips-ctor %patch22 -p1 -b .fips-reqs %patch24 -p1 -b .getrandom +%patch25 -p1 -b .cmac-selftest +%patch26 -p1 -b .fips-enttest +%patch27 -p1 -b .fips-enforce cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -169,6 +179,7 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %{_bindir}/mpicalc %{_includedir}/* %{_libdir}/*.so +%{_libdir}/pkgconfig/libgcrypt.pc %{_datadir}/aclocal/* %{_mandir}/man1/* @@ -177,6 +188,12 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Sep 3 2019 Tomáš Mráz 1.8.5-1 +- new upstream version 1.8.5 +- add CMAC selftest for FIPS POST +- add continuous FIPS entropy test +- disable non-approved FIPS hashes in the enforced FIPS mode + * Thu Jul 25 2019 Fedora Release Engineering - 1.8.4-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_31_Mass_Rebuild diff --git a/sources b/sources index 465ff20..7a67991 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.8.4-hobbled.tar.xz) = 9f124d84a401f6b63faabe46b983e157573a20064e9652fe47b4d18b58d580eab9458a47eb24694b26e8e8e7e8c82002f354f075a0fc7037e61fb4ab0eafdf19 +SHA512 (libgcrypt-1.8.5-hobbled.tar.xz) = 63391cdb4b2366dfc7869a45a9e5facbb05e4d28ada2646941cadfa2de93517ff5fb2a28aa7f486b79a1449cf701c8c36a6e99052d7c499b240dff606dd921a0 From 8c18517a2519c8acbf705612db701c063990ff59 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 23 Jan 2020 15:47:41 +0100 Subject: [PATCH 127/214] Intel CET support by H. J. Lu --- libgcrypt-1.8.5-intel-cet.patch | 348 ++++++++++++++++++++++++++++++++ libgcrypt.spec | 8 +- 2 files changed, 355 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.8.5-intel-cet.patch diff --git a/libgcrypt-1.8.5-intel-cet.patch b/libgcrypt-1.8.5-intel-cet.patch new file mode 100644 index 0000000..f58084e --- /dev/null +++ b/libgcrypt-1.8.5-intel-cet.patch @@ -0,0 +1,348 @@ +diff -up libgcrypt-1.8.5/cipher/camellia-aesni-avx2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/camellia-aesni-avx2-amd64.S +--- libgcrypt-1.8.5/cipher/camellia-aesni-avx2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/camellia-aesni-avx2-amd64.S 2020-01-23 15:36:44.148972045 +0100 +@@ -18,8 +18,9 @@ + * License along with this program; if not, see . + */ + +-#ifdef __x86_64 + #include ++ ++#ifdef __x86_64 + #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ + defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \ + defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT) +diff -up libgcrypt-1.8.5/cipher/camellia-aesni-avx-amd64.S.intel-cet libgcrypt-1.8.5/cipher/camellia-aesni-avx-amd64.S +--- libgcrypt-1.8.5/cipher/camellia-aesni-avx-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/camellia-aesni-avx-amd64.S 2020-01-23 15:36:44.145972088 +0100 +@@ -18,8 +18,9 @@ + * License along with this program; if not, see . + */ + +-#ifdef __x86_64 + #include ++ ++#ifdef __x86_64 + #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ + defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \ + defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT) +diff -up libgcrypt-1.8.5/cipher/chacha20-avx2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/chacha20-avx2-amd64.S +--- libgcrypt-1.8.5/cipher/chacha20-avx2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/chacha20-avx2-amd64.S 2020-01-23 15:36:16.780250066 +0100 +@@ -48,6 +48,9 @@ + .globl _gcry_chacha20_amd64_avx2_blocks + ELF(.type _gcry_chacha20_amd64_avx2_blocks,@function;) + _gcry_chacha20_amd64_avx2_blocks: ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + .Lchacha_blocks_avx2_local: + vzeroupper + pushq %rbx +diff -up libgcrypt-1.8.5/cipher/chacha20-sse2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/chacha20-sse2-amd64.S +--- libgcrypt-1.8.5/cipher/chacha20-sse2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/chacha20-sse2-amd64.S 2020-01-23 15:36:16.783250095 +0100 +@@ -41,6 +41,9 @@ + .globl _gcry_chacha20_amd64_sse2_blocks + ELF(.type _gcry_chacha20_amd64_sse2_blocks,@function;) + _gcry_chacha20_amd64_sse2_blocks: ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + .Lchacha_blocks_sse2_local: + pushq %rbx + pushq %rbp +diff -up libgcrypt-1.8.5/cipher/poly1305-avx2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/poly1305-avx2-amd64.S +--- libgcrypt-1.8.5/cipher/poly1305-avx2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/poly1305-avx2-amd64.S 2020-01-23 15:36:16.784250105 +0100 +@@ -43,6 +43,9 @@ + .globl _gcry_poly1305_amd64_avx2_init_ext + ELF(.type _gcry_poly1305_amd64_avx2_init_ext,@function;) + _gcry_poly1305_amd64_avx2_init_ext: ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + .Lpoly1305_init_ext_avx2_local: + xor %edx, %edx + vzeroupper +@@ -406,6 +409,9 @@ ELF(.size _gcry_poly1305_amd64_avx2_init + .globl _gcry_poly1305_amd64_avx2_blocks + ELF(.type _gcry_poly1305_amd64_avx2_blocks,@function;) + _gcry_poly1305_amd64_avx2_blocks: ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + .Lpoly1305_blocks_avx2_local: + vzeroupper + pushq %rbp +@@ -732,6 +738,9 @@ ELF(.size _gcry_poly1305_amd64_avx2_bloc + .globl _gcry_poly1305_amd64_avx2_finish_ext + ELF(.type _gcry_poly1305_amd64_avx2_finish_ext,@function;) + _gcry_poly1305_amd64_avx2_finish_ext: ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + .Lpoly1305_finish_ext_avx2_local: + vzeroupper + pushq %rbp +diff -up libgcrypt-1.8.5/cipher/poly1305-sse2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/poly1305-sse2-amd64.S +--- libgcrypt-1.8.5/cipher/poly1305-sse2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/poly1305-sse2-amd64.S 2020-01-23 15:36:16.787250134 +0100 +@@ -42,6 +42,9 @@ + .globl _gcry_poly1305_amd64_sse2_init_ext + ELF(.type _gcry_poly1305_amd64_sse2_init_ext,@function;) + _gcry_poly1305_amd64_sse2_init_ext: ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + .Lpoly1305_init_ext_x86_local: + xor %edx, %edx + pushq %r12 +@@ -288,6 +291,9 @@ ELF(.size _gcry_poly1305_amd64_sse2_init + .globl _gcry_poly1305_amd64_sse2_finish_ext + ELF(.type _gcry_poly1305_amd64_sse2_finish_ext,@function;) + _gcry_poly1305_amd64_sse2_finish_ext: ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + .Lpoly1305_finish_ext_x86_local: + pushq %rbp + movq %rsp, %rbp +@@ -439,6 +445,9 @@ ELF(.size _gcry_poly1305_amd64_sse2_fini + .globl _gcry_poly1305_amd64_sse2_blocks + ELF(.type _gcry_poly1305_amd64_sse2_blocks,@function;) + _gcry_poly1305_amd64_sse2_blocks: ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + .Lpoly1305_blocks_x86_local: + pushq %rbp + movq %rsp, %rbp +diff -up libgcrypt-1.8.5/cipher/serpent-avx2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/serpent-avx2-amd64.S +--- libgcrypt-1.8.5/cipher/serpent-avx2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/serpent-avx2-amd64.S 2020-01-23 15:36:44.151972003 +0100 +@@ -18,8 +18,9 @@ + * License along with this program; if not, see . + */ + +-#ifdef __x86_64 + #include ++ ++#ifdef __x86_64 + #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ + defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_SERPENT) && \ + defined(ENABLE_AVX2_SUPPORT) +diff -up libgcrypt-1.8.5/configure.ac.intel-cet libgcrypt-1.8.5/configure.ac +--- libgcrypt-1.8.5/configure.ac.intel-cet 2019-08-29 15:00:08.000000000 +0200 ++++ libgcrypt-1.8.5/configure.ac 2020-01-23 15:35:28.147774463 +0100 +@@ -95,6 +95,12 @@ AH_TOP([ + AH_BOTTOM([ + #define _GCRYPT_IN_LIBGCRYPT 1 + ++/* Add .note.gnu.property section for Intel CET in assembler sources ++ when CET is enabled. */ ++#if defined(__ASSEMBLER__) && defined(__CET__) ++# include ++#endif ++ + /* If the configure check for endianness has been disabled, get it from + OS macros. This is intended for making fat binary builds on OS X. */ + #ifdef DISABLED_ENDIAN_CHECK +diff -up libgcrypt-1.8.5/mpi/config.links.intel-cet libgcrypt-1.8.5/mpi/config.links +--- libgcrypt-1.8.5/mpi/config.links.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/mpi/config.links 2020-01-23 15:35:46.398952954 +0100 +@@ -382,6 +382,16 @@ if test x"$mpi_cpu_arch" = x ; then + mpi_cpu_arch="unknown" + fi + ++# Add .note.gnu.property section for Intel CET in assembler sources ++# when CET is enabled. */ ++if test x"$mpi_cpu_arch" = xx86 ; then ++ cat <> ./mpi/asm-syntax.h ++ ++#if defined(__ASSEMBLER__) && defined(__CET__) ++# include ++#endif ++EOF ++fi + + # Make sysdep.h + echo '/* created by config.links - do not edit */' >./mpi/sysdep.h +diff -up libgcrypt-1.8.5/mpi/i386/mpih-add1.S.intel-cet libgcrypt-1.8.5/mpi/i386/mpih-add1.S +--- libgcrypt-1.8.5/mpi/i386/mpih-add1.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/mpi/i386/mpih-add1.S 2020-01-23 15:37:40.470175379 +0100 +@@ -52,6 +52,10 @@ C_SYMBOL_NAME(_gcry_mpih_add_n:) + movl 20(%esp),%edx /* s2_ptr */ + movl 24(%esp),%ecx /* size */ + ++#if defined __CET__ && (__CET__ & 1) != 0 ++ pushl %ebx ++#endif ++ + movl %ecx,%eax + shrl $3,%ecx /* compute count for unrolled loop */ + negl %eax +@@ -63,6 +67,9 @@ C_SYMBOL_NAME(_gcry_mpih_add_n:) + subl %eax,%esi /* ... by a constant when we ... */ + subl %eax,%edx /* ... enter the loop */ + shrl $2,%eax /* restore previous value */ ++#if defined __CET__ && (__CET__ & 1) != 0 ++ leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */ ++#endif + #ifdef PIC + /* Calculate start address in loop for PIC. Due to limitations in some + assemblers, Loop-L0-3 cannot be put into the leal */ +@@ -75,29 +82,53 @@ L0: leal (%eax,%eax,8),%eax + /* Calculate start address in loop for non-PIC. */ + leal (Loop - 3)(%eax,%eax,8),%eax + #endif ++#if defined __CET__ && (__CET__ & 1) != 0 ++ addl %ebx,%eax /* Adjust for endbr32 */ ++#endif + jmp *%eax /* jump into loop */ + ALIGN (3) + Loop: movl (%esi),%eax + adcl (%edx),%eax + movl %eax,(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 4(%esi),%eax + adcl 4(%edx),%eax + movl %eax,4(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 8(%esi),%eax + adcl 8(%edx),%eax + movl %eax,8(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 12(%esi),%eax + adcl 12(%edx),%eax + movl %eax,12(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 16(%esi),%eax + adcl 16(%edx),%eax + movl %eax,16(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 20(%esi),%eax + adcl 20(%edx),%eax + movl %eax,20(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 24(%esi),%eax + adcl 24(%edx),%eax + movl %eax,24(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 28(%esi),%eax + adcl 28(%edx),%eax + movl %eax,28(%edi) +@@ -110,6 +141,10 @@ Loop: movl (%esi),%eax + sbbl %eax,%eax + negl %eax + ++#if defined __CET__ && (__CET__ & 1) != 0 ++ popl %ebx ++#endif ++ + popl %esi + popl %edi + ret +diff -up libgcrypt-1.8.5/mpi/i386/mpih-sub1.S.intel-cet libgcrypt-1.8.5/mpi/i386/mpih-sub1.S +--- libgcrypt-1.8.5/mpi/i386/mpih-sub1.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/mpi/i386/mpih-sub1.S 2020-01-23 15:37:40.472175351 +0100 +@@ -53,6 +53,10 @@ C_SYMBOL_NAME(_gcry_mpih_sub_n:) + movl 20(%esp),%edx /* s2_ptr */ + movl 24(%esp),%ecx /* size */ + ++#if defined __CET__ && (__CET__ & 1) != 0 ++ pushl %ebx ++#endif ++ + movl %ecx,%eax + shrl $3,%ecx /* compute count for unrolled loop */ + negl %eax +@@ -64,6 +68,9 @@ C_SYMBOL_NAME(_gcry_mpih_sub_n:) + subl %eax,%esi /* ... by a constant when we ... */ + subl %eax,%edx /* ... enter the loop */ + shrl $2,%eax /* restore previous value */ ++#if defined __CET__ && (__CET__ & 1) != 0 ++ leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */ ++#endif + #ifdef PIC + /* Calculate start address in loop for PIC. Due to limitations in some + assemblers, Loop-L0-3 cannot be put into the leal */ +@@ -76,29 +83,53 @@ L0: leal (%eax,%eax,8),%eax + /* Calculate start address in loop for non-PIC. */ + leal (Loop - 3)(%eax,%eax,8),%eax + #endif ++#if defined __CET__ && (__CET__ & 1) != 0 ++ addl %ebx,%eax /* Adjust for endbr32 */ ++#endif + jmp *%eax /* jump into loop */ + ALIGN (3) + Loop: movl (%esi),%eax + sbbl (%edx),%eax + movl %eax,(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 4(%esi),%eax + sbbl 4(%edx),%eax + movl %eax,4(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 8(%esi),%eax + sbbl 8(%edx),%eax + movl %eax,8(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 12(%esi),%eax + sbbl 12(%edx),%eax + movl %eax,12(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 16(%esi),%eax + sbbl 16(%edx),%eax + movl %eax,16(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 20(%esi),%eax + sbbl 20(%edx),%eax + movl %eax,20(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 24(%esi),%eax + sbbl 24(%edx),%eax + movl %eax,24(%edi) ++#ifdef _CET_ENDBR ++ _CET_ENDBR ++#endif + movl 28(%esi),%eax + sbbl 28(%edx),%eax + movl %eax,28(%edi) +@@ -111,6 +142,10 @@ Loop: movl (%esi),%eax + sbbl %eax,%eax + negl %eax + ++#if defined __CET__ && (__CET__ & 1) != 0 ++ popl %ebx ++#endif ++ + popl %esi + popl %edi + ret diff --git a/libgcrypt.spec b/libgcrypt.spec index 7abc068..1aca419 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.5 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -43,6 +43,8 @@ Patch25: libgcrypt-1.8.3-cmac-selftest.patch Patch26: libgcrypt-1.8.3-fips-enttest.patch # Disable non-approved FIPS hashes in the enforced FIPS mode Patch27: libgcrypt-1.8.3-md-fips-enforce.patch +# Intel CET support, in upstream master +Patch28: libgcrypt-1.8.5-intel-cet.patch %define gcrylibdir %{_libdir} @@ -89,6 +91,7 @@ applications using libgcrypt. %patch25 -p1 -b .cmac-selftest %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce +%patch28 -p1 -b .intel-cet cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -188,6 +191,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Jan 23 2020 Tomáš Mráz 1.8.5-2 +- Intel CET support by H. J. Lu + * Tue Sep 3 2019 Tomáš Mráz 1.8.5-1 - new upstream version 1.8.5 - add CMAC selftest for FIPS POST From e6a86d0e9182a2fb0bf722061cf1688967b2750d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Wed, 29 Jan 2020 09:11:09 +0000 Subject: [PATCH 128/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 1aca419..52543bc 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.5 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -191,6 +191,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Jan 29 2020 Fedora Release Engineering - 1.8.5-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild + * Thu Jan 23 2020 Tomáš Mráz 1.8.5-2 - Intel CET support by H. J. Lu From 95e0a34ad521cdec0ac318b9a53b6c43917568d7 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 30 Jan 2020 17:29:55 +0100 Subject: [PATCH 129/214] fix the build on ARMv7 --- libgcrypt.spec | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 52543bc..d1ee3fd 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -45,6 +45,8 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # Intel CET support, in upstream master Patch28: libgcrypt-1.8.5-intel-cet.patch +# Fix build on ARMv7 +Patch29: libgcrypt-1.8.5-build.patch %define gcrylibdir %{_libdir} @@ -92,6 +94,7 @@ applications using libgcrypt. %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet +%patch29 -p1 -b .build cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -191,8 +194,8 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog -* Wed Jan 29 2020 Fedora Release Engineering - 1.8.5-3 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_32_Mass_Rebuild +* Thu Jan 30 2020 Tomáš Mráz 1.8.5-3 +- fix the build on ARMv7 * Thu Jan 23 2020 Tomáš Mráz 1.8.5-2 - Intel CET support by H. J. Lu From 4dfc42c2d2374dcaa47bc659b184d424f264790c Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 30 Jan 2020 17:30:20 +0100 Subject: [PATCH 130/214] fix the build on ARMv7 --- libgcrypt-1.8.5-build.patch | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 libgcrypt-1.8.5-build.patch diff --git a/libgcrypt-1.8.5-build.patch b/libgcrypt-1.8.5-build.patch new file mode 100644 index 0000000..3e71238 --- /dev/null +++ b/libgcrypt-1.8.5-build.patch @@ -0,0 +1,14 @@ +diff -up libgcrypt-1.8.5/cipher/poly1305-armv7-neon.S.build libgcrypt-1.8.5/cipher/poly1305-armv7-neon.S +--- libgcrypt-1.8.5/cipher/poly1305-armv7-neon.S.build 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/poly1305-armv7-neon.S 2020-01-30 17:26:12.026404286 +0100 +@@ -87,9 +87,8 @@ _gcry_poly1305_armv7_neon_init_ext: + .Lpoly1305_init_ext_neon_local: + stmfd sp!, {r4-r11, lr} + sub sp, sp, #32 +- mov r14, r2 ++ mov r14, #-1 + and r2, r2, r2 +- moveq r14, #-1 + UNALIGNED_LDMIA4(r1, r2, r3, r4, r5) + GET_DATA_POINTER(r7,.Lpoly1305_init_constants_neon,r8) + mov r6, r2 From d7ce942d74d86e3ef4c1953fc76825b4ef2b3f9b Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 20 Apr 2020 19:36:34 +0200 Subject: [PATCH 131/214] FIPS selftest is run directly from the constructor FIPS module is implicit with kernel FIPS flag --- libgcrypt-1.8.3-fips-ctor.patch | 224 ++------------------------ libgcrypt-1.8.3-md-fips-enforce.patch | 12 +- libgcrypt-1.8.5-fips-module.patch | 139 ++++++++++++++++ libgcrypt.spec | 11 +- 4 files changed, 171 insertions(+), 215 deletions(-) create mode 100644 libgcrypt-1.8.5-fips-module.patch diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch index e04201f..66abd59 100644 --- a/libgcrypt-1.8.3-fips-ctor.patch +++ b/libgcrypt-1.8.3-fips-ctor.patch @@ -1,196 +1,7 @@ -diff -up libgcrypt-1.8.3/cipher/md.c.fips-ctor libgcrypt-1.8.3/cipher/md.c ---- libgcrypt-1.8.3/cipher/md.c.fips-ctor 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/cipher/md.c 2018-07-12 13:24:54.088403006 +0200 -@@ -411,11 +411,8 @@ md_enable (gcry_md_hd_t hd, int algorith - - if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) - { -- _gcry_inactivate_fips_mode ("MD5 used"); - if (_gcry_enforced_fips_mode () ) - { -- /* We should never get to here because we do not register -- MD5 in enforced fips mode. But better throw an error. */ - err = GPG_ERR_DIGEST_ALGO; - } - } -diff -up libgcrypt-1.8.3/src/fips.c.fips-ctor libgcrypt-1.8.3/src/fips.c ---- libgcrypt-1.8.3/src/fips.c.fips-ctor 2018-07-12 13:24:54.075402698 +0200 -+++ libgcrypt-1.8.3/src/fips.c 2018-07-12 13:24:54.088403006 +0200 -@@ -91,6 +91,31 @@ static void fips_new_state (enum module_ - - - -+/* Initialize the FSM lock - this function may only -+ be called once and is intended to be run from the library -+ constructor */ -+void -+_gcry_initialize_fsm_lock (void) -+{ -+ gpg_error_t err; -+ /* Intitialize the lock to protect the FSM. */ -+ err = gpgrt_lock_init (&fsm_lock); -+ if (err) -+ { -+ /* If that fails we can't do anything but abort the -+ process. We need to use log_info so that the FSM won't -+ get involved. */ -+ log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", -+ gpg_strerror (err)); -+#ifdef HAVE_SYSLOG -+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -+ "creating FSM lock failed: %s - abort", -+ gpg_strerror (err)); -+#endif /*HAVE_SYSLOG*/ -+ abort (); -+ } -+} -+ - /* Check whether the OS is in FIPS mode and record that in a module - local variable. If FORCE is passed as true, fips mode will be - enabled anyway. Note: This function is not thread-safe and should -@@ -100,7 +125,6 @@ void - _gcry_initialize_fips_mode (int force) - { - static int done; -- gpg_error_t err; - - /* Make sure we are not accidentally called twice. */ - if (done) -@@ -179,24 +203,6 @@ _gcry_initialize_fips_mode (int force) - /* Yes, we are in FIPS mode. */ - FILE *fp; - -- /* Intitialize the lock to protect the FSM. */ -- err = gpgrt_lock_init (&fsm_lock); -- if (err) -- { -- /* If that fails we can't do anything but abort the -- process. We need to use log_info so that the FSM won't -- get involved. */ -- log_info ("FATAL: failed to create the FSM lock in libgcrypt: %s\n", -- gpg_strerror (err)); --#ifdef HAVE_SYSLOG -- syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -- "creating FSM lock failed: %s - abort", -- gpg_strerror (err)); --#endif /*HAVE_SYSLOG*/ -- abort (); -- } -- -- - /* If the FIPS force files exists, is readable and has a number - != 0 on its first line, we enable the enforced fips mode. */ - fp = fopen (FIPS_FORCE_FILE, "r"); -@@ -359,16 +365,20 @@ _gcry_fips_is_operational (void) - { - int result; - -- if (!fips_mode ()) -+ lock_fsm (); -+ if (current_state == STATE_POWERON && !fips_mode ()) -+ /* If we are at this point in POWERON state it means the FIPS -+ module installation was not completed. (/etc/system-fips -+ is not present.) */ - result = 1; - else - { -- lock_fsm (); -- if (current_state == STATE_INIT) -+ if (current_state == STATE_INIT || current_state == STATE_SELFTEST) - { -- /* If we are still in the INIT state, we need to run the -- selftests so that the FSM can eventually get into -- operational state. Given that we would need a 2-phase -+ /* If we are still in the INIT (or SELFTEST) state, -+ we need to run (or finish) the selftests so -+ that the FSM can eventually get into operational -+ state. Given that we would need a 2-phase - initialization of libgcrypt, but that has traditionally - not been enforced, we use this on demand self-test - checking. Note that Proper applications would do the -@@ -384,9 +394,11 @@ _gcry_fips_is_operational (void) - lock_fsm (); - } - -- result = (current_state == STATE_OPERATIONAL); -- unlock_fsm (); -+ result = (current_state == STATE_OPERATIONAL) || !fips_mode (); -+ /* We always run the selftests but ignore the result -+ in non-FIPS mode. */ - } -+ unlock_fsm (); - return result; - } - -@@ -709,9 +721,25 @@ _gcry_fips_run_selftests (int extended) - { - enum module_states result = STATE_ERROR; - gcry_err_code_t ec = GPG_ERR_SELFTEST_FAILED; -+ int in_poweron; - -- if (fips_mode ()) -- fips_new_state (STATE_SELFTEST); -+ lock_fsm (); -+ in_poweron = (current_state == STATE_POWERON); -+ unlock_fsm (); -+ -+ fips_new_state (STATE_SELFTEST); -+ -+ /* We first check the integrity of the binary. -+ If run from the constructor we are in POWERON state, -+ we return and finish the remaining selftests before -+ real use of the library. It will be in the POWERON -+ state meanwhile. */ -+ if (in_poweron) -+ if (check_binary_integrity ()) -+ goto leave; -+ -+ if (in_poweron) -+ return 0; - - if (run_cipher_selftests (extended)) - goto leave; -@@ -730,18 +758,12 @@ _gcry_fips_run_selftests (int extended) - if (run_pubkey_selftests (extended)) - goto leave; - -- /* Now check the integrity of the binary. We do this this after -- having checked the HMAC code. */ -- if (check_binary_integrity ()) -- goto leave; -- - /* All selftests passed. */ - result = STATE_OPERATIONAL; - ec = 0; - - leave: -- if (fips_mode ()) -- fips_new_state (result); -+ fips_new_state (result); - - return ec; - } -@@ -797,6 +819,7 @@ fips_new_state (enum module_states new_s - { - case STATE_POWERON: - if (new_state == STATE_INIT -+ || new_state == STATE_SELFTEST - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; -@@ -811,6 +834,8 @@ fips_new_state (enum module_states new_s - - case STATE_SELFTEST: - if (new_state == STATE_OPERATIONAL -+ || new_state == STATE_INIT -+ || new_state == STATE_SELFTEST - || new_state == STATE_ERROR - || new_state == STATE_FATALERROR) - ok = 1; diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c --- libgcrypt-1.8.3/src/global.c.fips-ctor 2017-11-23 19:25:58.000000000 +0100 -+++ libgcrypt-1.8.3/src/global.c 2018-07-17 19:15:43.933827112 +0200 -@@ -141,6 +141,29 @@ global_init (void) ++++ libgcrypt-1.8.3/src/global.c 2020-04-17 16:29:59.258218015 +0200 +@@ -141,6 +141,34 @@ global_init (void) } @@ -202,25 +13,30 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c +{ + int rv; + -+ /* We always need the FSM lock to be functional. */ -+ _gcry_initialize_fsm_lock (); -+ + rv = access (FIPS_MODULE_PATH, F_OK); + if (rv < 0 && errno != ENOENT) + rv = 0; + + if (!rv) + { -+ /* We run the integrity check at this point. The remaining -+ selftests are run before use of the library by application. */ ++ int no_secmem_save; ++ ++ /* it should be always 0 at this point but let's keep on the safe side */ ++ no_secmem_save = no_secure_memory; ++ no_secure_memory = 1; ++ /* force selftests */ ++ global_init(); + _gcry_fips_run_selftests (0); ++ if (!fips_mode()) ++ _gcry_random_close_fds (); ++ no_secure_memory = no_secmem_save; + } +} + /* This function is called by the macro fips_is_operational and makes sure that the minimal initialization has been done. This is far from a perfect solution and hides problems with an improper -@@ -671,8 +694,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, +@@ -671,8 +699,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, case GCRYCTL_FIPS_MODE_P: if (fips_mode () @@ -230,7 +46,7 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c rc = GPG_ERR_GENERAL; /* Used as TRUE value */ break; -@@ -749,9 +771,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, +@@ -749,9 +776,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, break; case GCRYCTL_SET_ENFORCED_FIPS_FLAG: @@ -242,15 +58,3 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c _gcry_set_preferred_rng_type (0); _gcry_set_enforced_fips_mode (); } -diff -up libgcrypt-1.8.3/src/g10lib.h.fips-ctor libgcrypt-1.8.3/src/g10lib.h ---- libgcrypt-1.8.3/src/g10lib.h.fips-ctor 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/src/g10lib.h 2018-07-12 13:24:54.089403030 +0200 -@@ -422,6 +422,8 @@ gpg_err_code_t _gcry_sexp_vextract_param - - /*-- fips.c --*/ - -+void _gcry_initialize_fsm_lock (void); -+ - void _gcry_initialize_fips_mode (int force); - - int _gcry_fips_mode (void); diff --git a/libgcrypt-1.8.3-md-fips-enforce.patch b/libgcrypt-1.8.3-md-fips-enforce.patch index d040bfb..eed7fa5 100644 --- a/libgcrypt-1.8.3-md-fips-enforce.patch +++ b/libgcrypt-1.8.3-md-fips-enforce.patch @@ -1,12 +1,18 @@ diff -up libgcrypt-1.8.3/cipher/md.c.fips-enforce libgcrypt-1.8.3/cipher/md.c ---- libgcrypt-1.8.3/cipher/md.c.fips-enforce 2018-11-01 15:40:36.051865535 +0100 -+++ libgcrypt-1.8.3/cipher/md.c 2019-06-03 11:50:21.435401753 +0200 -@@ -409,7 +409,7 @@ md_enable (gcry_md_hd_t hd, int algorith +--- libgcrypt-1.8.3/cipher/md.c.fips-enforce 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.3/cipher/md.c 2020-04-17 15:07:31.364945130 +0200 +@@ -409,13 +409,10 @@ md_enable (gcry_md_hd_t hd, int algorith } - if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) + if (!err && !spec->flags.fips && fips_mode ()) { +- _gcry_inactivate_fips_mode ("MD5 used"); if (_gcry_enforced_fips_mode () ) { +- /* We should never get to here because we do not register +- MD5 in enforced fips mode. But better throw an error. */ + err = GPG_ERR_DIGEST_ALGO; + } + } diff --git a/libgcrypt-1.8.5-fips-module.patch b/libgcrypt-1.8.5-fips-module.patch new file mode 100644 index 0000000..60b9ce2 --- /dev/null +++ b/libgcrypt-1.8.5-fips-module.patch @@ -0,0 +1,139 @@ +diff -up libgcrypt-1.8.5/src/fips.c.fips-module libgcrypt-1.8.5/src/fips.c +--- libgcrypt-1.8.5/src/fips.c.fips-module 2020-04-20 19:07:45.924919645 +0200 ++++ libgcrypt-1.8.5/src/fips.c 2020-04-20 19:10:33.690722470 +0200 +@@ -35,10 +35,6 @@ + #include "hmac256.h" + + +-/* The name of the file used to force libgcrypt into fips mode. */ +-#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" +- +- + /* The states of the finite state machine used in fips mode. */ + enum module_states + { +@@ -122,54 +118,6 @@ _gcry_initialize_fips_mode (int force) + goto leave; + } + +- /* For testing the system it is useful to override the system +- provided detection of the FIPS mode and force FIPS mode using a +- file. The filename is hardwired so that there won't be any +- confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is +- actually used. The file itself may be empty. */ +- if ( !access (FIPS_FORCE_FILE, F_OK) ) +- { +- gcry_assert (!no_fips_mode_required); +- goto leave; +- } +- +- /* Checking based on /proc file properties. */ +- { +- static const char procfname[] = "/proc/sys/crypto/fips_enabled"; +- FILE *fp; +- int saved_errno; +- +- fp = fopen (procfname, "r"); +- if (fp) +- { +- char line[256]; +- +- if (fgets (line, sizeof line, fp) && atoi (line)) +- { +- /* System is in fips mode. */ +- fclose (fp); +- gcry_assert (!no_fips_mode_required); +- goto leave; +- } +- fclose (fp); +- } +- else if ((saved_errno = errno) != ENOENT +- && saved_errno != EACCES +- && !access ("/proc/version", F_OK) ) +- { +- /* Problem reading the fips file despite that we have the proc +- file system. We better stop right away. */ +- log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", +- procfname, strerror (saved_errno)); +-#ifdef HAVE_SYSLOG +- syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " +- "reading `%s' failed: %s - abort", +- procfname, strerror (saved_errno)); +-#endif /*HAVE_SYSLOG*/ +- abort (); +- } +- } +- + /* Fips not not requested, set flag. */ + no_fips_mode_required = 1; + +diff -up libgcrypt-1.8.5/src/g10lib.h.fips-module libgcrypt-1.8.5/src/g10lib.h +--- libgcrypt-1.8.5/src/g10lib.h.fips-module 2020-04-20 19:07:45.918919759 +0200 ++++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 19:11:05.003125740 +0200 +@@ -422,6 +422,9 @@ gpg_err_code_t _gcry_sexp_vextract_param + + /*-- fips.c --*/ + ++/* The name of the file used to force libgcrypt into fips mode. */ ++#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" ++ + void _gcry_initialize_fips_mode (int force); + + int _gcry_fips_mode (void); +diff -up libgcrypt-1.8.5/src/global.c.fips-module libgcrypt-1.8.5/src/global.c +--- libgcrypt-1.8.5/src/global.c.fips-module 2020-04-20 19:07:45.919919741 +0200 ++++ libgcrypt-1.8.5/src/global.c 2020-04-20 19:07:45.950919149 +0200 +@@ -160,6 +160,53 @@ void __attribute__ ((constructor)) _gcry + rv = access (FIPS_MODULE_PATH, F_OK); + if (rv < 0 && errno != ENOENT) + rv = 0; ++ ++ /* For testing the system it is useful to override the system ++ provided detection of the FIPS mode and force FIPS mode using a ++ file. The filename is hardwired so that there won't be any ++ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is ++ actually used. The file itself may be empty. */ ++ if ( !access (FIPS_FORCE_FILE, F_OK) ) ++ { ++ rv = 0; ++ force_fips_mode = 1; ++ } ++ ++ /* Checking based on /proc file properties. */ ++ { ++ static const char procfname[] = "/proc/sys/crypto/fips_enabled"; ++ FILE *fp; ++ int saved_errno; ++ ++ fp = fopen (procfname, "r"); ++ if (fp) ++ { ++ char line[256]; ++ ++ if (fgets (line, sizeof line, fp) && atoi (line)) ++ { ++ /* System is in fips mode. */ ++ rv = 0; ++ force_fips_mode = 1; ++ } ++ fclose (fp); ++ } ++ else if ((saved_errno = errno) != ENOENT ++ && saved_errno != EACCES ++ && !access ("/proc/version", F_OK) ) ++ { ++ /* Problem reading the fips file despite that we have the proc ++ file system. We better stop right away. */ ++ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", ++ procfname, strerror (saved_errno)); ++#ifdef HAVE_SYSLOG ++ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " ++ "reading `%s' failed: %s - abort", ++ procfname, strerror (saved_errno)); ++#endif /*HAVE_SYSLOG*/ ++ abort (); ++ } ++ } + + if (!rv) + { diff --git a/libgcrypt.spec b/libgcrypt.spec index d1ee3fd..214ccf2 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.5 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -36,7 +36,7 @@ Patch18: libgcrypt-1.8.3-fips-ctor.patch # Block some operations if in FIPS non-operational state Patch22: libgcrypt-1.7.3-fips-reqs.patch # Do not try to open /dev/urandom if getrandom() works -Patch24: libgcrypt-1.8.4-getrandom.patch +Patch24: libgcrypt-1.8.5-getrandom.patch # CMAC selftest for FIPS POST Patch25: libgcrypt-1.8.3-cmac-selftest.patch # Continuous FIPS entropy test @@ -47,6 +47,8 @@ Patch27: libgcrypt-1.8.3-md-fips-enforce.patch Patch28: libgcrypt-1.8.5-intel-cet.patch # Fix build on ARMv7 Patch29: libgcrypt-1.8.5-build.patch +# FIPS module is redefined a little bit (implicit by kernel FIPS mode) +Patch30: libgcrypt-1.8.5-fips-module.patch %define gcrylibdir %{_libdir} @@ -95,6 +97,7 @@ applications using libgcrypt. %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet %patch29 -p1 -b .build +%patch30 -p1 -b .fips-module cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -194,6 +197,10 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Mon Apr 20 2020 Tomáš Mráz 1.8.5-4 +- FIPS selftest is run directly from the constructor +- FIPS module is implicit with kernel FIPS flag + * Thu Jan 30 2020 Tomáš Mráz 1.8.5-3 - fix the build on ARMv7 From c9dfa19c5fe175a222a2b00e76331fb5993024c5 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 20 Apr 2020 19:37:11 +0200 Subject: [PATCH 132/214] Updated the getrandom patch --- libgcrypt-1.8.4-getrandom.patch | 134 --------------- libgcrypt-1.8.5-getrandom.patch | 285 ++++++++++++++++++++++++++++++++ 2 files changed, 285 insertions(+), 134 deletions(-) delete mode 100644 libgcrypt-1.8.4-getrandom.patch create mode 100644 libgcrypt-1.8.5-getrandom.patch diff --git a/libgcrypt-1.8.4-getrandom.patch b/libgcrypt-1.8.4-getrandom.patch deleted file mode 100644 index a2fb7b9..0000000 --- a/libgcrypt-1.8.4-getrandom.patch +++ /dev/null @@ -1,134 +0,0 @@ -diff -up libgcrypt-1.8.4/random/random.c.getrandom libgcrypt-1.8.4/random/random.c ---- libgcrypt-1.8.4/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/random/random.c 2018-11-20 15:52:41.738708554 +0100 -@@ -110,8 +110,8 @@ _gcry_random_read_conf (void) - unsigned int result = 0; - - fp = fopen (fname, "r"); -- if (!fp) -- return result; -+ if (!fp) /* We make only_urandom the default. */ -+ return RANDOM_CONF_ONLY_URANDOM; - - for (;;) - { -diff -up libgcrypt-1.8.4/random/random-csprng.c.getrandom libgcrypt-1.8.4/random/random-csprng.c ---- libgcrypt-1.8.4/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/random/random-csprng.c 2018-11-20 15:52:41.738708554 +0100 -@@ -55,6 +55,10 @@ - #ifdef __MINGW32__ - #include - #endif -+#if defined(__linux__) && defined(HAVE_SYSCALL) -+# include -+# include -+#endif - #include "g10lib.h" - #include "random.h" - #include "rand-internal.h" -@@ -1116,6 +1120,22 @@ getfnc_gather_random (void))(void (*)(co - enum random_origins, size_t, int); - - #if USE_RNDLINUX -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ long ret; -+ char buffer[1]; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret != -1 || errno != ENOSYS) -+ { -+ fnc = _gcry_rndlinux_gather_random; -+ return fnc; -+ } -+ else -+ /* The syscall is not supported - fallback to /dev/urandom. */ -+#endif - if ( !access (NAME_OF_DEV_RANDOM, R_OK) - && !access (NAME_OF_DEV_URANDOM, R_OK)) - { -diff -up libgcrypt-1.8.4/random/rndlinux.c.getrandom libgcrypt-1.8.4/random/rndlinux.c ---- libgcrypt-1.8.4/random/rndlinux.c.getrandom 2018-11-20 15:52:41.731708393 +0100 -+++ libgcrypt-1.8.4/random/rndlinux.c 2018-11-20 16:06:45.431207374 +0100 -@@ -35,6 +35,7 @@ - #include - #if defined(__linux__) && defined(HAVE_SYSCALL) - # include -+# include - #endif - - #include "types.h" -@@ -147,12 +148,12 @@ _gcry_rndlinux_gather_random (void (*add - if (!add) - { - /* Special mode to close the descriptors. */ -- if (fd_random != -1) -+ if (fd_random >= 0) - { - close (fd_random); - fd_random = -1; - } -- if (fd_urandom != -1) -+ if (fd_urandom >= 0) - { - close (fd_urandom); - fd_urandom = -1; -@@ -166,12 +167,12 @@ _gcry_rndlinux_gather_random (void (*add - apid = getpid (); - if (my_pid != apid) - { -- if (fd_random != -1) -+ if (fd_random >= 0) - { - close (fd_random); - fd_random = -1; - } -- if (fd_urandom != -1) -+ if (fd_urandom >= 0) - { - close (fd_urandom); - fd_urandom = -1; -@@ -216,6 +217,22 @@ _gcry_rndlinux_gather_random (void (*add - that we always require the device to be existent but want a more - graceful behaviour if the rarely needed close operation has been - used and the device needs to be re-opened later. */ -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ if (fd_urandom != -2) -+ { -+ long ret; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret > -1 || errno == EAGAIN || errno == EINTR) -+ { -+ fd_urandom = -2; -+ fd_random = -2; -+ } -+ } -+#endif - if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom) - { - if (fd_random == -1) -@@ -255,6 +272,7 @@ _gcry_rndlinux_gather_random (void (*add - * syscall and not a new device and thus we are not able to use - * select(2) to have a timeout. */ - #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ if (fd == -2) - { - long ret; - size_t nbytes; -@@ -270,9 +288,7 @@ _gcry_rndlinux_gather_random (void (*add - _gcry_post_syscall (); - } - while (ret == -1 && errno == EINTR); -- if (ret == -1 && errno == ENOSYS) -- ; /* The syscall is not supported - fallback to pulling from fd. */ -- else -+ if (1) - { /* The syscall is supported. Some sanity checks. */ - if (ret == -1) - log_fatal ("unexpected error from getrandom: %s\n", diff --git a/libgcrypt-1.8.5-getrandom.patch b/libgcrypt-1.8.5-getrandom.patch new file mode 100644 index 0000000..ff2ef3b --- /dev/null +++ b/libgcrypt-1.8.5-getrandom.patch @@ -0,0 +1,285 @@ +diff -up libgcrypt-1.8.5/random/rand-internal.h.getrandom libgcrypt-1.8.5/random/rand-internal.h +--- libgcrypt-1.8.5/random/rand-internal.h.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/random/rand-internal.h 2020-04-20 14:55:34.875949624 +0200 +@@ -47,6 +47,7 @@ void _gcry_random_progress (const char * + + /*-- random-csprng.c --*/ + void _gcry_rngcsprng_initialize (int full); ++void _gcry_rngcsprng_deinit (void); + void _gcry_rngcsprng_close_fds (void); + void _gcry_rngcsprng_dump_stats (void); + void _gcry_rngcsprng_secure_alloc (void); +@@ -68,6 +69,7 @@ void _gcry_rngcsprng_fast_poll (void); + + /*-- random-drbg.c --*/ + void _gcry_rngdrbg_inititialize (int full); ++void _gcry_rngdrbg_deinit (void); + void _gcry_rngdrbg_close_fds (void); + void _gcry_rngdrbg_dump_stats (void); + int _gcry_rngdrbg_is_faked (void); +diff -up libgcrypt-1.8.5/random/random.c.getrandom libgcrypt-1.8.5/random/random.c +--- libgcrypt-1.8.5/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/random/random.c 2020-04-20 14:55:34.876949605 +0200 +@@ -110,8 +110,8 @@ _gcry_random_read_conf (void) + unsigned int result = 0; + + fp = fopen (fname, "r"); +- if (!fp) +- return result; ++ if (!fp) /* We make only_urandom the default. */ ++ return RANDOM_CONF_ONLY_URANDOM; + + for (;;) + { +@@ -228,6 +228,22 @@ _gcry_random_initialize (int full) + } + + ++/* Deinitialize this random subsystem. */ ++void ++_gcry_random_deinit (void) ++{ ++ if (fips_mode ()) ++ _gcry_rngdrbg_deinit (); ++ else if (rng_types.standard) ++ _gcry_rngcsprng_deinit (); ++ else if (rng_types.fips) ++ _gcry_rngdrbg_deinit (); ++ else ++ _gcry_rngcsprng_deinit (); ++ /* not needed for system */ ++} ++ ++ + /* If possible close file descriptors used by the RNG. */ + void + _gcry_random_close_fds (void) +diff -up libgcrypt-1.8.5/random/random-csprng.c.getrandom libgcrypt-1.8.5/random/random-csprng.c +--- libgcrypt-1.8.5/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/random/random-csprng.c 2020-04-20 15:04:27.182877975 +0200 +@@ -55,6 +55,10 @@ + #ifdef __MINGW32__ + #include + #endif ++#if defined(__linux__) && defined(HAVE_SYSCALL) ++# include ++# include ++#endif + #include "g10lib.h" + #include "random.h" + #include "rand-internal.h" +@@ -343,6 +347,21 @@ _gcry_rngcsprng_initialize (int full) + } + + ++void ++_gcry_rngcsprng_deinit (void) ++{ ++ lock_pool(); ++ pool_writepos = 0; ++ pool_readpos = 0; ++ pool_filled = 0; ++ pool_filled_counter = 0; ++ did_initial_extra_seeding = 0; ++ pool_balance = 0; ++ just_mixed = 0; ++ unlock_pool(); ++} ++ ++ + /* Try to close the FDs of the random gather module. This is + currently only implemented for rndlinux. */ + void +@@ -1116,6 +1135,22 @@ getfnc_gather_random (void))(void (*)(co + enum random_origins, size_t, int); + + #if USE_RNDLINUX ++#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) ++ long ret; ++ char buffer[1]; ++ ++ _gcry_pre_syscall (); ++ ret = syscall (__NR_getrandom, ++ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); ++ _gcry_post_syscall (); ++ if (ret != -1 || errno != ENOSYS) ++ { ++ fnc = _gcry_rndlinux_gather_random; ++ return fnc; ++ } ++ else ++ /* The syscall is not supported - fallback to /dev/urandom. */ ++#endif + if ( !access (NAME_OF_DEV_RANDOM, R_OK) + && !access (NAME_OF_DEV_URANDOM, R_OK)) + { +diff -up libgcrypt-1.8.5/random/random-drbg.c.getrandom libgcrypt-1.8.5/random/random-drbg.c +--- libgcrypt-1.8.5/random/random-drbg.c.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/random/random-drbg.c 2020-04-20 15:02:37.782947902 +0200 +@@ -1811,6 +1811,22 @@ _gcry_rngdrbg_inititialize (int full) + } + + /* ++ * Deinitialize the DRBG invoked by the libgcrypt API ++ * It will be automatically re-initialized on next call ++ */ ++void ++_gcry_rngdrbg_deinit (void) ++{ ++ drbg_lock (); ++ if (drbg_state) ++ { ++ drbg_uninstantiate (drbg_state); ++ drbg_state = NULL; ++ } ++ drbg_unlock (); ++} ++ ++/* + * Backend handler function for GCRYCTL_DRBG_REINIT + * + * Select a different DRBG type and initialize it. +diff -up libgcrypt-1.8.5/random/random.h.getrandom libgcrypt-1.8.5/random/random.h +--- libgcrypt-1.8.5/random/random.h.getrandom 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/random/random.h 2020-04-20 14:55:34.877949586 +0200 +@@ -29,6 +29,7 @@ void _gcry_register_random_progress (voi + + void _gcry_set_preferred_rng_type (int type); + void _gcry_random_initialize (int full); ++void _gcry_random_deinit (void); + void _gcry_random_close_fds (void); + int _gcry_get_rng_type (int ignore_fips_mode); + void _gcry_random_dump_stats(void); +diff -up libgcrypt-1.8.5/random/rndlinux.c.getrandom libgcrypt-1.8.5/random/rndlinux.c +--- libgcrypt-1.8.5/random/rndlinux.c.getrandom 2020-04-20 15:01:50.159848963 +0200 ++++ libgcrypt-1.8.5/random/rndlinux.c 2020-04-20 16:14:21.901610921 +0200 +@@ -35,6 +35,7 @@ + #include + #if defined(__linux__) && defined(HAVE_SYSCALL) + # include ++# include + #endif + + #include "types.h" +@@ -147,12 +148,12 @@ _gcry_rndlinux_gather_random (void (*add + if (!add) + { + /* Special mode to close the descriptors. */ +- if (fd_random != -1) ++ if (fd_random >= 0) + { + close (fd_random); + fd_random = -1; + } +- if (fd_urandom != -1) ++ if (fd_urandom >= 0) + { + close (fd_urandom); + fd_urandom = -1; +@@ -166,12 +167,12 @@ _gcry_rndlinux_gather_random (void (*add + apid = getpid (); + if (my_pid != apid) + { +- if (fd_random != -1) ++ if (fd_random >= 0) + { + close (fd_random); + fd_random = -1; + } +- if (fd_urandom != -1) ++ if (fd_urandom >= 0) + { + close (fd_urandom); + fd_urandom = -1; +@@ -216,7 +217,23 @@ _gcry_rndlinux_gather_random (void (*add + that we always require the device to be existent but want a more + graceful behaviour if the rarely needed close operation has been + used and the device needs to be re-opened later. */ +- if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom) ++#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) ++ if (fd_urandom != -2 && !_gcry_in_constructor ()) ++ { ++ long ret; ++ ++ _gcry_pre_syscall (); ++ ret = syscall (__NR_getrandom, ++ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); ++ _gcry_post_syscall (); ++ if (ret > -1 || errno == EAGAIN || errno == EINTR) ++ { ++ fd_urandom = -2; ++ fd_random = -2; ++ } ++ } ++#endif ++ if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom && !_gcry_in_constructor ()) + { + if (fd_random == -1) + { +@@ -255,6 +272,7 @@ _gcry_rndlinux_gather_random (void (*add + * syscall and not a new device and thus we are not able to use + * select(2) to have a timeout. */ + #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) ++ if (fd == -2) + { + long ret; + size_t nbytes; +@@ -270,9 +288,7 @@ _gcry_rndlinux_gather_random (void (*add + _gcry_post_syscall (); + } + while (ret == -1 && errno == EINTR); +- if (ret == -1 && errno == ENOSYS) +- ; /* The syscall is not supported - fallback to pulling from fd. */ +- else ++ if (1) + { /* The syscall is supported. Some sanity checks. */ + if (ret == -1) + log_fatal ("unexpected error from getrandom: %s\n", +diff -up libgcrypt-1.8.5/src/g10lib.h.getrandom libgcrypt-1.8.5/src/g10lib.h +--- libgcrypt-1.8.5/src/g10lib.h.getrandom 2020-04-20 15:08:16.528538580 +0200 ++++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 15:08:28.641309399 +0200 +@@ -464,6 +464,6 @@ gpg_err_code_t _gcry_fips_run_selftests + void _gcry_fips_noreturn (void); + #define fips_noreturn() (_gcry_fips_noreturn ()) + +- ++int _gcry_in_constructor (void); + + #endif /* G10LIB_H */ +diff -up libgcrypt-1.8.5/src/global.c.getrandom libgcrypt-1.8.5/src/global.c +--- libgcrypt-1.8.5/src/global.c.getrandom 2020-04-20 15:06:21.891707597 +0200 ++++ libgcrypt-1.8.5/src/global.c 2020-04-20 15:07:29.018437509 +0200 +@@ -145,10 +145,18 @@ global_init (void) + #define FIPS_MODULE_PATH "/etc/system-fips" + #endif + ++static int in_constructor = 0; ++ ++int _gcry_in_constructor(void) ++{ ++ return in_constructor; ++} ++ + void __attribute__ ((constructor)) _gcry_global_constructor (void) + { + int rv; + ++ in_constructor = 1; + rv = access (FIPS_MODULE_PATH, F_OK); + if (rv < 0 && errno != ENOENT) + rv = 0; +@@ -163,10 +171,12 @@ void __attribute__ ((constructor)) _gcry + /* force selftests */ + global_init(); + _gcry_fips_run_selftests (0); +- if (!fips_mode()) +- _gcry_random_close_fds (); ++ _gcry_random_close_fds (); ++ _gcry_random_deinit (); + no_secure_memory = no_secmem_save; + } ++ ++ in_constructor = 0; + } + + /* This function is called by the macro fips_is_operational and makes From 618a71d4e9b7c342a906e269daafd509e4144b7e Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 22 Apr 2020 19:00:26 +0200 Subject: [PATCH 133/214] AES performance improvements backported from master branch --- libgcrypt-1.8.5-aes-perf.patch | 8157 ++++++++++++++++++++++++++++++++ libgcrypt.spec | 10 +- 2 files changed, 8166 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-1.8.5-aes-perf.patch diff --git a/libgcrypt-1.8.5-aes-perf.patch b/libgcrypt-1.8.5-aes-perf.patch new file mode 100644 index 0000000..3119989 --- /dev/null +++ b/libgcrypt-1.8.5-aes-perf.patch @@ -0,0 +1,8157 @@ +diff -up libgcrypt-1.8.5/cipher/arcfour.c.aes-perf libgcrypt-1.8.5/cipher/arcfour.c +--- libgcrypt-1.8.5/cipher/arcfour.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/arcfour.c 2020-04-22 18:29:41.662862382 +0200 +@@ -184,10 +184,12 @@ do_arcfour_setkey (void *context, const + } + + static gcry_err_code_t +-arcfour_setkey ( void *context, const byte *key, unsigned int keylen ) ++arcfour_setkey ( void *context, const byte *key, unsigned int keylen, ++ gcry_cipher_hd_t hd ) + { + ARCFOUR_context *ctx = (ARCFOUR_context *) context; + gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen ); ++ (void)hd; + return rc; + } + +@@ -207,11 +209,11 @@ selftest(void) + static const byte ciphertext_1[] = + { 0xF1, 0x38, 0x29, 0xC9, 0xDE }; + +- arcfour_setkey( &ctx, key_1, sizeof(key_1)); ++ arcfour_setkey( &ctx, key_1, sizeof(key_1), NULL); + encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1)); + if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1))) + return "Arcfour encryption test 1 failed."; +- arcfour_setkey( &ctx, key_1, sizeof(key_1)); ++ arcfour_setkey( &ctx, key_1, sizeof(key_1), NULL); + encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */ + if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1))) + return "Arcfour decryption test 1 failed."; +diff -up libgcrypt-1.8.5/cipher/blowfish.c.aes-perf libgcrypt-1.8.5/cipher/blowfish.c +--- libgcrypt-1.8.5/cipher/blowfish.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/blowfish.c 2020-04-22 18:29:41.663862363 +0200 +@@ -37,6 +37,7 @@ + #include "g10lib.h" + #include "cipher.h" + #include "bufhelp.h" ++#include "cipher-internal.h" + #include "cipher-selftest.h" + + #define BLOWFISH_BLOCKSIZE 8 +@@ -67,7 +68,8 @@ typedef struct { + u32 p[BLOWFISH_ROUNDS+2]; + } BLOWFISH_context; + +-static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen); ++static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen, ++ gcry_cipher_hd_t hd); + static unsigned int encrypt_block (void *bc, byte *outbuf, const byte *inbuf); + static unsigned int decrypt_block (void *bc, byte *outbuf, const byte *inbuf); + +@@ -703,7 +705,7 @@ _gcry_blowfish_ctr_enc(void *context, un + /* Encrypt the counter. */ + do_encrypt_block(ctx, tmpbuf, ctr); + /* XOR the input with the encrypted counter and store in output. */ +- buf_xor(outbuf, tmpbuf, inbuf, BLOWFISH_BLOCKSIZE); ++ cipher_block_xor(outbuf, tmpbuf, inbuf, BLOWFISH_BLOCKSIZE); + outbuf += BLOWFISH_BLOCKSIZE; + inbuf += BLOWFISH_BLOCKSIZE; + /* Increment the counter. */ +@@ -771,7 +773,7 @@ _gcry_blowfish_cbc_dec(void *context, un + the intermediate result to SAVEBUF. */ + do_decrypt_block (ctx, savebuf, inbuf); + +- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOWFISH_BLOCKSIZE); ++ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOWFISH_BLOCKSIZE); + inbuf += BLOWFISH_BLOCKSIZE; + outbuf += BLOWFISH_BLOCKSIZE; + } +@@ -828,7 +830,7 @@ _gcry_blowfish_cfb_dec(void *context, un + for ( ;nblocks; nblocks-- ) + { + do_encrypt_block(ctx, iv, iv); +- buf_xor_n_copy(outbuf, iv, inbuf, BLOWFISH_BLOCKSIZE); ++ cipher_block_xor_n_copy(outbuf, iv, inbuf, BLOWFISH_BLOCKSIZE); + outbuf += BLOWFISH_BLOCKSIZE; + inbuf += BLOWFISH_BLOCKSIZE; + } +@@ -897,7 +899,7 @@ selftest(void) + const char *r; + + bf_setkey( (void *) &c, +- (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 ); ++ (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26, NULL ); + encrypt_block( (void *) &c, buffer, plain ); + if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) + return "Blowfish selftest failed (1)."; +@@ -905,7 +907,7 @@ selftest(void) + if( memcmp( buffer, plain, 8 ) ) + return "Blowfish selftest failed (2)."; + +- bf_setkey( (void *) &c, key3, 8 ); ++ bf_setkey( (void *) &c, key3, 8, NULL ); + encrypt_block( (void *) &c, buffer, plain3 ); + if( memcmp( buffer, cipher3, 8 ) ) + return "Blowfish selftest failed (3)."; +@@ -1095,10 +1097,12 @@ do_bf_setkey (BLOWFISH_context *c, const + + + static gcry_err_code_t +-bf_setkey (void *context, const byte *key, unsigned keylen) ++bf_setkey (void *context, const byte *key, unsigned keylen, ++ gcry_cipher_hd_t hd) + { + BLOWFISH_context *c = (BLOWFISH_context *) context; + gcry_err_code_t rc = do_bf_setkey (c, key, keylen); ++ (void)hd; + return rc; + } + +diff -up libgcrypt-1.8.5/cipher/bufhelp.h.aes-perf libgcrypt-1.8.5/cipher/bufhelp.h +--- libgcrypt-1.8.5/cipher/bufhelp.h.aes-perf 2018-04-17 17:35:28.000000000 +0200 ++++ libgcrypt-1.8.5/cipher/bufhelp.h 2020-04-22 18:29:41.663862363 +0200 +@@ -450,7 +450,21 @@ static inline void buf_put_le64(void *_b + out->a = le_bswap64(val); + } + +- + #endif /*BUFHELP_UNALIGNED_ACCESS*/ + ++ ++/* Host-endian get/put macros */ ++#ifdef WORDS_BIGENDIAN ++# define buf_get_he32 buf_get_be32 ++# define buf_put_he32 buf_put_be32 ++# define buf_get_he64 buf_get_be64 ++# define buf_put_he64 buf_put_be64 ++#else ++# define buf_get_he32 buf_get_le32 ++# define buf_put_he32 buf_put_le32 ++# define buf_get_he64 buf_get_le64 ++# define buf_put_he64 buf_put_le64 ++#endif ++ ++ + #endif /*GCRYPT_BUFHELP_H*/ +diff -up libgcrypt-1.8.5/cipher/camellia-glue.c.aes-perf libgcrypt-1.8.5/cipher/camellia-glue.c +--- libgcrypt-1.8.5/cipher/camellia-glue.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/camellia-glue.c 2020-04-22 18:29:41.664862344 +0200 +@@ -204,7 +204,8 @@ extern void _gcry_camellia_aesni_avx2_oc + static const char *selftest(void); + + static gcry_err_code_t +-camellia_setkey(void *c, const byte *key, unsigned keylen) ++camellia_setkey(void *c, const byte *key, unsigned keylen, ++ gcry_cipher_hd_t hd) + { + CAMELLIA_context *ctx=c; + static int initialized=0; +@@ -213,6 +214,8 @@ camellia_setkey(void *c, const byte *key + unsigned int hwf = _gcry_get_hw_features (); + #endif + ++ (void)hd; ++ + if(keylen!=16 && keylen!=24 && keylen!=32) + return GPG_ERR_INV_KEYLEN; + +@@ -427,7 +430,7 @@ _gcry_camellia_ctr_enc(void *context, un + /* Encrypt the counter. */ + Camellia_EncryptBlock(ctx->keybitlength, ctr, ctx->keytable, tmpbuf); + /* XOR the input with the encrypted counter and store in output. */ +- buf_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE); ++ cipher_block_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE); + outbuf += CAMELLIA_BLOCK_SIZE; + inbuf += CAMELLIA_BLOCK_SIZE; + /* Increment the counter. */ +@@ -520,7 +523,8 @@ _gcry_camellia_cbc_dec(void *context, un + the intermediate result to SAVEBUF. */ + Camellia_DecryptBlock(ctx->keybitlength, inbuf, ctx->keytable, savebuf); + +- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAMELLIA_BLOCK_SIZE); ++ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, ++ CAMELLIA_BLOCK_SIZE); + inbuf += CAMELLIA_BLOCK_SIZE; + outbuf += CAMELLIA_BLOCK_SIZE; + } +@@ -602,7 +606,7 @@ _gcry_camellia_cfb_dec(void *context, un + for ( ;nblocks; nblocks-- ) + { + Camellia_EncryptBlock(ctx->keybitlength, iv, ctx->keytable, iv); +- buf_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE); ++ cipher_block_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE); + outbuf += CAMELLIA_BLOCK_SIZE; + inbuf += CAMELLIA_BLOCK_SIZE; + } +@@ -991,7 +995,7 @@ selftest(void) + 0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09 + }; + +- camellia_setkey(&ctx,key_128,sizeof(key_128)); ++ camellia_setkey(&ctx,key_128,sizeof(key_128),NULL); + camellia_encrypt(&ctx,scratch,plaintext); + if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0) + return "CAMELLIA-128 test encryption failed."; +@@ -999,7 +1003,7 @@ selftest(void) + if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) + return "CAMELLIA-128 test decryption failed."; + +- camellia_setkey(&ctx,key_192,sizeof(key_192)); ++ camellia_setkey(&ctx,key_192,sizeof(key_192),NULL); + camellia_encrypt(&ctx,scratch,plaintext); + if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0) + return "CAMELLIA-192 test encryption failed."; +@@ -1007,7 +1011,7 @@ selftest(void) + if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) + return "CAMELLIA-192 test decryption failed."; + +- camellia_setkey(&ctx,key_256,sizeof(key_256)); ++ camellia_setkey(&ctx,key_256,sizeof(key_256),NULL); + camellia_encrypt(&ctx,scratch,plaintext); + if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0) + return "CAMELLIA-256 test encryption failed."; +diff -up libgcrypt-1.8.5/cipher/cast5.c.aes-perf libgcrypt-1.8.5/cipher/cast5.c +--- libgcrypt-1.8.5/cipher/cast5.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cast5.c 2020-04-22 18:29:41.665862325 +0200 +@@ -44,6 +44,7 @@ + #include "cipher.h" + #include "bithelp.h" + #include "bufhelp.h" ++#include "cipher-internal.h" + #include "cipher-selftest.h" + + /* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ +@@ -72,7 +73,8 @@ typedef struct { + #endif + } CAST5_context; + +-static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen); ++static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen, ++ gcry_cipher_hd_t hd); + static unsigned int encrypt_block (void *c, byte *outbuf, const byte *inbuf); + static unsigned int decrypt_block (void *c, byte *outbuf, const byte *inbuf); + +@@ -671,7 +673,7 @@ _gcry_cast5_ctr_enc(void *context, unsig + /* Encrypt the counter. */ + do_encrypt_block(ctx, tmpbuf, ctr); + /* XOR the input with the encrypted counter and store in output. */ +- buf_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE); ++ cipher_block_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE); + outbuf += CAST5_BLOCKSIZE; + inbuf += CAST5_BLOCKSIZE; + /* Increment the counter. */ +@@ -739,7 +741,7 @@ _gcry_cast5_cbc_dec(void *context, unsig + the intermediate result to SAVEBUF. */ + do_decrypt_block (ctx, savebuf, inbuf); + +- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAST5_BLOCKSIZE); ++ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAST5_BLOCKSIZE); + inbuf += CAST5_BLOCKSIZE; + outbuf += CAST5_BLOCKSIZE; + } +@@ -795,7 +797,7 @@ _gcry_cast5_cfb_dec(void *context, unsig + for ( ;nblocks; nblocks-- ) + { + do_encrypt_block(ctx, iv, iv); +- buf_xor_n_copy(outbuf, iv, inbuf, CAST5_BLOCKSIZE); ++ cipher_block_xor_n_copy(outbuf, iv, inbuf, CAST5_BLOCKSIZE); + outbuf += CAST5_BLOCKSIZE; + inbuf += CAST5_BLOCKSIZE; + } +@@ -863,7 +865,7 @@ selftest(void) + byte buffer[8]; + const char *r; + +- cast_setkey( &c, key, 16 ); ++ cast_setkey( &c, key, 16, NULL ); + encrypt_block( &c, buffer, plain ); + if( memcmp( buffer, cipher, 8 ) ) + return "1"; +@@ -884,10 +886,10 @@ selftest(void) + 0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E }; + + for(i=0; i < 1000000; i++ ) { +- cast_setkey( &c, b0, 16 ); ++ cast_setkey( &c, b0, 16, NULL ); + encrypt_block( &c, a0, a0 ); + encrypt_block( &c, a0+8, a0+8 ); +- cast_setkey( &c, a0, 16 ); ++ cast_setkey( &c, a0, 16, NULL ); + encrypt_block( &c, b0, b0 ); + encrypt_block( &c, b0+8, b0+8 ); + } +@@ -1029,10 +1031,12 @@ do_cast_setkey( CAST5_context *c, const + } + + static gcry_err_code_t +-cast_setkey (void *context, const byte *key, unsigned keylen ) ++cast_setkey (void *context, const byte *key, unsigned keylen, ++ gcry_cipher_hd_t hd ) + { + CAST5_context *c = (CAST5_context *) context; + gcry_err_code_t rc = do_cast_setkey (c, key, keylen); ++ (void)hd; + return rc; + } + +diff -up libgcrypt-1.8.5/cipher/chacha20.c.aes-perf libgcrypt-1.8.5/cipher/chacha20.c +--- libgcrypt-1.8.5/cipher/chacha20.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/chacha20.c 2020-04-22 18:29:41.665862325 +0200 +@@ -419,10 +419,12 @@ chacha20_do_setkey (CHACHA20_context_t * + + + static gcry_err_code_t +-chacha20_setkey (void *context, const byte * key, unsigned int keylen) ++chacha20_setkey (void *context, const byte *key, unsigned int keylen, ++ gcry_cipher_hd_t hd) + { + CHACHA20_context_t *ctx = (CHACHA20_context_t *) context; + gcry_err_code_t rc = chacha20_do_setkey (ctx, key, keylen); ++ (void)hd; + _gcry_burn_stack (4 + sizeof (void *) + 4 * sizeof (void *)); + return rc; + } +@@ -569,7 +571,7 @@ selftest (void) + /* 16-byte alignment required for amd64 implementation. */ + ctx = (CHACHA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15); + +- chacha20_setkey (ctx, key_1, sizeof key_1); ++ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + scratch[sizeof (scratch) - 1] = 0; + chacha20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1); +@@ -577,7 +579,7 @@ selftest (void) + return "ChaCha20 encryption test 1 failed."; + if (scratch[sizeof (scratch) - 1]) + return "ChaCha20 wrote too much."; +- chacha20_setkey (ctx, key_1, sizeof (key_1)); ++ chacha20_setkey (ctx, key_1, sizeof (key_1), NULL); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + chacha20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1); + if (memcmp (scratch, plaintext_1, sizeof plaintext_1)) +@@ -585,12 +587,12 @@ selftest (void) + + for (i = 0; i < sizeof buf; i++) + buf[i] = i; +- chacha20_setkey (ctx, key_1, sizeof key_1); ++ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + /*encrypt */ + chacha20_encrypt_stream (ctx, buf, buf, sizeof buf); + /*decrypt */ +- chacha20_setkey (ctx, key_1, sizeof key_1); ++ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + chacha20_encrypt_stream (ctx, buf, buf, 1); + chacha20_encrypt_stream (ctx, buf + 1, buf + 1, (sizeof buf) - 1 - 1); +@@ -600,13 +602,13 @@ selftest (void) + if (buf[i] != (byte) i) + return "ChaCha20 encryption test 2 failed."; + +- chacha20_setkey (ctx, key_1, sizeof key_1); ++ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + /* encrypt */ + for (i = 0; i < sizeof buf; i++) + chacha20_encrypt_stream (ctx, &buf[i], &buf[i], 1); + /* decrypt */ +- chacha20_setkey (ctx, key_1, sizeof key_1); ++ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); + chacha20_setiv (ctx, nonce_1, sizeof nonce_1); + chacha20_encrypt_stream (ctx, buf, buf, sizeof buf); + for (i = 0; i < sizeof buf; i++) +diff -up libgcrypt-1.8.5/cipher/cipher-aeswrap.c.aes-perf libgcrypt-1.8.5/cipher/cipher-aeswrap.c +--- libgcrypt-1.8.5/cipher/cipher-aeswrap.c.aes-perf 2018-04-17 17:49:00.000000000 +0200 ++++ libgcrypt-1.8.5/cipher/cipher-aeswrap.c 2020-04-22 18:29:41.665862325 +0200 +@@ -99,7 +99,7 @@ _gcry_cipher_aeswrap_encrypt (gcry_ciphe + break; + } + /* A := MSB_64(B) ^ t */ +- buf_xor(a, b, t, 8); ++ cipher_block_xor(a, b, t, 8); + /* R[i] := LSB_64(B) */ + memcpy (r+i*8, b+8, 8); + } +@@ -170,7 +170,7 @@ _gcry_cipher_aeswrap_decrypt (gcry_ciphe + for (i = n; i >= 1; i--) + { + /* B := AES_k^1( (A ^ t)| R[i] ) */ +- buf_xor(b, a, t, 8); ++ cipher_block_xor(b, a, t, 8); + memcpy (b+8, r+(i-1)*8, 8); + nburn = c->spec->decrypt (&c->context.c, b, b); + burn = nburn > burn ? nburn : burn; +diff -up libgcrypt-1.8.5/cipher/cipher.c.aes-perf libgcrypt-1.8.5/cipher/cipher.c +--- libgcrypt-1.8.5/cipher/cipher.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher.c 2020-04-22 18:29:41.666862306 +0200 +@@ -92,6 +92,8 @@ static gcry_cipher_spec_t *cipher_list[] + + + ++static void _gcry_cipher_setup_mode_ops(gcry_cipher_hd_t c, int mode); ++ + + static int + map_algo (int algo) +@@ -532,6 +534,7 @@ _gcry_cipher_open_internal (gcry_cipher_ + h->bulk.ctr_enc = _gcry_aes_ctr_enc; + h->bulk.ocb_crypt = _gcry_aes_ocb_crypt; + h->bulk.ocb_auth = _gcry_aes_ocb_auth; ++ h->bulk.xts_crypt = _gcry_aes_xts_crypt; + break; + #endif /*USE_AES*/ + #ifdef USE_BLOWFISH +@@ -592,6 +595,9 @@ _gcry_cipher_open_internal (gcry_cipher_ + break; + } + ++ /* Setup mode routines. */ ++ _gcry_cipher_setup_mode_ops(h, mode); ++ + /* Setup defaults depending on the mode. */ + switch (mode) + { +@@ -609,8 +615,7 @@ _gcry_cipher_open_internal (gcry_cipher_ + default: + break; + } +- +- } ++ } + } + + /* Done. */ +@@ -675,7 +680,7 @@ cipher_setkey (gcry_cipher_hd_t c, byte + } + } + +- rc = c->spec->setkey (&c->context.c, key, keylen); ++ rc = c->spec->setkey (&c->context.c, key, keylen, c); + if (!rc) + { + /* Duplicate initial context. */ +@@ -701,7 +706,7 @@ cipher_setkey (gcry_cipher_hd_t c, byte + case GCRY_CIPHER_MODE_XTS: + /* Setup tweak cipher with second part of XTS key. */ + rc = c->spec->setkey (c->u_mode.xts.tweak_context, key + keylen, +- keylen); ++ keylen, c); + if (!rc) + { + /* Duplicate initial tweak context. */ +@@ -872,85 +877,78 @@ do_ecb_decrypt (gcry_cipher_hd_t c, + } + + +-/**************** +- * Encrypt INBUF to OUTBUF with the mode selected at open. +- * inbuf and outbuf may overlap or be the same. +- * Depending on the mode some constraints apply to INBUFLEN. +- */ + static gcry_err_code_t +-cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, +- const byte *inbuf, size_t inbuflen) ++do_stream_encrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, size_t outbuflen, ++ const unsigned char *inbuf, size_t inbuflen) ++{ ++ (void)outbuflen; ++ c->spec->stencrypt (&c->context.c, outbuf, (void *)inbuf, inbuflen); ++ return 0; ++} ++ ++static gcry_err_code_t ++do_stream_decrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, size_t outbuflen, ++ const unsigned char *inbuf, size_t inbuflen) ++{ ++ (void)outbuflen; ++ c->spec->stdecrypt (&c->context.c, outbuf, (void *)inbuf, inbuflen); ++ return 0; ++} ++ ++ ++static gcry_err_code_t ++do_encrypt_none_unknown (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, ++ const byte *inbuf, size_t inbuflen) + { + gcry_err_code_t rc; + +- if (c->mode != GCRY_CIPHER_MODE_NONE && !c->marks.key) +- { +- log_error ("cipher_encrypt: key not set\n"); +- return GPG_ERR_MISSING_KEY; +- } ++ (void)outbuflen; + + switch (c->mode) + { +- case GCRY_CIPHER_MODE_ECB: +- rc = do_ecb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_CBC: +- rc = _gcry_cipher_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_CFB: +- rc = _gcry_cipher_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ case GCRY_CIPHER_MODE_CMAC: ++ rc = GPG_ERR_INV_CIPHER_MODE; + break; + +- case GCRY_CIPHER_MODE_CFB8: +- rc = _gcry_cipher_cfb8_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ case GCRY_CIPHER_MODE_NONE: ++ if (fips_mode () || !_gcry_get_debug_flag (0)) ++ { ++ fips_signal_error ("cipher mode NONE used"); ++ rc = GPG_ERR_INV_CIPHER_MODE; ++ } ++ else ++ { ++ if (inbuf != outbuf) ++ memmove (outbuf, inbuf, inbuflen); ++ rc = 0; ++ } + break; + +- case GCRY_CIPHER_MODE_OFB: +- rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); ++ default: ++ log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode ); ++ rc = GPG_ERR_INV_CIPHER_MODE; + break; ++ } + +- case GCRY_CIPHER_MODE_CTR: +- rc = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; ++ return rc; ++} + +- case GCRY_CIPHER_MODE_AESWRAP: +- rc = _gcry_cipher_aeswrap_encrypt (c, outbuf, outbuflen, +- inbuf, inbuflen); +- break; ++static gcry_err_code_t ++do_decrypt_none_unknown (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, ++ const byte *inbuf, size_t inbuflen) ++{ ++ gcry_err_code_t rc; + +- case GCRY_CIPHER_MODE_CCM: +- rc = _gcry_cipher_ccm_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; ++ (void)outbuflen; + ++ switch (c->mode) ++ { + case GCRY_CIPHER_MODE_CMAC: + rc = GPG_ERR_INV_CIPHER_MODE; + break; + +- case GCRY_CIPHER_MODE_GCM: +- rc = _gcry_cipher_gcm_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_POLY1305: +- rc = _gcry_cipher_poly1305_encrypt (c, outbuf, outbuflen, +- inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_OCB: +- rc = _gcry_cipher_ocb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_XTS: +- rc = _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 1); +- break; +- +- case GCRY_CIPHER_MODE_STREAM: +- c->spec->stencrypt (&c->context.c, +- outbuf, (byte*)/*arggg*/inbuf, inbuflen); +- rc = 0; +- break; +- + case GCRY_CIPHER_MODE_NONE: + if (fips_mode () || !_gcry_get_debug_flag (0)) + { +@@ -966,7 +964,7 @@ cipher_encrypt (gcry_cipher_hd_t c, byte + break; + + default: +- log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode ); ++ log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode ); + rc = GPG_ERR_INV_CIPHER_MODE; + break; + } +@@ -991,7 +989,13 @@ _gcry_cipher_encrypt (gcry_cipher_hd_t h + inlen = outsize; + } + +- rc = cipher_encrypt (h, out, outsize, in, inlen); ++ if (h->mode != GCRY_CIPHER_MODE_NONE && !h->marks.key) ++ { ++ log_error ("cipher_decrypt: key not set\n"); ++ return GPG_ERR_MISSING_KEY; ++ } ++ ++ rc = h->mode_ops.encrypt (h, out, outsize, in, inlen); + + /* Failsafe: Make sure that the plaintext will never make it into + OUT if the encryption returned an error. */ +@@ -1002,110 +1006,10 @@ _gcry_cipher_encrypt (gcry_cipher_hd_t h + } + + +- + /**************** +- * Decrypt INBUF to OUTBUF with the mode selected at open. +- * inbuf and outbuf may overlap or be the same. +- * Depending on the mode some some constraints apply to INBUFLEN. ++ * Decrypt IN and write it to OUT. If IN is NULL, in-place encryption has ++ * been requested. + */ +-static gcry_err_code_t +-cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, +- const byte *inbuf, size_t inbuflen) +-{ +- gcry_err_code_t rc; +- +- if (c->mode != GCRY_CIPHER_MODE_NONE && !c->marks.key) +- { +- log_error ("cipher_decrypt: key not set\n"); +- return GPG_ERR_MISSING_KEY; +- } +- +- switch (c->mode) +- { +- case GCRY_CIPHER_MODE_ECB: +- rc = do_ecb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_CBC: +- rc = _gcry_cipher_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_CFB: +- rc = _gcry_cipher_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_CFB8: +- rc = _gcry_cipher_cfb8_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_OFB: +- rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_CTR: +- rc = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_AESWRAP: +- rc = _gcry_cipher_aeswrap_decrypt (c, outbuf, outbuflen, +- inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_CCM: +- rc = _gcry_cipher_ccm_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_CMAC: +- rc = GPG_ERR_INV_CIPHER_MODE; +- break; +- +- case GCRY_CIPHER_MODE_GCM: +- rc = _gcry_cipher_gcm_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_POLY1305: +- rc = _gcry_cipher_poly1305_decrypt (c, outbuf, outbuflen, +- inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_OCB: +- rc = _gcry_cipher_ocb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); +- break; +- +- case GCRY_CIPHER_MODE_XTS: +- rc = _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 0); +- break; +- +- case GCRY_CIPHER_MODE_STREAM: +- c->spec->stdecrypt (&c->context.c, +- outbuf, (byte*)/*arggg*/inbuf, inbuflen); +- rc = 0; +- break; +- +- case GCRY_CIPHER_MODE_NONE: +- if (fips_mode () || !_gcry_get_debug_flag (0)) +- { +- fips_signal_error ("cipher mode NONE used"); +- rc = GPG_ERR_INV_CIPHER_MODE; +- } +- else +- { +- if (inbuf != outbuf) +- memmove (outbuf, inbuf, inbuflen); +- rc = 0; +- } +- break; +- +- default: +- log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode ); +- rc = GPG_ERR_INV_CIPHER_MODE; +- break; +- } +- +- return rc; +-} +- +- + gcry_err_code_t + _gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize, + const void *in, size_t inlen) +@@ -1116,9 +1020,14 @@ _gcry_cipher_decrypt (gcry_cipher_hd_t h + inlen = outsize; + } + +- return cipher_decrypt (h, out, outsize, in, inlen); +-} ++ if (h->mode != GCRY_CIPHER_MODE_NONE && !h->marks.key) ++ { ++ log_error ("cipher_decrypt: key not set\n"); ++ return GPG_ERR_MISSING_KEY; ++ } + ++ return h->mode_ops.decrypt (h, out, outsize, in, inlen); ++} + + + /**************** +@@ -1149,33 +1058,10 @@ _gcry_cipher_setkey (gcry_cipher_hd_t hd + gcry_err_code_t + _gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen) + { +- gcry_err_code_t rc = 0; +- +- switch (hd->mode) +- { +- case GCRY_CIPHER_MODE_CCM: +- rc = _gcry_cipher_ccm_set_nonce (hd, iv, ivlen); +- break; +- +- case GCRY_CIPHER_MODE_GCM: +- rc = _gcry_cipher_gcm_setiv (hd, iv, ivlen); +- break; +- +- case GCRY_CIPHER_MODE_POLY1305: +- rc = _gcry_cipher_poly1305_setiv (hd, iv, ivlen); +- break; +- +- case GCRY_CIPHER_MODE_OCB: +- rc = _gcry_cipher_ocb_set_nonce (hd, iv, ivlen); +- break; +- +- default: +- rc = cipher_setiv (hd, iv, ivlen); +- break; +- } +- return rc; ++ return hd->mode_ops.setiv (hd, iv, ivlen); + } + ++ + /* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of + block size length, or (NULL,0) to set the CTR to the all-zero + block. */ +@@ -1209,38 +1095,40 @@ _gcry_cipher_getctr (gcry_cipher_hd_t hd + return 0; + } + ++ + gcry_err_code_t + _gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf, + size_t abuflen) + { + gcry_err_code_t rc; + +- switch (hd->mode) ++ if (hd->mode_ops.authenticate) + { +- case GCRY_CIPHER_MODE_CCM: +- rc = _gcry_cipher_ccm_authenticate (hd, abuf, abuflen); +- break; +- +- case GCRY_CIPHER_MODE_CMAC: +- rc = _gcry_cipher_cmac_authenticate (hd, abuf, abuflen); +- break; ++ rc = hd->mode_ops.authenticate (hd, abuf, abuflen); ++ } ++ else ++ { ++ log_error ("gcry_cipher_authenticate: invalid mode %d\n", hd->mode); ++ rc = GPG_ERR_INV_CIPHER_MODE; ++ } + +- case GCRY_CIPHER_MODE_GCM: +- rc = _gcry_cipher_gcm_authenticate (hd, abuf, abuflen); +- break; ++ return rc; ++} + +- case GCRY_CIPHER_MODE_POLY1305: +- rc = _gcry_cipher_poly1305_authenticate (hd, abuf, abuflen); +- break; + +- case GCRY_CIPHER_MODE_OCB: +- rc = _gcry_cipher_ocb_authenticate (hd, abuf, abuflen); +- break; ++gcry_err_code_t ++_gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen) ++{ ++ gcry_err_code_t rc; + +- default: +- log_error ("gcry_cipher_authenticate: invalid mode %d\n", hd->mode); ++ if (hd->mode_ops.get_tag) ++ { ++ rc = hd->mode_ops.get_tag (hd, outtag, taglen); ++ } ++ else ++ { ++ log_error ("gcry_cipher_gettag: invalid mode %d\n", hd->mode); + rc = GPG_ERR_INV_CIPHER_MODE; +- break; + } + + return rc; +@@ -1248,76 +1136,166 @@ _gcry_cipher_authenticate (gcry_cipher_h + + + gcry_err_code_t +-_gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen) ++_gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen) + { + gcry_err_code_t rc; + +- switch (hd->mode) ++ if (hd->mode_ops.check_tag) + { +- case GCRY_CIPHER_MODE_CCM: +- rc = _gcry_cipher_ccm_get_tag (hd, outtag, taglen); ++ rc = hd->mode_ops.check_tag (hd, intag, taglen); ++ } ++ else ++ { ++ log_error ("gcry_cipher_checktag: invalid mode %d\n", hd->mode); ++ rc = GPG_ERR_INV_CIPHER_MODE; ++ } ++ ++ return rc; ++} ++ ++ ++ ++static void ++_gcry_cipher_setup_mode_ops(gcry_cipher_hd_t c, int mode) ++{ ++ /* Setup encryption and decryption routines. */ ++ switch (mode) ++ { ++ case GCRY_CIPHER_MODE_STREAM: ++ c->mode_ops.encrypt = do_stream_encrypt; ++ c->mode_ops.decrypt = do_stream_decrypt; + break; + +- case GCRY_CIPHER_MODE_CMAC: +- rc = _gcry_cipher_cmac_get_tag (hd, outtag, taglen); ++ case GCRY_CIPHER_MODE_ECB: ++ c->mode_ops.encrypt = do_ecb_encrypt; ++ c->mode_ops.decrypt = do_ecb_decrypt; ++ break; ++ ++ case GCRY_CIPHER_MODE_CBC: ++ c->mode_ops.encrypt = _gcry_cipher_cbc_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_cbc_decrypt; ++ break; ++ ++ case GCRY_CIPHER_MODE_CFB: ++ c->mode_ops.encrypt = _gcry_cipher_cfb_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_cfb_decrypt; ++ break; ++ ++ case GCRY_CIPHER_MODE_CFB8: ++ c->mode_ops.encrypt = _gcry_cipher_cfb8_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_cfb8_decrypt; ++ break; ++ ++ case GCRY_CIPHER_MODE_OFB: ++ c->mode_ops.encrypt = _gcry_cipher_ofb_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_ofb_encrypt; ++ break; ++ ++ case GCRY_CIPHER_MODE_CTR: ++ c->mode_ops.encrypt = _gcry_cipher_ctr_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_ctr_encrypt; ++ break; ++ ++ case GCRY_CIPHER_MODE_AESWRAP: ++ c->mode_ops.encrypt = _gcry_cipher_aeswrap_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_aeswrap_decrypt; ++ break; ++ ++ case GCRY_CIPHER_MODE_CCM: ++ c->mode_ops.encrypt = _gcry_cipher_ccm_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_ccm_decrypt; + break; + + case GCRY_CIPHER_MODE_GCM: +- rc = _gcry_cipher_gcm_get_tag (hd, outtag, taglen); ++ c->mode_ops.encrypt = _gcry_cipher_gcm_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_gcm_decrypt; + break; + + case GCRY_CIPHER_MODE_POLY1305: +- rc = _gcry_cipher_poly1305_get_tag (hd, outtag, taglen); ++ c->mode_ops.encrypt = _gcry_cipher_poly1305_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_poly1305_decrypt; + break; + + case GCRY_CIPHER_MODE_OCB: +- rc = _gcry_cipher_ocb_get_tag (hd, outtag, taglen); ++ c->mode_ops.encrypt = _gcry_cipher_ocb_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_ocb_decrypt; ++ break; ++ ++ case GCRY_CIPHER_MODE_XTS: ++ c->mode_ops.encrypt = _gcry_cipher_xts_encrypt; ++ c->mode_ops.decrypt = _gcry_cipher_xts_decrypt; + break; + + default: +- log_error ("gcry_cipher_gettag: invalid mode %d\n", hd->mode); +- rc = GPG_ERR_INV_CIPHER_MODE; ++ c->mode_ops.encrypt = do_encrypt_none_unknown; ++ c->mode_ops.decrypt = do_decrypt_none_unknown; + break; + } + +- return rc; +-} ++ /* Setup IV setting routine. */ ++ switch (mode) ++ { ++ case GCRY_CIPHER_MODE_CCM: ++ c->mode_ops.setiv = _gcry_cipher_ccm_set_nonce; ++ break; ++ ++ case GCRY_CIPHER_MODE_GCM: ++ c->mode_ops.setiv = _gcry_cipher_gcm_setiv; ++ break; + ++ case GCRY_CIPHER_MODE_POLY1305: ++ c->mode_ops.setiv = _gcry_cipher_poly1305_setiv; ++ break; + +-gcry_err_code_t +-_gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen) +-{ +- gcry_err_code_t rc; ++ case GCRY_CIPHER_MODE_OCB: ++ c->mode_ops.setiv = _gcry_cipher_ocb_set_nonce; ++ break; + +- switch (hd->mode) ++ default: ++ c->mode_ops.setiv = cipher_setiv; ++ break; ++ } ++ ++ ++ /* Setup authentication routines for AEAD modes. */ ++ switch (mode) + { + case GCRY_CIPHER_MODE_CCM: +- rc = _gcry_cipher_ccm_check_tag (hd, intag, taglen); ++ c->mode_ops.authenticate = _gcry_cipher_ccm_authenticate; ++ c->mode_ops.get_tag = _gcry_cipher_ccm_get_tag; ++ c->mode_ops.check_tag = _gcry_cipher_ccm_check_tag; + break; + + case GCRY_CIPHER_MODE_CMAC: +- rc = _gcry_cipher_cmac_check_tag (hd, intag, taglen); ++ c->mode_ops.authenticate = _gcry_cipher_cmac_authenticate; ++ c->mode_ops.get_tag = _gcry_cipher_cmac_get_tag; ++ c->mode_ops.check_tag = _gcry_cipher_cmac_check_tag; + break; + + case GCRY_CIPHER_MODE_GCM: +- rc = _gcry_cipher_gcm_check_tag (hd, intag, taglen); ++ c->mode_ops.authenticate = _gcry_cipher_gcm_authenticate; ++ c->mode_ops.get_tag = _gcry_cipher_gcm_get_tag; ++ c->mode_ops.check_tag = _gcry_cipher_gcm_check_tag; + break; + + case GCRY_CIPHER_MODE_POLY1305: +- rc = _gcry_cipher_poly1305_check_tag (hd, intag, taglen); ++ c->mode_ops.authenticate = _gcry_cipher_poly1305_authenticate; ++ c->mode_ops.get_tag = _gcry_cipher_poly1305_get_tag; ++ c->mode_ops.check_tag = _gcry_cipher_poly1305_check_tag; + break; + + case GCRY_CIPHER_MODE_OCB: +- rc = _gcry_cipher_ocb_check_tag (hd, intag, taglen); ++ c->mode_ops.authenticate = _gcry_cipher_ocb_authenticate; ++ c->mode_ops.get_tag = _gcry_cipher_ocb_get_tag; ++ c->mode_ops.check_tag = _gcry_cipher_ocb_check_tag; + break; + + default: +- log_error ("gcry_cipher_checktag: invalid mode %d\n", hd->mode); +- rc = GPG_ERR_INV_CIPHER_MODE; ++ c->mode_ops.authenticate = NULL; ++ c->mode_ops.get_tag = NULL; ++ c->mode_ops.check_tag = NULL; + break; + } +- +- return rc; + } + + +diff -up libgcrypt-1.8.5/cipher/cipher-cbc.c.aes-perf libgcrypt-1.8.5/cipher/cipher-cbc.c +--- libgcrypt-1.8.5/cipher/cipher-cbc.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-cbc.c 2020-04-22 18:29:41.666862306 +0200 +@@ -79,7 +79,7 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd + + for (n=0; n < nblocks; n++ ) + { +- buf_xor (outbuf, inbuf, ivp, blocksize); ++ cipher_block_xor (outbuf, inbuf, ivp, blocksize); + nburn = enc_fn ( &c->context.c, outbuf, outbuf ); + burn = nburn > burn ? nburn : burn; + ivp = outbuf; +@@ -116,7 +116,7 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd + + nburn = enc_fn (&c->context.c, outbuf, outbuf); + burn = nburn > burn ? nburn : burn; +- buf_cpy (c->u_iv.iv, outbuf, blocksize); ++ cipher_block_cpy (c->u_iv.iv, outbuf, blocksize); + } + + if (burn > 0) +@@ -158,7 +158,7 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd + nblocks--; + if ((inbuflen % blocksize) == 0) + nblocks--; +- buf_cpy (c->lastiv, c->u_iv.iv, blocksize); ++ cipher_block_cpy (c->lastiv, c->u_iv.iv, blocksize); + } + + if (c->bulk.cbc_dec) +@@ -176,7 +176,8 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd + storage here because it is not used otherwise. */ + nburn = dec_fn ( &c->context.c, c->lastiv, inbuf ); + burn = nburn > burn ? nburn : burn; +- buf_xor_n_copy_2(outbuf, c->lastiv, c->u_iv.iv, inbuf, blocksize); ++ cipher_block_xor_n_copy_2 (outbuf, c->lastiv, c->u_iv.iv, inbuf, ++ blocksize); + inbuf += blocksize; + outbuf += blocksize; + } +@@ -191,7 +192,7 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd + else + restbytes = inbuflen % blocksize; + +- buf_cpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */ ++ cipher_block_cpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */ + buf_cpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */ + + nburn = dec_fn ( &c->context.c, outbuf, inbuf ); +@@ -203,7 +204,7 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd + c->u_iv.iv[i] = outbuf[i]; + nburn = dec_fn (&c->context.c, outbuf, c->u_iv.iv); + burn = nburn > burn ? nburn : burn; +- buf_xor(outbuf, outbuf, c->lastiv, blocksize); ++ cipher_block_xor(outbuf, outbuf, c->lastiv, blocksize); + /* c->lastiv is now really lastlastiv, does this matter? */ + } + +diff -up libgcrypt-1.8.5/cipher/cipher-ccm.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ccm.c +--- libgcrypt-1.8.5/cipher/cipher-ccm.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-ccm.c 2020-04-22 18:29:41.666862306 +0200 +@@ -67,7 +67,8 @@ do_cbc_mac (gcry_cipher_hd_t c, const un + if (unused > 0) + { + /* Process one block from macbuf. */ +- buf_xor(c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.macbuf, blocksize); ++ cipher_block_xor(c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.macbuf, ++ blocksize); + set_burn (burn, enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv )); + + unused = 0; +@@ -86,7 +87,7 @@ do_cbc_mac (gcry_cipher_hd_t c, const un + { + while (inlen >= blocksize) + { +- buf_xor(c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); ++ cipher_block_xor(c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); + + set_burn (burn, enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv )); + +@@ -272,7 +273,7 @@ _gcry_cipher_ccm_tag (gcry_cipher_hd_t c + burn = do_cbc_mac (c, NULL, 0, 1); /* Perform final padding. */ + + /* Add S_0 */ +- buf_xor (c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.s0, 16); ++ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.s0, 16); + + wipememory (c->u_ctr.ctr, 16); + wipememory (c->u_mode.ccm.s0, 16); +diff -up libgcrypt-1.8.5/cipher/cipher-cfb.c.aes-perf libgcrypt-1.8.5/cipher/cipher-cfb.c +--- libgcrypt-1.8.5/cipher/cipher-cfb.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-cfb.c 2020-04-22 18:29:41.667862287 +0200 +@@ -91,7 +91,7 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd + nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; + /* XOR the input with the IV and store input into IV. */ +- buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); ++ cipher_block_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; + inbuflen -= blocksize; +@@ -101,11 +101,11 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd + if ( inbuflen >= blocksize ) + { + /* Save the current IV and then encrypt the IV. */ +- buf_cpy( c->lastiv, c->u_iv.iv, blocksize ); ++ cipher_block_cpy( c->lastiv, c->u_iv.iv, blocksize ); + nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; + /* XOR the input with the IV and store input into IV */ +- buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); ++ cipher_block_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; + inbuflen -= blocksize; +@@ -113,7 +113,7 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd + if ( inbuflen ) + { + /* Save the current IV and then encrypt the IV. */ +- buf_cpy( c->lastiv, c->u_iv.iv, blocksize ); ++ cipher_block_cpy( c->lastiv, c->u_iv.iv, blocksize ); + nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; + c->unused = blocksize; +@@ -193,7 +193,7 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd + nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; + /* XOR the input with the IV and store input into IV. */ +- buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); ++ cipher_block_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; + inbuflen -= blocksize; +@@ -203,11 +203,11 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd + if (inbuflen >= blocksize ) + { + /* Save the current IV and then encrypt the IV. */ +- buf_cpy ( c->lastiv, c->u_iv.iv, blocksize); ++ cipher_block_cpy ( c->lastiv, c->u_iv.iv, blocksize); + nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; + /* XOR the input with the IV and store input into IV */ +- buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); ++ cipher_block_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; + inbuflen -= blocksize; +@@ -216,7 +216,7 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd + if (inbuflen) + { + /* Save the current IV and then encrypt the IV. */ +- buf_cpy ( c->lastiv, c->u_iv.iv, blocksize ); ++ cipher_block_cpy ( c->lastiv, c->u_iv.iv, blocksize ); + nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; + c->unused = blocksize; +diff -up libgcrypt-1.8.5/cipher/cipher-cmac.c.aes-perf libgcrypt-1.8.5/cipher/cipher-cmac.c +--- libgcrypt-1.8.5/cipher/cipher-cmac.c.aes-perf 2020-04-22 18:29:41.643862745 +0200 ++++ libgcrypt-1.8.5/cipher/cipher-cmac.c 2020-04-22 18:29:41.667862287 +0200 +@@ -63,7 +63,7 @@ cmac_write (gcry_cipher_hd_t c, const by + for (; inlen && c->unused < blocksize; inlen--) + c->lastiv[c->unused++] = *inbuf++; + +- buf_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); ++ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); + set_burn (burn, enc_fn (&c->context.c, c->u_iv.iv, c->u_iv.iv)); + + c->unused = 0; +@@ -83,7 +83,7 @@ cmac_write (gcry_cipher_hd_t c, const by + else + while (inlen > blocksize) + { +- buf_xor (c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); ++ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); + set_burn (burn, enc_fn (&c->context.c, c->u_iv.iv, c->u_iv.iv)); + inlen -= blocksize; + inbuf += blocksize; +@@ -174,9 +174,9 @@ cmac_final (gcry_cipher_hd_t c) + c->lastiv[count++] = 0; + } + +- buf_xor (c->lastiv, c->lastiv, subkey, blocksize); ++ cipher_block_xor (c->lastiv, c->lastiv, subkey, blocksize); + +- buf_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); ++ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); + burn = c->spec->encrypt (&c->context.c, c->u_iv.iv, c->u_iv.iv); + if (burn) + _gcry_burn_stack (burn + 4 * sizeof (void *)); +diff -up libgcrypt-1.8.5/cipher/cipher-ctr.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ctr.c +--- libgcrypt-1.8.5/cipher/cipher-ctr.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-ctr.c 2020-04-22 18:29:41.667862287 +0200 +@@ -81,24 +81,38 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd + { + unsigned char tmp[MAX_BLOCKSIZE]; + +- do { +- nburn = enc_fn (&c->context.c, tmp, c->u_ctr.ctr); +- burn = nburn > burn ? nburn : burn; +- +- for (i = blocksize; i > 0; i--) +- { +- c->u_ctr.ctr[i-1]++; +- if (c->u_ctr.ctr[i-1] != 0) +- break; +- } +- +- n = blocksize < inbuflen ? blocksize : inbuflen; +- buf_xor(outbuf, inbuf, tmp, n); +- +- inbuflen -= n; +- outbuf += n; +- inbuf += n; +- } while (inbuflen); ++ do ++ { ++ nburn = enc_fn (&c->context.c, tmp, c->u_ctr.ctr); ++ burn = nburn > burn ? nburn : burn; ++ ++ for (i = blocksize; i > 0; i--) ++ { ++ c->u_ctr.ctr[i-1]++; ++ if (c->u_ctr.ctr[i-1] != 0) ++ break; ++ } ++ ++ if (inbuflen < blocksize) ++ break; ++ n = blocksize; ++ cipher_block_xor(outbuf, inbuf, tmp, blocksize); ++ ++ inbuflen -= n; ++ outbuf += n; ++ inbuf += n; ++ } ++ while (inbuflen); ++ ++ if (inbuflen) ++ { ++ n = inbuflen; ++ buf_xor(outbuf, inbuf, tmp, inbuflen); ++ ++ inbuflen -= n; ++ outbuf += n; ++ inbuf += n; ++ } + + /* Save the unused bytes of the counter. */ + c->unused = blocksize - n; +diff -up libgcrypt-1.8.5/cipher/cipher-gcm.c.aes-perf libgcrypt-1.8.5/cipher/cipher-gcm.c +--- libgcrypt-1.8.5/cipher/cipher-gcm.c.aes-perf 2018-04-17 17:27:25.000000000 +0200 ++++ libgcrypt-1.8.5/cipher/cipher-gcm.c 2020-04-22 18:29:41.667862287 +0200 +@@ -150,7 +150,7 @@ do_ghash (unsigned char *result, const u + u32 A; + int i; + +- buf_xor (V, result, buf, 16); ++ cipher_block_xor (V, result, buf, 16); + V[0] = be_bswap64 (V[0]); + V[1] = be_bswap64 (V[1]); + +@@ -259,7 +259,7 @@ do_ghash (unsigned char *result, const u + u32 T[3]; + int i; + +- buf_xor (V, result, buf, 16); /* V is big-endian */ ++ cipher_block_xor (V, result, buf, 16); /* V is big-endian */ + + /* First round can be manually tweaked based on fact that 'tmp' is zero. */ + i = 15; +@@ -342,7 +342,7 @@ do_ghash (unsigned char *hsub, unsigned + #else + unsigned long T[4]; + +- buf_xor (V, result, buf, 16); ++ cipher_block_xor (V, result, buf, 16); + for (i = 0; i < 4; i++) + { + V[i] = (V[i] & 0x00ff00ff) << 8 | (V[i] & 0xff00ff00) >> 8; +@@ -358,7 +358,7 @@ do_ghash (unsigned char *hsub, unsigned + for (j = 0x80; j; j >>= 1) + { + if (hsub[i] & j) +- buf_xor (p, p, V, 16); ++ cipher_block_xor (p, p, V, 16); + if (bshift (V)) + V[0] ^= 0xe1000000; + } +@@ -598,7 +598,7 @@ gcm_ctr_encrypt (gcry_cipher_hd_t c, byt + } + + fix_ctr = 1; +- buf_cpy(ctr_copy, c->u_ctr.ctr, GCRY_GCM_BLOCK_LEN); ++ cipher_block_cpy(ctr_copy, c->u_ctr.ctr, GCRY_GCM_BLOCK_LEN); + } + } + +@@ -928,8 +928,8 @@ _gcry_cipher_gcm_tag (gcry_cipher_hd_t c + /* Add bitlengths to tag. */ + do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, (byte*)bitlengths, + GCRY_GCM_BLOCK_LEN, 1); +- buf_xor (c->u_mode.gcm.u_tag.tag, c->u_mode.gcm.tagiv, +- c->u_mode.gcm.u_tag.tag, GCRY_GCM_BLOCK_LEN); ++ cipher_block_xor (c->u_mode.gcm.u_tag.tag, c->u_mode.gcm.tagiv, ++ c->u_mode.gcm.u_tag.tag, GCRY_GCM_BLOCK_LEN); + c->marks.tag = 1; + + wipememory (bitlengths, sizeof (bitlengths)); +diff -up libgcrypt-1.8.5/cipher/cipher-gcm-intel-pclmul.c.aes-perf libgcrypt-1.8.5/cipher/cipher-gcm-intel-pclmul.c +--- libgcrypt-1.8.5/cipher/cipher-gcm-intel-pclmul.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-gcm-intel-pclmul.c 2020-04-22 18:29:41.668862268 +0200 +@@ -248,7 +248,8 @@ static inline void gfmul_pclmul_aggr4(vo + void + _gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c) + { +- u64 tmp[2]; ++ static const unsigned char be_mask[16] __attribute__ ((aligned (16))) = ++ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; + #if defined(__x86_64__) && defined(__WIN64__) + char win64tmp[3 * 16]; + +@@ -262,15 +263,19 @@ _gcry_ghash_setup_intel_pclmul (gcry_cip + #endif + + /* Swap endianness of hsub. */ +- tmp[0] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 8); +- tmp[1] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 0); +- buf_cpy (c->u_mode.gcm.u_ghash_key.key, tmp, GCRY_GCM_BLOCK_LEN); ++ asm volatile ("movdqu (%[key]), %%xmm0\n\t" ++ "pshufb %[be_mask], %%xmm0\n\t" ++ "movdqu %%xmm0, (%[key])\n\t" ++ : ++ : [key] "r" (c->u_mode.gcm.u_ghash_key.key), ++ [be_mask] "m" (*be_mask) ++ : "memory"); + + #ifdef __x86_64__ +- asm volatile ("movdqu %[h_1], %%xmm0\n\t" +- "movdqa %%xmm0, %%xmm1\n\t" ++ asm volatile ("movdqa %%xmm0, %%xmm1\n\t" ++ : + : +- : [h_1] "m" (*tmp)); ++ : "memory"); + + gfmul_pclmul (); /* H•H => H² */ + +@@ -324,8 +329,6 @@ _gcry_ghash_setup_intel_pclmul (gcry_cip + ::: "cc" ); + #endif + #endif +- +- wipememory (tmp, sizeof(tmp)); + } + + +diff -up libgcrypt-1.8.5/cipher/cipher-internal.h.aes-perf libgcrypt-1.8.5/cipher/cipher-internal.h +--- libgcrypt-1.8.5/cipher/cipher-internal.h.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-internal.h 2020-04-22 18:29:41.668862268 +0200 +@@ -121,6 +121,25 @@ struct gcry_cipher_handle + interface does not easily allow to retrieve this value. */ + int algo; + ++ /* A structure with function pointers for mode operations. */ ++ struct { ++ gcry_err_code_t (*encrypt)(gcry_cipher_hd_t c, ++ unsigned char *outbuf, size_t outbuflen, ++ const unsigned char *inbuf, size_t inbuflen); ++ gcry_err_code_t (*decrypt)(gcry_cipher_hd_t c, ++ unsigned char *outbuf, size_t outbuflen, ++ const unsigned char *inbuf, size_t inbuflen); ++ gcry_err_code_t (*setiv)(gcry_cipher_hd_t c, const unsigned char *iv, ++ size_t ivlen); ++ ++ gcry_err_code_t (*authenticate)(gcry_cipher_hd_t c, ++ const unsigned char *abuf, size_t abuflen); ++ gcry_err_code_t (*get_tag)(gcry_cipher_hd_t c, unsigned char *outtag, ++ size_t taglen); ++ gcry_err_code_t (*check_tag)(gcry_cipher_hd_t c, const unsigned char *intag, ++ size_t taglen); ++ } mode_ops; ++ + /* A structure with function pointers for bulk operations. Due to + limitations of the module system (we don't want to change the + API) we need to keep these function pointers here. The cipher +@@ -146,7 +165,7 @@ struct gcry_cipher_handle + const void *inbuf_arg, size_t nblocks, int encrypt); + size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg, + size_t nblocks); +- void (*xts_crypt)(gcry_cipher_hd_t c, unsigned char *tweak, ++ void (*xts_crypt)(void *context, unsigned char *tweak, + void *outbuf_arg, const void *inbuf_arg, + size_t nblocks, int encrypt); + } bulk; +@@ -479,9 +498,12 @@ gcry_err_code_t _gcry_cipher_ocb_check_t + + + /*-- cipher-xts.c --*/ +-gcry_err_code_t _gcry_cipher_xts_crypt ++gcry_err_code_t _gcry_cipher_xts_encrypt + /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, +- const unsigned char *inbuf, size_t inbuflen, int encrypt); ++ const unsigned char *inbuf, size_t inbuflen); ++gcry_err_code_t _gcry_cipher_xts_decrypt ++/* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, ++ const unsigned char *inbuf, size_t inbuflen); + + + /* Return the L-value for block N. Note: 'cipher_ocb.c' ensures that N +@@ -506,4 +528,145 @@ ocb_get_l (gcry_cipher_hd_t c, u64 n) + return c->u_mode.ocb.L[ntz]; + } + ++/* Optimized function for cipher block copying */ ++static inline void ++cipher_block_cpy(void *_dst, const void *_src, size_t blocksize) ++{ ++ byte *dst = _dst; ++ const byte *src = _src; ++ u64 s[2]; ++ ++ if (blocksize == 8) ++ { ++ buf_put_he64(dst + 0, buf_get_he64(src + 0)); ++ } ++ else /* blocksize == 16 */ ++ { ++ s[0] = buf_get_he64(src + 0); ++ s[1] = buf_get_he64(src + 8); ++ buf_put_he64(dst + 0, s[0]); ++ buf_put_he64(dst + 8, s[1]); ++ } ++} ++ ++ ++/* Optimized function for cipher block xoring */ ++static inline void ++cipher_block_xor(void *_dst, const void *_src1, const void *_src2, ++ size_t blocksize) ++{ ++ byte *dst = _dst; ++ const byte *src1 = _src1; ++ const byte *src2 = _src2; ++ u64 s1[2]; ++ u64 s2[2]; ++ ++ if (blocksize == 8) ++ { ++ buf_put_he64(dst + 0, buf_get_he64(src1 + 0) ^ buf_get_he64(src2 + 0)); ++ } ++ else /* blocksize == 16 */ ++ { ++ s1[0] = buf_get_he64(src1 + 0); ++ s1[1] = buf_get_he64(src1 + 8); ++ s2[0] = buf_get_he64(src2 + 0); ++ s2[1] = buf_get_he64(src2 + 8); ++ buf_put_he64(dst + 0, s1[0] ^ s2[0]); ++ buf_put_he64(dst + 8, s1[1] ^ s2[1]); ++ } ++} ++ ++ ++/* Optimized function for in-place cipher block xoring */ ++static inline void ++cipher_block_xor_1(void *_dst, const void *_src, size_t blocksize) ++{ ++ cipher_block_xor (_dst, _dst, _src, blocksize); ++} ++ ++ ++/* Optimized function for cipher block xoring with two destination cipher ++ blocks. Used mainly by CFB mode encryption. */ ++static inline void ++cipher_block_xor_2dst(void *_dst1, void *_dst2, const void *_src, ++ size_t blocksize) ++{ ++ byte *dst1 = _dst1; ++ byte *dst2 = _dst2; ++ const byte *src = _src; ++ u64 d2[2]; ++ u64 s[2]; ++ ++ if (blocksize == 8) ++ { ++ d2[0] = buf_get_he64(dst2 + 0) ^ buf_get_he64(src + 0); ++ buf_put_he64(dst2 + 0, d2[0]); ++ buf_put_he64(dst1 + 0, d2[0]); ++ } ++ else /* blocksize == 16 */ ++ { ++ s[0] = buf_get_he64(src + 0); ++ s[1] = buf_get_he64(src + 8); ++ d2[0] = buf_get_he64(dst2 + 0); ++ d2[1] = buf_get_he64(dst2 + 8); ++ d2[0] = d2[0] ^ s[0]; ++ d2[1] = d2[1] ^ s[1]; ++ buf_put_he64(dst2 + 0, d2[0]); ++ buf_put_he64(dst2 + 8, d2[1]); ++ buf_put_he64(dst1 + 0, d2[0]); ++ buf_put_he64(dst1 + 8, d2[1]); ++ } ++} ++ ++ ++/* Optimized function for combined cipher block xoring and copying. ++ Used by mainly CBC mode decryption. */ ++static inline void ++cipher_block_xor_n_copy_2(void *_dst_xor, const void *_src_xor, ++ void *_srcdst_cpy, const void *_src_cpy, ++ size_t blocksize) ++{ ++ byte *dst_xor = _dst_xor; ++ byte *srcdst_cpy = _srcdst_cpy; ++ const byte *src_xor = _src_xor; ++ const byte *src_cpy = _src_cpy; ++ u64 sc[2]; ++ u64 sx[2]; ++ u64 sdc[2]; ++ ++ if (blocksize == 8) ++ { ++ sc[0] = buf_get_he64(src_cpy + 0); ++ buf_put_he64(dst_xor + 0, ++ buf_get_he64(srcdst_cpy + 0) ^ buf_get_he64(src_xor + 0)); ++ buf_put_he64(srcdst_cpy + 0, sc[0]); ++ } ++ else /* blocksize == 16 */ ++ { ++ sc[0] = buf_get_he64(src_cpy + 0); ++ sc[1] = buf_get_he64(src_cpy + 8); ++ sx[0] = buf_get_he64(src_xor + 0); ++ sx[1] = buf_get_he64(src_xor + 8); ++ sdc[0] = buf_get_he64(srcdst_cpy + 0); ++ sdc[1] = buf_get_he64(srcdst_cpy + 8); ++ sx[0] ^= sdc[0]; ++ sx[1] ^= sdc[1]; ++ buf_put_he64(dst_xor + 0, sx[0]); ++ buf_put_he64(dst_xor + 8, sx[1]); ++ buf_put_he64(srcdst_cpy + 0, sc[0]); ++ buf_put_he64(srcdst_cpy + 8, sc[1]); ++ } ++} ++ ++ ++/* Optimized function for combined cipher block xoring and copying. ++ Used by mainly CFB mode decryption. */ ++static inline void ++cipher_block_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, ++ size_t blocksize) ++{ ++ cipher_block_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, blocksize); ++} ++ ++ + #endif /*G10_CIPHER_INTERNAL_H*/ +diff -up libgcrypt-1.8.5/cipher/cipher-ocb.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ocb.c +--- libgcrypt-1.8.5/cipher/cipher-ocb.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-ocb.c 2020-04-22 18:29:41.668862268 +0200 +@@ -82,7 +82,7 @@ static void + double_block_cpy (unsigned char *d, const unsigned char *s) + { + if (d != s) +- buf_cpy (d, s, OCB_BLOCK_LEN); ++ cipher_block_cpy (d, s, OCB_BLOCK_LEN); + double_block (d); + } + +@@ -181,8 +181,8 @@ _gcry_cipher_ocb_set_nonce (gcry_cipher_ + nburn = c->spec->encrypt (&c->context.c, ktop, ktop); + burn = nburn > burn ? nburn : burn; + /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */ +- buf_cpy (stretch, ktop, OCB_BLOCK_LEN); +- buf_xor (stretch + OCB_BLOCK_LEN, ktop, ktop + 1, 8); ++ cipher_block_cpy (stretch, ktop, OCB_BLOCK_LEN); ++ cipher_block_xor (stretch + OCB_BLOCK_LEN, ktop, ktop + 1, 8); + /* Offset_0 = Stretch[1+bottom..128+bottom] + (We use the IV field to store the offset) */ + bit_copy (c->u_iv.iv, stretch, bottom, OCB_BLOCK_LEN); +@@ -267,18 +267,18 @@ _gcry_cipher_ocb_authenticate (gcry_ciph + } + else + { +- buf_cpy (l_tmp, ocb_get_l (c, c->u_mode.ocb.aad_nblocks), +- OCB_BLOCK_LEN); ++ cipher_block_cpy (l_tmp, ocb_get_l (c, c->u_mode.ocb.aad_nblocks), ++ OCB_BLOCK_LEN); + } + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ +- buf_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); + /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ +- buf_xor (l_tmp, c->u_mode.ocb.aad_offset, +- c->u_mode.ocb.aad_leftover, OCB_BLOCK_LEN); ++ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, ++ c->u_mode.ocb.aad_leftover, OCB_BLOCK_LEN); + nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); + burn = nburn > burn ? nburn : burn; +- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); + + c->u_mode.ocb.aad_nleftover = 0; + } +@@ -309,12 +309,13 @@ _gcry_cipher_ocb_authenticate (gcry_ciph + ocb_get_L_big(c, c->u_mode.ocb.aad_nblocks, l_tmp); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ +- buf_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); + /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ +- buf_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, OCB_BLOCK_LEN); ++ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, ++ OCB_BLOCK_LEN); + nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); + burn = nburn > burn ? nburn : burn; +- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); + + abuf += OCB_BLOCK_LEN; + abuflen -= OCB_BLOCK_LEN; +@@ -349,14 +350,15 @@ _gcry_cipher_ocb_authenticate (gcry_ciph + gcry_assert(c->u_mode.ocb.aad_nblocks & table_size_mask); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ +- buf_xor_1 (c->u_mode.ocb.aad_offset, +- ocb_get_l (c, c->u_mode.ocb.aad_nblocks), +- OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, ++ ocb_get_l (c, c->u_mode.ocb.aad_nblocks), ++ OCB_BLOCK_LEN); + /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ +- buf_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, OCB_BLOCK_LEN); ++ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, ++ OCB_BLOCK_LEN); + nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); + burn = nburn > burn ? nburn : burn; +- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); + + abuf += OCB_BLOCK_LEN; + abuflen -= OCB_BLOCK_LEN; +@@ -397,18 +399,18 @@ ocb_aad_finalize (gcry_cipher_hd_t c) + if (c->u_mode.ocb.aad_nleftover) + { + /* Offset_* = Offset_m xor L_* */ +- buf_xor_1 (c->u_mode.ocb.aad_offset, +- c->u_mode.ocb.L_star, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, ++ c->u_mode.ocb.L_star, OCB_BLOCK_LEN); + /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */ + buf_cpy (l_tmp, c->u_mode.ocb.aad_leftover, c->u_mode.ocb.aad_nleftover); + memset (l_tmp + c->u_mode.ocb.aad_nleftover, 0, + OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover); + l_tmp[c->u_mode.ocb.aad_nleftover] = 0x80; +- buf_xor_1 (l_tmp, c->u_mode.ocb.aad_offset, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (l_tmp, c->u_mode.ocb.aad_offset, OCB_BLOCK_LEN); + /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */ + nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); + burn = nburn > burn ? nburn : burn; +- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); + + c->u_mode.ocb.aad_nleftover = 0; + } +@@ -431,7 +433,7 @@ ocb_checksum (unsigned char *chksum, con + while (nblks > 0) + { + /* Checksum_i = Checksum_{i-1} xor P_i */ +- buf_xor_1(chksum, plainbuf, OCB_BLOCK_LEN); ++ cipher_block_xor_1(chksum, plainbuf, OCB_BLOCK_LEN); + + plainbuf += OCB_BLOCK_LEN; + nblks--; +@@ -491,12 +493,12 @@ ocb_crypt (gcry_cipher_hd_t c, int encry + } + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ +- buf_xor_1 (c->u_iv.iv, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_iv.iv, l_tmp, OCB_BLOCK_LEN); + /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ +- buf_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); ++ cipher_block_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); + nburn = crypt_fn (&c->context.c, outbuf, outbuf); + burn = nburn > burn ? nburn : burn; +- buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); + + if (!encrypt) + { +@@ -551,14 +553,14 @@ ocb_crypt (gcry_cipher_hd_t c, int encry + gcry_assert(c->u_mode.ocb.data_nblocks & table_size_mask); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ +- buf_xor_1 (c->u_iv.iv, +- ocb_get_l (c, c->u_mode.ocb.data_nblocks), +- OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_iv.iv, ++ ocb_get_l (c, c->u_mode.ocb.data_nblocks), ++ OCB_BLOCK_LEN); + /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ +- buf_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); ++ cipher_block_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); + nburn = crypt_fn (&c->context.c, outbuf, outbuf); + burn = nburn > burn ? nburn : burn; +- buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); + + inbuf += OCB_BLOCK_LEN; + inbuflen -= OCB_BLOCK_LEN; +@@ -584,7 +586,7 @@ ocb_crypt (gcry_cipher_hd_t c, int encry + unsigned char pad[OCB_BLOCK_LEN]; + + /* Offset_* = Offset_m xor L_* */ +- buf_xor_1 (c->u_iv.iv, c->u_mode.ocb.L_star, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_iv.iv, c->u_mode.ocb.L_star, OCB_BLOCK_LEN); + /* Pad = ENCIPHER(K, Offset_*) */ + nburn = c->spec->encrypt (&c->context.c, pad, c->u_iv.iv); + burn = nburn > burn ? nburn : burn; +@@ -596,7 +598,7 @@ ocb_crypt (gcry_cipher_hd_t c, int encry + buf_cpy (l_tmp, inbuf, inbuflen); + memset (l_tmp + inbuflen, 0, OCB_BLOCK_LEN - inbuflen); + l_tmp[inbuflen] = 0x80; +- buf_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); + /* C_* = P_* xor Pad[1..bitlen(P_*)] */ + buf_xor (outbuf, inbuf, pad, inbuflen); + } +@@ -604,13 +606,13 @@ ocb_crypt (gcry_cipher_hd_t c, int encry + { + /* P_* = C_* xor Pad[1..bitlen(C_*)] */ + /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ +- buf_cpy (l_tmp, pad, OCB_BLOCK_LEN); ++ cipher_block_cpy (l_tmp, pad, OCB_BLOCK_LEN); + buf_cpy (l_tmp, inbuf, inbuflen); +- buf_xor_1 (l_tmp, pad, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (l_tmp, pad, OCB_BLOCK_LEN); + l_tmp[inbuflen] = 0x80; + buf_cpy (outbuf, l_tmp, inbuflen); + +- buf_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); + } + } + +@@ -618,8 +620,10 @@ ocb_crypt (gcry_cipher_hd_t c, int encry + if (c->marks.finalize) + { + /* Tag = ENCIPHER(K, Checksum xor Offset xor L_$) xor HASH(K,A) */ +- buf_xor (c->u_mode.ocb.tag, c->u_ctr.ctr, c->u_iv.iv, OCB_BLOCK_LEN); +- buf_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.L_dollar, OCB_BLOCK_LEN); ++ cipher_block_xor (c->u_mode.ocb.tag, c->u_ctr.ctr, c->u_iv.iv, ++ OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.L_dollar, ++ OCB_BLOCK_LEN); + nburn = c->spec->encrypt (&c->context.c, + c->u_mode.ocb.tag, c->u_mode.ocb.tag); + burn = nburn > burn ? nburn : burn; +@@ -672,7 +676,8 @@ compute_tag_if_needed (gcry_cipher_hd_t + if (!c->marks.tag) + { + ocb_aad_finalize (c); +- buf_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.aad_sum, OCB_BLOCK_LEN); ++ cipher_block_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.aad_sum, ++ OCB_BLOCK_LEN); + c->marks.tag = 1; + } + } +diff -up libgcrypt-1.8.5/cipher/cipher-ofb.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ofb.c +--- libgcrypt-1.8.5/cipher/cipher-ofb.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-ofb.c 2020-04-22 18:29:41.668862268 +0200 +@@ -76,7 +76,7 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd + /* Encrypt the IV (and save the current one). */ + nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); + burn = nburn > burn ? nburn : burn; +- buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize); ++ cipher_block_xor(outbuf, c->u_iv.iv, inbuf, blocksize); + outbuf += blocksize; + inbuf += blocksize; + inbuflen -= blocksize; +diff -up libgcrypt-1.8.5/cipher/cipher-selftest.c.aes-perf libgcrypt-1.8.5/cipher/cipher-selftest.c +--- libgcrypt-1.8.5/cipher/cipher-selftest.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-selftest.c 2020-04-22 18:29:41.669862248 +0200 +@@ -105,7 +105,7 @@ _gcry_selftest_helper_cbc (const char *c + ciphertext = plaintext2 + nblocks * blocksize; + + /* Initialize ctx */ +- if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) ++ if (setkey_func (ctx, key, sizeof(key), NULL) != GPG_ERR_NO_ERROR) + { + xfree(mem); + return "setkey failed"; +@@ -228,7 +228,7 @@ _gcry_selftest_helper_cfb (const char *c + ciphertext = plaintext2 + nblocks * blocksize; + + /* Initialize ctx */ +- if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) ++ if (setkey_func (ctx, key, sizeof(key), NULL) != GPG_ERR_NO_ERROR) + { + xfree(mem); + return "setkey failed"; +@@ -351,7 +351,7 @@ _gcry_selftest_helper_ctr (const char *c + ciphertext2 = ciphertext + nblocks * blocksize; + + /* Initialize ctx */ +- if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) ++ if (setkey_func (ctx, key, sizeof(key), NULL) != GPG_ERR_NO_ERROR) + { + xfree(mem); + return "setkey failed"; +diff -up libgcrypt-1.8.5/cipher/cipher-xts.c.aes-perf libgcrypt-1.8.5/cipher/cipher-xts.c +--- libgcrypt-1.8.5/cipher/cipher-xts.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/cipher-xts.c 2020-04-22 18:29:41.669862248 +0200 +@@ -93,7 +93,8 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t + /* Use a bulk method if available. */ + if (nblocks && c->bulk.xts_crypt) + { +- c->bulk.xts_crypt (c, c->u_ctr.ctr, outbuf, inbuf, nblocks, encrypt); ++ c->bulk.xts_crypt (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks, ++ encrypt); + inbuf += nblocks * GCRY_XTS_BLOCK_LEN; + outbuf += nblocks * GCRY_XTS_BLOCK_LEN; + inbuflen -= nblocks * GCRY_XTS_BLOCK_LEN; +@@ -106,10 +107,10 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t + while (nblocks) + { + /* Xor-Encrypt/Decrypt-Xor block. */ +- buf_xor (tmp.x64, inbuf, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); ++ cipher_block_xor (tmp.x64, inbuf, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); + nburn = crypt_fn (&c->context.c, tmp.x1, tmp.x1); + burn = nburn > burn ? nburn : burn; +- buf_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); ++ cipher_block_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); + + outbuf += GCRY_XTS_BLOCK_LEN; + inbuf += GCRY_XTS_BLOCK_LEN; +@@ -132,10 +133,10 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t + xts_gfmul_byA (tmp.x1, c->u_ctr.ctr); + + /* Decrypt last block first. */ +- buf_xor (outbuf, inbuf, tmp.x64, GCRY_XTS_BLOCK_LEN); ++ cipher_block_xor (outbuf, inbuf, tmp.x64, GCRY_XTS_BLOCK_LEN); + nburn = crypt_fn (&c->context.c, outbuf, outbuf); + burn = nburn > burn ? nburn : burn; +- buf_xor (outbuf, outbuf, tmp.x64, GCRY_XTS_BLOCK_LEN); ++ cipher_block_xor (outbuf, outbuf, tmp.x64, GCRY_XTS_BLOCK_LEN); + + inbuflen -= GCRY_XTS_BLOCK_LEN; + inbuf += GCRY_XTS_BLOCK_LEN; +@@ -146,15 +147,15 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t + outbuf -= GCRY_XTS_BLOCK_LEN; + + /* Steal ciphertext from previous block. */ +- buf_cpy (tmp.x64, outbuf, GCRY_XTS_BLOCK_LEN); ++ cipher_block_cpy (tmp.x64, outbuf, GCRY_XTS_BLOCK_LEN); + buf_cpy (tmp.x64, inbuf, inbuflen); + buf_cpy (outbuf + GCRY_XTS_BLOCK_LEN, outbuf, inbuflen); + + /* Decrypt/Encrypt last block. */ +- buf_xor (tmp.x64, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); ++ cipher_block_xor (tmp.x64, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); + nburn = crypt_fn (&c->context.c, tmp.x1, tmp.x1); + burn = nburn > burn ? nburn : burn; +- buf_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); ++ cipher_block_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); + } + + /* Auto-increment data-unit sequence number */ +@@ -168,3 +169,21 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t + + return 0; + } ++ ++ ++gcry_err_code_t ++_gcry_cipher_xts_encrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, size_t outbuflen, ++ const unsigned char *inbuf, size_t inbuflen) ++{ ++ return _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 1); ++} ++ ++ ++gcry_err_code_t ++_gcry_cipher_xts_decrypt (gcry_cipher_hd_t c, ++ unsigned char *outbuf, size_t outbuflen, ++ const unsigned char *inbuf, size_t inbuflen) ++{ ++ return _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 0); ++} +diff -up libgcrypt-1.8.5/cipher/des.c.aes-perf libgcrypt-1.8.5/cipher/des.c +--- libgcrypt-1.8.5/cipher/des.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/des.c 2020-04-22 18:29:41.669862248 +0200 +@@ -119,6 +119,7 @@ + #include "g10lib.h" + #include "cipher.h" + #include "bufhelp.h" ++#include "cipher-internal.h" + #include "cipher-selftest.h" + + +@@ -197,7 +198,8 @@ static unsigned int do_tripledes_encrypt + static unsigned int do_tripledes_decrypt(void *context, byte *outbuf, + const byte *inbuf ); + static gcry_err_code_t do_tripledes_setkey(void *context, const byte *key, +- unsigned keylen); ++ unsigned keylen, ++ gcry_cipher_hd_t hd); + + static int initialized; + +@@ -940,7 +942,7 @@ _gcry_3des_ctr_enc(void *context, unsign + /* Encrypt the counter. */ + tripledes_ecb_encrypt (ctx, ctr, tmpbuf); + /* XOR the input with the encrypted counter and store in output. */ +- buf_xor(outbuf, tmpbuf, inbuf, DES_BLOCKSIZE); ++ cipher_block_xor(outbuf, tmpbuf, inbuf, DES_BLOCKSIZE); + outbuf += DES_BLOCKSIZE; + inbuf += DES_BLOCKSIZE; + /* Increment the counter. */ +@@ -996,7 +998,7 @@ _gcry_3des_cbc_dec(void *context, unsign + the intermediate result to SAVEBUF. */ + tripledes_ecb_decrypt (ctx, inbuf, savebuf); + +- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, DES_BLOCKSIZE); ++ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, DES_BLOCKSIZE); + inbuf += DES_BLOCKSIZE; + outbuf += DES_BLOCKSIZE; + } +@@ -1041,7 +1043,7 @@ _gcry_3des_cfb_dec(void *context, unsign + for ( ;nblocks; nblocks-- ) + { + tripledes_ecb_encrypt (ctx, iv, iv); +- buf_xor_n_copy(outbuf, iv, inbuf, DES_BLOCKSIZE); ++ cipher_block_xor_n_copy(outbuf, iv, inbuf, DES_BLOCKSIZE); + outbuf += DES_BLOCKSIZE; + inbuf += DES_BLOCKSIZE; + } +@@ -1086,7 +1088,8 @@ is_weak_key ( const byte *key ) + + /* Alternative setkey for selftests; need larger key than default. */ + static gcry_err_code_t +-bulk_selftest_setkey (void *context, const byte *__key, unsigned __keylen) ++bulk_selftest_setkey (void *context, const byte *__key, unsigned __keylen, ++ gcry_cipher_hd_t hd) + { + static const unsigned char key[24] ATTR_ALIGNED_16 = { + 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, +@@ -1094,10 +1097,11 @@ bulk_selftest_setkey (void *context, con + 0x18,0x2A,0x39,0x47,0x5E,0x6F,0x75,0x82 + }; + ++ (void)hd; + (void)__key; + (void)__keylen; + +- return do_tripledes_setkey(context, key, sizeof(key)); ++ return do_tripledes_setkey(context, key, sizeof(key), NULL); + } + + +@@ -1349,10 +1353,13 @@ selftest (void) + + + static gcry_err_code_t +-do_tripledes_setkey ( void *context, const byte *key, unsigned keylen ) ++do_tripledes_setkey ( void *context, const byte *key, unsigned keylen, ++ gcry_cipher_hd_t hd ) + { + struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; + ++ (void)hd; ++ + if( keylen != 24 ) + return GPG_ERR_INV_KEYLEN; + +@@ -1413,10 +1420,13 @@ do_tripledes_decrypt( void *context, byt + } + + static gcry_err_code_t +-do_des_setkey (void *context, const byte *key, unsigned keylen) ++do_des_setkey (void *context, const byte *key, unsigned keylen, ++ gcry_cipher_hd_t hd) + { + struct _des_ctx *ctx = (struct _des_ctx *) context; + ++ (void)hd; ++ + if (keylen != 8) + return GPG_ERR_INV_KEYLEN; + +diff -up libgcrypt-1.8.5/cipher/gost28147.c.aes-perf libgcrypt-1.8.5/cipher/gost28147.c +--- libgcrypt-1.8.5/cipher/gost28147.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/gost28147.c 2020-04-22 18:29:41.669862248 +0200 +@@ -39,11 +39,14 @@ + #include "gost-sb.h" + + static gcry_err_code_t +-gost_setkey (void *c, const byte *key, unsigned keylen) ++gost_setkey (void *c, const byte *key, unsigned keylen, ++ gcry_cipher_hd_t hd) + { + int i; + GOST28147_context *ctx = c; + ++ (void)hd; ++ + if (keylen != 256 / 8) + return GPG_ERR_INV_KEYLEN; + +diff -up libgcrypt-1.8.5/cipher/idea.c.aes-perf libgcrypt-1.8.5/cipher/idea.c +--- libgcrypt-1.8.5/cipher/idea.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/idea.c 2020-04-22 18:29:41.670862229 +0200 +@@ -258,10 +258,12 @@ do_setkey( IDEA_context *c, const byte * + } + + static gcry_err_code_t +-idea_setkey (void *context, const byte *key, unsigned int keylen) ++idea_setkey (void *context, const byte *key, unsigned int keylen, ++ gcry_cipher_hd_t hd) + { + IDEA_context *ctx = context; + int rc = do_setkey (ctx, key, keylen); ++ (void)hd; + _gcry_burn_stack (23+6*sizeof(void*)); + return rc; + } +diff -up libgcrypt-1.8.5/cipher/Makefile.am.aes-perf libgcrypt-1.8.5/cipher/Makefile.am +--- libgcrypt-1.8.5/cipher/Makefile.am.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/Makefile.am 2020-04-22 18:29:41.670862229 +0200 +@@ -83,7 +83,8 @@ rijndael.c rijndael-internal.h rijndael- + rijndael-padlock.c rijndael-amd64.S rijndael-arm.S \ + rijndael-ssse3-amd64.c rijndael-ssse3-amd64-asm.S \ + rijndael-armv8-ce.c rijndael-armv8-aarch32-ce.S rijndael-armv8-aarch64-ce.S \ +- rijndael-aarch64.S \ ++ rijndael-aarch64.S rijndael-ppc.c rijndael-ppc9le.c \ ++ rijndael-ppc-common.h rijndael-ppc-functions.h \ + rmd160.c \ + rsa.c \ + salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \ +@@ -128,3 +129,23 @@ tiger.o: $(srcdir)/tiger.c + + tiger.lo: $(srcdir)/tiger.c + `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` ++ ++if ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS ++ppc_vcrypto_cflags = -maltivec -mvsx -mcrypto ++else ++ppc_vcrypto_cflags = ++endif ++ ++rijndael-ppc.o: $(srcdir)/rijndael-ppc.c Makefile ++ `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< ` ++ ++rijndael-ppc.lo: $(srcdir)/rijndael-ppc.c Makefile ++ `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< ` ++ ++rijndael-ppc9le.o: $(srcdir)/rijndael-ppc9le.c Makefile ++ `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< ` ++ ++rijndael-ppc9le.lo: $(srcdir)/rijndael-ppc9le.c Makefile ++ `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< ` ++ ++ +diff -up libgcrypt-1.8.5/cipher/rfc2268.c.aes-perf libgcrypt-1.8.5/cipher/rfc2268.c +--- libgcrypt-1.8.5/cipher/rfc2268.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/rfc2268.c 2020-04-22 18:29:41.670862229 +0200 +@@ -262,8 +262,10 @@ setkey_core (void *context, const unsign + } + + static gpg_err_code_t +-do_setkey (void *context, const unsigned char *key, unsigned int keylen) ++do_setkey (void *context, const unsigned char *key, unsigned int keylen, ++ gcry_cipher_hd_t hd) + { ++ (void)hd; + return setkey_core (context, key, keylen, 1); + } + +diff -up libgcrypt-1.8.5/cipher/rijndael-aesni.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-aesni.c +--- libgcrypt-1.8.5/cipher/rijndael-aesni.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/rijndael-aesni.c 2020-04-22 18:29:41.671862210 +0200 +@@ -327,8 +327,8 @@ _gcry_aes_aesni_do_setkey (RIJNDAEL_cont + + + /* Make a decryption key from an encryption key. */ +-void +-_gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx) ++static inline void ++do_aesni_prepare_decryption (RIJNDAEL_context *ctx) + { + /* The AES-NI decrypt instructions use the Equivalent Inverse + Cipher, thus we can't use the the standard decrypt key +@@ -338,8 +338,6 @@ _gcry_aes_aesni_prepare_decryption (RIJN + int rr; + int r; + +- aesni_prepare(); +- + #define DO_AESNI_AESIMC() \ + asm volatile ("movdqa %[ekey], %%xmm1\n\t" \ + /*"aesimc %%xmm1, %%xmm1\n\t"*/ \ +@@ -375,7 +373,13 @@ _gcry_aes_aesni_prepare_decryption (RIJN + dkey[r] = ekey[0]; + + #undef DO_AESNI_AESIMC ++} + ++void ++_gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx) ++{ ++ aesni_prepare(); ++ do_aesni_prepare_decryption (ctx); + aesni_cleanup(); + } + +@@ -1023,8 +1027,8 @@ _gcry_aes_aesni_encrypt (const RIJNDAEL_ + + + void +-_gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, ++_gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) + { + aesni_prepare (); +@@ -1059,8 +1063,8 @@ _gcry_aes_aesni_cfb_enc (RIJNDAEL_contex + + + void +-_gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, ++_gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks, int cbc_mac) + { + aesni_prepare_2_6_variable; +@@ -1105,8 +1109,8 @@ _gcry_aes_aesni_cbc_enc (RIJNDAEL_contex + + + void +-_gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *ctr, ++_gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *ctr, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) + { + static const unsigned char be_mask[16] __attribute__ ((aligned (16))) = +@@ -1160,8 +1164,8 @@ _gcry_aes_aesni_decrypt (const RIJNDAEL_ + + + void +-_gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, ++_gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) + { + aesni_prepare_2_6_variable; +@@ -1245,15 +1249,21 @@ _gcry_aes_aesni_cfb_dec (RIJNDAEL_contex + + + void +-_gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, +- size_t nblocks) ++_gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks) + { + aesni_prepare_2_6_variable; + + aesni_prepare (); + aesni_prepare_2_6(); + ++ if ( !ctx->decryption_prepared ) ++ { ++ do_aesni_prepare_decryption ( ctx ); ++ ctx->decryption_prepared = 1; ++ } ++ + asm volatile + ("movdqu %[iv], %%xmm5\n\t" /* use xmm5 as fast IV storage */ + : /* No output */ +@@ -1514,6 +1524,12 @@ aesni_ocb_dec (gcry_cipher_hd_t c, void + aesni_prepare (); + aesni_prepare_2_6 (); + ++ if ( !ctx->decryption_prepared ) ++ { ++ do_aesni_prepare_decryption ( ctx ); ++ ctx->decryption_prepared = 1; ++ } ++ + /* Preload Offset and Checksum */ + asm volatile ("movdqu %[iv], %%xmm5\n\t" + "movdqu %[ctr], %%xmm6\n\t" +@@ -1665,7 +1681,7 @@ aesni_ocb_dec (gcry_cipher_hd_t c, void + } + + +-void ++size_t + _gcry_aes_aesni_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg, + const void *inbuf_arg, size_t nblocks, int encrypt) + { +@@ -1673,10 +1689,12 @@ _gcry_aes_aesni_ocb_crypt(gcry_cipher_hd + aesni_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); + else + aesni_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); ++ ++ return 0; + } + + +-void ++size_t + _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, + size_t nblocks) + { +@@ -1813,4 +1831,303 @@ _gcry_aes_aesni_ocb_auth (gcry_cipher_hd + } + + ++static const u64 xts_gfmul_const[16] __attribute__ ((aligned (16))) = ++ { 0x87, 0x01 }; ++ ++ ++static void ++_gcry_aes_aesni_xts_enc (RIJNDAEL_context *ctx, unsigned char *tweak, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks) ++{ ++ aesni_prepare_2_6_variable; ++ ++ aesni_prepare (); ++ aesni_prepare_2_6 (); ++ ++ /* Preload Tweak */ ++ asm volatile ("movdqu %[tweak], %%xmm5\n\t" ++ "movdqa %[gfmul], %%xmm6\n\t" ++ : ++ : [tweak] "m" (*tweak), ++ [gfmul] "m" (*xts_gfmul_const) ++ : "memory" ); ++ ++ for ( ;nblocks >= 4; nblocks -= 4 ) ++ { ++ asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" ++ "movdqu %[inbuf0], %%xmm1\n\t" ++ "pxor %%xmm5, %%xmm1\n\t" ++ "movdqu %%xmm5, %[outbuf0]\n\t" ++ ++ "movdqa %%xmm4, %%xmm0\n\t" ++ "paddd %%xmm4, %%xmm4\n\t" ++ "psrad $31, %%xmm0\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm5\n\t" ++ : [outbuf0] "=m" (*(outbuf + 0 * 16)) ++ : [inbuf0] "m" (*(inbuf + 0 * 16)) ++ : "memory" ); ++ ++ asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" ++ "pxor %%xmm5, %%xmm2\n\t" ++ "movdqu %%xmm5, %[outbuf1]\n\t" ++ ++ "movdqa %%xmm4, %%xmm0\n\t" ++ "paddd %%xmm4, %%xmm4\n\t" ++ "psrad $31, %%xmm0\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm5\n\t" ++ : [outbuf1] "=m" (*(outbuf + 1 * 16)) ++ : [inbuf1] "m" (*(inbuf + 1 * 16)) ++ : "memory" ); ++ ++ asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" ++ "pxor %%xmm5, %%xmm3\n\t" ++ "movdqu %%xmm5, %[outbuf2]\n\t" ++ ++ "movdqa %%xmm4, %%xmm0\n\t" ++ "paddd %%xmm4, %%xmm4\n\t" ++ "psrad $31, %%xmm0\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm5\n\t" ++ : [outbuf2] "=m" (*(outbuf + 2 * 16)) ++ : [inbuf2] "m" (*(inbuf + 2 * 16)) ++ : "memory" ); ++ ++ asm volatile ("movdqa %%xmm4, %%xmm0\n\t" ++ "movdqu %[inbuf3], %%xmm4\n\t" ++ "pxor %%xmm5, %%xmm4\n\t" ++ "movdqu %%xmm5, %[outbuf3]\n\t" ++ ++ "psrad $31, %%xmm0\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm5\n\t" ++ : [outbuf3] "=m" (*(outbuf + 3 * 16)) ++ : [inbuf3] "m" (*(inbuf + 3 * 16)) ++ : "memory" ); ++ ++ do_aesni_enc_vec4 (ctx); ++ ++ asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm1\n\t" ++ "movdqu %[outbuf1], %%xmm0\n\t" ++ "movdqu %%xmm1, %[outbuf0]\n\t" ++ "movdqu %[outbuf2], %%xmm1\n\t" ++ "pxor %%xmm0, %%xmm2\n\t" ++ "movdqu %[outbuf3], %%xmm0\n\t" ++ "pxor %%xmm1, %%xmm3\n\t" ++ "pxor %%xmm0, %%xmm4\n\t" ++ "movdqu %%xmm2, %[outbuf1]\n\t" ++ "movdqu %%xmm3, %[outbuf2]\n\t" ++ "movdqu %%xmm4, %[outbuf3]\n\t" ++ : [outbuf0] "+m" (*(outbuf + 0 * 16)), ++ [outbuf1] "+m" (*(outbuf + 1 * 16)), ++ [outbuf2] "+m" (*(outbuf + 2 * 16)), ++ [outbuf3] "+m" (*(outbuf + 3 * 16)) ++ : ++ : "memory" ); ++ ++ outbuf += BLOCKSIZE * 4; ++ inbuf += BLOCKSIZE * 4; ++ } ++ ++ for ( ;nblocks; nblocks-- ) ++ { ++ asm volatile ("movdqu %[inbuf], %%xmm0\n\t" ++ "pxor %%xmm5, %%xmm0\n\t" ++ "movdqa %%xmm5, %%xmm4\n\t" ++ ++ "pshufd $0x13, %%xmm5, %%xmm1\n\t" ++ "psrad $31, %%xmm1\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm1\n\t" ++ "pxor %%xmm1, %%xmm5\n\t" ++ : ++ : [inbuf] "m" (*inbuf) ++ : "memory" ); ++ ++ do_aesni_enc (ctx); ++ ++ asm volatile ("pxor %%xmm4, %%xmm0\n\t" ++ "movdqu %%xmm0, %[outbuf]\n\t" ++ : [outbuf] "=m" (*outbuf) ++ : ++ : "memory" ); ++ ++ outbuf += BLOCKSIZE; ++ inbuf += BLOCKSIZE; ++ } ++ ++ asm volatile ("movdqu %%xmm5, %[tweak]\n\t" ++ : [tweak] "=m" (*tweak) ++ : ++ : "memory" ); ++ ++ aesni_cleanup (); ++ aesni_cleanup_2_6 (); ++ ++ return 0; ++} ++ ++ ++static void ++_gcry_aes_aesni_xts_dec (RIJNDAEL_context *ctx, unsigned char *tweak, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks) ++{ ++ aesni_prepare_2_6_variable; ++ ++ aesni_prepare (); ++ aesni_prepare_2_6 (); ++ ++ if ( !ctx->decryption_prepared ) ++ { ++ do_aesni_prepare_decryption ( ctx ); ++ ctx->decryption_prepared = 1; ++ } ++ ++ /* Preload Tweak */ ++ asm volatile ("movdqu %[tweak], %%xmm5\n\t" ++ "movdqa %[gfmul], %%xmm6\n\t" ++ : ++ : [tweak] "m" (*tweak), ++ [gfmul] "m" (*xts_gfmul_const) ++ : "memory" ); ++ ++ for ( ;nblocks >= 4; nblocks -= 4 ) ++ { ++ asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" ++ "movdqu %[inbuf0], %%xmm1\n\t" ++ "pxor %%xmm5, %%xmm1\n\t" ++ "movdqu %%xmm5, %[outbuf0]\n\t" ++ ++ "movdqa %%xmm4, %%xmm0\n\t" ++ "paddd %%xmm4, %%xmm4\n\t" ++ "psrad $31, %%xmm0\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm5\n\t" ++ : [outbuf0] "=m" (*(outbuf + 0 * 16)) ++ : [inbuf0] "m" (*(inbuf + 0 * 16)) ++ : "memory" ); ++ ++ asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" ++ "pxor %%xmm5, %%xmm2\n\t" ++ "movdqu %%xmm5, %[outbuf1]\n\t" ++ ++ "movdqa %%xmm4, %%xmm0\n\t" ++ "paddd %%xmm4, %%xmm4\n\t" ++ "psrad $31, %%xmm0\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm5\n\t" ++ : [outbuf1] "=m" (*(outbuf + 1 * 16)) ++ : [inbuf1] "m" (*(inbuf + 1 * 16)) ++ : "memory" ); ++ ++ asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" ++ "pxor %%xmm5, %%xmm3\n\t" ++ "movdqu %%xmm5, %[outbuf2]\n\t" ++ ++ "movdqa %%xmm4, %%xmm0\n\t" ++ "paddd %%xmm4, %%xmm4\n\t" ++ "psrad $31, %%xmm0\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm5\n\t" ++ : [outbuf2] "=m" (*(outbuf + 2 * 16)) ++ : [inbuf2] "m" (*(inbuf + 2 * 16)) ++ : "memory" ); ++ ++ asm volatile ("movdqa %%xmm4, %%xmm0\n\t" ++ "movdqu %[inbuf3], %%xmm4\n\t" ++ "pxor %%xmm5, %%xmm4\n\t" ++ "movdqu %%xmm5, %[outbuf3]\n\t" ++ ++ "psrad $31, %%xmm0\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm5\n\t" ++ : [outbuf3] "=m" (*(outbuf + 3 * 16)) ++ : [inbuf3] "m" (*(inbuf + 3 * 16)) ++ : "memory" ); ++ ++ do_aesni_dec_vec4 (ctx); ++ ++ asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" ++ "pxor %%xmm0, %%xmm1\n\t" ++ "movdqu %[outbuf1], %%xmm0\n\t" ++ "movdqu %%xmm1, %[outbuf0]\n\t" ++ "movdqu %[outbuf2], %%xmm1\n\t" ++ "pxor %%xmm0, %%xmm2\n\t" ++ "movdqu %[outbuf3], %%xmm0\n\t" ++ "pxor %%xmm1, %%xmm3\n\t" ++ "pxor %%xmm0, %%xmm4\n\t" ++ "movdqu %%xmm2, %[outbuf1]\n\t" ++ "movdqu %%xmm3, %[outbuf2]\n\t" ++ "movdqu %%xmm4, %[outbuf3]\n\t" ++ : [outbuf0] "+m" (*(outbuf + 0 * 16)), ++ [outbuf1] "+m" (*(outbuf + 1 * 16)), ++ [outbuf2] "+m" (*(outbuf + 2 * 16)), ++ [outbuf3] "+m" (*(outbuf + 3 * 16)) ++ : ++ : "memory" ); ++ ++ outbuf += BLOCKSIZE * 4; ++ inbuf += BLOCKSIZE * 4; ++ } ++ ++ for ( ;nblocks; nblocks-- ) ++ { ++ asm volatile ("movdqu %[inbuf], %%xmm0\n\t" ++ "pxor %%xmm5, %%xmm0\n\t" ++ "movdqa %%xmm5, %%xmm4\n\t" ++ ++ "pshufd $0x13, %%xmm5, %%xmm1\n\t" ++ "psrad $31, %%xmm1\n\t" ++ "paddq %%xmm5, %%xmm5\n\t" ++ "pand %%xmm6, %%xmm1\n\t" ++ "pxor %%xmm1, %%xmm5\n\t" ++ : ++ : [inbuf] "m" (*inbuf) ++ : "memory" ); ++ ++ do_aesni_dec (ctx); ++ ++ asm volatile ("pxor %%xmm4, %%xmm0\n\t" ++ "movdqu %%xmm0, %[outbuf]\n\t" ++ : [outbuf] "=m" (*outbuf) ++ : ++ : "memory" ); ++ ++ outbuf += BLOCKSIZE; ++ inbuf += BLOCKSIZE; ++ } ++ ++ asm volatile ("movdqu %%xmm5, %[tweak]\n\t" ++ : [tweak] "=m" (*tweak) ++ : ++ : "memory" ); ++ ++ aesni_cleanup (); ++ aesni_cleanup_2_6 (); ++} ++ ++ ++void ++_gcry_aes_aesni_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks, int encrypt) ++{ ++ if (encrypt) ++ _gcry_aes_aesni_xts_enc(ctx, tweak, outbuf, inbuf, nblocks); ++ else ++ _gcry_aes_aesni_xts_dec(ctx, tweak, outbuf, inbuf, nblocks); ++} ++ + #endif /* USE_AESNI */ +diff -up libgcrypt-1.8.5/cipher/rijndael-armv8-aarch32-ce.S.aes-perf libgcrypt-1.8.5/cipher/rijndael-armv8-aarch32-ce.S +--- libgcrypt-1.8.5/cipher/rijndael-armv8-aarch32-ce.S.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/rijndael-armv8-aarch32-ce.S 2020-04-22 18:29:41.673862172 +0200 +@@ -1517,6 +1517,317 @@ _gcry_aes_ocb_auth_armv8_ce: + .size _gcry_aes_ocb_auth_armv8_ce,.-_gcry_aes_ocb_auth_armv8_ce; + + ++ ++/* ++ * void _gcry_aes_xts_enc_armv8_ce (const void *keysched, ++ * unsigned char *outbuf, ++ * const unsigned char *inbuf, ++ * unsigned char *iv, unsigned int nrounds); ++ */ ++ ++.align 3 ++.globl _gcry_aes_xts_enc_armv8_ce ++.type _gcry_aes_xts_enc_armv8_ce,%function; ++_gcry_aes_xts_enc_armv8_ce: ++ /* input: ++ * r0: keysched ++ * r1: outbuf ++ * r2: inbuf ++ * r3: iv ++ * %st+0: nblocks => r4 ++ * %st+4: nrounds => r5 ++ */ ++ ++ vpush {q4-q7} ++ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */ ++ ldr r4, [sp, #(104+0)] ++ ldr r5, [sp, #(104+4)] ++ cmp r4, #0 ++ beq .Lxts_enc_skip ++ ++ cmp r5, #12 ++ ++ vld1.8 {q0}, [r3] /* load tweak */ ++ mov r7, #0x87; ++ ++ aes_preload_keys(r0, r6); ++ ++ beq .Lxts_enc_entry_192 ++ bhi .Lxts_enc_entry_256 ++ ++#define CTR_XTS(bits, ...) \ ++ .Lxts_enc_entry_##bits: \ ++ cmp r4, #4; \ ++ blo .Lxts_enc_loop_##bits; \ ++ \ ++ .Lxts_enc_loop4_##bits: \ ++ sub r4, r4, #4; \ ++ veor q9, q9, q9; \ ++ \ ++ vld1.8 {q1-q2}, [r2]!; /* load plaintext */ \ ++ veor q1, q1, q0; \ ++ cmp r4, #4; \ ++ vmov.u32 d18[0], r7; \ ++ vst1.8 {q0}, [r1]!; /* store tweak0 to temp */ \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ \ ++ vld1.8 {q3-q4}, [r2]!; /* load plaintext */ \ ++ veor q2, q2, q0; \ ++ vst1.8 {q0}, [r1]!; /* store tweak1 to temp */ \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ \ ++ veor q3, q3, q0; \ ++ vst1.8 {q0}, [r1]!; /* store tweak2 to temp */ \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ \ ++ veor q4, q4, q0; \ ++ vst1.8 {q0}, [r1]; /* store tweak3 to temp */ \ ++ sub r1, r1, #48; \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ \ ++ do_aes_4_##bits(e, mc, q1, q2, q3, q4, ##__VA_ARGS__); \ ++ \ ++ vld1.8 {q8-q9}, [r1]!; /* load tweak from temp */ \ ++ veor q1, q1, q8; \ ++ veor q2, q2, q9; \ ++ vld1.8 {q8-q9}, [r1]; /* load tweak from temp */ \ ++ sub r1, r1, #32; \ ++ veor q3, q3, q8; \ ++ veor q4, q4, q9; \ ++ vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \ ++ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \ ++ \ ++ bhs .Lxts_enc_loop4_##bits; \ ++ cmp r4, #0; \ ++ beq .Lxts_enc_done; \ ++ \ ++ .Lxts_enc_loop_##bits: \ ++ \ ++ vld1.8 {q1}, [r2]!; /* load ciphertext */ \ ++ \ ++ veor q9, q9, q9; \ ++ veor q1, q1, q0; \ ++ vmov.u32 d18[0], r7; \ ++ vmov q2, q0; \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ subs r4, r4, #1; \ ++ \ ++ do_aes_one##bits(e, mc, q1, q1, ##__VA_ARGS__); \ ++ \ ++ veor q1, q1, q2; \ ++ vst1.8 {q1}, [r1]!; /* store plaintext */ \ ++ \ ++ bne .Lxts_enc_loop_##bits; \ ++ b .Lxts_enc_done; ++ ++ CTR_XTS(128re, r0, r6) ++ CTR_XTS(192, r0, r6) ++ CTR_XTS(256, r0, r6) ++ ++#undef CTR_XTS ++ ++.Lxts_enc_done: ++ vst1.8 {q0}, [r3] /* store tweak */ ++ ++ CLEAR_REG(q0) ++ CLEAR_REG(q1) ++ CLEAR_REG(q2) ++ CLEAR_REG(q3) ++ CLEAR_REG(q8) ++ CLEAR_REG(q9) ++ CLEAR_REG(q10) ++ CLEAR_REG(q11) ++ CLEAR_REG(q12) ++ CLEAR_REG(q13) ++ CLEAR_REG(q14) ++ ++.Lxts_enc_skip: ++ pop {r4-r12,lr} ++ vpop {q4-q7} ++ bx lr ++.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce; ++ ++ ++/* ++ * void _gcry_aes_xts_dec_armv8_ce (const void *keysched, ++ * unsigned char *outbuf, ++ * const unsigned char *inbuf, ++ * unsigned char *iv, unsigned int nrounds); ++ */ ++ ++.align 3 ++.globl _gcry_aes_xts_dec_armv8_ce ++.type _gcry_aes_xts_dec_armv8_ce,%function; ++_gcry_aes_xts_dec_armv8_ce: ++ /* input: ++ * r0: keysched ++ * r1: outbuf ++ * r2: inbuf ++ * r3: iv ++ * %st+0: nblocks => r4 ++ * %st+4: nrounds => r5 ++ */ ++ ++ vpush {q4-q7} ++ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */ ++ ldr r4, [sp, #(104+0)] ++ ldr r5, [sp, #(104+4)] ++ cmp r4, #0 ++ beq .Lxts_dec_skip ++ ++ cmp r5, #12 ++ ++ vld1.8 {q0}, [r3] /* load tweak */ ++ mov r7, #0x87; ++ ++ aes_preload_keys(r0, r6); ++ ++ beq .Lxts_dec_entry_192 ++ bhi .Lxts_dec_entry_256 ++ ++#define CTR_XTS(bits, ...) \ ++ .Lxts_dec_entry_##bits: \ ++ cmp r4, #4; \ ++ blo .Lxts_dec_loop_##bits; \ ++ \ ++ .Lxts_dec_loop4_##bits: \ ++ sub r4, r4, #4; \ ++ veor q9, q9, q9; \ ++ \ ++ vld1.8 {q1-q2}, [r2]!; /* load plaintext */ \ ++ veor q1, q1, q0; \ ++ cmp r4, #4; \ ++ vmov.u32 d18[0], r7; \ ++ vst1.8 {q0}, [r1]!; /* store tweak0 to temp */ \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ \ ++ vld1.8 {q3-q4}, [r2]!; /* load plaintext */ \ ++ veor q2, q2, q0; \ ++ vst1.8 {q0}, [r1]!; /* store tweak1 to temp */ \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ \ ++ veor q3, q3, q0; \ ++ vst1.8 {q0}, [r1]!; /* store tweak2 to temp */ \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ \ ++ veor q4, q4, q0; \ ++ vst1.8 {q0}, [r1]; /* store tweak3 to temp */ \ ++ sub r1, r1, #48; \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ \ ++ do_aes_4_##bits(d, imc, q1, q2, q3, q4, ##__VA_ARGS__); \ ++ \ ++ vld1.8 {q8-q9}, [r1]!; /* load tweak from temp */ \ ++ veor q1, q1, q8; \ ++ veor q2, q2, q9; \ ++ vld1.8 {q8-q9}, [r1]; /* load tweak from temp */ \ ++ sub r1, r1, #32; \ ++ veor q3, q3, q8; \ ++ veor q4, q4, q9; \ ++ vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \ ++ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \ ++ \ ++ bhs .Lxts_dec_loop4_##bits; \ ++ cmp r4, #0; \ ++ beq .Lxts_dec_done; \ ++ \ ++ .Lxts_dec_loop_##bits: \ ++ \ ++ vld1.8 {q1}, [r2]!; /* load ciphertext */ \ ++ \ ++ veor q9, q9, q9; \ ++ veor q1, q1, q0; \ ++ vmov.u32 d18[0], r7; \ ++ vmov q2, q0; \ ++ \ ++ vshr.s64 d16, d1, #63; \ ++ vshr.u64 d17, d0, #63; \ ++ vadd.u64 q0, q0, q0; \ ++ vand d16, d16, d18; \ ++ veor q0, q0, q8; \ ++ subs r4, r4, #1; \ ++ \ ++ do_aes_one##bits(d, imc, q1, q1, ##__VA_ARGS__); \ ++ \ ++ veor q1, q1, q2; \ ++ vst1.8 {q1}, [r1]!; /* store plaintext */ \ ++ \ ++ bne .Lxts_dec_loop_##bits; \ ++ b .Lxts_dec_done; ++ ++ CTR_XTS(128re, r0, r6) ++ CTR_XTS(192, r0, r6) ++ CTR_XTS(256, r0, r6) ++ ++#undef CTR_XTS ++ ++.Lxts_dec_done: ++ vst1.8 {q0}, [r3] /* store tweak */ ++ ++ CLEAR_REG(q0) ++ CLEAR_REG(q1) ++ CLEAR_REG(q2) ++ CLEAR_REG(q3) ++ CLEAR_REG(q8) ++ CLEAR_REG(q9) ++ CLEAR_REG(q10) ++ CLEAR_REG(q11) ++ CLEAR_REG(q12) ++ CLEAR_REG(q13) ++ CLEAR_REG(q14) ++ ++.Lxts_dec_skip: ++ pop {r4-r12,lr} ++ vpop {q4-q7} ++ bx lr ++.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce; ++ ++ + /* + * u32 _gcry_aes_sbox4_armv8_ce(u32 in4b); + */ +diff -up libgcrypt-1.8.5/cipher/rijndael-armv8-aarch64-ce.S.aes-perf libgcrypt-1.8.5/cipher/rijndael-armv8-aarch64-ce.S +--- libgcrypt-1.8.5/cipher/rijndael-armv8-aarch64-ce.S.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/rijndael-armv8-aarch64-ce.S 2020-04-22 18:29:41.674862153 +0200 +@@ -1157,8 +1157,8 @@ _gcry_aes_ocb_auth_armv8_ce: + * w6: nrounds => w7 + * w7: blkn => w12 + */ +- mov x12, x7 +- mov x7, x6 ++ mov w12, w7 ++ mov w7, w6 + mov x6, x5 + mov x5, x4 + mov x4, x3 +@@ -1277,6 +1277,284 @@ _gcry_aes_ocb_auth_armv8_ce: + + + /* ++ * void _gcry_aes_xts_enc_armv8_ce (const void *keysched, ++ * unsigned char *outbuf, ++ * const unsigned char *inbuf, ++ * unsigned char *tweak, ++ * size_t nblocks, ++ * unsigned int nrounds); ++ */ ++ ++.align 3 ++.globl _gcry_aes_xts_enc_armv8_ce ++.type _gcry_aes_xts_enc_armv8_ce,%function; ++_gcry_aes_xts_enc_armv8_ce: ++ /* input: ++ * r0: keysched ++ * r1: outbuf ++ * r2: inbuf ++ * r3: tweak ++ * x4: nblocks ++ * w5: nrounds ++ */ ++ ++ cbz x4, .Lxts_enc_skip ++ ++ /* load tweak */ ++ ld1 {v0.16b}, [x3] ++ ++ /* load gfmul mask */ ++ mov x6, #0x87 ++ mov x7, #0x01 ++ mov v16.D[0], x6 ++ mov v16.D[1], x7 ++ ++ aes_preload_keys(x0, w5); ++ ++ b.eq .Lxts_enc_entry_192 ++ b.hi .Lxts_enc_entry_256 ++ ++#define XTS_ENC(bits) \ ++ .Lxts_enc_entry_##bits: \ ++ cmp x4, #4; \ ++ b.lo .Lxts_enc_loop_##bits; \ ++ \ ++ .Lxts_enc_loop4_##bits: \ ++ \ ++ ext v4.16b, v0.16b, v0.16b, #8; \ ++ \ ++ sshr v2.2d, v4.2d, #63; \ ++ add v5.2d, v0.2d, v0.2d; \ ++ and v2.16b, v2.16b, v16.16b; \ ++ add v4.2d, v4.2d, v4.2d; \ ++ eor v5.16b, v5.16b, v2.16b; \ ++ \ ++ sshr v2.2d, v4.2d, #63; \ ++ add v6.2d, v5.2d, v5.2d; \ ++ and v2.16b, v2.16b, v16.16b; \ ++ add v4.2d, v4.2d, v4.2d; \ ++ eor v6.16b, v6.16b, v2.16b; \ ++ \ ++ sshr v2.2d, v4.2d, #63; \ ++ add v7.2d, v6.2d, v6.2d; \ ++ and v2.16b, v2.16b, v16.16b; \ ++ add v4.2d, v4.2d, v4.2d; \ ++ eor v7.16b, v7.16b, v2.16b; \ ++ \ ++ sshr v2.2d, v4.2d, #63; \ ++ add v3.2d, v7.2d, v7.2d; \ ++ and v2.16b, v2.16b, v16.16b; \ ++ add v4.2d, v4.2d, v4.2d; \ ++ eor v3.16b, v3.16b, v2.16b; \ ++ ld1 {v1.16b-v2.16b}, [x2], #32; /* load plaintext */ \ ++ st1 {v3.16b}, [x3]; \ ++ sub x4, x4, #4; \ ++ eor v1.16b, v1.16b, v0.16b; \ ++ \ ++ ld1 {v3.16b-v4.16b}, [x2], #32; /* load plaintext */ \ ++ cmp x4, #4; \ ++ eor v2.16b, v2.16b, v5.16b; \ ++ eor v3.16b, v3.16b, v6.16b; \ ++ eor v4.16b, v4.16b, v7.16b; \ ++ \ ++ do_aes_4_##bits(e, mc, v1, v2, v3, v4); \ ++ \ ++ eor v1.16b, v1.16b, v0.16b; \ ++ ld1 {v0.16b}, [x3]; \ ++ eor v2.16b, v2.16b, v5.16b; \ ++ eor v3.16b, v3.16b, v6.16b; \ ++ eor v4.16b, v4.16b, v7.16b; \ ++ st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \ ++ \ ++ b.hs .Lxts_enc_loop4_##bits; \ ++ CLEAR_REG(v3); \ ++ CLEAR_REG(v4); \ ++ CLEAR_REG(v5); \ ++ CLEAR_REG(v6); \ ++ CLEAR_REG(v7); \ ++ cbz x4, .Lxts_enc_done; \ ++ \ ++ .Lxts_enc_loop_##bits: \ ++ \ ++ ld1 {v1.16b}, [x2], #16; /* load plaintext */ \ ++ ext v3.16b, v0.16b, v0.16b, #8; \ ++ mov v2.16b, v0.16b; \ ++ sshr v3.2d, v3.2d, #63; \ ++ add v0.2d, v0.2d, v0.2d; \ ++ and v3.16b, v3.16b, v16.16b; \ ++ eor v1.16b, v1.16b, v2.16b; \ ++ eor v0.16b, v0.16b, v3.16b; \ ++ sub x4, x4, #1; \ ++ \ ++ do_aes_one##bits(e, mc, v1, v1); \ ++ \ ++ eor v1.16b, v1.16b, v2.16b; \ ++ st1 {v1.16b}, [x1], #16; /* store ciphertext */ \ ++ \ ++ cbnz x4, .Lxts_enc_loop_##bits; \ ++ b .Lxts_enc_done; ++ ++ XTS_ENC(128) ++ XTS_ENC(192) ++ XTS_ENC(256) ++ ++#undef XTS_ENC ++ ++.Lxts_enc_done: ++ aes_clear_keys(w5) ++ ++ st1 {v0.16b}, [x3] /* store tweak */ ++ ++ CLEAR_REG(v0) ++ CLEAR_REG(v1) ++ CLEAR_REG(v2) ++ ++.Lxts_enc_skip: ++ ret ++ ++.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce; ++ ++ ++/* ++ * void _gcry_aes_xts_dec_armv8_ce (const void *keysched, ++ * unsigned char *outbuf, ++ * const unsigned char *inbuf, ++ * unsigned char *tweak, ++ * size_t nblocks, ++ * unsigned int nrounds); ++ */ ++ ++.align 3 ++.globl _gcry_aes_xts_dec_armv8_ce ++.type _gcry_aes_xts_dec_armv8_ce,%function; ++_gcry_aes_xts_dec_armv8_ce: ++ /* input: ++ * r0: keysched ++ * r1: outbuf ++ * r2: inbuf ++ * r3: tweak ++ * x4: nblocks ++ * w5: nrounds ++ */ ++ ++ cbz x4, .Lxts_dec_skip ++ ++ /* load tweak */ ++ ld1 {v0.16b}, [x3] ++ ++ /* load gfmul mask */ ++ mov x6, #0x87 ++ mov x7, #0x01 ++ mov v16.D[0], x6 ++ mov v16.D[1], x7 ++ ++ aes_preload_keys(x0, w5); ++ ++ b.eq .Lxts_dec_entry_192 ++ b.hi .Lxts_dec_entry_256 ++ ++#define XTS_DEC(bits) \ ++ .Lxts_dec_entry_##bits: \ ++ cmp x4, #4; \ ++ b.lo .Lxts_dec_loop_##bits; \ ++ \ ++ .Lxts_dec_loop4_##bits: \ ++ \ ++ ext v4.16b, v0.16b, v0.16b, #8; \ ++ \ ++ sshr v2.2d, v4.2d, #63; \ ++ add v5.2d, v0.2d, v0.2d; \ ++ and v2.16b, v2.16b, v16.16b; \ ++ add v4.2d, v4.2d, v4.2d; \ ++ eor v5.16b, v5.16b, v2.16b; \ ++ \ ++ sshr v2.2d, v4.2d, #63; \ ++ add v6.2d, v5.2d, v5.2d; \ ++ and v2.16b, v2.16b, v16.16b; \ ++ add v4.2d, v4.2d, v4.2d; \ ++ eor v6.16b, v6.16b, v2.16b; \ ++ \ ++ sshr v2.2d, v4.2d, #63; \ ++ add v7.2d, v6.2d, v6.2d; \ ++ and v2.16b, v2.16b, v16.16b; \ ++ add v4.2d, v4.2d, v4.2d; \ ++ eor v7.16b, v7.16b, v2.16b; \ ++ \ ++ sshr v2.2d, v4.2d, #63; \ ++ add v3.2d, v7.2d, v7.2d; \ ++ and v2.16b, v2.16b, v16.16b; \ ++ add v4.2d, v4.2d, v4.2d; \ ++ eor v3.16b, v3.16b, v2.16b; \ ++ ld1 {v1.16b-v2.16b}, [x2], #32; /* load plaintext */ \ ++ st1 {v3.16b}, [x3]; \ ++ sub x4, x4, #4; \ ++ eor v1.16b, v1.16b, v0.16b; \ ++ \ ++ ld1 {v3.16b-v4.16b}, [x2], #32; /* load plaintext */ \ ++ cmp x4, #4; \ ++ eor v2.16b, v2.16b, v5.16b; \ ++ eor v3.16b, v3.16b, v6.16b; \ ++ eor v4.16b, v4.16b, v7.16b; \ ++ \ ++ do_aes_4_##bits(d, imc, v1, v2, v3, v4); \ ++ \ ++ eor v1.16b, v1.16b, v0.16b; \ ++ ld1 {v0.16b}, [x3]; \ ++ eor v2.16b, v2.16b, v5.16b; \ ++ eor v3.16b, v3.16b, v6.16b; \ ++ eor v4.16b, v4.16b, v7.16b; \ ++ st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \ ++ \ ++ b.hs .Lxts_dec_loop4_##bits; \ ++ CLEAR_REG(v3); \ ++ CLEAR_REG(v4); \ ++ CLEAR_REG(v5); \ ++ CLEAR_REG(v6); \ ++ CLEAR_REG(v7); \ ++ cbz x4, .Lxts_dec_done; \ ++ \ ++ .Lxts_dec_loop_##bits: \ ++ \ ++ ld1 {v1.16b}, [x2], #16; /* load plaintext */ \ ++ ext v3.16b, v0.16b, v0.16b, #8; \ ++ mov v2.16b, v0.16b; \ ++ sshr v3.2d, v3.2d, #63; \ ++ add v0.2d, v0.2d, v0.2d; \ ++ and v3.16b, v3.16b, v16.16b; \ ++ eor v1.16b, v1.16b, v2.16b; \ ++ eor v0.16b, v0.16b, v3.16b; \ ++ sub x4, x4, #1; \ ++ \ ++ do_aes_one##bits(d, imc, v1, v1); \ ++ \ ++ eor v1.16b, v1.16b, v2.16b; \ ++ st1 {v1.16b}, [x1], #16; /* store ciphertext */ \ ++ \ ++ cbnz x4, .Lxts_dec_loop_##bits; \ ++ b .Lxts_dec_done; ++ ++ XTS_DEC(128) ++ XTS_DEC(192) ++ XTS_DEC(256) ++ ++#undef XTS_DEC ++ ++.Lxts_dec_done: ++ aes_clear_keys(w5) ++ ++ st1 {v0.16b}, [x3] /* store tweak */ ++ ++ CLEAR_REG(v0) ++ CLEAR_REG(v1) ++ CLEAR_REG(v2) ++ ++.Lxts_dec_skip: ++ ret ++ ++.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce; ++ ++ ++/* + * u32 _gcry_aes_sbox4_armv8_ce(u32 in4b); + */ + .align 3 +diff -up libgcrypt-1.8.5/cipher/rijndael-armv8-ce.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-armv8-ce.c +--- libgcrypt-1.8.5/cipher/rijndael-armv8-ce.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/rijndael-armv8-ce.c 2020-04-22 18:29:41.675862134 +0200 +@@ -101,6 +101,16 @@ extern void _gcry_aes_ocb_auth_armv8_ce + size_t nblocks, + unsigned int nrounds, + unsigned int blkn); ++extern void _gcry_aes_xts_enc_armv8_ce (const void *keysched, ++ unsigned char *outbuf, ++ const unsigned char *inbuf, ++ unsigned char *tweak, ++ size_t nblocks, unsigned int nrounds); ++extern void _gcry_aes_xts_dec_armv8_ce (const void *keysched, ++ unsigned char *outbuf, ++ const unsigned char *inbuf, ++ unsigned char *tweak, ++ size_t nblocks, unsigned int nrounds); + + typedef void (*ocb_crypt_fn_t) (const void *keysched, unsigned char *outbuf, + const unsigned char *inbuf, +@@ -108,6 +118,11 @@ typedef void (*ocb_crypt_fn_t) (const vo + unsigned char *L_table, size_t nblocks, + unsigned int nrounds, unsigned int blkn); + ++typedef void (*xts_crypt_fn_t) (const void *keysched, unsigned char *outbuf, ++ const unsigned char *inbuf, ++ unsigned char *tweak, size_t nblocks, ++ unsigned int nrounds); ++ + void + _gcry_aes_armv8_ce_setkey (RIJNDAEL_context *ctx, const byte *key) + { +@@ -269,8 +284,8 @@ _gcry_aes_armv8_ce_decrypt (const RIJNDA + } + + void +-_gcry_aes_armv8_ce_cbc_enc (const RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, ++_gcry_aes_armv8_ce_cbc_enc (const RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks, int cbc_mac) + { + const void *keysched = ctx->keyschenc32; +@@ -281,19 +296,25 @@ _gcry_aes_armv8_ce_cbc_enc (const RIJNDA + } + + void +-_gcry_aes_armv8_ce_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, ++_gcry_aes_armv8_ce_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) + { + const void *keysched = ctx->keyschdec32; + unsigned int nrounds = ctx->rounds; + ++ if ( !ctx->decryption_prepared ) ++ { ++ _gcry_aes_armv8_ce_prepare_decryption ( ctx ); ++ ctx->decryption_prepared = 1; ++ } ++ + _gcry_aes_cbc_dec_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); + } + + void +-_gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, ++_gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) + { + const void *keysched = ctx->keyschenc32; +@@ -303,8 +324,8 @@ _gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_con + } + + void +-_gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, ++_gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) + { + const void *keysched = ctx->keyschenc32; +@@ -314,8 +335,8 @@ _gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_con + } + + void +-_gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, ++_gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, + size_t nblocks) + { + const void *keysched = ctx->keyschenc32; +@@ -324,7 +345,7 @@ _gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_con + _gcry_aes_ctr_enc_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); + } + +-void ++size_t + _gcry_aes_armv8_ce_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, + const void *inbuf_arg, size_t nblocks, + int encrypt) +@@ -338,13 +359,21 @@ _gcry_aes_armv8_ce_ocb_crypt (gcry_ciphe + unsigned int nrounds = ctx->rounds; + u64 blkn = c->u_mode.ocb.data_nblocks; + ++ if ( !encrypt && !ctx->decryption_prepared ) ++ { ++ _gcry_aes_armv8_ce_prepare_decryption ( ctx ); ++ ctx->decryption_prepared = 1; ++ } ++ + c->u_mode.ocb.data_nblocks = blkn + nblocks; + + crypt_fn(keysched, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, + c->u_mode.ocb.L[0], nblocks, nrounds, (unsigned int)blkn); ++ ++ return 0; + } + +-void ++size_t + _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, void *abuf_arg, + size_t nblocks) + { +@@ -359,6 +388,27 @@ _gcry_aes_armv8_ce_ocb_auth (gcry_cipher + _gcry_aes_ocb_auth_armv8_ce(keysched, abuf, c->u_mode.ocb.aad_offset, + c->u_mode.ocb.aad_sum, c->u_mode.ocb.L[0], + nblocks, nrounds, (unsigned int)blkn); ++ ++ return 0; ++} ++ ++void ++_gcry_aes_armv8_ce_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks, int encrypt) ++{ ++ const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; ++ xts_crypt_fn_t crypt_fn = encrypt ? _gcry_aes_xts_enc_armv8_ce ++ : _gcry_aes_xts_dec_armv8_ce; ++ unsigned int nrounds = ctx->rounds; ++ ++ if ( !encrypt && !ctx->decryption_prepared ) ++ { ++ _gcry_aes_armv8_ce_prepare_decryption ( ctx ); ++ ctx->decryption_prepared = 1; ++ } ++ ++ crypt_fn(keysched, outbuf, inbuf, tweak, nblocks, nrounds); + } + + #endif /* USE_ARM_CE */ +diff -up libgcrypt-1.8.5/cipher/rijndael.c.aes-perf libgcrypt-1.8.5/cipher/rijndael.c +--- libgcrypt-1.8.5/cipher/rijndael.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/rijndael.c 2020-04-22 18:29:41.676862114 +0200 +@@ -77,32 +77,29 @@ extern unsigned int _gcry_aes_aesni_encr + extern unsigned int _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, + unsigned char *dst, + const unsigned char *src); +-extern void _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks, +- int cbc_mac); +-extern void _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *ctr, size_t nblocks); +-extern void _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, +- const void *inbuf_arg, size_t nblocks, +- int encrypt); +-extern void _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, +- size_t nblocks); ++extern void _gcry_aes_aesni_cfb_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_aesni_cbc_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, int cbc_mac); ++extern void _gcry_aes_aesni_ctr_enc (void *context, unsigned char *ctr, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_aesni_cfb_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_aesni_cbc_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern size_t _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, ++ const void *inbuf_arg, size_t nblocks, ++ int encrypt); ++extern size_t _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_aesni_xts_crypt (void *context, unsigned char *tweak, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, int encrypt); + #endif + + #ifdef USE_SSSE3 +@@ -116,32 +113,27 @@ extern unsigned int _gcry_aes_ssse3_encr + extern unsigned int _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, + unsigned char *dst, + const unsigned char *src); +-extern void _gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks, ++extern void _gcry_aes_ssse3_cfb_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ssse3_cbc_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, + int cbc_mac); +-extern void _gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *ctr, size_t nblocks); +-extern void _gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_ssse3_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, +- const void *inbuf_arg, size_t nblocks, +- int encrypt); +-extern void _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, +- size_t nblocks); ++extern void _gcry_aes_ssse3_ctr_enc (void *context, unsigned char *ctr, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ssse3_cfb_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ssse3_cbc_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern size_t _gcry_aes_ssse3_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, ++ const void *inbuf_arg, size_t nblocks, ++ int encrypt); ++extern size_t _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, ++ size_t nblocks); + #endif + + #ifdef USE_PADLOCK +@@ -180,34 +172,110 @@ extern unsigned int _gcry_aes_armv8_ce_d + unsigned char *dst, + const unsigned char *src); + +-extern void _gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_armv8_ce_cbc_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks, ++extern void _gcry_aes_armv8_ce_cfb_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_armv8_ce_cbc_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, + int cbc_mac); +-extern void _gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *ctr, size_t nblocks); +-extern void _gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_armv8_ce_cbc_dec (RIJNDAEL_context *ctx, +- unsigned char *outbuf, +- const unsigned char *inbuf, +- unsigned char *iv, size_t nblocks); +-extern void _gcry_aes_armv8_ce_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, +- const void *inbuf_arg, size_t nblocks, +- int encrypt); +-extern void _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, +- const void *abuf_arg, size_t nblocks); ++extern void _gcry_aes_armv8_ce_ctr_enc (void *context, unsigned char *ctr, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_armv8_ce_cfb_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_armv8_ce_cbc_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern size_t _gcry_aes_armv8_ce_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, ++ const void *inbuf_arg, size_t nblocks, ++ int encrypt); ++extern size_t _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, ++ const void *abuf_arg, size_t nblocks); ++extern void _gcry_aes_armv8_ce_xts_crypt (void *context, unsigned char *tweak, ++ void *outbuf_arg, ++ const void *inbuf_arg, ++ size_t nblocks, int encrypt); + #endif /*USE_ARM_ASM*/ + ++#ifdef USE_PPC_CRYPTO ++/* PowerPC Crypto implementations of AES */ ++extern void _gcry_aes_ppc8_setkey(RIJNDAEL_context *ctx, const byte *key); ++extern void _gcry_aes_ppc8_prepare_decryption(RIJNDAEL_context *ctx); ++ ++extern unsigned int _gcry_aes_ppc8_encrypt(const RIJNDAEL_context *ctx, ++ unsigned char *dst, ++ const unsigned char *src); ++extern unsigned int _gcry_aes_ppc8_decrypt(const RIJNDAEL_context *ctx, ++ unsigned char *dst, ++ const unsigned char *src); ++ ++extern void _gcry_aes_ppc8_cfb_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ppc8_cbc_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, int cbc_mac); ++extern void _gcry_aes_ppc8_ctr_enc (void *context, unsigned char *ctr, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ppc8_cfb_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ppc8_cbc_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++ ++extern size_t _gcry_aes_ppc8_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, ++ const void *inbuf_arg, size_t nblocks, ++ int encrypt); ++extern size_t _gcry_aes_ppc8_ocb_auth (gcry_cipher_hd_t c, ++ const void *abuf_arg, size_t nblocks); ++ ++extern void _gcry_aes_ppc8_xts_crypt (void *context, unsigned char *tweak, ++ void *outbuf_arg, ++ const void *inbuf_arg, ++ size_t nblocks, int encrypt); ++#endif /*USE_PPC_CRYPTO*/ ++ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++/* Power9 little-endian crypto implementations of AES */ ++extern unsigned int _gcry_aes_ppc9le_encrypt(const RIJNDAEL_context *ctx, ++ unsigned char *dst, ++ const unsigned char *src); ++extern unsigned int _gcry_aes_ppc9le_decrypt(const RIJNDAEL_context *ctx, ++ unsigned char *dst, ++ const unsigned char *src); ++ ++extern void _gcry_aes_ppc9le_cfb_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ppc9le_cbc_enc (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, int cbc_mac); ++extern void _gcry_aes_ppc9le_ctr_enc (void *context, unsigned char *ctr, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ppc9le_cfb_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++extern void _gcry_aes_ppc9le_cbc_dec (void *context, unsigned char *iv, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks); ++ ++extern size_t _gcry_aes_ppc9le_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, ++ const void *inbuf_arg, size_t nblocks, ++ int encrypt); ++extern size_t _gcry_aes_ppc9le_ocb_auth (gcry_cipher_hd_t c, ++ const void *abuf_arg, size_t nblocks); ++ ++extern void _gcry_aes_ppc9le_xts_crypt (void *context, unsigned char *tweak, ++ void *outbuf_arg, ++ const void *inbuf_arg, ++ size_t nblocks, int encrypt); ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++ + static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, + const unsigned char *ax); + static unsigned int do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, +@@ -260,7 +328,8 @@ static void prefetch_dec(void) + + /* Perform the key setup. */ + static gcry_err_code_t +-do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) ++do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen, ++ gcry_cipher_hd_t hd) + { + static int initialized = 0; + static const char *selftest_failed = 0; +@@ -268,7 +337,7 @@ do_setkey (RIJNDAEL_context *ctx, const + int i,j, r, t, rconpointer = 0; + int KC; + #if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3) \ +- || defined(USE_ARM_CE) ++ || defined(USE_ARM_CE) || defined(USE_PPC_CRYPTO) + unsigned int hwfeatures; + #endif + +@@ -310,7 +379,7 @@ do_setkey (RIJNDAEL_context *ctx, const + ctx->rounds = rounds; + + #if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3) \ +- || defined(USE_ARM_CE) ++ || defined(USE_ARM_CE) || defined(USE_PPC_CRYPTO) + hwfeatures = _gcry_get_hw_features (); + #endif + +@@ -327,6 +396,12 @@ do_setkey (RIJNDAEL_context *ctx, const + #ifdef USE_ARM_CE + ctx->use_arm_ce = 0; + #endif ++#ifdef USE_PPC_CRYPTO ++ ctx->use_ppc_crypto = 0; ++#endif ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ ctx->use_ppc9le_crypto = 0; ++#endif + + if (0) + { +@@ -340,6 +415,17 @@ do_setkey (RIJNDAEL_context *ctx, const + ctx->prefetch_enc_fn = NULL; + ctx->prefetch_dec_fn = NULL; + ctx->use_aesni = 1; ++ if (hd) ++ { ++ hd->bulk.cfb_enc = _gcry_aes_aesni_cfb_enc; ++ hd->bulk.cfb_dec = _gcry_aes_aesni_cfb_dec; ++ hd->bulk.cbc_enc = _gcry_aes_aesni_cbc_enc; ++ hd->bulk.cbc_dec = _gcry_aes_aesni_cbc_dec; ++ hd->bulk.ctr_enc = _gcry_aes_aesni_ctr_enc; ++ hd->bulk.ocb_crypt = _gcry_aes_aesni_ocb_crypt; ++ hd->bulk.ocb_auth = _gcry_aes_aesni_ocb_auth; ++ hd->bulk.xts_crypt = _gcry_aes_aesni_xts_crypt; ++ } + } + #endif + #ifdef USE_PADLOCK +@@ -361,6 +447,16 @@ do_setkey (RIJNDAEL_context *ctx, const + ctx->prefetch_enc_fn = NULL; + ctx->prefetch_dec_fn = NULL; + ctx->use_ssse3 = 1; ++ if (hd) ++ { ++ hd->bulk.cfb_enc = _gcry_aes_ssse3_cfb_enc; ++ hd->bulk.cfb_dec = _gcry_aes_ssse3_cfb_dec; ++ hd->bulk.cbc_enc = _gcry_aes_ssse3_cbc_enc; ++ hd->bulk.cbc_dec = _gcry_aes_ssse3_cbc_dec; ++ hd->bulk.ctr_enc = _gcry_aes_ssse3_ctr_enc; ++ hd->bulk.ocb_crypt = _gcry_aes_ssse3_ocb_crypt; ++ hd->bulk.ocb_auth = _gcry_aes_ssse3_ocb_auth; ++ } + } + #endif + #ifdef USE_ARM_CE +@@ -371,6 +467,60 @@ do_setkey (RIJNDAEL_context *ctx, const + ctx->prefetch_enc_fn = NULL; + ctx->prefetch_dec_fn = NULL; + ctx->use_arm_ce = 1; ++ if (hd) ++ { ++ hd->bulk.cfb_enc = _gcry_aes_armv8_ce_cfb_enc; ++ hd->bulk.cfb_dec = _gcry_aes_armv8_ce_cfb_dec; ++ hd->bulk.cbc_enc = _gcry_aes_armv8_ce_cbc_enc; ++ hd->bulk.cbc_dec = _gcry_aes_armv8_ce_cbc_dec; ++ hd->bulk.ctr_enc = _gcry_aes_armv8_ce_ctr_enc; ++ hd->bulk.ocb_crypt = _gcry_aes_armv8_ce_ocb_crypt; ++ hd->bulk.ocb_auth = _gcry_aes_armv8_ce_ocb_auth; ++ hd->bulk.xts_crypt = _gcry_aes_armv8_ce_xts_crypt; ++ } ++ } ++#endif ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if ((hwfeatures & HWF_PPC_VCRYPTO) && (hwfeatures & HWF_PPC_ARCH_3_00)) ++ { ++ ctx->encrypt_fn = _gcry_aes_ppc9le_encrypt; ++ ctx->decrypt_fn = _gcry_aes_ppc9le_decrypt; ++ ctx->prefetch_enc_fn = NULL; ++ ctx->prefetch_dec_fn = NULL; ++ ctx->use_ppc_crypto = 1; /* same key-setup as USE_PPC_CRYPTO */ ++ ctx->use_ppc9le_crypto = 1; ++ if (hd) ++ { ++ hd->bulk.cfb_enc = _gcry_aes_ppc9le_cfb_enc; ++ hd->bulk.cfb_dec = _gcry_aes_ppc9le_cfb_dec; ++ hd->bulk.cbc_enc = _gcry_aes_ppc9le_cbc_enc; ++ hd->bulk.cbc_dec = _gcry_aes_ppc9le_cbc_dec; ++ hd->bulk.ctr_enc = _gcry_aes_ppc9le_ctr_enc; ++ hd->bulk.ocb_crypt = _gcry_aes_ppc9le_ocb_crypt; ++ hd->bulk.ocb_auth = _gcry_aes_ppc9le_ocb_auth; ++ hd->bulk.xts_crypt = _gcry_aes_ppc9le_xts_crypt; ++ } ++ } ++#endif ++#ifdef USE_PPC_CRYPTO ++ else if (hwfeatures & HWF_PPC_VCRYPTO) ++ { ++ ctx->encrypt_fn = _gcry_aes_ppc8_encrypt; ++ ctx->decrypt_fn = _gcry_aes_ppc8_decrypt; ++ ctx->prefetch_enc_fn = NULL; ++ ctx->prefetch_dec_fn = NULL; ++ ctx->use_ppc_crypto = 1; ++ if (hd) ++ { ++ hd->bulk.cfb_enc = _gcry_aes_ppc8_cfb_enc; ++ hd->bulk.cfb_dec = _gcry_aes_ppc8_cfb_dec; ++ hd->bulk.cbc_enc = _gcry_aes_ppc8_cbc_enc; ++ hd->bulk.cbc_dec = _gcry_aes_ppc8_cbc_dec; ++ hd->bulk.ctr_enc = _gcry_aes_ppc8_ctr_enc; ++ hd->bulk.ocb_crypt = _gcry_aes_ppc8_ocb_crypt; ++ hd->bulk.ocb_auth = _gcry_aes_ppc8_ocb_auth; ++ hd->bulk.xts_crypt = _gcry_aes_ppc8_xts_crypt; ++ } + } + #endif + else +@@ -399,6 +549,10 @@ do_setkey (RIJNDAEL_context *ctx, const + else if (ctx->use_arm_ce) + _gcry_aes_armv8_ce_setkey (ctx, key); + #endif ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ _gcry_aes_ppc8_setkey (ctx, key); ++#endif + else + { + const byte *sbox = ((const byte *)encT) + 1; +@@ -503,10 +657,11 @@ do_setkey (RIJNDAEL_context *ctx, const + + + static gcry_err_code_t +-rijndael_setkey (void *context, const byte *key, const unsigned keylen) ++rijndael_setkey (void *context, const byte *key, const unsigned keylen, ++ gcry_cipher_hd_t hd) + { + RIJNDAEL_context *ctx = context; +- return do_setkey (ctx, key, keylen); ++ return do_setkey (ctx, key, keylen, hd); + } + + +@@ -535,7 +690,19 @@ prepare_decryption( RIJNDAEL_context *ct + { + _gcry_aes_armv8_ce_prepare_decryption (ctx); + } +-#endif /*USE_SSSE3*/ ++#endif /*USE_ARM_CE*/ ++#ifdef USE_ARM_CE ++ else if (ctx->use_arm_ce) ++ { ++ _gcry_aes_armv8_ce_prepare_decryption (ctx); ++ } ++#endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ _gcry_aes_ppc8_prepare_decryption (ctx); ++ } ++#endif + #ifdef USE_PADLOCK + else if (ctx->use_padlock) + { +@@ -790,42 +957,56 @@ _gcry_aes_cfb_enc (void *context, unsign + const unsigned char *inbuf = inbuf_arg; + unsigned int burn_depth = 0; + +- if (ctx->prefetch_enc_fn) +- ctx->prefetch_enc_fn(); +- + if (0) + ; + #ifdef USE_AESNI + else if (ctx->use_aesni) + { +- _gcry_aes_aesni_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_aesni_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_AESNI*/ + #ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { +- _gcry_aes_ssse3_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_ssse3_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_SSSE3*/ + #ifdef USE_ARM_CE + else if (ctx->use_arm_ce) + { +- _gcry_aes_armv8_ce_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_armv8_ce_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if (ctx->use_ppc9le_crypto) ++ { ++ _gcry_aes_ppc9le_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ _gcry_aes_ppc8_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO*/ + else + { + rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; + ++ if (ctx->prefetch_enc_fn) ++ ctx->prefetch_enc_fn(); ++ + for ( ;nblocks; nblocks-- ) + { + /* Encrypt the IV. */ + burn_depth = encrypt_fn (ctx, iv, iv); + /* XOR the input with the IV and store input into IV. */ +- buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); ++ cipher_block_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } +@@ -851,41 +1032,55 @@ _gcry_aes_cbc_enc (void *context, unsign + unsigned char *last_iv; + unsigned int burn_depth = 0; + +- if (ctx->prefetch_enc_fn) +- ctx->prefetch_enc_fn(); +- + if (0) + ; + #ifdef USE_AESNI + else if (ctx->use_aesni) + { +- _gcry_aes_aesni_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac); +- burn_depth = 0; ++ _gcry_aes_aesni_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); ++ return; + } + #endif /*USE_AESNI*/ + #ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { +- _gcry_aes_ssse3_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac); +- burn_depth = 0; ++ _gcry_aes_ssse3_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); ++ return; + } + #endif /*USE_SSSE3*/ + #ifdef USE_ARM_CE + else if (ctx->use_arm_ce) + { +- _gcry_aes_armv8_ce_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac); +- burn_depth = 0; ++ _gcry_aes_armv8_ce_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); ++ return; + } + #endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if (ctx->use_ppc9le_crypto) ++ { ++ _gcry_aes_ppc9le_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ _gcry_aes_ppc8_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO*/ + else + { + rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; + ++ if (ctx->prefetch_enc_fn) ++ ctx->prefetch_enc_fn(); ++ + last_iv = iv; + + for ( ;nblocks; nblocks-- ) + { +- buf_xor(outbuf, inbuf, last_iv, BLOCKSIZE); ++ cipher_block_xor(outbuf, inbuf, last_iv, BLOCKSIZE); + + burn_depth = encrypt_fn (ctx, outbuf, outbuf); + +@@ -896,7 +1091,7 @@ _gcry_aes_cbc_enc (void *context, unsign + } + + if (last_iv != iv) +- buf_cpy (iv, last_iv, BLOCKSIZE); ++ cipher_block_cpy (iv, last_iv, BLOCKSIZE); + } + + if (burn_depth) +@@ -920,43 +1115,57 @@ _gcry_aes_ctr_enc (void *context, unsign + unsigned int burn_depth = 0; + int i; + +- if (ctx->prefetch_enc_fn) +- ctx->prefetch_enc_fn(); +- + if (0) + ; + #ifdef USE_AESNI + else if (ctx->use_aesni) + { +- _gcry_aes_aesni_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks); +- burn_depth = 0; ++ _gcry_aes_aesni_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_AESNI*/ + #ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { +- _gcry_aes_ssse3_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks); +- burn_depth = 0; ++ _gcry_aes_ssse3_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_SSSE3*/ + #ifdef USE_ARM_CE + else if (ctx->use_arm_ce) + { +- _gcry_aes_armv8_ce_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks); +- burn_depth = 0; ++ _gcry_aes_armv8_ce_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if (ctx->use_ppc9le_crypto) ++ { ++ _gcry_aes_ppc9le_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ _gcry_aes_ppc8_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO*/ + else + { + union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } tmp; + rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; + ++ if (ctx->prefetch_enc_fn) ++ ctx->prefetch_enc_fn(); ++ + for ( ;nblocks; nblocks-- ) + { + /* Encrypt the counter. */ + burn_depth = encrypt_fn (ctx, tmp.x1, ctr); + /* XOR the input with the encrypted counter and store in output. */ +- buf_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE); ++ cipher_block_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + /* Increment the counter. */ +@@ -1187,40 +1396,54 @@ _gcry_aes_cfb_dec (void *context, unsign + const unsigned char *inbuf = inbuf_arg; + unsigned int burn_depth = 0; + +- if (ctx->prefetch_enc_fn) +- ctx->prefetch_enc_fn(); +- + if (0) + ; + #ifdef USE_AESNI + else if (ctx->use_aesni) + { +- _gcry_aes_aesni_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_aesni_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_AESNI*/ + #ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { +- _gcry_aes_ssse3_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_ssse3_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_SSSE3*/ + #ifdef USE_ARM_CE + else if (ctx->use_arm_ce) + { +- _gcry_aes_armv8_ce_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_armv8_ce_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if (ctx->use_ppc9le_crypto) ++ { ++ _gcry_aes_ppc9le_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ _gcry_aes_ppc8_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO*/ + else + { + rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; + ++ if (ctx->prefetch_enc_fn) ++ ctx->prefetch_enc_fn(); ++ + for ( ;nblocks; nblocks-- ) + { + burn_depth = encrypt_fn (ctx, iv, iv); +- buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); ++ cipher_block_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); + outbuf += BLOCKSIZE; + inbuf += BLOCKSIZE; + } +@@ -1245,39 +1468,53 @@ _gcry_aes_cbc_dec (void *context, unsign + const unsigned char *inbuf = inbuf_arg; + unsigned int burn_depth = 0; + +- check_decryption_preparation (ctx); +- +- if (ctx->prefetch_dec_fn) +- ctx->prefetch_dec_fn(); +- + if (0) + ; + #ifdef USE_AESNI + else if (ctx->use_aesni) + { +- _gcry_aes_aesni_cbc_dec (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_aesni_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_AESNI*/ + #ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { +- _gcry_aes_ssse3_cbc_dec (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_ssse3_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_SSSE3*/ + #ifdef USE_ARM_CE + else if (ctx->use_arm_ce) + { +- _gcry_aes_armv8_ce_cbc_dec (ctx, outbuf, inbuf, iv, nblocks); +- burn_depth = 0; ++ _gcry_aes_armv8_ce_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; + } + #endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if (ctx->use_ppc9le_crypto) ++ { ++ _gcry_aes_ppc9le_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ _gcry_aes_ppc8_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO*/ + else + { + unsigned char savebuf[BLOCKSIZE] ATTR_ALIGNED_16; + rijndael_cryptfn_t decrypt_fn = ctx->decrypt_fn; + ++ check_decryption_preparation (ctx); ++ ++ if (ctx->prefetch_dec_fn) ++ ctx->prefetch_dec_fn(); ++ + for ( ;nblocks; nblocks-- ) + { + /* INBUF is needed later and it may be identical to OUTBUF, so store +@@ -1285,7 +1522,7 @@ _gcry_aes_cbc_dec (void *context, unsign + + burn_depth = decrypt_fn (ctx, savebuf, inbuf); + +- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE); ++ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE); + inbuf += BLOCKSIZE; + outbuf += BLOCKSIZE; + } +@@ -1309,62 +1546,61 @@ _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, + const unsigned char *inbuf = inbuf_arg; + unsigned int burn_depth = 0; + +- if (encrypt) +- { +- if (ctx->prefetch_enc_fn) +- ctx->prefetch_enc_fn(); +- } +- else +- { +- check_decryption_preparation (ctx); +- +- if (ctx->prefetch_dec_fn) +- ctx->prefetch_dec_fn(); +- } +- + if (0) + ; + #ifdef USE_AESNI + else if (ctx->use_aesni) + { +- _gcry_aes_aesni_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); +- burn_depth = 0; ++ return _gcry_aes_aesni_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); + } + #endif /*USE_AESNI*/ + #ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { +- _gcry_aes_ssse3_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); +- burn_depth = 0; ++ return _gcry_aes_ssse3_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); + } + #endif /*USE_SSSE3*/ + #ifdef USE_ARM_CE + else if (ctx->use_arm_ce) + { +- _gcry_aes_armv8_ce_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); +- burn_depth = 0; ++ return _gcry_aes_armv8_ce_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); + } + #endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if (ctx->use_ppc9le_crypto) ++ { ++ return _gcry_aes_ppc9le_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); ++ } ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ return _gcry_aes_ppc8_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); ++ } ++#endif /*USE_PPC_CRYPTO*/ + else if (encrypt) + { + union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; + rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; + ++ if (ctx->prefetch_enc_fn) ++ ctx->prefetch_enc_fn(); ++ + for ( ;nblocks; nblocks-- ) + { + u64 i = ++c->u_mode.ocb.data_nblocks; + const unsigned char *l = ocb_get_l(c, i); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ +- buf_xor_1 (c->u_iv.iv, l, BLOCKSIZE); +- buf_cpy (l_tmp.x1, inbuf, BLOCKSIZE); ++ cipher_block_xor_1 (c->u_iv.iv, l, BLOCKSIZE); ++ cipher_block_cpy (l_tmp.x1, inbuf, BLOCKSIZE); + /* Checksum_i = Checksum_{i-1} xor P_i */ +- buf_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); ++ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); + /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ +- buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); ++ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); + burn_depth = encrypt_fn (ctx, l_tmp.x1, l_tmp.x1); +- buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); +- buf_cpy (outbuf, l_tmp.x1, BLOCKSIZE); ++ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); ++ cipher_block_cpy (outbuf, l_tmp.x1, BLOCKSIZE); + + inbuf += BLOCKSIZE; + outbuf += BLOCKSIZE; +@@ -1375,21 +1611,26 @@ _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, + union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; + rijndael_cryptfn_t decrypt_fn = ctx->decrypt_fn; + ++ check_decryption_preparation (ctx); ++ ++ if (ctx->prefetch_dec_fn) ++ ctx->prefetch_dec_fn(); ++ + for ( ;nblocks; nblocks-- ) + { + u64 i = ++c->u_mode.ocb.data_nblocks; + const unsigned char *l = ocb_get_l(c, i); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ +- buf_xor_1 (c->u_iv.iv, l, BLOCKSIZE); +- buf_cpy (l_tmp.x1, inbuf, BLOCKSIZE); ++ cipher_block_xor_1 (c->u_iv.iv, l, BLOCKSIZE); ++ cipher_block_cpy (l_tmp.x1, inbuf, BLOCKSIZE); + /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ +- buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); ++ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); + burn_depth = decrypt_fn (ctx, l_tmp.x1, l_tmp.x1); +- buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); ++ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); + /* Checksum_i = Checksum_{i-1} xor P_i */ +- buf_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); +- buf_cpy (outbuf, l_tmp.x1, BLOCKSIZE); ++ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); ++ cipher_block_cpy (outbuf, l_tmp.x1, BLOCKSIZE); + + inbuf += BLOCKSIZE; + outbuf += BLOCKSIZE; +@@ -1411,48 +1652,58 @@ _gcry_aes_ocb_auth (gcry_cipher_hd_t c, + const unsigned char *abuf = abuf_arg; + unsigned int burn_depth = 0; + +- if (ctx->prefetch_enc_fn) +- ctx->prefetch_enc_fn(); +- + if (0) + ; + #ifdef USE_AESNI + else if (ctx->use_aesni) + { +- _gcry_aes_aesni_ocb_auth (c, abuf, nblocks); +- burn_depth = 0; ++ return _gcry_aes_aesni_ocb_auth (c, abuf, nblocks); + } + #endif /*USE_AESNI*/ + #ifdef USE_SSSE3 + else if (ctx->use_ssse3) + { +- _gcry_aes_ssse3_ocb_auth (c, abuf, nblocks); +- burn_depth = 0; ++ return _gcry_aes_ssse3_ocb_auth (c, abuf, nblocks); + } + #endif /*USE_SSSE3*/ + #ifdef USE_ARM_CE + else if (ctx->use_arm_ce) + { +- _gcry_aes_armv8_ce_ocb_auth (c, abuf, nblocks); +- burn_depth = 0; ++ return _gcry_aes_armv8_ce_ocb_auth (c, abuf, nblocks); + } + #endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if (ctx->use_ppc9le_crypto) ++ { ++ return _gcry_aes_ppc9le_ocb_auth (c, abuf, nblocks); ++ } ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ return _gcry_aes_ppc8_ocb_auth (c, abuf, nblocks); ++ } ++#endif /*USE_PPC_CRYPTO*/ + else + { + union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; + rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; + ++ if (ctx->prefetch_enc_fn) ++ ctx->prefetch_enc_fn(); ++ + for ( ;nblocks; nblocks-- ) + { + u64 i = ++c->u_mode.ocb.aad_nblocks; + const unsigned char *l = ocb_get_l(c, i); + + /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ +- buf_xor_1 (c->u_mode.ocb.aad_offset, l, BLOCKSIZE); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l, BLOCKSIZE); + /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ +- buf_xor (l_tmp.x1, c->u_mode.ocb.aad_offset, abuf, BLOCKSIZE); ++ cipher_block_xor (l_tmp.x1, c->u_mode.ocb.aad_offset, abuf, ++ BLOCKSIZE); + burn_depth = encrypt_fn (ctx, l_tmp.x1, l_tmp.x1); +- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp.x1, BLOCKSIZE); ++ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp.x1, BLOCKSIZE); + + abuf += BLOCKSIZE; + } +@@ -1467,6 +1718,106 @@ _gcry_aes_ocb_auth (gcry_cipher_hd_t c, + } + + ++/* Bulk encryption/decryption of complete blocks in XTS mode. */ ++void ++_gcry_aes_xts_crypt (void *context, unsigned char *tweak, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, int encrypt) ++{ ++ RIJNDAEL_context *ctx = context; ++ unsigned char *outbuf = outbuf_arg; ++ const unsigned char *inbuf = inbuf_arg; ++ unsigned int burn_depth = 0; ++ rijndael_cryptfn_t crypt_fn; ++ u64 tweak_lo, tweak_hi, tweak_next_lo, tweak_next_hi, tmp_lo, tmp_hi, carry; ++ ++ if (0) ++ ; ++#ifdef USE_AESNI ++ else if (ctx->use_aesni) ++ { ++ _gcry_aes_aesni_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); ++ return; ++ } ++#endif /*USE_AESNI*/ ++#ifdef USE_ARM_CE ++ else if (ctx->use_arm_ce) ++ { ++ _gcry_aes_armv8_ce_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); ++ return; ++ } ++#endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ else if (ctx->use_ppc9le_crypto) ++ { ++ _gcry_aes_ppc9le_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ ++#ifdef USE_PPC_CRYPTO ++ else if (ctx->use_ppc_crypto) ++ { ++ _gcry_aes_ppc8_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); ++ return; ++ } ++#endif /*USE_PPC_CRYPTO*/ ++ else ++ { ++ if (encrypt) ++ { ++ if (ctx->prefetch_enc_fn) ++ ctx->prefetch_enc_fn(); ++ ++ crypt_fn = ctx->encrypt_fn; ++ } ++ else ++ { ++ check_decryption_preparation (ctx); ++ ++ if (ctx->prefetch_dec_fn) ++ ctx->prefetch_dec_fn(); ++ ++ crypt_fn = ctx->decrypt_fn; ++ } ++ ++ tweak_next_lo = buf_get_le64 (tweak + 0); ++ tweak_next_hi = buf_get_le64 (tweak + 8); ++ ++ while (nblocks) ++ { ++ tweak_lo = tweak_next_lo; ++ tweak_hi = tweak_next_hi; ++ ++ /* Xor-Encrypt/Decrypt-Xor block. */ ++ tmp_lo = buf_get_le64 (inbuf + 0) ^ tweak_lo; ++ tmp_hi = buf_get_le64 (inbuf + 8) ^ tweak_hi; ++ ++ buf_put_le64 (outbuf + 0, tmp_lo); ++ buf_put_le64 (outbuf + 8, tmp_hi); ++ ++ /* Generate next tweak. */ ++ carry = -(tweak_next_hi >> 63) & 0x87; ++ tweak_next_hi = (tweak_next_hi << 1) + (tweak_next_lo >> 63); ++ tweak_next_lo = (tweak_next_lo << 1) ^ carry; ++ ++ burn_depth = crypt_fn (ctx, outbuf, outbuf); ++ ++ buf_put_le64 (outbuf + 0, buf_get_le64 (outbuf + 0) ^ tweak_lo); ++ buf_put_le64 (outbuf + 8, buf_get_le64 (outbuf + 8) ^ tweak_hi); ++ ++ outbuf += GCRY_XTS_BLOCK_LEN; ++ inbuf += GCRY_XTS_BLOCK_LEN; ++ nblocks--; ++ } ++ ++ buf_put_le64 (tweak + 0, tweak_next_lo); ++ buf_put_le64 (tweak + 8, tweak_next_hi); ++ } ++ ++ if (burn_depth) ++ _gcry_burn_stack (burn_depth + 5 * sizeof(void *)); ++} ++ + + /* Run the self-tests for AES 128. Returns NULL on success. */ + static const char* +@@ -1522,7 +1873,7 @@ selftest_basic_128 (void) + if (!ctx) + return "failed to allocate memory"; + +- rijndael_setkey (ctx, key_128, sizeof (key_128)); ++ rijndael_setkey (ctx, key_128, sizeof (key_128), NULL); + rijndael_encrypt (ctx, scratch, plaintext_128); + if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128))) + { +@@ -1565,7 +1916,7 @@ selftest_basic_192 (void) + ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); + if (!ctx) + return "failed to allocate memory"; +- rijndael_setkey (ctx, key_192, sizeof(key_192)); ++ rijndael_setkey (ctx, key_192, sizeof(key_192), NULL); + rijndael_encrypt (ctx, scratch, plaintext_192); + if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192))) + { +@@ -1610,7 +1961,7 @@ selftest_basic_256 (void) + ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); + if (!ctx) + return "failed to allocate memory"; +- rijndael_setkey (ctx, key_256, sizeof(key_256)); ++ rijndael_setkey (ctx, key_256, sizeof(key_256), NULL); + rijndael_encrypt (ctx, scratch, plaintext_256); + if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256))) + { +diff -up libgcrypt-1.8.5/cipher/rijndael-internal.h.aes-perf libgcrypt-1.8.5/cipher/rijndael-internal.h +--- libgcrypt-1.8.5/cipher/rijndael-internal.h.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/rijndael-internal.h 2020-04-22 18:29:41.676862114 +0200 +@@ -73,7 +73,7 @@ + # define USE_PADLOCK 1 + # endif + # endif +-#endif /*ENABLE_PADLOCK_SUPPORT*/ ++#endif /* ENABLE_PADLOCK_SUPPORT */ + + /* USE_AESNI inidicates whether to compile with Intel AES-NI code. We + need the vector-size attribute which seems to be available since +@@ -102,6 +102,23 @@ + # endif + #endif /* ENABLE_ARM_CRYPTO_SUPPORT */ + ++/* USE_PPC_CRYPTO indicates whether to enable PowerPC vector crypto ++ * accelerated code. USE_PPC_CRYPTO_WITH_PPC9LE indicates whether to ++ * enable POWER9 optimized variant. */ ++#undef USE_PPC_CRYPTO ++#undef USE_PPC_CRYPTO_WITH_PPC9LE ++#ifdef ENABLE_PPC_CRYPTO_SUPPORT ++# if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \ ++ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) ++# if __GNUC__ >= 4 ++# define USE_PPC_CRYPTO 1 ++# if !defined(WORDS_BIGENDIAN) && defined(HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00) ++# define USE_PPC_CRYPTO_WITH_PPC9LE 1 ++# endif ++# endif ++# endif ++#endif /* ENABLE_PPC_CRYPTO_SUPPORT */ ++ + struct RIJNDAEL_context_s; + + typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx, +@@ -150,6 +167,12 @@ typedef struct RIJNDAEL_context_s + #ifdef USE_ARM_CE + unsigned int use_arm_ce:1; /* ARMv8 CE shall be used. */ + #endif /*USE_ARM_CE*/ ++#ifdef USE_PPC_CRYPTO ++ unsigned int use_ppc_crypto:1; /* PowerPC crypto shall be used. */ ++#endif /*USE_PPC_CRYPTO*/ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ unsigned int use_ppc9le_crypto:1; /* POWER9 LE crypto shall be used. */ ++#endif + rijndael_cryptfn_t encrypt_fn; + rijndael_cryptfn_t decrypt_fn; + rijndael_prefetchfn_t prefetch_enc_fn; +diff -up libgcrypt-1.8.5/cipher/rijndael-ppc9le.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-ppc9le.c +--- libgcrypt-1.8.5/cipher/rijndael-ppc9le.c.aes-perf 2020-04-22 18:29:41.677862096 +0200 ++++ libgcrypt-1.8.5/cipher/rijndael-ppc9le.c 2020-04-22 18:29:41.677862096 +0200 +@@ -0,0 +1,102 @@ ++/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation ++ * Copyright (C) 2019 Shawn Landden ++ * Copyright (C) 2019-2020 Jussi Kivilinna ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt 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. ++ * ++ * Libgcrypt 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 program; if not, see . ++ * ++ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project, ++ * and Cryptogams by Andy Polyakov, and if made part of a release of either ++ * or both projects, is thereafter dual-licensed under the license said project ++ * is released under. ++ */ ++ ++#include ++ ++#include "rijndael-internal.h" ++#include "cipher-internal.h" ++#include "bufhelp.h" ++ ++#ifdef USE_PPC_CRYPTO_WITH_PPC9LE ++ ++#include "rijndael-ppc-common.h" ++ ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_load_be_const(void) ++{ ++ static const block vec_dummy = { 0 }; ++ return vec_dummy; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_be_swap(block vec, block be_bswap_const) ++{ ++ (void)be_bswap_const; ++ return vec; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_load_be_noswap(unsigned long offset, const void *ptr) ++{ ++ block vec; ++#if __GNUC__ >= 4 ++ if (__builtin_constant_p (offset) && offset == 0) ++ __asm__ volatile ("lxvb16x %x0,0,%1\n\t" ++ : "=wa" (vec) ++ : "r" ((uintptr_t)ptr) ++ : "memory"); ++ else ++#endif ++ __asm__ volatile ("lxvb16x %x0,%1,%2\n\t" ++ : "=wa" (vec) ++ : "r" (offset), "r" ((uintptr_t)ptr) ++ : "memory", "r0"); ++ return vec; ++} ++ ++static ASM_FUNC_ATTR_INLINE void ++asm_store_be_noswap(block vec, unsigned long offset, void *ptr) ++{ ++#if __GNUC__ >= 4 ++ if (__builtin_constant_p (offset) && offset == 0) ++ __asm__ volatile ("stxvb16x %x0,0,%1\n\t" ++ : ++ : "wa" (vec), "r" ((uintptr_t)ptr) ++ : "memory"); ++ else ++#endif ++ __asm__ volatile ("stxvb16x %x0,%1,%2\n\t" ++ : ++ : "wa" (vec), "r" (offset), "r" ((uintptr_t)ptr) ++ : "memory", "r0"); ++} ++ ++ ++#define GCRY_AES_PPC9LE 1 ++#define ENCRYPT_BLOCK_FUNC _gcry_aes_ppc9le_encrypt ++#define DECRYPT_BLOCK_FUNC _gcry_aes_ppc9le_decrypt ++#define CFB_ENC_FUNC _gcry_aes_ppc9le_cfb_enc ++#define CFB_DEC_FUNC _gcry_aes_ppc9le_cfb_dec ++#define CBC_ENC_FUNC _gcry_aes_ppc9le_cbc_enc ++#define CBC_DEC_FUNC _gcry_aes_ppc9le_cbc_dec ++#define CTR_ENC_FUNC _gcry_aes_ppc9le_ctr_enc ++#define OCB_CRYPT_FUNC _gcry_aes_ppc9le_ocb_crypt ++#define OCB_AUTH_FUNC _gcry_aes_ppc9le_ocb_auth ++#define XTS_CRYPT_FUNC _gcry_aes_ppc9le_xts_crypt ++ ++#include ++ ++#endif /* USE_PPC_CRYPTO */ +diff -up libgcrypt-1.8.5/cipher/rijndael-ppc.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-ppc.c +--- libgcrypt-1.8.5/cipher/rijndael-ppc.c.aes-perf 2020-04-22 18:29:41.677862096 +0200 ++++ libgcrypt-1.8.5/cipher/rijndael-ppc.c 2020-04-22 18:29:41.677862096 +0200 +@@ -0,0 +1,259 @@ ++/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation ++ * Copyright (C) 2019 Shawn Landden ++ * Copyright (C) 2019-2020 Jussi Kivilinna ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt 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. ++ * ++ * Libgcrypt 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 program; if not, see . ++ * ++ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project, ++ * and Cryptogams by Andy Polyakov, and if made part of a release of either ++ * or both projects, is thereafter dual-licensed under the license said project ++ * is released under. ++ */ ++ ++#include ++ ++#include "rijndael-internal.h" ++#include "cipher-internal.h" ++#include "bufhelp.h" ++ ++#ifdef USE_PPC_CRYPTO ++ ++#include "rijndael-ppc-common.h" ++ ++ ++#ifdef WORDS_BIGENDIAN ++static const block vec_bswap32_const = ++ { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 }; ++#else ++static const block vec_bswap32_const_neg = ++ { ~3, ~2, ~1, ~0, ~7, ~6, ~5, ~4, ~11, ~10, ~9, ~8, ~15, ~14, ~13, ~12 }; ++#endif ++ ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_load_be_const(void) ++{ ++#ifndef WORDS_BIGENDIAN ++ return ALIGNED_LOAD (&vec_bswap32_const_neg, 0); ++#else ++ static const block vec_dummy = { 0 }; ++ return vec_dummy; ++#endif ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_be_swap(block vec, block be_bswap_const) ++{ ++ (void)be_bswap_const; ++#ifndef WORDS_BIGENDIAN ++ return asm_vperm1 (vec, be_bswap_const); ++#else ++ return vec; ++#endif ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_load_be_noswap(unsigned long offset, const void *ptr) ++{ ++ block vec; ++#if __GNUC__ >= 4 ++ if (__builtin_constant_p (offset) && offset == 0) ++ __asm__ volatile ("lxvw4x %x0,0,%1\n\t" ++ : "=wa" (vec) ++ : "r" ((uintptr_t)ptr) ++ : "memory"); ++ else ++#endif ++ __asm__ volatile ("lxvw4x %x0,%1,%2\n\t" ++ : "=wa" (vec) ++ : "r" (offset), "r" ((uintptr_t)ptr) ++ : "memory", "r0"); ++ /* NOTE: vec needs to be be-swapped using 'asm_be_swap' by caller */ ++ return vec; ++} ++ ++static ASM_FUNC_ATTR_INLINE void ++asm_store_be_noswap(block vec, unsigned long offset, void *ptr) ++{ ++ /* NOTE: vec be-swapped using 'asm_be_swap' by caller */ ++#if __GNUC__ >= 4 ++ if (__builtin_constant_p (offset) && offset == 0) ++ __asm__ volatile ("stxvw4x %x0,0,%1\n\t" ++ : ++ : "wa" (vec), "r" ((uintptr_t)ptr) ++ : "memory"); ++ else ++#endif ++ __asm__ volatile ("stxvw4x %x0,%1,%2\n\t" ++ : ++ : "wa" (vec), "r" (offset), "r" ((uintptr_t)ptr) ++ : "memory", "r0"); ++} ++ ++ ++static ASM_FUNC_ATTR_INLINE u32 ++_gcry_aes_sbox4_ppc8(u32 fourbytes) ++{ ++ union ++ { ++ PROPERLY_ALIGNED_TYPE dummy; ++ block data_vec; ++ u32 data32[4]; ++ } u; ++ ++ u.data32[0] = fourbytes; ++ u.data_vec = vec_sbox_be(u.data_vec); ++ return u.data32[0]; ++} ++ ++void ++_gcry_aes_ppc8_setkey (RIJNDAEL_context *ctx, const byte *key) ++{ ++ const block bige_const = asm_load_be_const(); ++ union ++ { ++ PROPERLY_ALIGNED_TYPE dummy; ++ byte data[MAXKC][4]; ++ u32 data32[MAXKC]; ++ } tkk[2]; ++ unsigned int rounds = ctx->rounds; ++ int KC = rounds - 6; ++ unsigned int keylen = KC * 4; ++ u128_t *ekey = (u128_t *)(void *)ctx->keyschenc; ++ unsigned int i, r, t; ++ byte rcon = 1; ++ int j; ++#define k tkk[0].data ++#define k_u32 tkk[0].data32 ++#define tk tkk[1].data ++#define tk_u32 tkk[1].data32 ++#define W (ctx->keyschenc) ++#define W_u32 (ctx->keyschenc32) ++ ++ for (i = 0; i < keylen; i++) ++ { ++ k[i >> 2][i & 3] = key[i]; ++ } ++ ++ for (j = KC-1; j >= 0; j--) ++ { ++ tk_u32[j] = k_u32[j]; ++ } ++ r = 0; ++ t = 0; ++ /* Copy values into round key array. */ ++ for (j = 0; (j < KC) && (r < rounds + 1); ) ++ { ++ for (; (j < KC) && (t < 4); j++, t++) ++ { ++ W_u32[r][t] = le_bswap32(tk_u32[j]); ++ } ++ if (t == 4) ++ { ++ r++; ++ t = 0; ++ } ++ } ++ while (r < rounds + 1) ++ { ++ tk_u32[0] ^= ++ le_bswap32( ++ _gcry_aes_sbox4_ppc8(rol(le_bswap32(tk_u32[KC - 1]), 24)) ^ rcon); ++ ++ if (KC != 8) ++ { ++ for (j = 1; j < KC; j++) ++ { ++ tk_u32[j] ^= tk_u32[j-1]; ++ } ++ } ++ else ++ { ++ for (j = 1; j < KC/2; j++) ++ { ++ tk_u32[j] ^= tk_u32[j-1]; ++ } ++ ++ tk_u32[KC/2] ^= ++ le_bswap32(_gcry_aes_sbox4_ppc8(le_bswap32(tk_u32[KC/2 - 1]))); ++ ++ for (j = KC/2 + 1; j < KC; j++) ++ { ++ tk_u32[j] ^= tk_u32[j-1]; ++ } ++ } ++ ++ /* Copy values into round key array. */ ++ for (j = 0; (j < KC) && (r < rounds + 1); ) ++ { ++ for (; (j < KC) && (t < 4); j++, t++) ++ { ++ W_u32[r][t] = le_bswap32(tk_u32[j]); ++ } ++ if (t == 4) ++ { ++ r++; ++ t = 0; ++ } ++ } ++ ++ rcon = (rcon << 1) ^ (-(rcon >> 7) & 0x1b); ++ } ++ ++ /* Store in big-endian order. */ ++ for (r = 0; r <= rounds; r++) ++ { ++#ifndef WORDS_BIGENDIAN ++ VEC_STORE_BE(ekey, r, ALIGNED_LOAD (ekey, r), bige_const); ++#else ++ block rvec = ALIGNED_LOAD (ekey, r); ++ ALIGNED_STORE (ekey, r, ++ vec_perm(rvec, rvec, vec_bswap32_const)); ++ (void)bige_const; ++#endif ++ } ++ ++#undef W ++#undef tk ++#undef k ++#undef W_u32 ++#undef tk_u32 ++#undef k_u32 ++ wipememory(&tkk, sizeof(tkk)); ++} ++ ++void ++_gcry_aes_ppc8_prepare_decryption (RIJNDAEL_context *ctx) ++{ ++ internal_aes_ppc_prepare_decryption (ctx); ++} ++ ++ ++#define GCRY_AES_PPC8 1 ++#define ENCRYPT_BLOCK_FUNC _gcry_aes_ppc8_encrypt ++#define DECRYPT_BLOCK_FUNC _gcry_aes_ppc8_decrypt ++#define CFB_ENC_FUNC _gcry_aes_ppc8_cfb_enc ++#define CFB_DEC_FUNC _gcry_aes_ppc8_cfb_dec ++#define CBC_ENC_FUNC _gcry_aes_ppc8_cbc_enc ++#define CBC_DEC_FUNC _gcry_aes_ppc8_cbc_dec ++#define CTR_ENC_FUNC _gcry_aes_ppc8_ctr_enc ++#define OCB_CRYPT_FUNC _gcry_aes_ppc8_ocb_crypt ++#define OCB_AUTH_FUNC _gcry_aes_ppc8_ocb_auth ++#define XTS_CRYPT_FUNC _gcry_aes_ppc8_xts_crypt ++ ++#include ++ ++#endif /* USE_PPC_CRYPTO */ +diff -up libgcrypt-1.8.5/cipher/rijndael-ppc-common.h.aes-perf libgcrypt-1.8.5/cipher/rijndael-ppc-common.h +--- libgcrypt-1.8.5/cipher/rijndael-ppc-common.h.aes-perf 2020-04-22 18:29:41.678862076 +0200 ++++ libgcrypt-1.8.5/cipher/rijndael-ppc-common.h 2020-04-22 18:29:41.678862076 +0200 +@@ -0,0 +1,342 @@ ++/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation ++ * Copyright (C) 2019 Shawn Landden ++ * Copyright (C) 2019-2020 Jussi Kivilinna ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt 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. ++ * ++ * Libgcrypt 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 program; if not, see . ++ * ++ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project, ++ * and Cryptogams by Andy Polyakov, and if made part of a release of either ++ * or both projects, is thereafter dual-licensed under the license said project ++ * is released under. ++ */ ++ ++#ifndef G10_RIJNDAEL_PPC_COMMON_H ++#define G10_RIJNDAEL_PPC_COMMON_H ++ ++#include ++ ++ ++typedef vector unsigned char block; ++ ++typedef union ++{ ++ u32 data32[4]; ++} __attribute__((packed, aligned(1), may_alias)) u128_t; ++ ++ ++#define ALWAYS_INLINE inline __attribute__((always_inline)) ++#define NO_INLINE __attribute__((noinline)) ++#define NO_INSTRUMENT_FUNCTION __attribute__((no_instrument_function)) ++ ++#define ASM_FUNC_ATTR NO_INSTRUMENT_FUNCTION ++#define ASM_FUNC_ATTR_INLINE ASM_FUNC_ATTR ALWAYS_INLINE ++#define ASM_FUNC_ATTR_NOINLINE ASM_FUNC_ATTR NO_INLINE ++ ++ ++#define ALIGNED_LOAD(in_ptr, offs) \ ++ (asm_aligned_ld ((offs) * 16, (const void *)(in_ptr))) ++ ++#define ALIGNED_STORE(out_ptr, offs, vec) \ ++ (asm_aligned_st ((vec), (offs) * 16, (void *)(out_ptr))) ++ ++#define VEC_BE_SWAP(vec, bige_const) (asm_be_swap ((vec), (bige_const))) ++ ++#define VEC_LOAD_BE(in_ptr, offs, bige_const) \ ++ (asm_be_swap (asm_load_be_noswap ((offs) * 16, (const void *)(in_ptr)), \ ++ bige_const)) ++ ++#define VEC_LOAD_BE_NOSWAP(in_ptr, offs) \ ++ (asm_load_be_noswap ((offs) * 16, (const unsigned char *)(in_ptr))) ++ ++#define VEC_STORE_BE(out_ptr, offs, vec, bige_const) \ ++ (asm_store_be_noswap (asm_be_swap ((vec), (bige_const)), (offs) * 16, \ ++ (void *)(out_ptr))) ++ ++#define VEC_STORE_BE_NOSWAP(out_ptr, offs, vec) \ ++ (asm_store_be_noswap ((vec), (offs) * 16, (void *)(out_ptr))) ++ ++ ++#define ROUND_KEY_VARIABLES \ ++ block rkey0, rkeylast ++ ++#define PRELOAD_ROUND_KEYS(nrounds) \ ++ do { \ ++ rkey0 = ALIGNED_LOAD (rk, 0); \ ++ rkeylast = ALIGNED_LOAD (rk, nrounds); \ ++ } while (0) ++ ++#define AES_ENCRYPT(blk, nrounds) \ ++ do { \ ++ blk ^= rkey0; \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 1)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 2)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 3)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 4)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 5)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 6)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 7)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 8)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 9)); \ ++ if (nrounds >= 12) \ ++ { \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 10)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 11)); \ ++ if (rounds > 12) \ ++ { \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 12)); \ ++ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 13)); \ ++ } \ ++ } \ ++ blk = asm_cipherlast_be (blk, rkeylast); \ ++ } while (0) ++ ++#define AES_DECRYPT(blk, nrounds) \ ++ do { \ ++ blk ^= rkey0; \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 1)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 2)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 3)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 4)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 5)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 6)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 7)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 8)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 9)); \ ++ if (nrounds >= 12) \ ++ { \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 10)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 11)); \ ++ if (rounds > 12) \ ++ { \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 12)); \ ++ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 13)); \ ++ } \ ++ } \ ++ blk = asm_ncipherlast_be (blk, rkeylast); \ ++ } while (0) ++ ++ ++#define ROUND_KEY_VARIABLES_ALL \ ++ block rkey0, rkey1, rkey2, rkey3, rkey4, rkey5, rkey6, rkey7, rkey8, \ ++ rkey9, rkey10, rkey11, rkey12, rkey13, rkeylast ++ ++#define PRELOAD_ROUND_KEYS_ALL(nrounds) \ ++ do { \ ++ rkey0 = ALIGNED_LOAD (rk, 0); \ ++ rkey1 = ALIGNED_LOAD (rk, 1); \ ++ rkey2 = ALIGNED_LOAD (rk, 2); \ ++ rkey3 = ALIGNED_LOAD (rk, 3); \ ++ rkey4 = ALIGNED_LOAD (rk, 4); \ ++ rkey5 = ALIGNED_LOAD (rk, 5); \ ++ rkey6 = ALIGNED_LOAD (rk, 6); \ ++ rkey7 = ALIGNED_LOAD (rk, 7); \ ++ rkey8 = ALIGNED_LOAD (rk, 8); \ ++ rkey9 = ALIGNED_LOAD (rk, 9); \ ++ if (nrounds >= 12) \ ++ { \ ++ rkey10 = ALIGNED_LOAD (rk, 10); \ ++ rkey11 = ALIGNED_LOAD (rk, 11); \ ++ if (rounds > 12) \ ++ { \ ++ rkey12 = ALIGNED_LOAD (rk, 12); \ ++ rkey13 = ALIGNED_LOAD (rk, 13); \ ++ } \ ++ } \ ++ rkeylast = ALIGNED_LOAD (rk, nrounds); \ ++ } while (0) ++ ++#define AES_ENCRYPT_ALL(blk, nrounds) \ ++ do { \ ++ blk ^= rkey0; \ ++ blk = asm_cipher_be (blk, rkey1); \ ++ blk = asm_cipher_be (blk, rkey2); \ ++ blk = asm_cipher_be (blk, rkey3); \ ++ blk = asm_cipher_be (blk, rkey4); \ ++ blk = asm_cipher_be (blk, rkey5); \ ++ blk = asm_cipher_be (blk, rkey6); \ ++ blk = asm_cipher_be (blk, rkey7); \ ++ blk = asm_cipher_be (blk, rkey8); \ ++ blk = asm_cipher_be (blk, rkey9); \ ++ if (nrounds >= 12) \ ++ { \ ++ blk = asm_cipher_be (blk, rkey10); \ ++ blk = asm_cipher_be (blk, rkey11); \ ++ if (rounds > 12) \ ++ { \ ++ blk = asm_cipher_be (blk, rkey12); \ ++ blk = asm_cipher_be (blk, rkey13); \ ++ } \ ++ } \ ++ blk = asm_cipherlast_be (blk, rkeylast); \ ++ } while (0) ++ ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_aligned_ld(unsigned long offset, const void *ptr) ++{ ++ block vec; ++#if __GNUC__ >= 4 ++ if (__builtin_constant_p (offset) && offset == 0) ++ __asm__ volatile ("lvx %0,0,%1\n\t" ++ : "=v" (vec) ++ : "r" ((uintptr_t)ptr) ++ : "memory"); ++ else ++#endif ++ __asm__ volatile ("lvx %0,%1,%2\n\t" ++ : "=v" (vec) ++ : "r" (offset), "r" ((uintptr_t)ptr) ++ : "memory", "r0"); ++ return vec; ++} ++ ++static ASM_FUNC_ATTR_INLINE void ++asm_aligned_st(block vec, unsigned long offset, void *ptr) ++{ ++#if __GNUC__ >= 4 ++ if (__builtin_constant_p (offset) && offset == 0) ++ __asm__ volatile ("stvx %0,0,%1\n\t" ++ : ++ : "v" (vec), "r" ((uintptr_t)ptr) ++ : "memory"); ++ else ++#endif ++ __asm__ volatile ("stvx %0,%1,%2\n\t" ++ : ++ : "v" (vec), "r" (offset), "r" ((uintptr_t)ptr) ++ : "memory", "r0"); ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_vperm1(block vec, block mask) ++{ ++ block o; ++ __asm__ volatile ("vperm %0,%1,%1,%2\n\t" ++ : "=v" (o) ++ : "v" (vec), "v" (mask)); ++ return o; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_add_uint128(block a, block b) ++{ ++ block res; ++ __asm__ volatile ("vadduqm %0,%1,%2\n\t" ++ : "=v" (res) ++ : "v" (a), "v" (b)); ++ return res; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_add_uint64(block a, block b) ++{ ++ block res; ++ __asm__ volatile ("vaddudm %0,%1,%2\n\t" ++ : "=v" (res) ++ : "v" (a), "v" (b)); ++ return res; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_sra_int64(block a, block b) ++{ ++ block res; ++ __asm__ volatile ("vsrad %0,%1,%2\n\t" ++ : "=v" (res) ++ : "v" (a), "v" (b)); ++ return res; ++} ++ ++static block ++asm_swap_uint64_halfs(block a) ++{ ++ block res; ++ __asm__ volatile ("xxswapd %x0, %x1" ++ : "=wa" (res) ++ : "wa" (a)); ++ return res; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_xor(block a, block b) ++{ ++ block res; ++ __asm__ volatile ("vxor %0,%1,%2\n\t" ++ : "=v" (res) ++ : "v" (a), "v" (b)); ++ return res; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_cipher_be(block b, block rk) ++{ ++ block o; ++ __asm__ volatile ("vcipher %0, %1, %2\n\t" ++ : "=v" (o) ++ : "v" (b), "v" (rk)); ++ return o; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_cipherlast_be(block b, block rk) ++{ ++ block o; ++ __asm__ volatile ("vcipherlast %0, %1, %2\n\t" ++ : "=v" (o) ++ : "v" (b), "v" (rk)); ++ return o; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_ncipher_be(block b, block rk) ++{ ++ block o; ++ __asm__ volatile ("vncipher %0, %1, %2\n\t" ++ : "=v" (o) ++ : "v" (b), "v" (rk)); ++ return o; ++} ++ ++static ASM_FUNC_ATTR_INLINE block ++asm_ncipherlast_be(block b, block rk) ++{ ++ block o; ++ __asm__ volatile ("vncipherlast %0, %1, %2\n\t" ++ : "=v" (o) ++ : "v" (b), "v" (rk)); ++ return o; ++} ++ ++ ++/* Make a decryption key from an encryption key. */ ++static ASM_FUNC_ATTR_INLINE void ++internal_aes_ppc_prepare_decryption (RIJNDAEL_context *ctx) ++{ ++ u128_t *ekey = (u128_t *)(void *)ctx->keyschenc; ++ u128_t *dkey = (u128_t *)(void *)ctx->keyschdec; ++ int rounds = ctx->rounds; ++ int rr; ++ int r; ++ ++ r = 0; ++ rr = rounds; ++ for (r = 0, rr = rounds; r <= rounds; r++, rr--) ++ { ++ ALIGNED_STORE (dkey, r, ALIGNED_LOAD (ekey, rr)); ++ } ++} ++ ++#endif /* G10_RIJNDAEL_PPC_COMMON_H */ +diff -up libgcrypt-1.8.5/cipher/rijndael-ppc-functions.h.aes-perf libgcrypt-1.8.5/cipher/rijndael-ppc-functions.h +--- libgcrypt-1.8.5/cipher/rijndael-ppc-functions.h.aes-perf 2020-04-22 18:29:41.679862057 +0200 ++++ libgcrypt-1.8.5/cipher/rijndael-ppc-functions.h 2020-04-22 18:29:41.679862057 +0200 +@@ -0,0 +1,2020 @@ ++/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation ++ * Copyright (C) 2019 Shawn Landden ++ * Copyright (C) 2019-2020 Jussi Kivilinna ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt 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. ++ * ++ * Libgcrypt 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 program; if not, see . ++ * ++ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project, ++ * and Cryptogams by Andy Polyakov, and if made part of a release of either ++ * or both projects, is thereafter dual-licensed under the license said project ++ * is released under. ++ */ ++ ++unsigned int ENCRYPT_BLOCK_FUNC (const RIJNDAEL_context *ctx, ++ unsigned char *out, ++ const unsigned char *in) ++{ ++ const block bige_const = asm_load_be_const(); ++ const u128_t *rk = (u128_t *)&ctx->keyschenc; ++ int rounds = ctx->rounds; ++ ROUND_KEY_VARIABLES; ++ block b; ++ ++ b = VEC_LOAD_BE (in, 0, bige_const); ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ ++ AES_ENCRYPT (b, rounds); ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ return 0; /* does not use stack */ ++} ++ ++ ++unsigned int DECRYPT_BLOCK_FUNC (const RIJNDAEL_context *ctx, ++ unsigned char *out, ++ const unsigned char *in) ++{ ++ const block bige_const = asm_load_be_const(); ++ const u128_t *rk = (u128_t *)&ctx->keyschdec; ++ int rounds = ctx->rounds; ++ ROUND_KEY_VARIABLES; ++ block b; ++ ++ b = VEC_LOAD_BE (in, 0, bige_const); ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ ++ AES_DECRYPT (b, rounds); ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ return 0; /* does not use stack */ ++} ++ ++ ++void CFB_ENC_FUNC (void *context, unsigned char *iv_arg, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks) ++{ ++ const block bige_const = asm_load_be_const(); ++ RIJNDAEL_context *ctx = context; ++ const u128_t *rk = (u128_t *)&ctx->keyschenc; ++ const u128_t *in = (const u128_t *)inbuf_arg; ++ u128_t *out = (u128_t *)outbuf_arg; ++ int rounds = ctx->rounds; ++ ROUND_KEY_VARIABLES_ALL; ++ block rkeylast_orig; ++ block iv; ++ ++ iv = VEC_LOAD_BE (iv_arg, 0, bige_const); ++ ++ PRELOAD_ROUND_KEYS_ALL (rounds); ++ rkeylast_orig = rkeylast; ++ ++ for (; nblocks >= 2; nblocks -= 2) ++ { ++ block in2, iv1; ++ ++ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in, 0, bige_const); ++ in2 = VEC_LOAD_BE (in + 1, 0, bige_const); ++ in += 2; ++ ++ AES_ENCRYPT_ALL (iv, rounds); ++ ++ iv1 = iv; ++ rkeylast = rkeylast_orig ^ in2; ++ ++ AES_ENCRYPT_ALL (iv, rounds); ++ ++ VEC_STORE_BE (out++, 0, iv1, bige_const); ++ VEC_STORE_BE (out++, 0, iv, bige_const); ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in++, 0, bige_const); ++ ++ AES_ENCRYPT_ALL (iv, rounds); ++ ++ VEC_STORE_BE (out++, 0, iv, bige_const); ++ } ++ ++ VEC_STORE_BE (iv_arg, 0, iv, bige_const); ++} ++ ++void CFB_DEC_FUNC (void *context, unsigned char *iv_arg, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks) ++{ ++ const block bige_const = asm_load_be_const(); ++ RIJNDAEL_context *ctx = context; ++ const u128_t *rk = (u128_t *)&ctx->keyschenc; ++ const u128_t *in = (const u128_t *)inbuf_arg; ++ u128_t *out = (u128_t *)outbuf_arg; ++ int rounds = ctx->rounds; ++ ROUND_KEY_VARIABLES; ++ block rkeylast_orig; ++ block iv, b, bin; ++ block in0, in1, in2, in3, in4, in5, in6, in7; ++ block b0, b1, b2, b3, b4, b5, b6, b7; ++ block rkey; ++ ++ iv = VEC_LOAD_BE (iv_arg, 0, bige_const); ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ rkeylast_orig = rkeylast; ++ ++ for (; nblocks >= 8; nblocks -= 8) ++ { ++ in0 = iv; ++ in1 = VEC_LOAD_BE_NOSWAP (in, 0); ++ in2 = VEC_LOAD_BE_NOSWAP (in, 1); ++ in3 = VEC_LOAD_BE_NOSWAP (in, 2); ++ in4 = VEC_LOAD_BE_NOSWAP (in, 3); ++ in1 = VEC_BE_SWAP (in1, bige_const); ++ in2 = VEC_BE_SWAP (in2, bige_const); ++ in5 = VEC_LOAD_BE_NOSWAP (in, 4); ++ in6 = VEC_LOAD_BE_NOSWAP (in, 5); ++ in3 = VEC_BE_SWAP (in3, bige_const); ++ in4 = VEC_BE_SWAP (in4, bige_const); ++ in7 = VEC_LOAD_BE_NOSWAP (in, 6); ++ iv = VEC_LOAD_BE_NOSWAP (in, 7); ++ in += 8; ++ in5 = VEC_BE_SWAP (in5, bige_const); ++ in6 = VEC_BE_SWAP (in6, bige_const); ++ b0 = asm_xor (rkey0, in0); ++ b1 = asm_xor (rkey0, in1); ++ in7 = VEC_BE_SWAP (in7, bige_const); ++ iv = VEC_BE_SWAP (iv, bige_const); ++ b2 = asm_xor (rkey0, in2); ++ b3 = asm_xor (rkey0, in3); ++ b4 = asm_xor (rkey0, in4); ++ b5 = asm_xor (rkey0, in5); ++ b6 = asm_xor (rkey0, in6); ++ b7 = asm_xor (rkey0, in7); ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); \ ++ b4 = asm_cipher_be (b4, rkey); \ ++ b5 = asm_cipher_be (b5, rkey); \ ++ b6 = asm_cipher_be (b6, rkey); \ ++ b7 = asm_cipher_be (b7, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ in1 = asm_xor (rkeylast, in1); ++ in2 = asm_xor (rkeylast, in2); ++ in3 = asm_xor (rkeylast, in3); ++ in4 = asm_xor (rkeylast, in4); ++ b0 = asm_cipherlast_be (b0, in1); ++ b1 = asm_cipherlast_be (b1, in2); ++ in5 = asm_xor (rkeylast, in5); ++ in6 = asm_xor (rkeylast, in6); ++ b2 = asm_cipherlast_be (b2, in3); ++ b3 = asm_cipherlast_be (b3, in4); ++ in7 = asm_xor (rkeylast, in7); ++ in0 = asm_xor (rkeylast, iv); ++ b0 = VEC_BE_SWAP (b0, bige_const); ++ b1 = VEC_BE_SWAP (b1, bige_const); ++ b4 = asm_cipherlast_be (b4, in5); ++ b5 = asm_cipherlast_be (b5, in6); ++ b2 = VEC_BE_SWAP (b2, bige_const); ++ b3 = VEC_BE_SWAP (b3, bige_const); ++ b6 = asm_cipherlast_be (b6, in7); ++ b7 = asm_cipherlast_be (b7, in0); ++ b4 = VEC_BE_SWAP (b4, bige_const); ++ b5 = VEC_BE_SWAP (b5, bige_const); ++ b6 = VEC_BE_SWAP (b6, bige_const); ++ b7 = VEC_BE_SWAP (b7, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 0, b0); ++ VEC_STORE_BE_NOSWAP (out, 1, b1); ++ VEC_STORE_BE_NOSWAP (out, 2, b2); ++ VEC_STORE_BE_NOSWAP (out, 3, b3); ++ VEC_STORE_BE_NOSWAP (out, 4, b4); ++ VEC_STORE_BE_NOSWAP (out, 5, b5); ++ VEC_STORE_BE_NOSWAP (out, 6, b6); ++ VEC_STORE_BE_NOSWAP (out, 7, b7); ++ out += 8; ++ } ++ ++ if (nblocks >= 4) ++ { ++ in0 = iv; ++ in1 = VEC_LOAD_BE (in, 0, bige_const); ++ in2 = VEC_LOAD_BE (in, 1, bige_const); ++ in3 = VEC_LOAD_BE (in, 2, bige_const); ++ iv = VEC_LOAD_BE (in, 3, bige_const); ++ ++ b0 = asm_xor (rkey0, in0); ++ b1 = asm_xor (rkey0, in1); ++ b2 = asm_xor (rkey0, in2); ++ b3 = asm_xor (rkey0, in3); ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ in1 = asm_xor (rkeylast, in1); ++ in2 = asm_xor (rkeylast, in2); ++ in3 = asm_xor (rkeylast, in3); ++ in0 = asm_xor (rkeylast, iv); ++ b0 = asm_cipherlast_be (b0, in1); ++ b1 = asm_cipherlast_be (b1, in2); ++ b2 = asm_cipherlast_be (b2, in3); ++ b3 = asm_cipherlast_be (b3, in0); ++ VEC_STORE_BE (out, 0, b0, bige_const); ++ VEC_STORE_BE (out, 1, b1, bige_const); ++ VEC_STORE_BE (out, 2, b2, bige_const); ++ VEC_STORE_BE (out, 3, b3, bige_const); ++ ++ in += 4; ++ out += 4; ++ nblocks -= 4; ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ bin = VEC_LOAD_BE (in, 0, bige_const); ++ rkeylast = rkeylast_orig ^ bin; ++ b = iv; ++ iv = bin; ++ ++ AES_ENCRYPT (b, rounds); ++ ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ out++; ++ in++; ++ } ++ ++ VEC_STORE_BE (iv_arg, 0, iv, bige_const); ++} ++ ++ ++void CBC_ENC_FUNC (void *context, unsigned char *iv_arg, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, int cbc_mac) ++{ ++ const block bige_const = asm_load_be_const(); ++ RIJNDAEL_context *ctx = context; ++ const u128_t *rk = (u128_t *)&ctx->keyschenc; ++ const u128_t *in = (const u128_t *)inbuf_arg; ++ byte *out = (byte *)outbuf_arg; ++ int rounds = ctx->rounds; ++ ROUND_KEY_VARIABLES_ALL; ++ block lastiv, b; ++ unsigned int outadd = -(!cbc_mac) & 16; ++ ++ lastiv = VEC_LOAD_BE (iv_arg, 0, bige_const); ++ ++ PRELOAD_ROUND_KEYS_ALL (rounds); ++ ++ for (; nblocks >= 2; nblocks -= 2) ++ { ++ block in2, lastiv1; ++ ++ b = lastiv ^ VEC_LOAD_BE (in, 0, bige_const); ++ in2 = VEC_LOAD_BE (in + 1, 0, bige_const); ++ in += 2; ++ ++ AES_ENCRYPT_ALL (b, rounds); ++ ++ lastiv1 = b; ++ b = lastiv1 ^ in2; ++ ++ AES_ENCRYPT_ALL (b, rounds); ++ ++ lastiv = b; ++ VEC_STORE_BE ((u128_t *)out, 0, lastiv1, bige_const); ++ out += outadd; ++ VEC_STORE_BE ((u128_t *)out, 0, lastiv, bige_const); ++ out += outadd; ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ b = lastiv ^ VEC_LOAD_BE (in++, 0, bige_const); ++ ++ AES_ENCRYPT_ALL (b, rounds); ++ ++ lastiv = b; ++ VEC_STORE_BE ((u128_t *)out, 0, b, bige_const); ++ out += outadd; ++ } ++ ++ VEC_STORE_BE (iv_arg, 0, lastiv, bige_const); ++} ++ ++void CBC_DEC_FUNC (void *context, unsigned char *iv_arg, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks) ++{ ++ const block bige_const = asm_load_be_const(); ++ RIJNDAEL_context *ctx = context; ++ const u128_t *rk = (u128_t *)&ctx->keyschdec; ++ const u128_t *in = (const u128_t *)inbuf_arg; ++ u128_t *out = (u128_t *)outbuf_arg; ++ int rounds = ctx->rounds; ++ ROUND_KEY_VARIABLES; ++ block rkeylast_orig; ++ block in0, in1, in2, in3, in4, in5, in6, in7; ++ block b0, b1, b2, b3, b4, b5, b6, b7; ++ block rkey; ++ block iv, b; ++ ++ if (!ctx->decryption_prepared) ++ { ++ internal_aes_ppc_prepare_decryption (ctx); ++ ctx->decryption_prepared = 1; ++ } ++ ++ iv = VEC_LOAD_BE (iv_arg, 0, bige_const); ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ rkeylast_orig = rkeylast; ++ ++ for (; nblocks >= 8; nblocks -= 8) ++ { ++ in0 = VEC_LOAD_BE_NOSWAP (in, 0); ++ in1 = VEC_LOAD_BE_NOSWAP (in, 1); ++ in2 = VEC_LOAD_BE_NOSWAP (in, 2); ++ in3 = VEC_LOAD_BE_NOSWAP (in, 3); ++ in0 = VEC_BE_SWAP (in0, bige_const); ++ in1 = VEC_BE_SWAP (in1, bige_const); ++ in4 = VEC_LOAD_BE_NOSWAP (in, 4); ++ in5 = VEC_LOAD_BE_NOSWAP (in, 5); ++ in2 = VEC_BE_SWAP (in2, bige_const); ++ in3 = VEC_BE_SWAP (in3, bige_const); ++ in6 = VEC_LOAD_BE_NOSWAP (in, 6); ++ in7 = VEC_LOAD_BE_NOSWAP (in, 7); ++ in += 8; ++ b0 = asm_xor (rkey0, in0); ++ b1 = asm_xor (rkey0, in1); ++ in4 = VEC_BE_SWAP (in4, bige_const); ++ in5 = VEC_BE_SWAP (in5, bige_const); ++ b2 = asm_xor (rkey0, in2); ++ b3 = asm_xor (rkey0, in3); ++ in6 = VEC_BE_SWAP (in6, bige_const); ++ in7 = VEC_BE_SWAP (in7, bige_const); ++ b4 = asm_xor (rkey0, in4); ++ b5 = asm_xor (rkey0, in5); ++ b6 = asm_xor (rkey0, in6); ++ b7 = asm_xor (rkey0, in7); ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_ncipher_be (b0, rkey); \ ++ b1 = asm_ncipher_be (b1, rkey); \ ++ b2 = asm_ncipher_be (b2, rkey); \ ++ b3 = asm_ncipher_be (b3, rkey); \ ++ b4 = asm_ncipher_be (b4, rkey); \ ++ b5 = asm_ncipher_be (b5, rkey); \ ++ b6 = asm_ncipher_be (b6, rkey); \ ++ b7 = asm_ncipher_be (b7, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ iv = asm_xor (rkeylast, iv); ++ in0 = asm_xor (rkeylast, in0); ++ in1 = asm_xor (rkeylast, in1); ++ in2 = asm_xor (rkeylast, in2); ++ b0 = asm_ncipherlast_be (b0, iv); ++ iv = in7; ++ b1 = asm_ncipherlast_be (b1, in0); ++ in3 = asm_xor (rkeylast, in3); ++ in4 = asm_xor (rkeylast, in4); ++ b2 = asm_ncipherlast_be (b2, in1); ++ b3 = asm_ncipherlast_be (b3, in2); ++ in5 = asm_xor (rkeylast, in5); ++ in6 = asm_xor (rkeylast, in6); ++ b0 = VEC_BE_SWAP (b0, bige_const); ++ b1 = VEC_BE_SWAP (b1, bige_const); ++ b4 = asm_ncipherlast_be (b4, in3); ++ b5 = asm_ncipherlast_be (b5, in4); ++ b2 = VEC_BE_SWAP (b2, bige_const); ++ b3 = VEC_BE_SWAP (b3, bige_const); ++ b6 = asm_ncipherlast_be (b6, in5); ++ b7 = asm_ncipherlast_be (b7, in6); ++ b4 = VEC_BE_SWAP (b4, bige_const); ++ b5 = VEC_BE_SWAP (b5, bige_const); ++ b6 = VEC_BE_SWAP (b6, bige_const); ++ b7 = VEC_BE_SWAP (b7, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 0, b0); ++ VEC_STORE_BE_NOSWAP (out, 1, b1); ++ VEC_STORE_BE_NOSWAP (out, 2, b2); ++ VEC_STORE_BE_NOSWAP (out, 3, b3); ++ VEC_STORE_BE_NOSWAP (out, 4, b4); ++ VEC_STORE_BE_NOSWAP (out, 5, b5); ++ VEC_STORE_BE_NOSWAP (out, 6, b6); ++ VEC_STORE_BE_NOSWAP (out, 7, b7); ++ out += 8; ++ } ++ ++ if (nblocks >= 4) ++ { ++ in0 = VEC_LOAD_BE (in, 0, bige_const); ++ in1 = VEC_LOAD_BE (in, 1, bige_const); ++ in2 = VEC_LOAD_BE (in, 2, bige_const); ++ in3 = VEC_LOAD_BE (in, 3, bige_const); ++ ++ b0 = asm_xor (rkey0, in0); ++ b1 = asm_xor (rkey0, in1); ++ b2 = asm_xor (rkey0, in2); ++ b3 = asm_xor (rkey0, in3); ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_ncipher_be (b0, rkey); \ ++ b1 = asm_ncipher_be (b1, rkey); \ ++ b2 = asm_ncipher_be (b2, rkey); \ ++ b3 = asm_ncipher_be (b3, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ iv = asm_xor (rkeylast, iv); ++ in0 = asm_xor (rkeylast, in0); ++ in1 = asm_xor (rkeylast, in1); ++ in2 = asm_xor (rkeylast, in2); ++ ++ b0 = asm_ncipherlast_be (b0, iv); ++ iv = in3; ++ b1 = asm_ncipherlast_be (b1, in0); ++ b2 = asm_ncipherlast_be (b2, in1); ++ b3 = asm_ncipherlast_be (b3, in2); ++ ++ VEC_STORE_BE (out, 0, b0, bige_const); ++ VEC_STORE_BE (out, 1, b1, bige_const); ++ VEC_STORE_BE (out, 2, b2, bige_const); ++ VEC_STORE_BE (out, 3, b3, bige_const); ++ ++ in += 4; ++ out += 4; ++ nblocks -= 4; ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ rkeylast = rkeylast_orig ^ iv; ++ ++ iv = VEC_LOAD_BE (in, 0, bige_const); ++ b = iv; ++ AES_DECRYPT (b, rounds); ++ ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ in++; ++ out++; ++ } ++ ++ VEC_STORE_BE (iv_arg, 0, iv, bige_const); ++} ++ ++ ++void CTR_ENC_FUNC (void *context, unsigned char *ctr_arg, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks) ++{ ++ static const unsigned char vec_one_const[16] = ++ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; ++ const block bige_const = asm_load_be_const(); ++ RIJNDAEL_context *ctx = context; ++ const u128_t *rk = (u128_t *)&ctx->keyschenc; ++ const u128_t *in = (const u128_t *)inbuf_arg; ++ u128_t *out = (u128_t *)outbuf_arg; ++ int rounds = ctx->rounds; ++ ROUND_KEY_VARIABLES; ++ block rkeylast_orig; ++ block ctr, b, one; ++ ++ ctr = VEC_LOAD_BE (ctr_arg, 0, bige_const); ++ one = VEC_LOAD_BE (&vec_one_const, 0, bige_const); ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ rkeylast_orig = rkeylast; ++ ++ if (nblocks >= 4) ++ { ++ block in0, in1, in2, in3, in4, in5, in6, in7; ++ block b0, b1, b2, b3, b4, b5, b6, b7; ++ block two, three, four; ++ block rkey; ++ ++ two = asm_add_uint128 (one, one); ++ three = asm_add_uint128 (two, one); ++ four = asm_add_uint128 (two, two); ++ ++ for (; nblocks >= 8; nblocks -= 8) ++ { ++ b1 = asm_add_uint128 (ctr, one); ++ b2 = asm_add_uint128 (ctr, two); ++ b3 = asm_add_uint128 (ctr, three); ++ b4 = asm_add_uint128 (ctr, four); ++ b5 = asm_add_uint128 (b1, four); ++ b6 = asm_add_uint128 (b2, four); ++ b7 = asm_add_uint128 (b3, four); ++ b0 = asm_xor (rkey0, ctr); ++ rkey = ALIGNED_LOAD (rk, 1); ++ ctr = asm_add_uint128 (b4, four); ++ b1 = asm_xor (rkey0, b1); ++ b2 = asm_xor (rkey0, b2); ++ b3 = asm_xor (rkey0, b3); ++ b0 = asm_cipher_be (b0, rkey); ++ b1 = asm_cipher_be (b1, rkey); ++ b2 = asm_cipher_be (b2, rkey); ++ b3 = asm_cipher_be (b3, rkey); ++ b4 = asm_xor (rkey0, b4); ++ b5 = asm_xor (rkey0, b5); ++ b6 = asm_xor (rkey0, b6); ++ b7 = asm_xor (rkey0, b7); ++ b4 = asm_cipher_be (b4, rkey); ++ b5 = asm_cipher_be (b5, rkey); ++ b6 = asm_cipher_be (b6, rkey); ++ b7 = asm_cipher_be (b7, rkey); ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); \ ++ b4 = asm_cipher_be (b4, rkey); \ ++ b5 = asm_cipher_be (b5, rkey); \ ++ b6 = asm_cipher_be (b6, rkey); \ ++ b7 = asm_cipher_be (b7, rkey); ++ ++ in0 = VEC_LOAD_BE_NOSWAP (in, 0); ++ DO_ROUND(2); ++ in1 = VEC_LOAD_BE_NOSWAP (in, 1); ++ DO_ROUND(3); ++ in2 = VEC_LOAD_BE_NOSWAP (in, 2); ++ DO_ROUND(4); ++ in3 = VEC_LOAD_BE_NOSWAP (in, 3); ++ DO_ROUND(5); ++ in4 = VEC_LOAD_BE_NOSWAP (in, 4); ++ DO_ROUND(6); ++ in5 = VEC_LOAD_BE_NOSWAP (in, 5); ++ DO_ROUND(7); ++ in6 = VEC_LOAD_BE_NOSWAP (in, 6); ++ DO_ROUND(8); ++ in7 = VEC_LOAD_BE_NOSWAP (in, 7); ++ in += 8; ++ DO_ROUND(9); ++ ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ in0 = VEC_BE_SWAP (in0, bige_const); ++ in1 = VEC_BE_SWAP (in1, bige_const); ++ in2 = VEC_BE_SWAP (in2, bige_const); ++ in3 = VEC_BE_SWAP (in3, bige_const); ++ in4 = VEC_BE_SWAP (in4, bige_const); ++ in5 = VEC_BE_SWAP (in5, bige_const); ++ in6 = VEC_BE_SWAP (in6, bige_const); ++ in7 = VEC_BE_SWAP (in7, bige_const); ++ ++ in0 = asm_xor (rkeylast, in0); ++ in1 = asm_xor (rkeylast, in1); ++ in2 = asm_xor (rkeylast, in2); ++ in3 = asm_xor (rkeylast, in3); ++ b0 = asm_cipherlast_be (b0, in0); ++ b1 = asm_cipherlast_be (b1, in1); ++ in4 = asm_xor (rkeylast, in4); ++ in5 = asm_xor (rkeylast, in5); ++ b2 = asm_cipherlast_be (b2, in2); ++ b3 = asm_cipherlast_be (b3, in3); ++ in6 = asm_xor (rkeylast, in6); ++ in7 = asm_xor (rkeylast, in7); ++ b4 = asm_cipherlast_be (b4, in4); ++ b5 = asm_cipherlast_be (b5, in5); ++ b6 = asm_cipherlast_be (b6, in6); ++ b7 = asm_cipherlast_be (b7, in7); ++ ++ b0 = VEC_BE_SWAP (b0, bige_const); ++ b1 = VEC_BE_SWAP (b1, bige_const); ++ b2 = VEC_BE_SWAP (b2, bige_const); ++ b3 = VEC_BE_SWAP (b3, bige_const); ++ b4 = VEC_BE_SWAP (b4, bige_const); ++ b5 = VEC_BE_SWAP (b5, bige_const); ++ b6 = VEC_BE_SWAP (b6, bige_const); ++ b7 = VEC_BE_SWAP (b7, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 0, b0); ++ VEC_STORE_BE_NOSWAP (out, 1, b1); ++ VEC_STORE_BE_NOSWAP (out, 2, b2); ++ VEC_STORE_BE_NOSWAP (out, 3, b3); ++ VEC_STORE_BE_NOSWAP (out, 4, b4); ++ VEC_STORE_BE_NOSWAP (out, 5, b5); ++ VEC_STORE_BE_NOSWAP (out, 6, b6); ++ VEC_STORE_BE_NOSWAP (out, 7, b7); ++ out += 8; ++ } ++ ++ if (nblocks >= 4) ++ { ++ b1 = asm_add_uint128 (ctr, one); ++ b2 = asm_add_uint128 (ctr, two); ++ b3 = asm_add_uint128 (ctr, three); ++ b0 = asm_xor (rkey0, ctr); ++ ctr = asm_add_uint128 (ctr, four); ++ b1 = asm_xor (rkey0, b1); ++ b2 = asm_xor (rkey0, b2); ++ b3 = asm_xor (rkey0, b3); ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ ++ in0 = VEC_LOAD_BE (in, 0, bige_const); ++ in1 = VEC_LOAD_BE (in, 1, bige_const); ++ in2 = VEC_LOAD_BE (in, 2, bige_const); ++ in3 = VEC_LOAD_BE (in, 3, bige_const); ++ ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ in0 = asm_xor (rkeylast, in0); ++ in1 = asm_xor (rkeylast, in1); ++ in2 = asm_xor (rkeylast, in2); ++ in3 = asm_xor (rkeylast, in3); ++ ++ b0 = asm_cipherlast_be (b0, in0); ++ b1 = asm_cipherlast_be (b1, in1); ++ b2 = asm_cipherlast_be (b2, in2); ++ b3 = asm_cipherlast_be (b3, in3); ++ ++ VEC_STORE_BE (out, 0, b0, bige_const); ++ VEC_STORE_BE (out, 1, b1, bige_const); ++ VEC_STORE_BE (out, 2, b2, bige_const); ++ VEC_STORE_BE (out, 3, b3, bige_const); ++ ++ in += 4; ++ out += 4; ++ nblocks -= 4; ++ } ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ b = ctr; ++ ctr = asm_add_uint128 (ctr, one); ++ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in, 0, bige_const); ++ ++ AES_ENCRYPT (b, rounds); ++ ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ out++; ++ in++; ++ } ++ ++ VEC_STORE_BE (ctr_arg, 0, ctr, bige_const); ++} ++ ++ ++size_t OCB_CRYPT_FUNC (gcry_cipher_hd_t c, void *outbuf_arg, ++ const void *inbuf_arg, size_t nblocks, ++ int encrypt) ++{ ++ const block bige_const = asm_load_be_const(); ++ RIJNDAEL_context *ctx = (void *)&c->context.c; ++ const u128_t *in = (const u128_t *)inbuf_arg; ++ u128_t *out = (u128_t *)outbuf_arg; ++ int rounds = ctx->rounds; ++ u64 data_nblocks = c->u_mode.ocb.data_nblocks; ++ block l0, l1, l2, l; ++ block b0, b1, b2, b3, b4, b5, b6, b7, b; ++ block iv0, iv1, iv2, iv3, iv4, iv5, iv6, iv7; ++ block rkey, rkeylf; ++ block ctr, iv; ++ ROUND_KEY_VARIABLES; ++ ++ iv = VEC_LOAD_BE (c->u_iv.iv, 0, bige_const); ++ ctr = VEC_LOAD_BE (c->u_ctr.ctr, 0, bige_const); ++ ++ l0 = VEC_LOAD_BE (c->u_mode.ocb.L[0], 0, bige_const); ++ l1 = VEC_LOAD_BE (c->u_mode.ocb.L[1], 0, bige_const); ++ l2 = VEC_LOAD_BE (c->u_mode.ocb.L[2], 0, bige_const); ++ ++ if (encrypt) ++ { ++ const u128_t *rk = (u128_t *)&ctx->keyschenc; ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ ++ for (; nblocks >= 8 && data_nblocks % 8; nblocks--) ++ { ++ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); ++ b = VEC_LOAD_BE (in, 0, bige_const); ++ ++ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ ++ iv ^= l; ++ /* Checksum_i = Checksum_{i-1} xor P_i */ ++ ctr ^= b; ++ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ ++ b ^= iv; ++ AES_ENCRYPT (b, rounds); ++ b ^= iv; ++ ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ in += 1; ++ out += 1; ++ } ++ ++ for (; nblocks >= 8; nblocks -= 8) ++ { ++ b0 = VEC_LOAD_BE_NOSWAP (in, 0); ++ b1 = VEC_LOAD_BE_NOSWAP (in, 1); ++ b2 = VEC_LOAD_BE_NOSWAP (in, 2); ++ b3 = VEC_LOAD_BE_NOSWAP (in, 3); ++ b4 = VEC_LOAD_BE_NOSWAP (in, 4); ++ b5 = VEC_LOAD_BE_NOSWAP (in, 5); ++ b6 = VEC_LOAD_BE_NOSWAP (in, 6); ++ b7 = VEC_LOAD_BE_NOSWAP (in, 7); ++ in += 8; ++ l = VEC_LOAD_BE_NOSWAP (ocb_get_l (c, data_nblocks += 8), 0); ++ b0 = VEC_BE_SWAP(b0, bige_const); ++ b1 = VEC_BE_SWAP(b1, bige_const); ++ b2 = VEC_BE_SWAP(b2, bige_const); ++ b3 = VEC_BE_SWAP(b3, bige_const); ++ b4 = VEC_BE_SWAP(b4, bige_const); ++ b5 = VEC_BE_SWAP(b5, bige_const); ++ b6 = VEC_BE_SWAP(b6, bige_const); ++ b7 = VEC_BE_SWAP(b7, bige_const); ++ l = VEC_BE_SWAP(l, bige_const); ++ ++ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7; ++ ++ iv ^= rkey0; ++ ++ iv0 = iv ^ l0; ++ iv1 = iv ^ l0 ^ l1; ++ iv2 = iv ^ l1; ++ iv3 = iv ^ l1 ^ l2; ++ iv4 = iv ^ l1 ^ l2 ^ l0; ++ iv5 = iv ^ l2 ^ l0; ++ iv6 = iv ^ l2; ++ iv7 = iv ^ l2 ^ l; ++ ++ b0 ^= iv0; ++ b1 ^= iv1; ++ b2 ^= iv2; ++ b3 ^= iv3; ++ b4 ^= iv4; ++ b5 ^= iv5; ++ b6 ^= iv6; ++ b7 ^= iv7; ++ iv = iv7 ^ rkey0; ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); \ ++ b4 = asm_cipher_be (b4, rkey); \ ++ b5 = asm_cipher_be (b5, rkey); \ ++ b6 = asm_cipher_be (b6, rkey); \ ++ b7 = asm_cipher_be (b7, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ ++ rkeylf = asm_xor (rkeylast, rkey0); ++ ++ DO_ROUND(8); ++ ++ iv0 = asm_xor (rkeylf, iv0); ++ iv1 = asm_xor (rkeylf, iv1); ++ iv2 = asm_xor (rkeylf, iv2); ++ iv3 = asm_xor (rkeylf, iv3); ++ iv4 = asm_xor (rkeylf, iv4); ++ iv5 = asm_xor (rkeylf, iv5); ++ iv6 = asm_xor (rkeylf, iv6); ++ iv7 = asm_xor (rkeylf, iv7); ++ ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ b0 = asm_cipherlast_be (b0, iv0); ++ b1 = asm_cipherlast_be (b1, iv1); ++ b2 = asm_cipherlast_be (b2, iv2); ++ b3 = asm_cipherlast_be (b3, iv3); ++ b4 = asm_cipherlast_be (b4, iv4); ++ b5 = asm_cipherlast_be (b5, iv5); ++ b6 = asm_cipherlast_be (b6, iv6); ++ b7 = asm_cipherlast_be (b7, iv7); ++ ++ b0 = VEC_BE_SWAP (b0, bige_const); ++ b1 = VEC_BE_SWAP (b1, bige_const); ++ b2 = VEC_BE_SWAP (b2, bige_const); ++ b3 = VEC_BE_SWAP (b3, bige_const); ++ b4 = VEC_BE_SWAP (b4, bige_const); ++ b5 = VEC_BE_SWAP (b5, bige_const); ++ b6 = VEC_BE_SWAP (b6, bige_const); ++ b7 = VEC_BE_SWAP (b7, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 0, b0); ++ VEC_STORE_BE_NOSWAP (out, 1, b1); ++ VEC_STORE_BE_NOSWAP (out, 2, b2); ++ VEC_STORE_BE_NOSWAP (out, 3, b3); ++ VEC_STORE_BE_NOSWAP (out, 4, b4); ++ VEC_STORE_BE_NOSWAP (out, 5, b5); ++ VEC_STORE_BE_NOSWAP (out, 6, b6); ++ VEC_STORE_BE_NOSWAP (out, 7, b7); ++ out += 8; ++ } ++ ++ if (nblocks >= 4 && (data_nblocks % 4) == 0) ++ { ++ b0 = VEC_LOAD_BE (in, 0, bige_const); ++ b1 = VEC_LOAD_BE (in, 1, bige_const); ++ b2 = VEC_LOAD_BE (in, 2, bige_const); ++ b3 = VEC_LOAD_BE (in, 3, bige_const); ++ ++ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const); ++ ++ ctr ^= b0 ^ b1 ^ b2 ^ b3; ++ ++ iv ^= rkey0; ++ ++ iv0 = iv ^ l0; ++ iv1 = iv ^ l0 ^ l1; ++ iv2 = iv ^ l1; ++ iv3 = iv ^ l1 ^ l; ++ ++ b0 ^= iv0; ++ b1 ^= iv1; ++ b2 ^= iv2; ++ b3 ^= iv3; ++ iv = iv3 ^ rkey0; ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ rkey = rkeylast ^ rkey0; ++ b0 = asm_cipherlast_be (b0, rkey ^ iv0); ++ b1 = asm_cipherlast_be (b1, rkey ^ iv1); ++ b2 = asm_cipherlast_be (b2, rkey ^ iv2); ++ b3 = asm_cipherlast_be (b3, rkey ^ iv3); ++ ++ VEC_STORE_BE (out, 0, b0, bige_const); ++ VEC_STORE_BE (out, 1, b1, bige_const); ++ VEC_STORE_BE (out, 2, b2, bige_const); ++ VEC_STORE_BE (out, 3, b3, bige_const); ++ ++ in += 4; ++ out += 4; ++ nblocks -= 4; ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); ++ b = VEC_LOAD_BE (in, 0, bige_const); ++ ++ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ ++ iv ^= l; ++ /* Checksum_i = Checksum_{i-1} xor P_i */ ++ ctr ^= b; ++ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ ++ b ^= iv; ++ AES_ENCRYPT (b, rounds); ++ b ^= iv; ++ ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ in += 1; ++ out += 1; ++ } ++ } ++ else ++ { ++ const u128_t *rk = (u128_t *)&ctx->keyschdec; ++ ++ if (!ctx->decryption_prepared) ++ { ++ internal_aes_ppc_prepare_decryption (ctx); ++ ctx->decryption_prepared = 1; ++ } ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ ++ for (; nblocks >= 8 && data_nblocks % 8; nblocks--) ++ { ++ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); ++ b = VEC_LOAD_BE (in, 0, bige_const); ++ ++ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ ++ iv ^= l; ++ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ ++ b ^= iv; ++ AES_DECRYPT (b, rounds); ++ b ^= iv; ++ /* Checksum_i = Checksum_{i-1} xor P_i */ ++ ctr ^= b; ++ ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ in += 1; ++ out += 1; ++ } ++ ++ for (; nblocks >= 8; nblocks -= 8) ++ { ++ b0 = VEC_LOAD_BE_NOSWAP (in, 0); ++ b1 = VEC_LOAD_BE_NOSWAP (in, 1); ++ b2 = VEC_LOAD_BE_NOSWAP (in, 2); ++ b3 = VEC_LOAD_BE_NOSWAP (in, 3); ++ b4 = VEC_LOAD_BE_NOSWAP (in, 4); ++ b5 = VEC_LOAD_BE_NOSWAP (in, 5); ++ b6 = VEC_LOAD_BE_NOSWAP (in, 6); ++ b7 = VEC_LOAD_BE_NOSWAP (in, 7); ++ in += 8; ++ l = VEC_LOAD_BE_NOSWAP (ocb_get_l (c, data_nblocks += 8), 0); ++ b0 = VEC_BE_SWAP(b0, bige_const); ++ b1 = VEC_BE_SWAP(b1, bige_const); ++ b2 = VEC_BE_SWAP(b2, bige_const); ++ b3 = VEC_BE_SWAP(b3, bige_const); ++ b4 = VEC_BE_SWAP(b4, bige_const); ++ b5 = VEC_BE_SWAP(b5, bige_const); ++ b6 = VEC_BE_SWAP(b6, bige_const); ++ b7 = VEC_BE_SWAP(b7, bige_const); ++ l = VEC_BE_SWAP(l, bige_const); ++ ++ iv ^= rkey0; ++ ++ iv0 = iv ^ l0; ++ iv1 = iv ^ l0 ^ l1; ++ iv2 = iv ^ l1; ++ iv3 = iv ^ l1 ^ l2; ++ iv4 = iv ^ l1 ^ l2 ^ l0; ++ iv5 = iv ^ l2 ^ l0; ++ iv6 = iv ^ l2; ++ iv7 = iv ^ l2 ^ l; ++ ++ b0 ^= iv0; ++ b1 ^= iv1; ++ b2 ^= iv2; ++ b3 ^= iv3; ++ b4 ^= iv4; ++ b5 ^= iv5; ++ b6 ^= iv6; ++ b7 ^= iv7; ++ iv = iv7 ^ rkey0; ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_ncipher_be (b0, rkey); \ ++ b1 = asm_ncipher_be (b1, rkey); \ ++ b2 = asm_ncipher_be (b2, rkey); \ ++ b3 = asm_ncipher_be (b3, rkey); \ ++ b4 = asm_ncipher_be (b4, rkey); \ ++ b5 = asm_ncipher_be (b5, rkey); \ ++ b6 = asm_ncipher_be (b6, rkey); \ ++ b7 = asm_ncipher_be (b7, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ ++ rkeylf = asm_xor (rkeylast, rkey0); ++ ++ DO_ROUND(8); ++ ++ iv0 = asm_xor (rkeylf, iv0); ++ iv1 = asm_xor (rkeylf, iv1); ++ iv2 = asm_xor (rkeylf, iv2); ++ iv3 = asm_xor (rkeylf, iv3); ++ iv4 = asm_xor (rkeylf, iv4); ++ iv5 = asm_xor (rkeylf, iv5); ++ iv6 = asm_xor (rkeylf, iv6); ++ iv7 = asm_xor (rkeylf, iv7); ++ ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ b0 = asm_ncipherlast_be (b0, iv0); ++ b1 = asm_ncipherlast_be (b1, iv1); ++ b2 = asm_ncipherlast_be (b2, iv2); ++ b3 = asm_ncipherlast_be (b3, iv3); ++ b4 = asm_ncipherlast_be (b4, iv4); ++ b5 = asm_ncipherlast_be (b5, iv5); ++ b6 = asm_ncipherlast_be (b6, iv6); ++ b7 = asm_ncipherlast_be (b7, iv7); ++ ++ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7; ++ ++ b0 = VEC_BE_SWAP (b0, bige_const); ++ b1 = VEC_BE_SWAP (b1, bige_const); ++ b2 = VEC_BE_SWAP (b2, bige_const); ++ b3 = VEC_BE_SWAP (b3, bige_const); ++ b4 = VEC_BE_SWAP (b4, bige_const); ++ b5 = VEC_BE_SWAP (b5, bige_const); ++ b6 = VEC_BE_SWAP (b6, bige_const); ++ b7 = VEC_BE_SWAP (b7, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 0, b0); ++ VEC_STORE_BE_NOSWAP (out, 1, b1); ++ VEC_STORE_BE_NOSWAP (out, 2, b2); ++ VEC_STORE_BE_NOSWAP (out, 3, b3); ++ VEC_STORE_BE_NOSWAP (out, 4, b4); ++ VEC_STORE_BE_NOSWAP (out, 5, b5); ++ VEC_STORE_BE_NOSWAP (out, 6, b6); ++ VEC_STORE_BE_NOSWAP (out, 7, b7); ++ out += 8; ++ } ++ ++ if (nblocks >= 4 && (data_nblocks % 4) == 0) ++ { ++ b0 = VEC_LOAD_BE (in, 0, bige_const); ++ b1 = VEC_LOAD_BE (in, 1, bige_const); ++ b2 = VEC_LOAD_BE (in, 2, bige_const); ++ b3 = VEC_LOAD_BE (in, 3, bige_const); ++ ++ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const); ++ ++ iv ^= rkey0; ++ ++ iv0 = iv ^ l0; ++ iv1 = iv ^ l0 ^ l1; ++ iv2 = iv ^ l1; ++ iv3 = iv ^ l1 ^ l; ++ ++ b0 ^= iv0; ++ b1 ^= iv1; ++ b2 ^= iv2; ++ b3 ^= iv3; ++ iv = iv3 ^ rkey0; ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_ncipher_be (b0, rkey); \ ++ b1 = asm_ncipher_be (b1, rkey); \ ++ b2 = asm_ncipher_be (b2, rkey); \ ++ b3 = asm_ncipher_be (b3, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ rkey = rkeylast ^ rkey0; ++ b0 = asm_ncipherlast_be (b0, rkey ^ iv0); ++ b1 = asm_ncipherlast_be (b1, rkey ^ iv1); ++ b2 = asm_ncipherlast_be (b2, rkey ^ iv2); ++ b3 = asm_ncipherlast_be (b3, rkey ^ iv3); ++ ++ VEC_STORE_BE (out, 0, b0, bige_const); ++ VEC_STORE_BE (out, 1, b1, bige_const); ++ VEC_STORE_BE (out, 2, b2, bige_const); ++ VEC_STORE_BE (out, 3, b3, bige_const); ++ ++ ctr ^= b0 ^ b1 ^ b2 ^ b3; ++ ++ in += 4; ++ out += 4; ++ nblocks -= 4; ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); ++ b = VEC_LOAD_BE (in, 0, bige_const); ++ ++ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ ++ iv ^= l; ++ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ ++ b ^= iv; ++ AES_DECRYPT (b, rounds); ++ b ^= iv; ++ /* Checksum_i = Checksum_{i-1} xor P_i */ ++ ctr ^= b; ++ ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ in += 1; ++ out += 1; ++ } ++ } ++ ++ VEC_STORE_BE (c->u_iv.iv, 0, iv, bige_const); ++ VEC_STORE_BE (c->u_ctr.ctr, 0, ctr, bige_const); ++ c->u_mode.ocb.data_nblocks = data_nblocks; ++ ++ return 0; ++} ++ ++size_t OCB_AUTH_FUNC (gcry_cipher_hd_t c, void *abuf_arg, size_t nblocks) ++{ ++ const block bige_const = asm_load_be_const(); ++ RIJNDAEL_context *ctx = (void *)&c->context.c; ++ const u128_t *rk = (u128_t *)&ctx->keyschenc; ++ const u128_t *abuf = (const u128_t *)abuf_arg; ++ int rounds = ctx->rounds; ++ u64 data_nblocks = c->u_mode.ocb.aad_nblocks; ++ block l0, l1, l2, l; ++ block b0, b1, b2, b3, b4, b5, b6, b7, b; ++ block iv0, iv1, iv2, iv3, iv4, iv5, iv6, iv7; ++ block rkey, frkey; ++ block ctr, iv; ++ ROUND_KEY_VARIABLES; ++ ++ iv = VEC_LOAD_BE (c->u_mode.ocb.aad_offset, 0, bige_const); ++ ctr = VEC_LOAD_BE (c->u_mode.ocb.aad_sum, 0, bige_const); ++ ++ l0 = VEC_LOAD_BE (c->u_mode.ocb.L[0], 0, bige_const); ++ l1 = VEC_LOAD_BE (c->u_mode.ocb.L[1], 0, bige_const); ++ l2 = VEC_LOAD_BE (c->u_mode.ocb.L[2], 0, bige_const); ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ ++ for (; nblocks >= 8 && data_nblocks % 8; nblocks--) ++ { ++ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); ++ b = VEC_LOAD_BE (abuf, 0, bige_const); ++ ++ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ ++ iv ^= l; ++ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ ++ b ^= iv; ++ AES_ENCRYPT (b, rounds); ++ ctr ^= b; ++ ++ abuf += 1; ++ } ++ ++ for (; nblocks >= 8; nblocks -= 8) ++ { ++ b0 = VEC_LOAD_BE (abuf, 0, bige_const); ++ b1 = VEC_LOAD_BE (abuf, 1, bige_const); ++ b2 = VEC_LOAD_BE (abuf, 2, bige_const); ++ b3 = VEC_LOAD_BE (abuf, 3, bige_const); ++ b4 = VEC_LOAD_BE (abuf, 4, bige_const); ++ b5 = VEC_LOAD_BE (abuf, 5, bige_const); ++ b6 = VEC_LOAD_BE (abuf, 6, bige_const); ++ b7 = VEC_LOAD_BE (abuf, 7, bige_const); ++ ++ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 8), 0, bige_const); ++ ++ frkey = rkey0; ++ iv ^= frkey; ++ ++ iv0 = iv ^ l0; ++ iv1 = iv ^ l0 ^ l1; ++ iv2 = iv ^ l1; ++ iv3 = iv ^ l1 ^ l2; ++ iv4 = iv ^ l1 ^ l2 ^ l0; ++ iv5 = iv ^ l2 ^ l0; ++ iv6 = iv ^ l2; ++ iv7 = iv ^ l2 ^ l; ++ ++ b0 ^= iv0; ++ b1 ^= iv1; ++ b2 ^= iv2; ++ b3 ^= iv3; ++ b4 ^= iv4; ++ b5 ^= iv5; ++ b6 ^= iv6; ++ b7 ^= iv7; ++ iv = iv7 ^ frkey; ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); \ ++ b4 = asm_cipher_be (b4, rkey); \ ++ b5 = asm_cipher_be (b5, rkey); \ ++ b6 = asm_cipher_be (b6, rkey); \ ++ b7 = asm_cipher_be (b7, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ rkey = rkeylast; ++ b0 = asm_cipherlast_be (b0, rkey); ++ b1 = asm_cipherlast_be (b1, rkey); ++ b2 = asm_cipherlast_be (b2, rkey); ++ b3 = asm_cipherlast_be (b3, rkey); ++ b4 = asm_cipherlast_be (b4, rkey); ++ b5 = asm_cipherlast_be (b5, rkey); ++ b6 = asm_cipherlast_be (b6, rkey); ++ b7 = asm_cipherlast_be (b7, rkey); ++ ++ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7; ++ ++ abuf += 8; ++ } ++ ++ if (nblocks >= 4 && (data_nblocks % 4) == 0) ++ { ++ b0 = VEC_LOAD_BE (abuf, 0, bige_const); ++ b1 = VEC_LOAD_BE (abuf, 1, bige_const); ++ b2 = VEC_LOAD_BE (abuf, 2, bige_const); ++ b3 = VEC_LOAD_BE (abuf, 3, bige_const); ++ ++ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const); ++ ++ frkey = rkey0; ++ iv ^= frkey; ++ ++ iv0 = iv ^ l0; ++ iv1 = iv ^ l0 ^ l1; ++ iv2 = iv ^ l1; ++ iv3 = iv ^ l1 ^ l; ++ ++ b0 ^= iv0; ++ b1 ^= iv1; ++ b2 ^= iv2; ++ b3 ^= iv3; ++ iv = iv3 ^ frkey; ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ rkey = rkeylast; ++ b0 = asm_cipherlast_be (b0, rkey); ++ b1 = asm_cipherlast_be (b1, rkey); ++ b2 = asm_cipherlast_be (b2, rkey); ++ b3 = asm_cipherlast_be (b3, rkey); ++ ++ ctr ^= b0 ^ b1 ^ b2 ^ b3; ++ ++ abuf += 4; ++ nblocks -= 4; ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); ++ b = VEC_LOAD_BE (abuf, 0, bige_const); ++ ++ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ ++ iv ^= l; ++ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ ++ b ^= iv; ++ AES_ENCRYPT (b, rounds); ++ ctr ^= b; ++ ++ abuf += 1; ++ } ++ ++ VEC_STORE_BE (c->u_mode.ocb.aad_offset, 0, iv, bige_const); ++ VEC_STORE_BE (c->u_mode.ocb.aad_sum, 0, ctr, bige_const); ++ c->u_mode.ocb.aad_nblocks = data_nblocks; ++ ++ return 0; ++} ++ ++ ++void XTS_CRYPT_FUNC (void *context, unsigned char *tweak_arg, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, int encrypt) ++{ ++#ifdef WORDS_BIGENDIAN ++ static const block vec_bswap128_const = ++ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; ++#else ++ static const block vec_bswap128_const = ++ { ~15, ~14, ~13, ~12, ~11, ~10, ~9, ~8, ~7, ~6, ~5, ~4, ~3, ~2, ~1, ~0 }; ++#endif ++ static const unsigned char vec_tweak_const[16] = ++ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x87 }; ++ static const vector unsigned long long vec_shift63_const = ++ { 63, 63 }; ++ const block bige_const = asm_load_be_const(); ++ RIJNDAEL_context *ctx = context; ++ const u128_t *in = (const u128_t *)inbuf_arg; ++ u128_t *out = (u128_t *)outbuf_arg; ++ int rounds = ctx->rounds; ++ block tweak; ++ block b0, b1, b2, b3, b4, b5, b6, b7, b, rkey, rkeylf; ++ block tweak0, tweak1, tweak2, tweak3, tweak4, tweak5, tweak6, tweak7; ++ block tweak_const, bswap128_const, shift63_const; ++ ROUND_KEY_VARIABLES; ++ ++ tweak_const = VEC_LOAD_BE (&vec_tweak_const, 0, bige_const); ++ bswap128_const = ALIGNED_LOAD (&vec_bswap128_const, 0); ++ shift63_const = ALIGNED_LOAD (&vec_shift63_const, 0); ++ ++ tweak = VEC_LOAD_BE (tweak_arg, 0, bige_const); ++ tweak = asm_vperm1 (tweak, bswap128_const); ++ ++#define GEN_TWEAK(tout, tin) /* Generate next tweak. */ \ ++ do { \ ++ block tmp1, tmp2; \ ++ tmp1 = asm_swap_uint64_halfs(tin); \ ++ tmp2 = asm_add_uint64(tin, tin); \ ++ tmp1 = asm_sra_int64(tmp1, shift63_const) & tweak_const; \ ++ tout = asm_xor(tmp1, tmp2); \ ++ } while (0) ++ ++ if (encrypt) ++ { ++ const u128_t *rk = (u128_t *)&ctx->keyschenc; ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ ++ for (; nblocks >= 8; nblocks -= 8) ++ { ++ b0 = VEC_LOAD_BE_NOSWAP (in, 0); ++ b1 = VEC_LOAD_BE_NOSWAP (in, 1); ++ b2 = VEC_LOAD_BE_NOSWAP (in, 2); ++ b3 = VEC_LOAD_BE_NOSWAP (in, 3); ++ tweak0 = tweak; ++ GEN_TWEAK (tweak1, tweak0); ++ tweak0 = asm_vperm1 (tweak0, bswap128_const); ++ b4 = VEC_LOAD_BE_NOSWAP (in, 4); ++ b5 = VEC_LOAD_BE_NOSWAP (in, 5); ++ GEN_TWEAK (tweak2, tweak1); ++ tweak1 = asm_vperm1 (tweak1, bswap128_const); ++ b6 = VEC_LOAD_BE_NOSWAP (in, 6); ++ b7 = VEC_LOAD_BE_NOSWAP (in, 7); ++ in += 8; ++ ++ b0 = VEC_BE_SWAP(b0, bige_const); ++ b1 = VEC_BE_SWAP(b1, bige_const); ++ GEN_TWEAK (tweak3, tweak2); ++ tweak2 = asm_vperm1 (tweak2, bswap128_const); ++ GEN_TWEAK (tweak4, tweak3); ++ tweak3 = asm_vperm1 (tweak3, bswap128_const); ++ b2 = VEC_BE_SWAP(b2, bige_const); ++ b3 = VEC_BE_SWAP(b3, bige_const); ++ GEN_TWEAK (tweak5, tweak4); ++ tweak4 = asm_vperm1 (tweak4, bswap128_const); ++ GEN_TWEAK (tweak6, tweak5); ++ tweak5 = asm_vperm1 (tweak5, bswap128_const); ++ b4 = VEC_BE_SWAP(b4, bige_const); ++ b5 = VEC_BE_SWAP(b5, bige_const); ++ GEN_TWEAK (tweak7, tweak6); ++ tweak6 = asm_vperm1 (tweak6, bswap128_const); ++ GEN_TWEAK (tweak, tweak7); ++ tweak7 = asm_vperm1 (tweak7, bswap128_const); ++ b6 = VEC_BE_SWAP(b6, bige_const); ++ b7 = VEC_BE_SWAP(b7, bige_const); ++ ++ tweak0 = asm_xor (tweak0, rkey0); ++ tweak1 = asm_xor (tweak1, rkey0); ++ tweak2 = asm_xor (tweak2, rkey0); ++ tweak3 = asm_xor (tweak3, rkey0); ++ tweak4 = asm_xor (tweak4, rkey0); ++ tweak5 = asm_xor (tweak5, rkey0); ++ tweak6 = asm_xor (tweak6, rkey0); ++ tweak7 = asm_xor (tweak7, rkey0); ++ ++ b0 = asm_xor (b0, tweak0); ++ b1 = asm_xor (b1, tweak1); ++ b2 = asm_xor (b2, tweak2); ++ b3 = asm_xor (b3, tweak3); ++ b4 = asm_xor (b4, tweak4); ++ b5 = asm_xor (b5, tweak5); ++ b6 = asm_xor (b6, tweak6); ++ b7 = asm_xor (b7, tweak7); ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); \ ++ b4 = asm_cipher_be (b4, rkey); \ ++ b5 = asm_cipher_be (b5, rkey); \ ++ b6 = asm_cipher_be (b6, rkey); \ ++ b7 = asm_cipher_be (b7, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ ++ rkeylf = asm_xor (rkeylast, rkey0); ++ ++ DO_ROUND(8); ++ ++ tweak0 = asm_xor (tweak0, rkeylf); ++ tweak1 = asm_xor (tweak1, rkeylf); ++ tweak2 = asm_xor (tweak2, rkeylf); ++ tweak3 = asm_xor (tweak3, rkeylf); ++ tweak4 = asm_xor (tweak4, rkeylf); ++ tweak5 = asm_xor (tweak5, rkeylf); ++ tweak6 = asm_xor (tweak6, rkeylf); ++ tweak7 = asm_xor (tweak7, rkeylf); ++ ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ b0 = asm_cipherlast_be (b0, tweak0); ++ b1 = asm_cipherlast_be (b1, tweak1); ++ b2 = asm_cipherlast_be (b2, tweak2); ++ b3 = asm_cipherlast_be (b3, tweak3); ++ b0 = VEC_BE_SWAP (b0, bige_const); ++ b1 = VEC_BE_SWAP (b1, bige_const); ++ b4 = asm_cipherlast_be (b4, tweak4); ++ b5 = asm_cipherlast_be (b5, tweak5); ++ b2 = VEC_BE_SWAP (b2, bige_const); ++ b3 = VEC_BE_SWAP (b3, bige_const); ++ b6 = asm_cipherlast_be (b6, tweak6); ++ b7 = asm_cipherlast_be (b7, tweak7); ++ VEC_STORE_BE_NOSWAP (out, 0, b0); ++ VEC_STORE_BE_NOSWAP (out, 1, b1); ++ b4 = VEC_BE_SWAP (b4, bige_const); ++ b5 = VEC_BE_SWAP (b5, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 2, b2); ++ VEC_STORE_BE_NOSWAP (out, 3, b3); ++ b6 = VEC_BE_SWAP (b6, bige_const); ++ b7 = VEC_BE_SWAP (b7, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 4, b4); ++ VEC_STORE_BE_NOSWAP (out, 5, b5); ++ VEC_STORE_BE_NOSWAP (out, 6, b6); ++ VEC_STORE_BE_NOSWAP (out, 7, b7); ++ out += 8; ++ } ++ ++ if (nblocks >= 4) ++ { ++ tweak0 = tweak; ++ GEN_TWEAK (tweak1, tweak0); ++ GEN_TWEAK (tweak2, tweak1); ++ GEN_TWEAK (tweak3, tweak2); ++ GEN_TWEAK (tweak, tweak3); ++ ++ b0 = VEC_LOAD_BE (in, 0, bige_const); ++ b1 = VEC_LOAD_BE (in, 1, bige_const); ++ b2 = VEC_LOAD_BE (in, 2, bige_const); ++ b3 = VEC_LOAD_BE (in, 3, bige_const); ++ ++ tweak0 = asm_vperm1 (tweak0, bswap128_const); ++ tweak1 = asm_vperm1 (tweak1, bswap128_const); ++ tweak2 = asm_vperm1 (tweak2, bswap128_const); ++ tweak3 = asm_vperm1 (tweak3, bswap128_const); ++ ++ b0 ^= tweak0 ^ rkey0; ++ b1 ^= tweak1 ^ rkey0; ++ b2 ^= tweak2 ^ rkey0; ++ b3 ^= tweak3 ^ rkey0; ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_cipher_be (b0, rkey); \ ++ b1 = asm_cipher_be (b1, rkey); \ ++ b2 = asm_cipher_be (b2, rkey); \ ++ b3 = asm_cipher_be (b3, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ rkey = rkeylast; ++ b0 = asm_cipherlast_be (b0, rkey ^ tweak0); ++ b1 = asm_cipherlast_be (b1, rkey ^ tweak1); ++ b2 = asm_cipherlast_be (b2, rkey ^ tweak2); ++ b3 = asm_cipherlast_be (b3, rkey ^ tweak3); ++ ++ VEC_STORE_BE (out, 0, b0, bige_const); ++ VEC_STORE_BE (out, 1, b1, bige_const); ++ VEC_STORE_BE (out, 2, b2, bige_const); ++ VEC_STORE_BE (out, 3, b3, bige_const); ++ ++ in += 4; ++ out += 4; ++ nblocks -= 4; ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ tweak0 = asm_vperm1 (tweak, bswap128_const); ++ ++ /* Xor-Encrypt/Decrypt-Xor block. */ ++ b = VEC_LOAD_BE (in, 0, bige_const) ^ tweak0; ++ ++ /* Generate next tweak. */ ++ GEN_TWEAK (tweak, tweak); ++ ++ AES_ENCRYPT (b, rounds); ++ ++ b ^= tweak0; ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ in++; ++ out++; ++ } ++ } ++ else ++ { ++ const u128_t *rk = (u128_t *)&ctx->keyschdec; ++ ++ if (!ctx->decryption_prepared) ++ { ++ internal_aes_ppc_prepare_decryption (ctx); ++ ctx->decryption_prepared = 1; ++ } ++ ++ PRELOAD_ROUND_KEYS (rounds); ++ ++ for (; nblocks >= 8; nblocks -= 8) ++ { ++ b0 = VEC_LOAD_BE_NOSWAP (in, 0); ++ b1 = VEC_LOAD_BE_NOSWAP (in, 1); ++ b2 = VEC_LOAD_BE_NOSWAP (in, 2); ++ b3 = VEC_LOAD_BE_NOSWAP (in, 3); ++ tweak0 = tweak; ++ GEN_TWEAK (tweak1, tweak0); ++ tweak0 = asm_vperm1 (tweak0, bswap128_const); ++ b4 = VEC_LOAD_BE_NOSWAP (in, 4); ++ b5 = VEC_LOAD_BE_NOSWAP (in, 5); ++ GEN_TWEAK (tweak2, tweak1); ++ tweak1 = asm_vperm1 (tweak1, bswap128_const); ++ b6 = VEC_LOAD_BE_NOSWAP (in, 6); ++ b7 = VEC_LOAD_BE_NOSWAP (in, 7); ++ in += 8; ++ ++ b0 = VEC_BE_SWAP(b0, bige_const); ++ b1 = VEC_BE_SWAP(b1, bige_const); ++ GEN_TWEAK (tweak3, tweak2); ++ tweak2 = asm_vperm1 (tweak2, bswap128_const); ++ GEN_TWEAK (tweak4, tweak3); ++ tweak3 = asm_vperm1 (tweak3, bswap128_const); ++ b2 = VEC_BE_SWAP(b2, bige_const); ++ b3 = VEC_BE_SWAP(b3, bige_const); ++ GEN_TWEAK (tweak5, tweak4); ++ tweak4 = asm_vperm1 (tweak4, bswap128_const); ++ GEN_TWEAK (tweak6, tweak5); ++ tweak5 = asm_vperm1 (tweak5, bswap128_const); ++ b4 = VEC_BE_SWAP(b4, bige_const); ++ b5 = VEC_BE_SWAP(b5, bige_const); ++ GEN_TWEAK (tweak7, tweak6); ++ tweak6 = asm_vperm1 (tweak6, bswap128_const); ++ GEN_TWEAK (tweak, tweak7); ++ tweak7 = asm_vperm1 (tweak7, bswap128_const); ++ b6 = VEC_BE_SWAP(b6, bige_const); ++ b7 = VEC_BE_SWAP(b7, bige_const); ++ ++ tweak0 = asm_xor (tweak0, rkey0); ++ tweak1 = asm_xor (tweak1, rkey0); ++ tweak2 = asm_xor (tweak2, rkey0); ++ tweak3 = asm_xor (tweak3, rkey0); ++ tweak4 = asm_xor (tweak4, rkey0); ++ tweak5 = asm_xor (tweak5, rkey0); ++ tweak6 = asm_xor (tweak6, rkey0); ++ tweak7 = asm_xor (tweak7, rkey0); ++ ++ b0 = asm_xor (b0, tweak0); ++ b1 = asm_xor (b1, tweak1); ++ b2 = asm_xor (b2, tweak2); ++ b3 = asm_xor (b3, tweak3); ++ b4 = asm_xor (b4, tweak4); ++ b5 = asm_xor (b5, tweak5); ++ b6 = asm_xor (b6, tweak6); ++ b7 = asm_xor (b7, tweak7); ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_ncipher_be (b0, rkey); \ ++ b1 = asm_ncipher_be (b1, rkey); \ ++ b2 = asm_ncipher_be (b2, rkey); \ ++ b3 = asm_ncipher_be (b3, rkey); \ ++ b4 = asm_ncipher_be (b4, rkey); \ ++ b5 = asm_ncipher_be (b5, rkey); \ ++ b6 = asm_ncipher_be (b6, rkey); \ ++ b7 = asm_ncipher_be (b7, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ ++ rkeylf = asm_xor (rkeylast, rkey0); ++ ++ DO_ROUND(8); ++ ++ tweak0 = asm_xor (tweak0, rkeylf); ++ tweak1 = asm_xor (tweak1, rkeylf); ++ tweak2 = asm_xor (tweak2, rkeylf); ++ tweak3 = asm_xor (tweak3, rkeylf); ++ tweak4 = asm_xor (tweak4, rkeylf); ++ tweak5 = asm_xor (tweak5, rkeylf); ++ tweak6 = asm_xor (tweak6, rkeylf); ++ tweak7 = asm_xor (tweak7, rkeylf); ++ ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ b0 = asm_ncipherlast_be (b0, tweak0); ++ b1 = asm_ncipherlast_be (b1, tweak1); ++ b2 = asm_ncipherlast_be (b2, tweak2); ++ b3 = asm_ncipherlast_be (b3, tweak3); ++ b0 = VEC_BE_SWAP (b0, bige_const); ++ b1 = VEC_BE_SWAP (b1, bige_const); ++ b4 = asm_ncipherlast_be (b4, tweak4); ++ b5 = asm_ncipherlast_be (b5, tweak5); ++ b2 = VEC_BE_SWAP (b2, bige_const); ++ b3 = VEC_BE_SWAP (b3, bige_const); ++ b6 = asm_ncipherlast_be (b6, tweak6); ++ b7 = asm_ncipherlast_be (b7, tweak7); ++ VEC_STORE_BE_NOSWAP (out, 0, b0); ++ VEC_STORE_BE_NOSWAP (out, 1, b1); ++ b4 = VEC_BE_SWAP (b4, bige_const); ++ b5 = VEC_BE_SWAP (b5, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 2, b2); ++ VEC_STORE_BE_NOSWAP (out, 3, b3); ++ b6 = VEC_BE_SWAP (b6, bige_const); ++ b7 = VEC_BE_SWAP (b7, bige_const); ++ VEC_STORE_BE_NOSWAP (out, 4, b4); ++ VEC_STORE_BE_NOSWAP (out, 5, b5); ++ VEC_STORE_BE_NOSWAP (out, 6, b6); ++ VEC_STORE_BE_NOSWAP (out, 7, b7); ++ out += 8; ++ } ++ ++ if (nblocks >= 4) ++ { ++ tweak0 = tweak; ++ GEN_TWEAK (tweak1, tweak0); ++ GEN_TWEAK (tweak2, tweak1); ++ GEN_TWEAK (tweak3, tweak2); ++ GEN_TWEAK (tweak, tweak3); ++ ++ b0 = VEC_LOAD_BE (in, 0, bige_const); ++ b1 = VEC_LOAD_BE (in, 1, bige_const); ++ b2 = VEC_LOAD_BE (in, 2, bige_const); ++ b3 = VEC_LOAD_BE (in, 3, bige_const); ++ ++ tweak0 = asm_vperm1 (tweak0, bswap128_const); ++ tweak1 = asm_vperm1 (tweak1, bswap128_const); ++ tweak2 = asm_vperm1 (tweak2, bswap128_const); ++ tweak3 = asm_vperm1 (tweak3, bswap128_const); ++ ++ b0 ^= tweak0 ^ rkey0; ++ b1 ^= tweak1 ^ rkey0; ++ b2 ^= tweak2 ^ rkey0; ++ b3 ^= tweak3 ^ rkey0; ++ ++#define DO_ROUND(r) \ ++ rkey = ALIGNED_LOAD (rk, r); \ ++ b0 = asm_ncipher_be (b0, rkey); \ ++ b1 = asm_ncipher_be (b1, rkey); \ ++ b2 = asm_ncipher_be (b2, rkey); \ ++ b3 = asm_ncipher_be (b3, rkey); ++ ++ DO_ROUND(1); ++ DO_ROUND(2); ++ DO_ROUND(3); ++ DO_ROUND(4); ++ DO_ROUND(5); ++ DO_ROUND(6); ++ DO_ROUND(7); ++ DO_ROUND(8); ++ DO_ROUND(9); ++ if (rounds >= 12) ++ { ++ DO_ROUND(10); ++ DO_ROUND(11); ++ if (rounds > 12) ++ { ++ DO_ROUND(12); ++ DO_ROUND(13); ++ } ++ } ++ ++#undef DO_ROUND ++ ++ rkey = rkeylast; ++ b0 = asm_ncipherlast_be (b0, rkey ^ tweak0); ++ b1 = asm_ncipherlast_be (b1, rkey ^ tweak1); ++ b2 = asm_ncipherlast_be (b2, rkey ^ tweak2); ++ b3 = asm_ncipherlast_be (b3, rkey ^ tweak3); ++ ++ VEC_STORE_BE (out, 0, b0, bige_const); ++ VEC_STORE_BE (out, 1, b1, bige_const); ++ VEC_STORE_BE (out, 2, b2, bige_const); ++ VEC_STORE_BE (out, 3, b3, bige_const); ++ ++ in += 4; ++ out += 4; ++ nblocks -= 4; ++ } ++ ++ for (; nblocks; nblocks--) ++ { ++ tweak0 = asm_vperm1 (tweak, bswap128_const); ++ ++ /* Xor-Encrypt/Decrypt-Xor block. */ ++ b = VEC_LOAD_BE (in, 0, bige_const) ^ tweak0; ++ ++ /* Generate next tweak. */ ++ GEN_TWEAK (tweak, tweak); ++ ++ AES_DECRYPT (b, rounds); ++ ++ b ^= tweak0; ++ VEC_STORE_BE (out, 0, b, bige_const); ++ ++ in++; ++ out++; ++ } ++ } ++ ++ tweak = asm_vperm1 (tweak, bswap128_const); ++ VEC_STORE_BE (tweak_arg, 0, tweak, bige_const); ++ ++#undef GEN_TWEAK ++} +diff -up libgcrypt-1.8.5/cipher/rijndael-ssse3-amd64.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-ssse3-amd64.c +--- libgcrypt-1.8.5/cipher/rijndael-ssse3-amd64.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/rijndael-ssse3-amd64.c 2020-04-22 18:29:41.679862057 +0200 +@@ -208,11 +208,11 @@ _gcry_aes_ssse3_do_setkey (RIJNDAEL_cont + + + /* Make a decryption key from an encryption key. */ +-void +-_gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx) ++static inline void ++do_ssse3_prepare_decryption (RIJNDAEL_context *ctx, ++ byte ssse3_state[SSSE3_STATE_SIZE]) + { + unsigned int keybits = (ctx->rounds - 10) * 32 + 128; +- byte ssse3_state[SSSE3_STATE_SIZE]; + + vpaes_ssse3_prepare(); + +@@ -237,6 +237,14 @@ _gcry_aes_ssse3_prepare_decryption (RIJN + vpaes_ssse3_cleanup(); + } + ++void ++_gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx) ++{ ++ byte ssse3_state[SSSE3_STATE_SIZE]; ++ ++ do_ssse3_prepare_decryption(ctx, ssse3_state); ++} ++ + + /* Encrypt one block using the Intel SSSE3 instructions. Block is input + * and output through SSE register xmm0. */ +@@ -295,9 +303,9 @@ _gcry_aes_ssse3_encrypt (const RIJNDAEL_ + + + void +-_gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, +- size_t nblocks) ++_gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks) + { + unsigned int nrounds = ctx->rounds; + byte ssse3_state[SSSE3_STATE_SIZE]; +@@ -334,9 +342,9 @@ _gcry_aes_ssse3_cfb_enc (RIJNDAEL_contex + + + void +-_gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, +- size_t nblocks, int cbc_mac) ++_gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks, int cbc_mac) + { + unsigned int nrounds = ctx->rounds; + byte ssse3_state[SSSE3_STATE_SIZE]; +@@ -379,9 +387,9 @@ _gcry_aes_ssse3_cbc_enc (RIJNDAEL_contex + + + void +-_gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *ctr, +- size_t nblocks) ++_gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, unsigned char *ctr, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks) + { + static const unsigned char be_mask[16] __attribute__ ((aligned (16))) = + { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; +@@ -447,7 +455,7 @@ _gcry_aes_ssse3_ctr_enc (RIJNDAEL_contex + + unsigned int + _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, +- const unsigned char *src) ++ const unsigned char *src) + { + unsigned int nrounds = ctx->rounds; + byte ssse3_state[SSSE3_STATE_SIZE]; +@@ -468,9 +476,9 @@ _gcry_aes_ssse3_decrypt (const RIJNDAEL_ + + + void +-_gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, +- size_t nblocks) ++_gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks) + { + unsigned int nrounds = ctx->rounds; + byte ssse3_state[SSSE3_STATE_SIZE]; +@@ -508,13 +516,19 @@ _gcry_aes_ssse3_cfb_dec (RIJNDAEL_contex + + + void +-_gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, +- const unsigned char *inbuf, unsigned char *iv, +- size_t nblocks) ++_gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, ++ unsigned char *outbuf, const unsigned char *inbuf, ++ size_t nblocks) + { + unsigned int nrounds = ctx->rounds; + byte ssse3_state[SSSE3_STATE_SIZE]; + ++ if ( !ctx->decryption_prepared ) ++ { ++ do_ssse3_prepare_decryption ( ctx, ssse3_state ); ++ ctx->decryption_prepared = 1; ++ } ++ + vpaes_ssse3_prepare_dec (); + + asm volatile ("movdqu %[iv], %%xmm7\n\t" /* use xmm7 as fast IV storage */ +@@ -626,6 +640,12 @@ ssse3_ocb_dec (gcry_cipher_hd_t c, void + unsigned int nrounds = ctx->rounds; + byte ssse3_state[SSSE3_STATE_SIZE]; + ++ if ( !ctx->decryption_prepared ) ++ { ++ do_ssse3_prepare_decryption ( ctx, ssse3_state ); ++ ctx->decryption_prepared = 1; ++ } ++ + vpaes_ssse3_prepare_dec (); + + /* Preload Offset and Checksum */ +@@ -679,7 +699,7 @@ ssse3_ocb_dec (gcry_cipher_hd_t c, void + } + + +-void ++size_t + _gcry_aes_ssse3_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg, + const void *inbuf_arg, size_t nblocks, int encrypt) + { +@@ -687,10 +707,12 @@ _gcry_aes_ssse3_ocb_crypt(gcry_cipher_hd + ssse3_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); + else + ssse3_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); ++ ++ return 0; + } + + +-void ++size_t + _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, + size_t nblocks) + { +@@ -746,6 +768,8 @@ _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd + : "memory" ); + + vpaes_ssse3_cleanup (); ++ ++ return 0; + } + + #endif /* USE_SSSE3 */ +diff -up libgcrypt-1.8.5/cipher/salsa20.c.aes-perf libgcrypt-1.8.5/cipher/salsa20.c +--- libgcrypt-1.8.5/cipher/salsa20.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/salsa20.c 2020-04-22 18:29:41.679862057 +0200 +@@ -366,10 +366,12 @@ salsa20_do_setkey (SALSA20_context_t *ct + + + static gcry_err_code_t +-salsa20_setkey (void *context, const byte *key, unsigned int keylen) ++salsa20_setkey (void *context, const byte *key, unsigned int keylen, ++ gcry_cipher_hd_t hd) + { + SALSA20_context_t *ctx = (SALSA20_context_t *)context; + gcry_err_code_t rc = salsa20_do_setkey (ctx, key, keylen); ++ (void)hd; + _gcry_burn_stack (4 + sizeof (void *) + 4 * sizeof (void *)); + return rc; + } +@@ -522,7 +524,7 @@ selftest (void) + /* 16-byte alignment required for amd64 implementation. */ + ctx = (SALSA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15); + +- salsa20_setkey (ctx, key_1, sizeof key_1); ++ salsa20_setkey (ctx, key_1, sizeof key_1, NULL); + salsa20_setiv (ctx, nonce_1, sizeof nonce_1); + scratch[8] = 0; + salsa20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1); +@@ -530,7 +532,7 @@ selftest (void) + return "Salsa20 encryption test 1 failed."; + if (scratch[8]) + return "Salsa20 wrote too much."; +- salsa20_setkey( ctx, key_1, sizeof(key_1)); ++ salsa20_setkey( ctx, key_1, sizeof(key_1), NULL); + salsa20_setiv (ctx, nonce_1, sizeof nonce_1); + salsa20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1); + if (memcmp (scratch, plaintext_1, sizeof plaintext_1)) +@@ -538,12 +540,12 @@ selftest (void) + + for (i = 0; i < sizeof buf; i++) + buf[i] = i; +- salsa20_setkey (ctx, key_1, sizeof key_1); ++ salsa20_setkey (ctx, key_1, sizeof key_1, NULL); + salsa20_setiv (ctx, nonce_1, sizeof nonce_1); + /*encrypt*/ + salsa20_encrypt_stream (ctx, buf, buf, sizeof buf); + /*decrypt*/ +- salsa20_setkey (ctx, key_1, sizeof key_1); ++ salsa20_setkey (ctx, key_1, sizeof key_1, NULL); + salsa20_setiv (ctx, nonce_1, sizeof nonce_1); + salsa20_encrypt_stream (ctx, buf, buf, 1); + salsa20_encrypt_stream (ctx, buf+1, buf+1, (sizeof buf)-1-1); +diff -up libgcrypt-1.8.5/cipher/seed.c.aes-perf libgcrypt-1.8.5/cipher/seed.c +--- libgcrypt-1.8.5/cipher/seed.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/seed.c 2020-04-22 18:29:41.680862038 +0200 +@@ -309,11 +309,12 @@ do_setkey (SEED_context *ctx, const byte + } + + static gcry_err_code_t +-seed_setkey (void *context, const byte *key, const unsigned keylen) ++seed_setkey (void *context, const byte *key, const unsigned keylen, ++ gcry_cipher_hd_t hd) + { + SEED_context *ctx = context; +- + int rc = do_setkey (ctx, key, keylen); ++ (void)hd; + _gcry_burn_stack (4*6 + sizeof(void*)*2 + sizeof(int)*2); + return rc; + } +@@ -446,7 +447,7 @@ selftest (void) + 0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A, + }; + +- seed_setkey (&ctx, key, sizeof(key)); ++ seed_setkey (&ctx, key, sizeof(key), NULL); + seed_encrypt (&ctx, scratch, plaintext); + if (memcmp (scratch, ciphertext, sizeof (ciphertext))) + return "SEED test encryption failed."; +diff -up libgcrypt-1.8.5/cipher/serpent.c.aes-perf libgcrypt-1.8.5/cipher/serpent.c +--- libgcrypt-1.8.5/cipher/serpent.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/serpent.c 2020-04-22 18:29:41.680862038 +0200 +@@ -748,13 +748,16 @@ serpent_setkey_internal (serpent_context + /* Initialize CTX with the key KEY of KEY_LENGTH bytes. */ + static gcry_err_code_t + serpent_setkey (void *ctx, +- const byte *key, unsigned int key_length) ++ const byte *key, unsigned int key_length, ++ gcry_cipher_hd_t hd) + { + serpent_context_t *context = ctx; + static const char *serpent_test_ret; + static int serpent_init_done; + gcry_err_code_t ret = GPG_ERR_NO_ERROR; + ++ (void)hd; ++ + if (! serpent_init_done) + { + /* Execute a self-test the first time, Serpent is used. */ +@@ -999,7 +1002,7 @@ _gcry_serpent_ctr_enc(void *context, uns + /* Encrypt the counter. */ + serpent_encrypt_internal(ctx, ctr, tmpbuf); + /* XOR the input with the encrypted counter and store in output. */ +- buf_xor(outbuf, tmpbuf, inbuf, sizeof(serpent_block_t)); ++ cipher_block_xor(outbuf, tmpbuf, inbuf, sizeof(serpent_block_t)); + outbuf += sizeof(serpent_block_t); + inbuf += sizeof(serpent_block_t); + /* Increment the counter. */ +@@ -1114,7 +1117,8 @@ _gcry_serpent_cbc_dec(void *context, uns + the intermediate result to SAVEBUF. */ + serpent_decrypt_internal (ctx, inbuf, savebuf); + +- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, sizeof(serpent_block_t)); ++ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, ++ sizeof(serpent_block_t)); + inbuf += sizeof(serpent_block_t); + outbuf += sizeof(serpent_block_t); + } +@@ -1218,7 +1222,7 @@ _gcry_serpent_cfb_dec(void *context, uns + for ( ;nblocks; nblocks-- ) + { + serpent_encrypt_internal(ctx, iv, iv); +- buf_xor_n_copy(outbuf, iv, inbuf, sizeof(serpent_block_t)); ++ cipher_block_xor_n_copy(outbuf, iv, inbuf, sizeof(serpent_block_t)); + outbuf += sizeof(serpent_block_t); + inbuf += sizeof(serpent_block_t); + } +diff -up libgcrypt-1.8.5/cipher/twofish.c.aes-perf libgcrypt-1.8.5/cipher/twofish.c +--- libgcrypt-1.8.5/cipher/twofish.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/cipher/twofish.c 2020-04-22 18:29:41.680862038 +0200 +@@ -734,12 +734,15 @@ do_twofish_setkey (TWOFISH_context *ctx, + } + + static gcry_err_code_t +-twofish_setkey (void *context, const byte *key, unsigned int keylen) ++twofish_setkey (void *context, const byte *key, unsigned int keylen, ++ gcry_cipher_hd_t hd) + { + TWOFISH_context *ctx = context; + unsigned int hwfeatures = _gcry_get_hw_features (); + int rc; + ++ (void)hd; ++ + rc = do_twofish_setkey (ctx, key, keylen); + + #ifdef USE_AVX2 +@@ -1245,7 +1248,7 @@ _gcry_twofish_ctr_enc(void *context, uns + burn_stack_depth = burn; + + /* XOR the input with the encrypted counter and store in output. */ +- buf_xor(outbuf, tmpbuf, inbuf, TWOFISH_BLOCKSIZE); ++ cipher_block_xor(outbuf, tmpbuf, inbuf, TWOFISH_BLOCKSIZE); + outbuf += TWOFISH_BLOCKSIZE; + inbuf += TWOFISH_BLOCKSIZE; + /* Increment the counter. */ +@@ -1327,7 +1330,7 @@ _gcry_twofish_cbc_dec(void *context, uns + if (burn > burn_stack_depth) + burn_stack_depth = burn; + +- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, TWOFISH_BLOCKSIZE); ++ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, TWOFISH_BLOCKSIZE); + inbuf += TWOFISH_BLOCKSIZE; + outbuf += TWOFISH_BLOCKSIZE; + } +@@ -1399,7 +1402,7 @@ _gcry_twofish_cfb_dec(void *context, uns + if (burn > burn_stack_depth) + burn_stack_depth = burn; + +- buf_xor_n_copy(outbuf, iv, inbuf, TWOFISH_BLOCKSIZE); ++ cipher_block_xor_n_copy(outbuf, iv, inbuf, TWOFISH_BLOCKSIZE); + outbuf += TWOFISH_BLOCKSIZE; + inbuf += TWOFISH_BLOCKSIZE; + } +@@ -1710,7 +1713,7 @@ selftest (void) + 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA + }; + +- twofish_setkey (&ctx, key, sizeof(key)); ++ twofish_setkey (&ctx, key, sizeof(key), NULL); + twofish_encrypt (&ctx, scratch, plaintext); + if (memcmp (scratch, ciphertext, sizeof (ciphertext))) + return "Twofish-128 test encryption failed."; +@@ -1718,7 +1721,7 @@ selftest (void) + if (memcmp (scratch, plaintext, sizeof (plaintext))) + return "Twofish-128 test decryption failed."; + +- twofish_setkey (&ctx, key_256, sizeof(key_256)); ++ twofish_setkey (&ctx, key_256, sizeof(key_256), NULL); + twofish_encrypt (&ctx, scratch, plaintext_256); + if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256))) + return "Twofish-256 test encryption failed."; +@@ -1800,13 +1803,13 @@ main() + /* Encryption test. */ + for (i = 0; i < 125; i++) + { +- twofish_setkey (&ctx, buffer[0], sizeof (buffer[0])); ++ twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]), NULL); + for (j = 0; j < 1000; j++) + twofish_encrypt (&ctx, buffer[2], buffer[2]); +- twofish_setkey (&ctx, buffer[1], sizeof (buffer[1])); ++ twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]), NULL); + for (j = 0; j < 1000; j++) + twofish_encrypt (&ctx, buffer[3], buffer[3]); +- twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2); ++ twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2, NULL); + for (j = 0; j < 1000; j++) { + twofish_encrypt (&ctx, buffer[0], buffer[0]); + twofish_encrypt (&ctx, buffer[1], buffer[1]); +@@ -1818,15 +1821,15 @@ main() + /* Decryption test. */ + for (i = 0; i < 125; i++) + { +- twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2); ++ twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2, NULL); + for (j = 0; j < 1000; j++) { + twofish_decrypt (&ctx, buffer[0], buffer[0]); + twofish_decrypt (&ctx, buffer[1], buffer[1]); + } +- twofish_setkey (&ctx, buffer[1], sizeof (buffer[1])); ++ twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]), NULL); + for (j = 0; j < 1000; j++) + twofish_decrypt (&ctx, buffer[3], buffer[3]); +- twofish_setkey (&ctx, buffer[0], sizeof (buffer[0])); ++ twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]), NULL); + for (j = 0; j < 1000; j++) + twofish_decrypt (&ctx, buffer[2], buffer[2]); + } +diff -up libgcrypt-1.8.5/configure.ac.aes-perf libgcrypt-1.8.5/configure.ac +--- libgcrypt-1.8.5/configure.ac.aes-perf 2020-04-22 18:29:41.655862516 +0200 ++++ libgcrypt-1.8.5/configure.ac 2020-04-22 18:29:41.681862019 +0200 +@@ -649,6 +649,14 @@ AC_ARG_ENABLE(arm-crypto-support, + armcryptosupport=$enableval,armcryptosupport=yes) + AC_MSG_RESULT($armcryptosupport) + ++# Implementation of the --disable-ppc-crypto-support switch. ++AC_MSG_CHECKING([whether PPC crypto support is requested]) ++AC_ARG_ENABLE(ppc-crypto-support, ++ AC_HELP_STRING([--disable-ppc-crypto-support], ++ [Disable support for the PPC crypto instructions introduced in POWER 8 (PowerISA 2.07)]), ++ ppccryptosupport=$enableval,ppccryptosupport=yes) ++AC_MSG_RESULT($ppccryptosupport) ++ + # Implementation of the --disable-O-flag-munging switch. + AC_MSG_CHECKING([whether a -O flag munging is requested]) + AC_ARG_ENABLE([O-flag-munging], +@@ -1196,6 +1204,9 @@ if test "$mpi_cpu_arch" != "arm" ; then + fi + fi + ++if test "$mpi_cpu_arch" != "ppc"; then ++ ppccryptosupport="n/a" ++fi + + ############################################# + #### #### +@@ -1722,6 +1733,113 @@ if test "$gcry_cv_gcc_inline_asm_aarch64 + fi + + ++# ++# Check whether PowerPC AltiVec/VSX intrinsics ++# ++AC_CACHE_CHECK([whether compiler supports PowerPC AltiVec/VSX intrinsics], ++ [gcry_cv_cc_ppc_altivec], ++ [if test "$mpi_cpu_arch" != "ppc" ; then ++ gcry_cv_cc_ppc_altivec="n/a" ++ else ++ gcry_cv_cc_ppc_altivec=no ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE( ++ [[#include ++ typedef vector unsigned char block; ++ block fn(block in) ++ { ++ block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0)); ++ return vec_cipher_be (t, in); ++ } ++ ]])], ++ [gcry_cv_cc_ppc_altivec=yes]) ++ fi]) ++if test "$gcry_cv_cc_ppc_altivec" = "yes" ; then ++ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC,1, ++ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics]) ++fi ++ ++_gcc_cflags_save=$CFLAGS ++CFLAGS="$CFLAGS -maltivec -mvsx -mcrypto" ++ ++if test "$gcry_cv_cc_ppc_altivec" = "no" && ++ test "$mpi_cpu_arch" = "ppc" ; then ++ AC_CACHE_CHECK([whether compiler supports PowerPC AltiVec/VSX/crypto intrinsics with extra GCC flags], ++ [gcry_cv_cc_ppc_altivec_cflags], ++ [gcry_cv_cc_ppc_altivec_cflags=no ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE( ++ [[#include ++ typedef vector unsigned char block; ++ block fn(block in) ++ { ++ block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0)); ++ return vec_cipher_be (t, in); ++ }]])], ++ [gcry_cv_cc_ppc_altivec_cflags=yes])]) ++ if test "$gcry_cv_cc_ppc_altivec_cflags" = "yes" ; then ++ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC,1, ++ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics]) ++ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC_WITH_CFLAGS,1, ++ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics with extra GCC flags]) ++ fi ++fi ++ ++AM_CONDITIONAL(ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS, ++ test "$gcry_cv_cc_ppc_altivec_cflags" = "yes") ++ ++# Restore flags. ++CFLAGS=$_gcc_cflags_save; ++ ++ ++# ++# Check whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions ++# ++AC_CACHE_CHECK([whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions], ++ [gcry_cv_gcc_inline_asm_ppc_altivec], ++ [if test "$mpi_cpu_arch" != "ppc" ; then ++ gcry_cv_gcc_inline_asm_ppc_altivec="n/a" ++ else ++ gcry_cv_gcc_inline_asm_ppc_altivec=no ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE( ++ [[__asm__(".globl testfn;\n" ++ "testfn:\n" ++ "stvx %v31,%r12,%r0;\n" ++ "lvx %v20,%r12,%r0;\n" ++ "vcipher %v0, %v1, %v22;\n" ++ "lxvw4x %vs32, %r0, %r1;\n" ++ "vadduwm %v0, %v1, %v22;\n" ++ ); ++ ]])], ++ [gcry_cv_gcc_inline_asm_ppc_altivec=yes]) ++ fi]) ++if test "$gcry_cv_gcc_inline_asm_ppc_altivec" = "yes" ; then ++ AC_DEFINE(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC,1, ++ [Defined if inline assembler supports PowerPC AltiVec/VSX/crypto instructions]) ++fi ++ ++ ++# ++# Check whether GCC inline assembler supports PowerISA 3.00 instructions ++# ++AC_CACHE_CHECK([whether GCC inline assembler supports PowerISA 3.00 instructions], ++ [gcry_cv_gcc_inline_asm_ppc_arch_3_00], ++ [if test "$mpi_cpu_arch" != "ppc" ; then ++ gcry_cv_gcc_inline_asm_ppc_arch_3_00="n/a" ++ else ++ gcry_cv_gcc_inline_asm_ppc_arch_3_00=no ++ AC_COMPILE_IFELSE([AC_LANG_SOURCE( ++ [[__asm__(".globl testfn;\n" ++ "testfn:\n" ++ "stxvb16x %r1,%v12,%v30;\n" ++ ); ++ ]])], ++ [gcry_cv_gcc_inline_asm_ppc_arch_3_00=yes]) ++ fi]) ++if test "$gcry_cv_gcc_inline_asm_ppc_arch_3_00" = "yes" ; then ++ AC_DEFINE(HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00,1, ++ [Defined if inline assembler supports PowerISA 3.00 instructions]) ++fi ++ ++ + ####################################### + #### Checks for library functions. #### + ####################################### +@@ -1999,6 +2117,10 @@ if test x"$armcryptosupport" = xyes ; th + AC_DEFINE(ENABLE_ARM_CRYPTO_SUPPORT,1, + [Enable support for ARMv8 Crypto Extension instructions.]) + fi ++if test x"$ppccryptosupport" = xyes ; then ++ AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1, ++ [Enable support for POWER 8 (PowerISA 2.07) crypto extension.]) ++fi + if test x"$jentsupport" = xyes ; then + AC_DEFINE(ENABLE_JENT_SUPPORT, 1, + [Enable support for the jitter entropy collector.]) +@@ -2106,6 +2228,21 @@ if test "$found" = "1" ; then + GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-ce.lo" + GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-aarch64-ce.lo" + ;; ++ powerpc64le-*-*) ++ # Build with the crypto extension implementation ++ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo" ++ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc9le.lo" ++ ;; ++ powerpc64-*-*) ++ # Big-Endian. ++ # Build with the crypto extension implementation ++ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo" ++ ;; ++ powerpc-*-*) ++ # Big-Endian. ++ # Build with the crypto extension implementation ++ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo" ++ ;; + esac + + case "$mpi_cpu_arch" in +@@ -2555,6 +2692,7 @@ case "$mpi_cpu_arch" in + ;; + ppc) + AC_DEFINE(HAVE_CPU_ARCH_PPC, 1, [Defined for PPC platforms]) ++ GCRYPT_HWF_MODULES="hwf-ppc.lo" + ;; + arm) + AC_DEFINE(HAVE_CPU_ARCH_ARM, 1, [Defined for ARM platforms]) +@@ -2653,6 +2791,7 @@ GCRY_MSG_SHOW([Try using Intel AVX: + GCRY_MSG_SHOW([Try using Intel AVX2: ],[$avx2support]) + GCRY_MSG_SHOW([Try using ARM NEON: ],[$neonsupport]) + GCRY_MSG_SHOW([Try using ARMv8 crypto: ],[$armcryptosupport]) ++GCRY_MSG_SHOW([Try using PPC crypto: ],[$ppccryptosupport]) + GCRY_MSG_SHOW([],[]) + + if test "x${gpg_config_script_warn}" != x; then +diff -up libgcrypt-1.8.5/src/cipher.h.aes-perf libgcrypt-1.8.5/src/cipher.h +--- libgcrypt-1.8.5/src/cipher.h.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/src/cipher.h 2020-04-22 18:29:41.681862019 +0200 +@@ -158,6 +158,9 @@ size_t _gcry_aes_ocb_crypt (gcry_cipher_ + const void *inbuf_arg, size_t nblocks, int encrypt); + size_t _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, + size_t nblocks); ++void _gcry_aes_xts_crypt (void *context, unsigned char *tweak, ++ void *outbuf_arg, const void *inbuf_arg, ++ size_t nblocks, int encrypt); + + /*-- blowfish.c --*/ + void _gcry_blowfish_cfb_dec (void *context, unsigned char *iv, +diff -up libgcrypt-1.8.5/src/cipher-proto.h.aes-perf libgcrypt-1.8.5/src/cipher-proto.h +--- libgcrypt-1.8.5/src/cipher-proto.h.aes-perf 2020-04-22 18:29:41.643862745 +0200 ++++ libgcrypt-1.8.5/src/cipher-proto.h 2020-04-22 18:29:41.681862019 +0200 +@@ -132,7 +132,8 @@ typedef struct gcry_pk_spec + /* Type for the cipher_setkey function. */ + typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c, + const unsigned char *key, +- unsigned keylen); ++ unsigned keylen, ++ gcry_cipher_hd_t hd); + + /* Type for the cipher_encrypt function. */ + typedef unsigned int (*gcry_cipher_encrypt_t) (void *c, +diff -up libgcrypt-1.8.5/src/g10lib.h.aes-perf libgcrypt-1.8.5/src/g10lib.h +--- libgcrypt-1.8.5/src/g10lib.h.aes-perf 2020-04-22 18:29:41.660862420 +0200 ++++ libgcrypt-1.8.5/src/g10lib.h 2020-04-22 18:50:46.990661309 +0200 +@@ -233,7 +233,9 @@ char **_gcry_strtokenize (const char *st + + #define HWF_INTEL_RDTSC (1 << 20) + +- ++#define HWF_PPC_VCRYPTO (1 << 22) ++#define HWF_PPC_ARCH_3_00 (1 << 23) ++#define HWF_PPC_ARCH_2_07 (1 << 24) + + gpg_err_code_t _gcry_disable_hw_feature (const char *name); + void _gcry_detect_hw_features (void); +diff -up libgcrypt-1.8.5/src/hwf-common.h.aes-perf libgcrypt-1.8.5/src/hwf-common.h +--- libgcrypt-1.8.5/src/hwf-common.h.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/src/hwf-common.h 2020-04-22 18:29:41.682862000 +0200 +@@ -22,6 +22,6 @@ + + unsigned int _gcry_hwf_detect_x86 (void); + unsigned int _gcry_hwf_detect_arm (void); +- ++unsigned int _gcry_hwf_detect_ppc (void); + + #endif /*HWF_COMMON_H*/ +diff -up libgcrypt-1.8.5/src/hwfeatures.c.aes-perf libgcrypt-1.8.5/src/hwfeatures.c +--- libgcrypt-1.8.5/src/hwfeatures.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/src/hwfeatures.c 2020-04-22 18:51:48.326487879 +0200 +@@ -42,6 +42,7 @@ static struct + const char *desc; + } hwflist[] = + { ++#if defined(HAVE_CPU_ARCH_X86) + { HWF_PADLOCK_RNG, "padlock-rng" }, + { HWF_PADLOCK_AES, "padlock-aes" }, + { HWF_PADLOCK_SHA, "padlock-sha" }, +@@ -58,11 +59,17 @@ static struct + { HWF_INTEL_AVX2, "intel-avx2" }, + { HWF_INTEL_FAST_VPGATHER, "intel-fast-vpgather" }, + { HWF_INTEL_RDTSC, "intel-rdtsc" }, ++#elif defined(HAVE_CPU_ARCH_ARM) + { HWF_ARM_NEON, "arm-neon" }, + { HWF_ARM_AES, "arm-aes" }, + { HWF_ARM_SHA1, "arm-sha1" }, + { HWF_ARM_SHA2, "arm-sha2" }, +- { HWF_ARM_PMULL, "arm-pmull" } ++ { HWF_ARM_PMULL, "arm-pmull" }, ++#elif defined(HAVE_CPU_ARCH_PPC) ++ { HWF_PPC_VCRYPTO, "ppc-vcrypto" }, ++ { HWF_PPC_ARCH_3_00, "ppc-arch_3_00" }, ++ { HWF_PPC_ARCH_2_07, "ppc-arch_2_07" }, ++#endif + }; + + /* A bit vector with the hardware features which shall not be used. +@@ -207,12 +214,14 @@ _gcry_detect_hw_features (void) + { + hw_features = _gcry_hwf_detect_x86 (); + } +-#endif /* HAVE_CPU_ARCH_X86 */ +-#if defined (HAVE_CPU_ARCH_ARM) ++#elif defined (HAVE_CPU_ARCH_ARM) + { + hw_features = _gcry_hwf_detect_arm (); + } +-#endif /* HAVE_CPU_ARCH_ARM */ +- ++#elif defined (HAVE_CPU_ARCH_PPC) ++ { ++ hw_features = _gcry_hwf_detect_ppc (); ++ } ++#endif + hw_features &= ~disabled_hw_features; + } +diff -up libgcrypt-1.8.5/src/hwf-ppc.c.aes-perf libgcrypt-1.8.5/src/hwf-ppc.c +--- libgcrypt-1.8.5/src/hwf-ppc.c.aes-perf 2020-04-22 18:29:41.682862000 +0200 ++++ libgcrypt-1.8.5/src/hwf-ppc.c 2020-04-22 18:50:21.396150974 +0200 +@@ -0,0 +1,243 @@ ++/* hwf-ppc.c - Detect hardware features - PPC part ++ * Copyright (C) 2013,2019 Jussi Kivilinna ++ * Copyright (C) 2019 Shawn Landden ++ * ++ * This file is part of Libgcrypt. ++ * ++ * Libgcrypt 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. ++ * ++ * Libgcrypt 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 program; if not, see . ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#if defined(HAVE_SYS_AUXV_H) && (defined(HAVE_GETAUXVAL) || \ ++ defined(HAVE_ELF_AUX_INFO)) ++#include ++#endif ++ ++#include "g10lib.h" ++#include "hwf-common.h" ++ ++#if !defined (__powerpc__) && !defined (__powerpc64__) ++# error Module build for wrong CPU. ++#endif ++ ++ ++#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ELF_AUX_INFO) && \ ++ !defined(HAVE_GETAUXVAL) && defined(AT_HWCAP) ++#define HAVE_GETAUXVAL ++static unsigned long getauxval(unsigned long type) ++{ ++ unsigned long auxval = 0; ++ int err; ++ ++ /* FreeBSD provides 'elf_aux_info' function that does the same as ++ * 'getauxval' on Linux. */ ++ ++ err = elf_aux_info (type, &auxval, sizeof(auxval)); ++ if (err) ++ { ++ errno = err; ++ auxval = 0; ++ } ++ ++ return auxval; ++} ++#endif ++ ++ ++#undef HAS_SYS_AT_HWCAP ++#if defined(__linux__) || \ ++ (defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL)) ++#define HAS_SYS_AT_HWCAP 1 ++ ++struct feature_map_s ++ { ++ unsigned int hwcap_flag; ++ unsigned int hwcap2_flag; ++ unsigned int hwf_flag; ++ }; ++ ++#if defined(__powerpc__) || defined(__powerpc64__) ++ ++/* Note: These macros have same values on Linux and FreeBSD. */ ++#ifndef AT_HWCAP ++# define AT_HWCAP 16 ++#endif ++#ifndef AT_HWCAP2 ++# define AT_HWCAP2 26 ++#endif ++ ++#ifndef PPC_FEATURE2_ARCH_2_07 ++# define PPC_FEATURE2_ARCH_2_07 0x80000000 ++#endif ++#ifndef PPC_FEATURE2_VEC_CRYPTO ++# define PPC_FEATURE2_VEC_CRYPTO 0x02000000 ++#endif ++#ifndef PPC_FEATURE2_ARCH_3_00 ++# define PPC_FEATURE2_ARCH_3_00 0x00800000 ++#endif ++ ++static const struct feature_map_s ppc_features[] = ++ { ++ { 0, PPC_FEATURE2_ARCH_2_07, HWF_PPC_ARCH_2_07 }, ++#ifdef ENABLE_PPC_CRYPTO_SUPPORT ++ { 0, PPC_FEATURE2_VEC_CRYPTO, HWF_PPC_VCRYPTO }, ++#endif ++ { 0, PPC_FEATURE2_ARCH_3_00, HWF_PPC_ARCH_3_00 }, ++ }; ++#endif ++ ++static int ++get_hwcap(unsigned int *hwcap, unsigned int *hwcap2) ++{ ++ struct { unsigned long a_type; unsigned long a_val; } auxv; ++ FILE *f; ++ int err = -1; ++ static int hwcap_initialized = 0; ++ static unsigned int stored_hwcap = 0; ++ static unsigned int stored_hwcap2 = 0; ++ ++ if (hwcap_initialized) ++ { ++ *hwcap = stored_hwcap; ++ *hwcap2 = stored_hwcap2; ++ return 0; ++ } ++ ++#if 0 // TODO: configure.ac detection for __builtin_cpu_supports ++ // TODO: move to 'detect_ppc_builtin_cpu_supports' ++#if defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ >= 6 ++ /* __builtin_cpu_supports returns 0 if glibc support doesn't exist, so ++ * we can only trust positive results. */ ++#ifdef ENABLE_PPC_CRYPTO_SUPPORT ++ if (__builtin_cpu_supports("vcrypto")) /* TODO: Configure.ac */ ++ { ++ stored_hwcap2 |= PPC_FEATURE2_VEC_CRYPTO; ++ hwcap_initialized = 1; ++ } ++#endif ++ ++ if (__builtin_cpu_supports("arch_3_00")) /* TODO: Configure.ac */ ++ { ++ stored_hwcap2 |= PPC_FEATURE2_ARCH_3_00; ++ hwcap_initialized = 1; ++ } ++#endif ++#endif ++ ++#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL) ++ errno = 0; ++ auxv.a_val = getauxval (AT_HWCAP); ++ if (errno == 0) ++ { ++ stored_hwcap |= auxv.a_val; ++ hwcap_initialized = 1; ++ } ++ ++ if (AT_HWCAP2 >= 0) ++ { ++ errno = 0; ++ auxv.a_val = getauxval (AT_HWCAP2); ++ if (errno == 0) ++ { ++ stored_hwcap2 |= auxv.a_val; ++ hwcap_initialized = 1; ++ } ++ } ++ ++ if (hwcap_initialized && (stored_hwcap || stored_hwcap2)) ++ { ++ *hwcap = stored_hwcap; ++ *hwcap2 = stored_hwcap2; ++ return 0; ++ } ++#endif ++ ++ f = fopen("/proc/self/auxv", "r"); ++ if (!f) ++ { ++ *hwcap = stored_hwcap; ++ *hwcap2 = stored_hwcap2; ++ return -1; ++ } ++ ++ while (fread(&auxv, sizeof(auxv), 1, f) > 0) ++ { ++ if (auxv.a_type == AT_HWCAP) ++ { ++ stored_hwcap |= auxv.a_val; ++ hwcap_initialized = 1; ++ } ++ ++ if (auxv.a_type == AT_HWCAP2) ++ { ++ stored_hwcap2 |= auxv.a_val; ++ hwcap_initialized = 1; ++ } ++ } ++ ++ if (hwcap_initialized) ++ err = 0; ++ ++ fclose(f); ++ ++ *hwcap = stored_hwcap; ++ *hwcap2 = stored_hwcap2; ++ return err; ++} ++ ++static unsigned int ++detect_ppc_at_hwcap(void) ++{ ++ unsigned int hwcap; ++ unsigned int hwcap2; ++ unsigned int features = 0; ++ unsigned int i; ++ ++ if (get_hwcap(&hwcap, &hwcap2) < 0) ++ return features; ++ ++ for (i = 0; i < DIM(ppc_features); i++) ++ { ++ if (hwcap & ppc_features[i].hwcap_flag) ++ features |= ppc_features[i].hwf_flag; ++ ++ if (hwcap2 & ppc_features[i].hwcap2_flag) ++ features |= ppc_features[i].hwf_flag; ++ } ++ ++ return features; ++} ++ ++#endif ++ ++unsigned int ++_gcry_hwf_detect_ppc (void) ++{ ++ unsigned int ret = 0; ++ unsigned int broken_hwfs = 0; ++ ++#if defined (HAS_SYS_AT_HWCAP) ++ ret |= detect_ppc_at_hwcap (); ++#endif ++ ++ ret &= ~broken_hwfs; ++ ++ return ret; ++} +diff -up libgcrypt-1.8.5/src/Makefile.am.aes-perf libgcrypt-1.8.5/src/Makefile.am +--- libgcrypt-1.8.5/src/Makefile.am.aes-perf 2018-11-14 14:16:40.000000000 +0100 ++++ libgcrypt-1.8.5/src/Makefile.am 2020-04-22 18:29:41.683861981 +0200 +@@ -66,7 +66,7 @@ libgcrypt_la_SOURCES = \ + hmac256.c hmac256.h context.c context.h \ + ec-context.h + +-EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c ++EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c hwf-ppc.c + gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@ + + diff --git a/libgcrypt.spec b/libgcrypt.spec index 214ccf2..911457a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.5 -Release: 4%{?dist} +Release: 5%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -49,6 +49,8 @@ Patch28: libgcrypt-1.8.5-intel-cet.patch Patch29: libgcrypt-1.8.5-build.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch +# Backported AES performance improvements +Patch31: libgcrypt-1.8.5-aes-perf.patch %define gcrylibdir %{_libdir} @@ -62,6 +64,7 @@ BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig BuildRequires: fipscheck # This is needed only when patching the .texi doc. BuildRequires: texinfo +BuildRequires: autoconf, automake, libtool %package devel Summary: Development files for the %{name} package @@ -98,11 +101,13 @@ applications using libgcrypt. %patch28 -p1 -b .intel-cet %patch29 -p1 -b .build %patch30 -p1 -b .fips-module +%patch31 -p1 -b .aes-perf cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ %build +autoreconf -f %configure --disable-static \ %ifarch sparc64 --disable-asm \ @@ -197,6 +202,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Apr 22 2020 Tomáš Mráz 1.8.5-5 +- AES performance improvements backported from master branch + * Mon Apr 20 2020 Tomáš Mráz 1.8.5-4 - FIPS selftest is run directly from the constructor - FIPS module is implicit with kernel FIPS flag From a51c9f8187a9ba9e33efdcc9ffa2cceaed068c7a Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 23 Apr 2020 10:22:16 +0200 Subject: [PATCH 134/214] Fix regression - missing -ldl linkage --- ...tch => libgcrypt-1.8.5-use-fipscheck.patch | 22 +++++++++---------- libgcrypt.spec | 7 ++++-- 2 files changed, 16 insertions(+), 13 deletions(-) rename libgcrypt-1.6.2-use-fipscheck.patch => libgcrypt-1.8.5-use-fipscheck.patch (75%) diff --git a/libgcrypt-1.6.2-use-fipscheck.patch b/libgcrypt-1.8.5-use-fipscheck.patch similarity index 75% rename from libgcrypt-1.6.2-use-fipscheck.patch rename to libgcrypt-1.8.5-use-fipscheck.patch index 26af6bf..298ec4c 100644 --- a/libgcrypt-1.6.2-use-fipscheck.patch +++ b/libgcrypt-1.8.5-use-fipscheck.patch @@ -1,7 +1,7 @@ -diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c ---- libgcrypt-1.6.2/src/fips.c.use-fipscheck 2014-08-21 14:50:39.000000000 +0200 -+++ libgcrypt-1.6.2/src/fips.c 2014-09-26 11:42:20.999588282 +0200 -@@ -578,23 +578,50 @@ run_random_selftests (void) +diff -up libgcrypt-1.8.5/src/fips.c.use-fipscheck libgcrypt-1.8.5/src/fips.c +--- libgcrypt-1.8.5/src/fips.c.use-fipscheck 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.5/src/fips.c 2020-04-23 10:18:36.235764741 +0200 +@@ -581,23 +581,50 @@ run_random_selftests (void) return !!err; } @@ -57,7 +57,7 @@ diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c key, strlen (key)); if (dlen < 0) err = gpg_error_from_syserror (); -@@ -602,7 +629,7 @@ check_binary_integrity (void) +@@ -605,7 +632,7 @@ check_binary_integrity (void) err = gpg_error (GPG_ERR_INTERNAL); else { @@ -66,7 +66,7 @@ diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c if (!fname) err = gpg_error_from_syserror (); else -@@ -611,7 +638,7 @@ check_binary_integrity (void) +@@ -614,7 +641,7 @@ check_binary_integrity (void) char *p; /* Prefix the basename with a dot. */ @@ -75,15 +75,15 @@ diff -up libgcrypt-1.6.2/src/fips.c.use-fipscheck libgcrypt-1.6.2/src/fips.c p = strrchr (fname, '/'); if (p) p++; -diff -up libgcrypt-1.6.2/src/Makefile.in.use-fipscheck libgcrypt-1.6.2/src/Makefile.in ---- libgcrypt-1.6.2/src/Makefile.in.use-fipscheck 2014-08-21 15:14:08.000000000 +0200 -+++ libgcrypt-1.6.2/src/Makefile.in 2014-09-26 11:41:13.271059281 +0200 -@@ -449,7 +449,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \ +diff -up libgcrypt-1.8.5/src/Makefile.am.use-fipscheck libgcrypt-1.8.5/src/Makefile.am +--- libgcrypt-1.8.5/src/Makefile.am.use-fipscheck 2020-04-23 10:18:36.237764702 +0200 ++++ libgcrypt-1.8.5/src/Makefile.am 2020-04-23 10:19:03.186247455 +0200 +@@ -125,7 +125,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \ ../cipher/libcipher.la \ ../random/librandom.la \ ../mpi/libmpi.la \ - ../compat/libcompat.la $(GPG_ERROR_LIBS) + ../compat/libcompat.la $(GPG_ERROR_LIBS) -ldl + dumpsexp_SOURCES = dumpsexp.c - dumpsexp_CFLAGS = $(arch_gpg_error_cflags) diff --git a/libgcrypt.spec b/libgcrypt.spec index 911457a..4d8bde8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.5 -Release: 5%{?dist} +Release: 6%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -18,7 +18,7 @@ Source6: t-mpi-point.c Source7: random.conf # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump -Patch2: libgcrypt-1.6.2-use-fipscheck.patch +Patch2: libgcrypt-1.8.5-use-fipscheck.patch # modify FIPS RSA and DSA keygen to comply with requirements Patch5: libgcrypt-1.8.4-fips-keygen.patch # fix the tests to work correctly in the FIPS mode @@ -202,6 +202,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Apr 23 2020 Tomáš Mráz 1.8.5-6 +- Fix regression - missing -ldl linkage + * Wed Apr 22 2020 Tomáš Mráz 1.8.5-5 - AES performance improvements backported from master branch From 26769c9e863c32e114ad360c16099b91c206c2ca Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 23 Apr 2020 13:13:57 +0200 Subject: [PATCH 135/214] Temporary hack to workaround fipshmac incompatibility --- libgcrypt.spec | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index 4d8bde8..6b0f204 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -121,6 +121,7 @@ make %{?_smp_mflags} %check fipshmac src/.libs/libgcrypt.so.?? +mv src/.libs/libgcrypt.so.20.hmac src/.libs/.libgcrypt.so.20.hmac make check # Add generation of HMAC checksums of the final stripped binaries @@ -129,6 +130,7 @@ make check %{__arch_install_post} \ %{__os_install_post} \ fipshmac $RPM_BUILD_ROOT%{gcrylibdir}/*.so.?? \ + mv $RPM_BUILD_ROOT%{gcrylibdir}/libgcrypt.so.20.hmac $RPM_BUILD_ROOT%{gcrylibdir}/.libgcrypt.so.20.hmac \ %{nil} %install From 4b43d13b58e7042949d23f7d3c1b9acaf2af36de Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 23 Apr 2020 15:31:46 +0200 Subject: [PATCH 136/214] Revert "Temporary hack to workaround fipshmac incompatibility" This reverts commit 26769c9e863c32e114ad360c16099b91c206c2ca. --- libgcrypt.spec | 2 -- 1 file changed, 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6b0f204..4d8bde8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -121,7 +121,6 @@ make %{?_smp_mflags} %check fipshmac src/.libs/libgcrypt.so.?? -mv src/.libs/libgcrypt.so.20.hmac src/.libs/.libgcrypt.so.20.hmac make check # Add generation of HMAC checksums of the final stripped binaries @@ -130,7 +129,6 @@ make check %{__arch_install_post} \ %{__os_install_post} \ fipshmac $RPM_BUILD_ROOT%{gcrylibdir}/*.so.?? \ - mv $RPM_BUILD_ROOT%{gcrylibdir}/libgcrypt.so.20.hmac $RPM_BUILD_ROOT%{gcrylibdir}/.libgcrypt.so.20.hmac \ %{nil} %install From 5cbca409ee6861e5b580b48dda3958dc1f160b91 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Tue, 30 Jun 2020 13:42:31 -0600 Subject: [PATCH 137/214] Disable LTO. --- libgcrypt.spec | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 4d8bde8..91b0793 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.5 -Release: 6%{?dist} +Release: 7%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -107,6 +107,12 @@ cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ %build +# configure tests try to compile code containing ASMs to a .o file +# In an LTO world, that always works as compilation does not happen until +# link time. As a result we get the wrong results from configure. +# Disable LTO. +%define _lto_cflags %{nil} + autoreconf -f %configure --disable-static \ %ifarch sparc64 @@ -202,6 +208,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Jun 30 2020 Jeff Law 1.8.5-7 +Disable LTO + * Thu Apr 23 2020 Tomáš Mráz 1.8.5-6 - Fix regression - missing -ldl linkage From 0a37c41ff7b336ed797fba5d9d32c77330b17945 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Wed, 1 Jul 2020 13:45:33 +0200 Subject: [PATCH 138/214] use the hmac256 tool to calculate the library hmac --- libgcrypt.spec | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 91b0793..c19d392 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -52,7 +52,9 @@ Patch30: libgcrypt-1.8.5-fips-module.patch # Backported AES performance improvements Patch31: libgcrypt-1.8.5-aes-perf.patch -%define gcrylibdir %{_libdir} +%global gcrylibdir %{_libdir} +%global gcrysoname libgcrypt.so.20 +%global hmackey orboDeJITITejsirpADONivirpUkvarP # Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. # Documentation and some utilities are GPLv2+ licensed. These files @@ -61,7 +63,6 @@ License: LGPLv2+ Summary: A general-purpose cryptography library BuildRequires: gcc BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig -BuildRequires: fipscheck # This is needed only when patching the .texi doc. BuildRequires: texinfo BuildRequires: autoconf, automake, libtool @@ -126,7 +127,8 @@ sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib make %{?_smp_mflags} %check -fipshmac src/.libs/libgcrypt.so.?? +src/hmac256 %{hmackey} src/.libs/%{gcrysoname} | cut -f1 -d ' ' >src/.libs/.%{gcrysoname}.hmac + make check # Add generation of HMAC checksums of the final stripped binaries @@ -134,7 +136,7 @@ make check %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ %{__os_install_post} \ - fipshmac $RPM_BUILD_ROOT%{gcrylibdir}/*.so.?? \ + src/hmac256 %{hmackey} $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname} | cut -f1 -d ' ' >$RPM_BUILD_ROOT%{gcrylibdir}/.%{gcrysoname}.hmac \ %{nil} %install @@ -186,8 +188,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %files %dir /etc/gcrypt %config(noreplace) /etc/gcrypt/random.conf -%{gcrylibdir}/libgcrypt.so.* -%{gcrylibdir}/.libgcrypt.so.*.hmac +%{gcrylibdir}/libgcrypt.so.*.* +%{gcrylibdir}/%{gcrysoname} +%{gcrylibdir}/.%{gcrysoname}.hmac %{!?_licensedir:%global license %%doc} %license COPYING.LIB %doc AUTHORS NEWS THANKS @@ -208,8 +211,11 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog -* Tue Jun 30 2020 Jeff Law 1.8.5-7 -Disable LTO +* Wed Jul 1 2020 Tomáš Mráz 1.8.5-7 +- use the hmac256 tool to calculate the library hmac + +* Tue Jun 30 2020 Jeff Law +- Disable LTO * Thu Apr 23 2020 Tomáš Mráz 1.8.5-6 - Fix regression - missing -ldl linkage From 31bc02d1fa7b4e459baf183f5a0bbfb640c16a86 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 20 Jul 2020 16:41:19 +0200 Subject: [PATCH 139/214] new upstream version 1.8.6 --- .gitignore | 1 + ecc-curves.c | 8 ++++++-- libgcrypt-1.8.5-build.patch | 14 -------------- libgcrypt.spec | 10 +++++----- sources | 2 +- t-mpi-point.c | 14 +------------- 6 files changed, 14 insertions(+), 35 deletions(-) delete mode 100644 libgcrypt-1.8.5-build.patch diff --git a/.gitignore b/.gitignore index e510ea5..48ec3ad 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.3-hobbled.tar.xz /libgcrypt-1.8.4-hobbled.tar.xz /libgcrypt-1.8.5-hobbled.tar.xz +/libgcrypt-1.8.6-hobbled.tar.xz diff --git a/ecc-curves.c b/ecc-curves.c index 7378bae..666ebc1 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -40,8 +40,12 @@ static const struct const char *other; /* Other name. */ } curve_aliases[] = { - { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, - { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, + { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, /* OpenPGP */ + { "Curve25519", "1.3.101.110" }, /* rfc8410 */ + { "Curve25519", "X25519" }, /* rfc8410 */ + + { "Ed25519", "1.3.6.1.4.1.11591.15.1" },/* OpenPGP */ + { "Ed25519", "1.3.101.112" }, /* rfc8410 */ { "NIST P-224", "secp224r1" }, { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */ diff --git a/libgcrypt-1.8.5-build.patch b/libgcrypt-1.8.5-build.patch deleted file mode 100644 index 3e71238..0000000 --- a/libgcrypt-1.8.5-build.patch +++ /dev/null @@ -1,14 +0,0 @@ -diff -up libgcrypt-1.8.5/cipher/poly1305-armv7-neon.S.build libgcrypt-1.8.5/cipher/poly1305-armv7-neon.S ---- libgcrypt-1.8.5/cipher/poly1305-armv7-neon.S.build 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/poly1305-armv7-neon.S 2020-01-30 17:26:12.026404286 +0100 -@@ -87,9 +87,8 @@ _gcry_poly1305_armv7_neon_init_ext: - .Lpoly1305_init_ext_neon_local: - stmfd sp!, {r4-r11, lr} - sub sp, sp, #32 -- mov r14, r2 -+ mov r14, #-1 - and r2, r2, r2 -- moveq r14, #-1 - UNALIGNED_LDMIA4(r1, r2, r3, r4, r5) - GET_DATA_POINTER(r7,.Lpoly1305_init_constants_neon,r8) - mov r6, r2 diff --git a/libgcrypt.spec b/libgcrypt.spec index c19d392..c48f4f8 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.8.5 -Release: 7%{?dist} +Version: 1.8.6 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -45,8 +45,6 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # Intel CET support, in upstream master Patch28: libgcrypt-1.8.5-intel-cet.patch -# Fix build on ARMv7 -Patch29: libgcrypt-1.8.5-build.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch # Backported AES performance improvements @@ -100,7 +98,6 @@ applications using libgcrypt. %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet -%patch29 -p1 -b .build %patch30 -p1 -b .fips-module %patch31 -p1 -b .aes-perf @@ -211,6 +208,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Mon Jul 20 2020 Tomáš Mráz 1.8.6-1 +- new upstream version 1.8.6 + * Wed Jul 1 2020 Tomáš Mráz 1.8.5-7 - use the hmac256 tool to calculate the library hmac diff --git a/sources b/sources index 7a67991..09310c9 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.8.5-hobbled.tar.xz) = 63391cdb4b2366dfc7869a45a9e5facbb05e4d28ada2646941cadfa2de93517ff5fb2a28aa7f486b79a1449cf701c8c36a6e99052d7c499b240dff606dd921a0 +SHA512 (libgcrypt-1.8.6-hobbled.tar.xz) = b59a3c6544e989033acb1f75a526487075b12aac65f18e38264aa9921fe89306485bfee5f4b0dd75d9ed4a35f23851d302359983c75d6f5a0d6f74007a553743 diff --git a/t-mpi-point.c b/t-mpi-point.c index b12a8ba..2a8c36c 100644 --- a/t-mpi-point.c +++ b/t-mpi-point.c @@ -737,23 +737,11 @@ basic_ec_math (void) gcry_mpi_ec_mul (Q, tmp, G, ctx); gcry_mpi_release (tmp); gcry_mpi_point_get (x, y, z, Q); - if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 0) - || gcry_mpi_cmp_ui (z, 0)) + if (gcry_mpi_cmp_ui (z, 0)) fail ("multiply a point by zero failed\n"); } gcry_mpi_ec_mul (Q, d, G, ctx); - gcry_mpi_point_get (x, y, z, Q); - if (cmp_mpihex (x, "222D9EC717C89D047E0898C9185B033CD11C0A981EE6DC66") - || cmp_mpihex (y, "605DE0A82D70D3E0F84A127D0739ED33D657DF0D054BFDE8") - || cmp_mpihex (z, "00B06B519071BC536999AC8F2D3934B3C1FC9EACCD0A31F88F")) - fail ("computed public key does not match\n"); - if (debug) - { - print_mpi ("Q.x", x); - print_mpi ("Q.y", y); - print_mpi ("Q.z", z); - } if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) fail ("failed to get affine coordinates\n"); From a87016377dc1503e9456acbac35a3c7fffdba1e7 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 21 Jul 2020 20:26:48 +0000 Subject: [PATCH 140/214] Use make macros https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro --- libgcrypt.spec | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index c48f4f8..ad02377 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.6 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -121,7 +121,7 @@ autoreconf -f --enable-pubkey-ciphers='dsa elgamal rsa ecc' \ --disable-O-flag-munging sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool -make %{?_smp_mflags} +%make_build %check src/hmac256 %{hmackey} src/.libs/%{gcrysoname} | cut -f1 -d ' ' >src/.libs/.%{gcrysoname}.hmac @@ -137,7 +137,7 @@ make check %{nil} %install -make install DESTDIR=$RPM_BUILD_ROOT +%make_install # Change /usr/lib64 back to /usr/lib. This saves us from having to patch the # script to "know" that -L/usr/lib64 should be suppressed, and also removes @@ -208,6 +208,10 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Jul 21 2020 Tom Stellard - 1.8.6-2 +- Use make macros +- https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro + * Mon Jul 20 2020 Tomáš Mráz 1.8.6-1 - new upstream version 1.8.6 From 0bb7c38613ba67a926785160fde7f7c95dfe2762 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Tue, 28 Jul 2020 04:41:49 +0000 Subject: [PATCH 141/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index ad02377..c082e02 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.6 -Release: 2%{?dist} +Release: 3%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -208,6 +208,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Jul 28 2020 Fedora Release Engineering - 1.8.6-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild + * Tue Jul 21 2020 Tom Stellard - 1.8.6-2 - Use make macros - https://fedoraproject.org/wiki/Changes/UseMakeBuildInstallMacro From b49c0d6908399d32544d0acf682890734946e72f Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Mon, 3 Aug 2020 19:10:44 +0200 Subject: [PATCH 142/214] Fix warnings introduced by aes-perf patch --- libgcrypt-1.8.5-aes-perf.patch | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/libgcrypt-1.8.5-aes-perf.patch b/libgcrypt-1.8.5-aes-perf.patch index 3119989..268ce70 100644 --- a/libgcrypt-1.8.5-aes-perf.patch +++ b/libgcrypt-1.8.5-aes-perf.patch @@ -1216,7 +1216,7 @@ diff -up libgcrypt-1.8.5/cipher/cipher-cmac.c.aes-perf libgcrypt-1.8.5/cipher/ci diff -up libgcrypt-1.8.5/cipher/cipher-ctr.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ctr.c --- libgcrypt-1.8.5/cipher/cipher-ctr.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.5/cipher/cipher-ctr.c 2020-04-22 18:29:41.667862287 +0200 -@@ -81,24 +81,38 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd +@@ -81,24 +81,34 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd { unsigned char tmp[MAX_BLOCKSIZE]; @@ -1265,10 +1265,6 @@ diff -up libgcrypt-1.8.5/cipher/cipher-ctr.c.aes-perf libgcrypt-1.8.5/cipher/cip + { + n = inbuflen; + buf_xor(outbuf, inbuf, tmp, inbuflen); -+ -+ inbuflen -= n; -+ outbuf += n; -+ inbuf += n; + } /* Save the unused bytes of the counter. */ @@ -2104,7 +2100,7 @@ diff -up libgcrypt-1.8.5/cipher/rfc2268.c.aes-perf libgcrypt-1.8.5/cipher/rfc226 diff -up libgcrypt-1.8.5/cipher/rijndael-aesni.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-aesni.c --- libgcrypt-1.8.5/cipher/rijndael-aesni.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rijndael-aesni.c 2020-04-22 18:29:41.671862210 +0200 ++++ libgcrypt-1.8.5/cipher/rijndael-aesni.c 2020-04-28 11:22:26.025519954 +0200 @@ -327,8 +327,8 @@ _gcry_aes_aesni_do_setkey (RIJNDAEL_cont @@ -2244,7 +2240,12 @@ diff -up libgcrypt-1.8.5/cipher/rijndael-aesni.c.aes-perf libgcrypt-1.8.5/cipher _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, size_t nblocks) { -@@ -1813,4 +1831,303 @@ _gcry_aes_aesni_ocb_auth (gcry_cipher_hd +@@ -1810,7 +1828,306 @@ _gcry_aes_aesni_ocb_auth (gcry_cipher_hd + + aesni_cleanup (); + aesni_cleanup_2_6 (); ++ ++ return 0; } @@ -2387,8 +2388,6 @@ diff -up libgcrypt-1.8.5/cipher/rijndael-aesni.c.aes-perf libgcrypt-1.8.5/cipher + + aesni_cleanup (); + aesni_cleanup_2_6 (); -+ -+ return 0; +} + + From 42e8971b6466fdb92f842f1859d5ae803430d7ef Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Fri, 21 Aug 2020 16:34:01 -0600 Subject: [PATCH 143/214] Re-enable LTO --- libgcrypt.spec | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index c082e02..89f5ef1 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.8.6 -Release: 3%{?dist} +Release: 4%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -105,11 +105,14 @@ cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ %build -# configure tests try to compile code containing ASMs to a .o file -# In an LTO world, that always works as compilation does not happen until -# link time. As a result we get the wrong results from configure. -# Disable LTO. -%define _lto_cflags %{nil} +# This package has a configure test which uses ASMs, but does not link the +# resultant .o files. As such the ASM test is always successful, even on +# architectures were the ASM is not valid when compiling with LTO. +# +# -ffat-lto-objects is sufficient to address this issue. It is the default +# for F33, but is expected to only be enabled for packages that need it in +# F34, so we use it here explicitly +%define _lto_cflags -flto=auto -ffat-lto-objects autoreconf -f %configure --disable-static \ @@ -208,6 +211,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Fri Aug 21 2020 Jeff Law - 1.8.6-4 +- Re-enable LTO + * Tue Jul 28 2020 Fedora Release Engineering - 1.8.6-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild From 762053927e30370238ecaf5b8be229323dc3251d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 24 Nov 2020 15:09:21 +0100 Subject: [PATCH 144/214] 1.8.7-1 --- .gitignore | 1 + libgcrypt.spec | 10 ++++++++-- sources | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index 48ec3ad..956ba5f 100644 --- a/.gitignore +++ b/.gitignore @@ -22,3 +22,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.4-hobbled.tar.xz /libgcrypt-1.8.5-hobbled.tar.xz /libgcrypt-1.8.6-hobbled.tar.xz +/libgcrypt-1.8.7-hobbled.tar.xz diff --git a/libgcrypt.spec b/libgcrypt.spec index 89f5ef1..6c82b2e 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,12 +1,15 @@ Name: libgcrypt -Version: 1.8.6 -Release: 4%{?dist} +Version: 1.8.7 +Release: 1%{?dist} URL: http://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with # the hobble-libgcrypt script. # (We replace it with RH approved ECC in Source4-5) +# tar -xf libgcrypt-1.8.7.tar.bz2 +# pushd libgcrypt-1.8.7 && ../hobble-libgcrypt && popd +# tar -cvJf libgcrypt-1.8.7-hobbled.tar.xz libgcrypt-1.8.7 #Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2 #Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2.sig Source2: wk@g10code.com @@ -211,6 +214,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Nov 24 2020 Jakub Jelen - 1.8.7-1 +- new upstream release (#1891123) + * Fri Aug 21 2020 Jeff Law - 1.8.6-4 - Re-enable LTO diff --git a/sources b/sources index 09310c9..b46a259 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.8.6-hobbled.tar.xz) = b59a3c6544e989033acb1f75a526487075b12aac65f18e38264aa9921fe89306485bfee5f4b0dd75d9ed4a35f23851d302359983c75d6f5a0d6f74007a553743 +SHA512 (libgcrypt-1.8.7-hobbled.tar.xz) = e9655f5387f08d18dcfcef3bce737aa7bb0242a5ebcb2be0dd2892fad3761496e3e51b283b61e8537b30b157a3ef5657a5bf4288c7d3aec94982b0c6da749876 From 3f76a6d4b78e5b500ff600fcd0aa7c8d57b22649 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 24 Nov 2020 16:50:18 +0100 Subject: [PATCH 145/214] Replace version in comments with x.y.z to prevent copy&paste errors --- libgcrypt.spec | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6c82b2e..729a733 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -7,9 +7,9 @@ Source0: libgcrypt-%{version}-hobbled.tar.xz # cipher support. We have to remove it in the tarball we ship with # the hobble-libgcrypt script. # (We replace it with RH approved ECC in Source4-5) -# tar -xf libgcrypt-1.8.7.tar.bz2 -# pushd libgcrypt-1.8.7 && ../hobble-libgcrypt && popd -# tar -cvJf libgcrypt-1.8.7-hobbled.tar.xz libgcrypt-1.8.7 +# tar -xf libgcrypt-x.y.z.tar.bz2 +# pushd libgcrypt-x.y.z && ../hobble-libgcrypt && popd +# tar -cvJf libgcrypt-x.y.z-hobbled.tar.xz libgcrypt-x.y.z #Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2 #Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2.sig Source2: wk@g10code.com From 45da8f74c11389a053691c0183a92cb63214b0a5 Mon Sep 17 00:00:00 2001 From: Robert Scheck Date: Thu, 24 Dec 2020 10:23:45 +0000 Subject: [PATCH 146/214] Spec file cleanup Remove instructions no longer needed on any active branch --- libgcrypt.spec | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 729a733..00fcd85 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,7 +1,7 @@ Name: libgcrypt Version: 1.8.7 Release: 1%{?dist} -URL: http://www.gnupg.org/ +URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC # cipher support. We have to remove it in the tarball we ship with @@ -72,7 +72,7 @@ BuildRequires: autoconf, automake, libtool Summary: Development files for the %{name} package License: LGPLv2+ and GPLv2+ Requires: libgpg-error-devel -Requires: %{name} = %{version}-%{release} +Requires: %{name}%{?_isa} = %{version}-%{release} Requires: pkgconfig %description @@ -194,7 +194,6 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %{gcrylibdir}/libgcrypt.so.*.* %{gcrylibdir}/%{gcrysoname} %{gcrylibdir}/.%{gcrysoname}.hmac -%{!?_licensedir:%global license %%doc} %license COPYING.LIB %doc AUTHORS NEWS THANKS @@ -210,7 +209,6 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %{_mandir}/man1/* %{_infodir}/gcrypt.info* -%{!?_licensedir:%global license %%doc} %license COPYING %changelog From 30dbcc9e603cbaf3493c2cefe22b832371e8d72e Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Tue, 5 Jan 2021 01:51:09 +0000 Subject: [PATCH 147/214] Add BuildRequires: make https://fedoraproject.org/wiki/Changes/Remove_make_from_BuildRoot --- libgcrypt.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index 00fcd85..797a042 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -67,6 +67,7 @@ BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig # This is needed only when patching the .texi doc. BuildRequires: texinfo BuildRequires: autoconf, automake, libtool +BuildRequires: make %package devel Summary: Development files for the %{name} package From c3f576ebd7c15ae7f5889618c6897881ce4840dc Mon Sep 17 00:00:00 2001 From: Robert Scheck Date: Mon, 18 Jan 2021 01:16:45 +0000 Subject: [PATCH 148/214] Update source URLs to HTTPS --- libgcrypt.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 797a042..803c618 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -10,8 +10,8 @@ Source0: libgcrypt-%{version}-hobbled.tar.xz # tar -xf libgcrypt-x.y.z.tar.bz2 # pushd libgcrypt-x.y.z && ../hobble-libgcrypt && popd # tar -cvJf libgcrypt-x.y.z-hobbled.tar.xz libgcrypt-x.y.z -#Source0: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2 -#Source1: ftp://ftp.gnupg.org/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2.sig +#Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2 +#Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2.sig Source2: wk@g10code.com Source3: hobble-libgcrypt # Approved ECC support From b661d80e2fdf4eef9556b0aba8d30ceb993f5f61 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 20 Jan 2021 01:34:36 +0100 Subject: [PATCH 149/214] libgcrypt-1.9.0-1 --- .gitignore | 1 + curves.c | 14 +- ecc-curves.c | 758 ++- libgcrypt-1.8.3-cmac-selftest.patch | 322 - libgcrypt-1.8.3-fips-ctor.patch | 2 +- libgcrypt-1.8.3-fips-enttest.patch | 2 +- libgcrypt-1.8.4-tests-fipsmode.patch | 25 +- libgcrypt-1.8.4-use-poll.patch | 8 +- libgcrypt-1.8.5-aes-perf.patch | 8156 -------------------------- libgcrypt-1.8.5-fips-module.patch | 10 +- libgcrypt-1.8.5-getrandom.patch | 24 +- libgcrypt-1.8.5-intel-cet.patch | 348 -- libgcrypt-1.8.5-use-fipscheck.patch | 12 - libgcrypt.spec | 14 +- sources | 2 +- t-mpi-point.c | 8 +- 16 files changed, 545 insertions(+), 9161 deletions(-) delete mode 100644 libgcrypt-1.8.3-cmac-selftest.patch delete mode 100644 libgcrypt-1.8.5-aes-perf.patch delete mode 100644 libgcrypt-1.8.5-intel-cet.patch diff --git a/.gitignore b/.gitignore index 956ba5f..fed427b 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.5-hobbled.tar.xz /libgcrypt-1.8.6-hobbled.tar.xz /libgcrypt-1.8.7-hobbled.tar.xz +/libgcrypt-1.9.0-hobbled.tar.xz diff --git a/curves.c b/curves.c index b68e0e2..5441b53 100644 --- a/curves.c +++ b/curves.c @@ -32,8 +32,8 @@ #define PGM "curves" #include "t-common.h" -/* Number of curves defined in ../cipger/ecc.c */ -#define N_CURVES 14 +/* Number of curves defined in ../cipger/ecc-curves.c */ +#define N_CURVES 19 /* A real world sample public key. */ static char const sample_key_1[] = @@ -52,8 +52,6 @@ static char const sample_key_1[] = static char const sample_key_1_curve[] = "NIST P-256"; static unsigned int sample_key_1_nbits = 256; - - static void list_curves (void) { @@ -95,7 +93,6 @@ check_matching (void) sample_key_1_nbits, nbits); gcry_sexp_release (key); - } @@ -117,7 +114,6 @@ check_get_params (void) sample_key_1_curve, name); gcry_sexp_release (param); - } @@ -132,10 +128,10 @@ main (int argc, char **argv) if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); - xgcry_control (GCRYCTL_DISABLE_SECMEM, 0); - xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); if (debug) - xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); list_curves (); check_matching (); check_get_params (); diff --git a/ecc-curves.c b/ecc-curves.c index 666ebc1..4242117 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -26,6 +26,7 @@ #include "g10lib.h" #include "mpi.h" +#include "mpi-internal.h" #include "cipher.h" #include "context.h" #include "ec-context.h" @@ -33,6 +34,10 @@ #include "ecc-common.h" +static gpg_err_code_t +point_from_keyparam (gcry_mpi_point_t *r_a, + gcry_sexp_t keyparam, const char *name, mpi_ec_t ec); + /* This tables defines aliases for curve names. */ static const struct { @@ -40,12 +45,15 @@ static const struct const char *other; /* Other name. */ } curve_aliases[] = { + { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, /* OpenPGP */ + { "Ed25519", "1.3.101.112" }, /* rfc8410 */ + { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, /* OpenPGP */ { "Curve25519", "1.3.101.110" }, /* rfc8410 */ { "Curve25519", "X25519" }, /* rfc8410 */ - { "Ed25519", "1.3.6.1.4.1.11591.15.1" },/* OpenPGP */ - { "Ed25519", "1.3.101.112" }, /* rfc8410 */ + { "Ed448", "1.3.101.113" }, /* rfc8410 */ + { "X448", "1.3.101.111" }, /* rfc8410 */ { "NIST P-224", "secp224r1" }, { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */ @@ -73,11 +81,26 @@ static const struct { "GOST2001-CryptoPro-A", "1.2.643.2.2.36.0" }, { "GOST2001-CryptoPro-C", "1.2.643.2.2.36.1" }, - { "GOST2012-tc26-A", "1.2.643.7.1.2.1.2.1" }, - { "GOST2012-tc26-B", "1.2.643.7.1.2.1.2.2" }, + { "GOST2012-256-tc26-A", "1.2.643.7.1.2.1.1.1" }, + { "GOST2001-CryptoPro-A", "1.2.643.7.1.2.1.1.2" }, + { "GOST2001-CryptoPro-A", "GOST2012-256-tc26-B" }, + { "GOST2001-CryptoPro-B", "1.2.643.7.1.2.1.1.3" }, + { "GOST2001-CryptoPro-B", "GOST2012-256-tc26-C" }, + { "GOST2001-CryptoPro-C", "1.2.643.7.1.2.1.1.4" }, + { "GOST2001-CryptoPro-C", "GOST2012-256-tc26-D" }, + + { "GOST2012-512-test", "GOST2012-test" }, + { "GOST2012-512-test", "1.2.643.7.1.2.1.2.0" }, + { "GOST2012-512-tc26-A", "GOST2012-tc26-A" }, + { "GOST2012-512-tc26-B", "GOST2012-tc26-B" }, + { "GOST2012-512-tc26-A", "1.2.643.7.1.2.1.2.1" }, + { "GOST2012-512-tc26-B", "1.2.643.7.1.2.1.2.2" }, + { "GOST2012-512-tc26-C", "1.2.643.7.1.2.1.2.3" }, { "secp256k1", "1.3.132.0.10" }, + { "sm2p256v1", "1.2.156.10197.1.301" }, + { NULL, NULL} }; @@ -102,7 +125,7 @@ typedef struct Curves (a,b) has ((A-2)/4,B^-1). */ const char *n; /* The order of the base point. */ const char *g_x, *g_y; /* Base point. */ - const char *h; /* Cofactor. */ + unsigned int h; /* Cofactor. */ } ecc_domain_parms_t; @@ -111,7 +134,7 @@ static const ecc_domain_parms_t domain_parms[] = { { /* (-x^2 + y^2 = 1 + dx^2y^2) */ - "Ed25519", 256, 0, + "Ed25519", 255, 0, MPI_EC_EDWARDS, ECC_DIALECT_ED25519, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", "-0x01", @@ -119,11 +142,11 @@ static const ecc_domain_parms_t domain_parms[] = "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", "0x6666666666666666666666666666666666666666666666666666666666666658", - "0x08" + 8 }, { /* (y^2 = x^3 + 486662*x^2 + x) */ - "Curve25519", 256, 0, + "Curve25519", 255, 0, MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD, "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", "0x01DB41", @@ -131,7 +154,45 @@ static const ecc_domain_parms_t domain_parms[] = "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", "0x0000000000000000000000000000000000000000000000000000000000000009", "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9", - "0x08" + 8 + /* Note: As per RFC-7748 errata eid4730 the g_y value should be + * "0x5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14" + * but that breaks the keygrip. The new value is recovered in + * the function _gcry_ecc_fill_in_curve. See bug #4712. + */ + }, + { + /* (x^2 + y^2 = 1 + dx^2y^2) */ + "Ed448", 448, 0, + MPI_EC_EDWARDS, ECC_DIALECT_SAFECURVE, + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "0x01", + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756", + "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3", + "0x4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324" + "A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E", + "0x693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E" + "05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14", + 4, + }, + { + /* (y^2 = x^3 + 156326*x^2 + x) */ + "X448", 448, 0, + MPI_EC_MONTGOMERY, ECC_DIALECT_SAFECURVE, + "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", + "0x98A9", + "0x01", + "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3", + "0x00000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000005", + "0x7D235D1295F5B1F66C98AB6E58326FCECBAE5D34F55545D060F75DC2" + "8DF3F6EDB8027E2346430D211312C4B150677AF76FD7223D457B5B1A", + 4, }, { "NIST P-224", 224, 1, @@ -143,7 +204,7 @@ static const ecc_domain_parms_t domain_parms[] = "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", - "0x01" + 1 }, { "NIST P-256", 256, 1, @@ -155,7 +216,7 @@ static const ecc_domain_parms_t domain_parms[] = "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", - "0x01" + 1 }, { "NIST P-384", 384, 1, @@ -173,7 +234,7 @@ static const ecc_domain_parms_t domain_parms[] = "5502f25dbf55296c3a545e3872760ab7", "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" "0a60b1ce1d7e819d7a431d7c90ea0e5f", - "0x01" + 1 }, { "NIST P-521", 521, 1, @@ -184,14 +245,14 @@ static const ecc_domain_parms_t domain_parms[] = "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", - "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", + "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", - "0x01" + 1 }, { @@ -204,7 +265,7 @@ static const ecc_domain_parms_t domain_parms[] = "0x0000000000000000000000000000000000000000000000000000000000000002", "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8", - "0x01" + 1 }, { "GOST2001-CryptoPro-A", 256, 0, @@ -215,7 +276,7 @@ static const ecc_domain_parms_t domain_parms[] = "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14", - "0x01" + 1 }, { "GOST2001-CryptoPro-B", 256, 0, @@ -226,7 +287,7 @@ static const ecc_domain_parms_t domain_parms[] = "0x800000000000000000000000000000015f700cfff1a624e5e497161bcc8a198f", "0x0000000000000000000000000000000000000000000000000000000000000001", "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc", - "0x01" + 1 }, { "GOST2001-CryptoPro-C", 256, 0, @@ -237,10 +298,21 @@ static const ecc_domain_parms_t domain_parms[] = "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9", "0x0000000000000000000000000000000000000000000000000000000000000000", "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67", - "0x01" + 1 }, { - "GOST2012-test", 511, 0, + "GOST2012-256-A", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97", + "0xc2173f1513981673af4892c23035a27ce25e2013bf95aa33b22c656f277e7335", + "0x295f9bae7428ed9ccc20e7c359a9d41a22fccd9108e17bf7ba9337a6f8ae9513", + "0x400000000000000000000000000000000fd8cddfc87b6635c115af556c360c67", + "0x91e38443a5e82c0d880923425712b2bb658b9196932e02c78b2582fe742daa28", + "0x32879423ab1a0375895786c4bb46e9565fde0b5344766740af268adb32322e5c", + 4 + }, + { + "GOST2012-512-test", 511, 0, MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373", @@ -254,10 +326,10 @@ static const ecc_domain_parms_t domain_parms[] = "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a", "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2" "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e", - "0x01" + 1 }, { - "GOST2012-tc26-A", 512, 0, + "GOST2012-512-tc26-A", 512, 0, MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7", @@ -271,10 +343,10 @@ static const ecc_domain_parms_t domain_parms[] = "0000000000000000000000000000000000000000000000000000000000000003", "0x7503cfe87a836ae3a61b8816e25450e6ce5e1c93acf1abc1778064fdcbefa921" "df1626be4fd036e93d75e6a50e3a41e98028fe5fc235f5b889a589cb5215f2a4", - "0x01" + 1 }, { - "GOST2012-tc26-B", 512, 0, + "GOST2012-512-tc26-B", 512, 0, MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, "0x8000000000000000000000000000000000000000000000000000000000000000" "000000000000000000000000000000000000000000000000000000000000006f", @@ -288,7 +360,24 @@ static const ecc_domain_parms_t domain_parms[] = "0000000000000000000000000000000000000000000000000000000000000002", "0x1a8f7eda389b094c2c071e3647a8940f3c123b697578c213be6dd9e6c8ec7335" "dcb228fd1edf4a39152cbcaaf8c0398828041055f94ceeec7e21340780fe41bd", - "0x01" + 1 + }, + { + "GOST2012-512-tc26-C", 512, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7", + "0xdc9203e514a721875485a529d2c722fb187bc8980eb866644de41c68e1430645" + "46e861c0e2c9edd92ade71f46fcf50ff2ad97f951fda9f2a2eb6546f39689bd3", + "0xb4c4ee28cebc6c2c8ac12952cf37f16ac7efb6a9f69f4b57ffda2e4f0de5ade0" + "38cbc2fff719d2c18de0284b8bfef3b52b8cc7a5f5bf0a3c8d2319a5312557e1", + "0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" + "c98cdba46506ab004c33a9ff5147502cc8eda9e7a769a12694623cef47f023ed", + "0xe2e31edfc23de7bdebe241ce593ef5de2295b7a9cbaef021d385f7074cea043a" + "a27272a7ae602bf2a7b9033db9ed3610c6fb85487eae97aac5bc7928c1950148", + "0xf5ce40d95b5eb899abbccff5911cb8577939804d6527378b8c108c3d2090ff9be" + "18e2d33e3021ed2ef32d85822423b6304f726aa854bae07d0396e9a9addc40f", + 4 }, { @@ -300,7 +389,19 @@ static const ecc_domain_parms_t domain_parms[] = "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", - "0x01" + 1 + }, + + { + "sm2p256v1", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xfffffffeffffffffffffffffffffffffffffffff00000000ffffffffffffffff", + "0xfffffffeffffffffffffffffffffffffffffffff00000000fffffffffffffffc", + "0x28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93", + "0xfffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123", + "0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7", + "0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0", + 1 }, { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } @@ -431,22 +532,43 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, { curve->a = scanval (domain_parms[idx].a); if (curve->a->sign) - mpi_add (curve->a, curve->p, curve->a); + { + mpi_resize (curve->a, curve->p->nlimbs); + _gcry_mpih_sub_n (curve->a->d, curve->p->d, + curve->a->d, curve->p->nlimbs); + curve->a->nlimbs = curve->p->nlimbs; + curve->a->sign = 0; + } } if (!curve->b) { curve->b = scanval (domain_parms[idx].b); if (curve->b->sign) - mpi_add (curve->b, curve->p, curve->b); + { + mpi_resize (curve->b, curve->p->nlimbs); + _gcry_mpih_sub_n (curve->b->d, curve->p->d, + curve->b->d, curve->p->nlimbs); + curve->b->nlimbs = curve->p->nlimbs; + curve->b->sign = 0; + } } if (!curve->n) curve->n = scanval (domain_parms[idx].n); - if (!curve->h) - curve->h = scanval (domain_parms[idx].h); if (!curve->G.x) curve->G.x = scanval (domain_parms[idx].g_x); if (!curve->G.y) curve->G.y = scanval (domain_parms[idx].g_y); + curve->h = domain_parms[idx].h; + + /* + * In the constants of domain_parms, we defined Curve25519 + * domain parameters as the ones in RFC-7748 before the errata + * (eid4730). To keep the computation having exact same values, + * we recover the new value of g_y, here. + */ + if (!strcmp (resname, "Curve25519")) + mpi_sub (curve->G.y, curve->p, curve->G.y); + if (!curve->G.z) curve->G.z = mpi_alloc_set_ui (1); if (!curve->name) @@ -458,15 +580,15 @@ _gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, /* Give the name of the curve NAME, store the curve parameters into P, - A, B, G, N, and H if they point to NULL value. Note that G is returned - in standard uncompressed format. Also update MODEL and DIALECT if - they are not NULL. */ + A, B, G, and N if they point to NULL value. Note that G is + returned in standard uncompressed format. Also update MODEL and + DIALECT if they are not NULL. */ gpg_err_code_t _gcry_ecc_update_curve_param (const char *name, enum gcry_mpi_ec_models *model, enum ecc_dialects *dialect, gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, - gcry_mpi_t *g, gcry_mpi_t *n, gcry_mpi_t *h) + gcry_mpi_t *g, gcry_mpi_t *n) { int idx; @@ -516,11 +638,6 @@ _gcry_ecc_update_curve_param (const char *name, _gcry_mpi_release (*n); *n = scanval (domain_parms[idx].n); } - if (h) - { - _gcry_mpi_release (*h); - *h = scanval (domain_parms[idx].h); - } return 0; } @@ -533,7 +650,7 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) gpg_err_code_t rc; const char *result = NULL; elliptic_curve_t E; - gcry_mpi_t mpi_g = NULL; + gcry_mpi_point_t G = NULL; gcry_mpi_t tmp = NULL; int idx; @@ -558,9 +675,8 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) /* * Extract the curve parameters.. */ - rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "-pabgnh", - &E.p, &E.a, &E.b, &mpi_g, &E.n, &E.h, - NULL)); + rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "pabn", + &E.p, &E.a, &E.b, &E.n, NULL)); if (rc == GPG_ERR_NO_OBJ) { /* This might be the second use case of checking whether a @@ -591,72 +707,100 @@ _gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) if (rc) goto leave; - if (mpi_g) - { - _gcry_mpi_point_init (&E.G); - if (_gcry_ecc_os2ec (&E.G, mpi_g)) - goto leave; - } + rc = point_from_keyparam (&G, keyparms, "g", NULL); + if (rc) + goto leave; + + _gcry_mpi_point_init (&E.G); + _gcry_mpi_point_set (&E.G, G->x, G->y, G->z); for (idx = 0; domain_parms[idx].desc; idx++) { mpi_free (tmp); tmp = scanval (domain_parms[idx].p); - if (!mpi_cmp (tmp, E.p)) + if (mpi_cmp (tmp, E.p)) + continue; + + mpi_free (tmp); + tmp = scanval (domain_parms[idx].a); + if (tmp->sign) { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].a); - if (!mpi_cmp (tmp, E.a)) + if (!mpi_cmpabs (tmp, E.a)) + /* For backward compatibility to <= libgcrypt 1.8, we + allow this match to support existing keys in SEXP. */ + ; + else { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].b); - if (!mpi_cmp (tmp, E.b)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].n); - if (!mpi_cmp (tmp, E.n)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].h); - if (!mpi_cmp (tmp, E.h)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (!mpi_cmp (tmp, E.G.x)) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (!mpi_cmp (tmp, E.G.y)) - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - goto leave; - } - } - } - } - } + mpi_resize (tmp, E.p->nlimbs); + _gcry_mpih_sub_n (tmp->d, E.p->d, + tmp->d, E.p->nlimbs); + tmp->nlimbs = E.p->nlimbs; + tmp->sign = 0; + if (mpi_cmp (tmp, E.a)) + continue; } } + else if (mpi_cmp (tmp, E.a)) + continue; + + mpi_free (tmp); + tmp = scanval (domain_parms[idx].b); + if (tmp->sign) + { + if (!mpi_cmpabs (tmp, E.b)) + /* Same for backward compatibility, see above. */ + ; + else + { + mpi_resize (tmp, E.p->nlimbs); + _gcry_mpih_sub_n (tmp->d, E.p->d, + tmp->d, E.p->nlimbs); + tmp->nlimbs = E.p->nlimbs; + tmp->sign = 0; + if (mpi_cmp (tmp, E.b)) + continue; + } + } + else if (mpi_cmp (tmp, E.b)) + continue; + + mpi_free (tmp); + tmp = scanval (domain_parms[idx].n); + if (mpi_cmp (tmp, E.n)) + continue; + + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_x); + if (mpi_cmp (tmp, E.G.x)) + continue; + + mpi_free (tmp); + tmp = scanval (domain_parms[idx].g_y); + if (mpi_cmp (tmp, E.G.y)) + continue; + + result = domain_parms[idx].desc; + if (r_nbits) + *r_nbits = domain_parms[idx].nbits; + break; } leave: + _gcry_mpi_point_release (G); _gcry_mpi_release (tmp); _gcry_mpi_release (E.p); _gcry_mpi_release (E.a); _gcry_mpi_release (E.b); - _gcry_mpi_release (mpi_g); _gcry_mpi_point_free_parts (&E.G); _gcry_mpi_release (E.n); - _gcry_mpi_release (E.h); return result; } /* Helper to extract an MPI from key parameters. */ static gpg_err_code_t -mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name) +mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name, + int opaque) { gcry_err_code_t ec = 0; gcry_sexp_t l1; @@ -664,7 +808,7 @@ mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name) l1 = sexp_find_token (keyparam, name, 0); if (l1) { - *r_a = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + *r_a = sexp_nth_mpi (l1, 1, opaque? GCRYMPI_FMT_OPAQUE : GCRYMPI_FMT_USG); sexp_release (l1); if (!*r_a) ec = GPG_ERR_INV_OBJ; @@ -696,10 +840,7 @@ point_from_keyparam (gcry_mpi_point_t *r_a, return GPG_ERR_INV_OBJ; point = mpi_point_new (0); - if (ec && ec->dialect == ECC_DIALECT_ED25519) - rc = _gcry_ecc_eddsa_decodepoint (a, ec, point, NULL, NULL); - else - rc = _gcry_ecc_os2ec (point, a); + rc = _gcry_mpi_ec_decode_point (point, a, ec); mpi_free (a); if (rc) { @@ -718,14 +859,14 @@ point_from_keyparam (gcry_mpi_point_t *r_a, if (!tmpname) return gpg_err_code_from_syserror (); strcpy (stpcpy (tmpname, name), ".x"); - rc = mpi_from_keyparam (&x, keyparam, tmpname); + rc = mpi_from_keyparam (&x, keyparam, tmpname, 0); if (rc) { xfree (tmpname); return rc; } strcpy (stpcpy (tmpname, name), ".y"); - rc = mpi_from_keyparam (&y, keyparam, tmpname); + rc = mpi_from_keyparam (&y, keyparam, tmpname, 0); if (rc) { mpi_free (x); @@ -733,7 +874,7 @@ point_from_keyparam (gcry_mpi_point_t *r_a, return rc; } strcpy (stpcpy (tmpname, name), ".z"); - rc = mpi_from_keyparam (&z, keyparam, tmpname); + rc = mpi_from_keyparam (&z, keyparam, tmpname, 0); if (rc) { mpi_free (y); @@ -761,33 +902,22 @@ point_from_keyparam (gcry_mpi_point_t *r_a, } -/* This function creates a new context for elliptic curve operations. - Either KEYPARAM or CURVENAME must be given. If both are given and - KEYPARAM has no curve parameter, CURVENAME is used to add missing - parameters. On success 0 is returned and the new context stored at - R_CTX. On error NULL is stored at R_CTX and an error code is - returned. The context needs to be released using - gcry_ctx_release. */ -gpg_err_code_t -_gcry_mpi_ec_new (gcry_ctx_t *r_ctx, - gcry_sexp_t keyparam, const char *curvename) + +static gpg_err_code_t +mpi_ec_get_elliptic_curve (elliptic_curve_t *E, int *r_flags, + gcry_sexp_t keyparam, const char *curvename) { gpg_err_code_t errc; - gcry_ctx_t ctx = NULL; - enum gcry_mpi_ec_models model = MPI_EC_WEIERSTRASS; - enum ecc_dialects dialect = ECC_DIALECT_STANDARD; - gcry_mpi_t p = NULL; - gcry_mpi_t a = NULL; - gcry_mpi_t b = NULL; - gcry_mpi_point_t G = NULL; - gcry_mpi_t n = NULL; - gcry_mpi_t h = NULL; - gcry_mpi_point_t Q = NULL; - gcry_mpi_t d = NULL; - int flags = 0; + unsigned int nbits; gcry_sexp_t l1; - *r_ctx = NULL; + errc = _gcry_pk_util_get_nbits (keyparam, &nbits); + if (errc) + return errc; + + E->model = MPI_EC_WEIERSTRASS; + E->dialect = ECC_DIALECT_STANDARD; + E->h = 1; if (keyparam) { @@ -795,11 +925,23 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, l1 = sexp_find_token (keyparam, "flags", 0); if (l1) { + int flags = 0; + errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL); sexp_release (l1); l1 = NULL; if (errc) goto leave; + + *r_flags |= flags; + } + + /* Parse the deprecated optional transient-key flag. */ + l1 = sexp_find_token (keyparam, "transient-key", 0); + if (l1) + { + *r_flags |= PUBKEY_FLAG_TRANSIENT_KEY; + sexp_release (l1); } /* Check whether a curve name was given. */ @@ -807,26 +949,41 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, /* If we don't have a curve name or if override parameters have explicitly been requested, parse them. */ - if (!l1 || (flags & PUBKEY_FLAG_PARAM)) + if (!l1 || (*r_flags & PUBKEY_FLAG_PARAM)) { - errc = mpi_from_keyparam (&p, keyparam, "p"); + gcry_mpi_point_t G = NULL; + gcry_mpi_t cofactor = NULL; + + errc = mpi_from_keyparam (&E->p, keyparam, "p", 0); if (errc) goto leave; - errc = mpi_from_keyparam (&a, keyparam, "a"); + errc = mpi_from_keyparam (&E->a, keyparam, "a", 0); if (errc) goto leave; - errc = mpi_from_keyparam (&b, keyparam, "b"); + errc = mpi_from_keyparam (&E->b, keyparam, "b", 0); if (errc) goto leave; errc = point_from_keyparam (&G, keyparam, "g", NULL); if (errc) goto leave; - errc = mpi_from_keyparam (&n, keyparam, "n"); + if (G) + { + _gcry_mpi_point_init (&E->G); + mpi_point_set (&E->G, G->x, G->y, G->z); + mpi_point_set (G, NULL, NULL, NULL); + mpi_point_release (G); + } + errc = mpi_from_keyparam (&E->n, keyparam, "n", 0); if (errc) goto leave; - errc = mpi_from_keyparam (&h, keyparam, "h"); + errc = mpi_from_keyparam (&cofactor, keyparam, "h", 0); if (errc) goto leave; + if (cofactor) + { + mpi_get_ui (&E->h, cofactor); + mpi_free (cofactor); + } } } else @@ -836,10 +993,9 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, in missing values. If no curve parameter is available try an optional provided curvename. If only the curvename has been given use that one. */ - if (l1 || curvename) + if (l1 || curvename || nbits) { char *name; - elliptic_curve_t *E; if (l1) { @@ -854,129 +1010,213 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, else name = NULL; - E = xtrycalloc (1, sizeof *E); - if (!E) - { - errc = gpg_err_code_from_syserror (); - xfree (name); - goto leave; - } - - errc = _gcry_ecc_fill_in_curve (0, name? name : curvename, E, NULL); + errc = _gcry_ecc_fill_in_curve (nbits, name? name : curvename, E, NULL); xfree (name); if (errc) - { - xfree (E); - goto leave; - } - - model = E->model; - dialect = E->dialect; - - if (!p) - { - p = E->p; - E->p = NULL; - } - if (!a) - { - a = E->a; - E->a = NULL; - } - if (!b) - { - b = E->b; - E->b = NULL; - } - if (!G) - { - G = mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z); - E->G.x = NULL; - E->G.y = NULL; - E->G.z = NULL; - } - if (!n) - { - n = E->n; - E->n = NULL; - } - if (!h) - { - h = E->h; - E->h = NULL; - } - _gcry_ecc_curve_free (E); - xfree (E); - } - - - errc = _gcry_mpi_ec_p_new (&ctx, model, dialect, flags, p, a, b); - if (!errc) - { - mpi_ec_t ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); - - if (b) - { - mpi_free (ec->b); - ec->b = b; - b = NULL; - } - if (G) - { - ec->G = G; - G = NULL; - } - if (n) - { - ec->n = n; - n = NULL; - } - if (h) - { - ec->h = h; - h = NULL; - } - - /* Now that we know the curve name we can look for the public key - Q. point_from_keyparam needs to know the curve parameters so - that it is able to use the correct decompression. Parsing - the private key D could have been done earlier but it is less - surprising if we do it here as well. */ - if (keyparam) - { - errc = point_from_keyparam (&Q, keyparam, "q", ec); - if (errc) - goto leave; - errc = mpi_from_keyparam (&d, keyparam, "d"); - if (errc) - goto leave; - } - - if (Q) - { - ec->Q = Q; - Q = NULL; - } - if (d) - { - ec->d = d; - d = NULL; - } - - *r_ctx = ctx; - ctx = NULL; + goto leave; } leave: + return errc; +} + +static gpg_err_code_t +mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags, + elliptic_curve_t *E, gcry_sexp_t keyparam) +{ + gpg_err_code_t errc = 0; + + ec->G = mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z); + E->G.x = NULL; + E->G.y = NULL; + E->G.z = NULL; + ec->n = E->n; + E->n = NULL; + ec->h = E->h; + ec->name = E->name; + + /* Now that we know the curve name we can look for the public key + Q. point_from_keyparam needs to know the curve parameters so + that it is able to use the correct decompression. Parsing + the private key D could have been done earlier but it is less + surprising if we do it here as well. */ + if (keyparam) + { + int is_opaque_bytes = ((ec->dialect == ECC_DIALECT_ED25519 + && (flags & PUBKEY_FLAG_EDDSA)) + || (ec->dialect == ECC_DIALECT_SAFECURVE)); + + errc = point_from_keyparam (&ec->Q, keyparam, "q", ec); + if (errc) + return errc; + errc = mpi_from_keyparam (&ec->d, keyparam, "d", is_opaque_bytes); + + /* Size of opaque bytes should match size of P. */ + if (!errc && ec->d && is_opaque_bytes) + { + unsigned int n = mpi_get_nbits (ec->d); + unsigned int len; + + len = (ec->nbits+7)/8; + /* EdDSA requires additional bit for sign. */ + if ((ec->nbits%8) == 0 && ec->model == MPI_EC_EDWARDS) + len++; + + if ((n+7)/8 != len) + { + if ((n+7)/8 < len && ec->dialect == ECC_DIALECT_ED25519) + { + /* + * GnuPG (<= 2.2) or OpenPGP implementations with no + * SOS support may remove zeros at the beginning. + * Recover those zeros. + */ + const unsigned char *buf; + unsigned char *value; + + buf = mpi_get_opaque (ec->d, &n); + if (!buf) + return GPG_ERR_INV_OBJ; + + value = xtrycalloc_secure (1, len); + if (!value) + return gpg_err_code_from_syserror (); + + memset (value, 0, len - (n+7)/8); + memcpy (value + len - (n+7)/8, buf, (n+7)/8); + mpi_set_opaque (ec->d, value, len); + } + else + { + if (DBG_CIPHER) + log_debug ("scalar size (%d) != prime size (%d)", + (n+7)/8, len); + + errc = GPG_ERR_INV_OBJ; + } + } + } + } + + return errc; +} + +gpg_err_code_t +_gcry_mpi_ec_internal_new (mpi_ec_t *r_ec, int *r_flags, const char *name_op, + gcry_sexp_t keyparam, const char *curvename) +{ + gpg_err_code_t errc; + elliptic_curve_t E; + mpi_ec_t ec; + + *r_ec = NULL; + + memset (&E, 0, sizeof E); + errc = mpi_ec_get_elliptic_curve (&E, r_flags, keyparam, curvename); + if (errc) + goto leave; + + ec = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, *r_flags, + E.p, E.a, E.b); + if (!ec) + goto leave; + + errc = mpi_ec_setup_elliptic_curve (ec, *r_flags, &E, keyparam); + if (errc) + { + _gcry_mpi_ec_free (ec); + goto leave; + } + else + *r_ec = ec; + + if (!errc && DBG_CIPHER) + { + gcry_mpi_t mpi_q = NULL; + gcry_sexp_t l1; + char msg[80]; + + l1 = sexp_find_token (keyparam, "q", 0); + if (l1) + { + mpi_q = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE); + sexp_release (l1); + } + + log_debug ("%s info: %s/%s%s\n", name_op, + _gcry_ecc_model2str (ec->model), + _gcry_ecc_dialect2str (ec->dialect), + (*r_flags & PUBKEY_FLAG_EDDSA)? "+EdDSA" : ""); + if (ec->name) + log_debug ("%s name: %s\n", name_op, ec->name); + snprintf (msg, sizeof msg, "%s p", name_op); + log_printmpi (msg, ec->p); + snprintf (msg, sizeof msg, "%s a", name_op); + log_printmpi (msg, ec->a); + snprintf (msg, sizeof msg, "%s b", name_op); + log_printmpi (msg, ec->b); + snprintf (msg, sizeof msg, "%s g", name_op); + log_printpnt (msg, ec->G, NULL); + snprintf (msg, sizeof msg, "%s n", name_op); + log_printmpi (msg, ec->n); + log_debug ("%s h:+%02x\n", name_op, ec->h); + if (mpi_q) + { + snprintf (msg, sizeof msg, "%s q", name_op); + log_printmpi (msg, mpi_q); + mpi_free (mpi_q); + } + if (!fips_mode () && ec->d) + { + snprintf (msg, sizeof msg, "%s d", name_op); + log_printmpi (msg, ec->d); + } + } + + leave: + _gcry_ecc_curve_free (&E); + return errc; +} + +/* This function creates a new context for elliptic curve operations. + Either KEYPARAM or CURVENAME must be given. If both are given and + KEYPARAM has no curve parameter, CURVENAME is used to add missing + parameters. On success 0 is returned and the new context stored at + R_CTX. On error NULL is stored at R_CTX and an error code is + returned. The context needs to be released using + gcry_ctx_release. */ +gpg_err_code_t +_gcry_mpi_ec_new (gcry_ctx_t *r_ctx, + gcry_sexp_t keyparam, const char *curvename) +{ + gpg_err_code_t errc; + elliptic_curve_t E; + gcry_ctx_t ctx = NULL; + int flags = 0; + mpi_ec_t ec; + + *r_ctx = NULL; + + memset (&E, 0, sizeof E); + errc = mpi_ec_get_elliptic_curve (&E, &flags, keyparam, curvename); + if (errc) + goto leave; + + errc = _gcry_mpi_ec_p_new (&ctx, E.model, E.dialect, flags, E.p, E.a, E.b); + if (errc) + goto leave; + + ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); + errc = mpi_ec_setup_elliptic_curve (ec, flags, &E, keyparam); + if (errc) + goto leave; + + *r_ctx = ctx; + ctx = NULL; + + leave: + _gcry_ecc_curve_free (&E); _gcry_ctx_release (ctx); - mpi_free (p); - mpi_free (a); - mpi_free (b); - _gcry_mpi_point_release (G); - mpi_free (n); - mpi_free (h); - _gcry_mpi_point_release (Q); - mpi_free (d); return errc; } @@ -989,7 +1229,7 @@ _gcry_ecc_get_param_sexp (const char *name) elliptic_curve_t E; mpi_ec_t ctx; gcry_mpi_t g_x, g_y; - gcry_mpi_t pkey[7]; + gcry_mpi_t pkey[5]; gcry_sexp_t result; int i; @@ -999,10 +1239,10 @@ _gcry_ecc_get_param_sexp (const char *name) g_x = mpi_new (0); g_y = mpi_new (0); - ctx = _gcry_mpi_ec_p_internal_new (MPI_EC_WEIERSTRASS, - ECC_DIALECT_STANDARD, + ctx = _gcry_mpi_ec_p_internal_new (E.model, + E.dialect, 0, - E.p, E.a, NULL); + E.p, E.a, E.b); if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx)) log_fatal ("ecc get param: Failed to get affine coordinates\n"); _gcry_mpi_ec_free (ctx); @@ -1013,18 +1253,16 @@ _gcry_ecc_get_param_sexp (const char *name) pkey[2] = E.b; pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p); pkey[4] = E.n; - pkey[5] = E.h; - pkey[6] = NULL; mpi_free (g_x); mpi_free (g_y); if (sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%m)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], pkey[5])) + "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)))", + pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], E.h)) result = NULL; - for (i=0; pkey[i]; i++) + for (i=0; i < DIM (pkey); i++) _gcry_mpi_release (pkey[i]); return result; @@ -1048,8 +1286,12 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); if (!strcmp (name, "n") && ec->n) return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); - if (!strcmp (name, "h") && ec->h) - return mpi_is_const (ec->h) && !copy? ec->h : mpi_copy (ec->h); + if (!strcmp (name, "h")) + { + gcry_mpi_t h = _gcry_mpi_get_const (ec->h); + + return !copy? h : mpi_set (NULL, h); + } if (!strcmp (name, "d") && ec->d) return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); @@ -1075,7 +1317,7 @@ _gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) { /* If only the private key is given, compute the public key. */ if (!ec->Q) - ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL); + ec->Q = _gcry_ecc_compute_public (NULL, ec); if (!ec->Q) return NULL; @@ -1108,7 +1350,7 @@ _gcry_ecc_get_point (const char *name, mpi_ec_t ec) { /* If only the private key is given, compute the public key. */ if (!ec->Q) - ec->Q = _gcry_ecc_compute_public (NULL, ec, NULL, NULL); + ec->Q = _gcry_ecc_compute_public (NULL, ec); if (ec->Q) return point_copy (ec->Q); @@ -1150,8 +1392,7 @@ _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) } else if (!strcmp (name, "h")) { - mpi_free (ec->h); - ec->h = mpi_copy (newvalue); + mpi_get_ui (&ec->h, newvalue); } else if (*name == 'q' && (!name[1] || name[1] == '@')) { @@ -1159,10 +1400,7 @@ _gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) { if (!ec->Q) ec->Q = mpi_point_new (0); - if (ec->dialect == ECC_DIALECT_ED25519) - rc = _gcry_ecc_eddsa_decodepoint (newvalue, ec, ec->Q, NULL, NULL); - else - rc = _gcry_ecc_os2ec (ec->Q, newvalue); + rc = _gcry_mpi_ec_decode_point (ec->Q, newvalue, ec); } if (rc || !newvalue) { diff --git a/libgcrypt-1.8.3-cmac-selftest.patch b/libgcrypt-1.8.3-cmac-selftest.patch deleted file mode 100644 index d480092..0000000 --- a/libgcrypt-1.8.3-cmac-selftest.patch +++ /dev/null @@ -1,322 +0,0 @@ -diff -up libgcrypt-1.8.3/cipher/cipher-cmac.c.cmac-selftest libgcrypt-1.8.3/cipher/cipher-cmac.c ---- libgcrypt-1.8.3/cipher/cipher-cmac.c.cmac-selftest 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/cipher/cipher-cmac.c 2019-05-31 17:33:35.594407152 +0200 -@@ -251,3 +251,246 @@ _gcry_cipher_cmac_set_subkeys (gcry_ciph - - return GPG_ERR_NO_ERROR; - } -+ -+/* CMAC selftests. -+ * Copyright (C) 2008 Free Software Foundation, Inc. -+ * Copyright (C) 2019 Red Hat, Inc. -+ */ -+ -+ -+ -+/* Check one MAC with MAC ALGO using the regular MAC -+ * API. (DATA,DATALEN) is the data to be MACed, (KEY,KEYLEN) the key -+ * and (EXPECT,EXPECTLEN) the expected result. If TRUNC is set, the -+ * EXPECTLEN may be less than the digest length. Returns NULL on -+ * success or a string describing the failure. */ -+static const char * -+check_one (int algo, -+ const void *data, size_t datalen, -+ const void *key, size_t keylen, -+ const void *expect, size_t expectlen) -+{ -+ gcry_mac_hd_t hd; -+ unsigned char mac[512]; /* hardcoded to avoid allocation */ -+ size_t macoutlen = expectlen; -+ -+/* printf ("MAC algo %d\n", algo); */ -+ if (_gcry_mac_get_algo_maclen (algo) != expectlen || -+ expectlen > sizeof (mac)) -+ return "invalid tests data"; -+ if (_gcry_mac_open (&hd, algo, 0, NULL)) -+ return "gcry_mac_open failed"; -+ if (_gcry_mac_setkey (hd, key, keylen)) -+ { -+ _gcry_mac_close (hd); -+ return "gcry_md_setkey failed"; -+ } -+ if (_gcry_mac_write (hd, data, datalen)) -+ { -+ _gcry_mac_close (hd); -+ return "gcry_mac_write failed"; -+ } -+ if (_gcry_mac_read (hd, mac, &macoutlen)) -+ { -+ _gcry_mac_close (hd); -+ return "gcry_mac_read failed"; -+ } -+ _gcry_mac_close (hd); -+ if (macoutlen != expectlen || memcmp (mac, expect, expectlen)) -+ { -+/* int i; */ -+ -+/* fputs (" {", stdout); */ -+/* for (i=0; i < expectlen-1; i++) */ -+/* { */ -+/* if (i && !(i % 8)) */ -+/* fputs ("\n ", stdout); */ -+/* printf (" 0x%02x,", mac[i]); */ -+/* } */ -+/* printf (" 0x%02x } },\n", mac[i]); */ -+ -+ return "does not match"; -+ } -+ return NULL; -+} -+ -+ -+static gpg_err_code_t -+selftests_cmac_tdes (int extended, selftest_report_func_t report) -+{ -+ const char *what; -+ const char *errtxt; -+ -+ what = "Basic TDES"; -+ errtxt = check_one (GCRY_MAC_CMAC_3DES, -+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" -+ "\xae\x2d\x8a\x57", 20, -+ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" -+ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, -+ "\x74\x3d\xdb\xe0\xce\x2d\xc2\xed", 8); -+ if (errtxt) -+ goto failed; -+ -+ if (extended) -+ { -+ what = "Extended TDES #1"; -+ errtxt = check_one (GCRY_MAC_CMAC_3DES, -+ "", 0, -+ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" -+ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, -+ "\xb7\xa6\x88\xe1\x22\xff\xaf\x95", 8); -+ if (errtxt) -+ goto failed; -+ -+ what = "Extended TDES #2"; -+ errtxt = check_one (GCRY_MAC_CMAC_3DES, -+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96", 8, -+ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" -+ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, -+ "\x8e\x8f\x29\x31\x36\x28\x37\x97", 8); -+ if (errtxt) -+ goto failed; -+ -+ what = "Extended TDES #3"; -+ errtxt = check_one (GCRY_MAC_CMAC_3DES, -+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" -+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", 32, -+ "\x8a\xa8\x3b\xf8\xcb\xda\x10\x62\x0b\xc1\xbf\x19\xfb\xb6\xcd\x58" -+ "\xbc\x31\x3d\x4a\x37\x1c\xa8\xb5", 24, -+ "\x33\xe6\xb1\x09\x24\x00\xea\xe5", 8); -+ if (errtxt) -+ goto failed; -+ } -+ -+ return 0; /* Succeeded. */ -+ -+ failed: -+ if (report) -+ report ("cmac", GCRY_MAC_CMAC_3DES, what, errtxt); -+ return GPG_ERR_SELFTEST_FAILED; -+} -+ -+ -+ -+static gpg_err_code_t -+selftests_cmac_aes (int extended, selftest_report_func_t report) -+{ -+ const char *what; -+ const char *errtxt; -+ -+ what = "Basic AES128"; -+ errtxt = check_one (GCRY_MAC_CMAC_AES, -+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" -+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" -+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, -+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, -+ "\xdf\xa6\x67\x47\xde\x9a\xe6\x30\x30\xca\x32\x61\x14\x97\xc8\x27", 16); -+ if (errtxt) -+ goto failed; -+ -+ what = "Basic AES192"; -+ errtxt = check_one (GCRY_MAC_CMAC_AES, -+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" -+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" -+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, -+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" -+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, -+ "\x8a\x1d\xe5\xbe\x2e\xb3\x1a\xad\x08\x9a\x82\xe6\xee\x90\x8b\x0e", 16); -+ if (errtxt) -+ goto failed; -+ -+ what = "Basic AES256"; -+ errtxt = check_one (GCRY_MAC_CMAC_AES, -+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" -+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" -+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11", 40, -+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" -+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, -+ "\xaa\xf3\xd8\xf1\xde\x56\x40\xc2\x32\xf5\xb1\x69\xb9\xc9\x11\xe6", 16); -+ if (errtxt) -+ goto failed; -+ if (extended) -+ { -+ what = "Extended AES #1"; -+ errtxt = check_one (GCRY_MAC_CMAC_AES, -+ "", 0, -+ "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", 16, -+ "\xbb\x1d\x69\x29\xe9\x59\x37\x28\x7f\xa3\x7d\x12\x9b\x75\x67\x46", 16); -+ if (errtxt) -+ goto failed; -+ -+ what = "Extended AES #2"; -+ errtxt = check_one (GCRY_MAC_CMAC_AES, -+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", 16, -+ "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b\x80\x90\x79\xe5" -+ "\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", 24, -+ "\x9e\x99\xa7\xbf\x31\xe7\x10\x90\x06\x62\xf6\x5e\x61\x7c\x51\x84", 16); -+ if (errtxt) -+ goto failed; -+ -+ what = "Extended AES #3"; -+ errtxt = check_one (GCRY_MAC_CMAC_AES, -+ "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a" -+ "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51" -+ "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef" -+ "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", 64, -+ "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" -+ "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", 32, -+ "\xe1\x99\x21\x90\x54\x9f\x6e\xd5\x69\x6a\x2c\x05\x6c\x31\x54\x10", 16 ); -+ if (errtxt) -+ goto failed; -+ } -+ -+ return 0; /* Succeeded. */ -+ -+ failed: -+ if (report) -+ report ("cmac", GCRY_MAC_CMAC_AES, what, errtxt); -+ return GPG_ERR_SELFTEST_FAILED; -+} -+ -+ -+/* Run a full self-test for ALGO and return 0 on success. */ -+static gpg_err_code_t -+run_cmac_selftests (int algo, int extended, selftest_report_func_t report) -+{ -+ gpg_err_code_t ec; -+ -+ switch (algo) -+ { -+ case GCRY_MAC_CMAC_3DES: -+ ec = selftests_cmac_tdes (extended, report); -+ break; -+ case GCRY_MAC_CMAC_AES: -+ ec = selftests_cmac_aes (extended, report); -+ break; -+ -+ default: -+ ec = GPG_ERR_MAC_ALGO; -+ break; -+ } -+ return ec; -+} -+ -+ -+ -+ -+/* Run the selftests for CMAC with CMAC algorithm ALGO with optional -+ reporting function REPORT. */ -+gpg_error_t -+_gcry_cmac_selftest (int algo, int extended, selftest_report_func_t report) -+{ -+ gcry_err_code_t ec = 0; -+ -+ if (!_gcry_mac_algo_info( algo, GCRYCTL_TEST_ALGO, NULL, NULL )) -+ { -+ ec = run_cmac_selftests (algo, extended, report); -+ } -+ else -+ { -+ ec = GPG_ERR_MAC_ALGO; -+ if (report) -+ report ("mac", algo, "module", "algorithm not available"); -+ } -+ return gpg_error (ec); -+} -diff -up libgcrypt-1.8.3/src/cipher-proto.h.cmac-selftest libgcrypt-1.8.3/src/cipher-proto.h ---- libgcrypt-1.8.3/src/cipher-proto.h.cmac-selftest 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/src/cipher-proto.h 2019-05-31 17:29:34.574588234 +0200 -@@ -256,6 +256,8 @@ gcry_error_t _gcry_pk_selftest (int algo - selftest_report_func_t report); - gcry_error_t _gcry_hmac_selftest (int algo, int extended, - selftest_report_func_t report); -+gcry_error_t _gcry_cmac_selftest (int algo, int extended, -+ selftest_report_func_t report); - - gcry_error_t _gcry_random_selftest (selftest_report_func_t report); - -diff -up libgcrypt-1.8.3/src/fips.c.cmac-selftest libgcrypt-1.8.3/src/fips.c ---- libgcrypt-1.8.3/src/fips.c.cmac-selftest 2018-11-01 15:40:36.051865535 +0100 -+++ libgcrypt-1.8.3/src/fips.c 2019-05-31 17:31:20.157756640 +0200 -@@ -521,29 +521,32 @@ run_digest_selftests (int extended) - - /* Run self-tests for all HMAC algorithms. Return 0 on success. */ - static int --run_hmac_selftests (int extended) -+run_mac_selftests (int extended) - { -- static int algos[] = -+ static int algos[][2] = - { -- GCRY_MD_SHA1, -- GCRY_MD_SHA224, -- GCRY_MD_SHA256, -- GCRY_MD_SHA384, -- GCRY_MD_SHA512, -- GCRY_MD_SHA3_224, -- GCRY_MD_SHA3_256, -- GCRY_MD_SHA3_384, -- GCRY_MD_SHA3_512, -- 0 -+ { GCRY_MD_SHA1, 0 }, -+ { GCRY_MD_SHA224, 0 }, -+ { GCRY_MD_SHA256, 0 }, -+ { GCRY_MD_SHA384, 0 }, -+ { GCRY_MD_SHA512, 0 }, -+ { GCRY_MD_SHA3_224, 0 }, -+ { GCRY_MD_SHA3_256, 0 }, -+ { GCRY_MD_SHA3_384, 0 }, -+ { GCRY_MD_SHA3_512, 0 }, -+ { GCRY_MAC_CMAC_3DES, 1 }, -+ { GCRY_MAC_CMAC_AES, 1 }, -+ { 0, 0 } - }; - int idx; - gpg_error_t err; - int anyerr = 0; - -- for (idx=0; algos[idx]; idx++) -+ for (idx=0; algos[idx][0]; idx++) - { -- err = _gcry_hmac_selftest (algos[idx], extended, reporter); -- reporter ("hmac", algos[idx], NULL, -+ err = algos[idx][1] ? _gcry_cmac_selftest (algos[idx][0], extended, reporter) : -+ _gcry_hmac_selftest (algos[idx][0], extended, reporter); -+ reporter (algos[idx][1] ? "cmac" : "hmac", algos[idx][0], NULL, - err? gpg_strerror (err):NULL); - if (err) - anyerr = 1; -@@ -747,7 +750,7 @@ _gcry_fips_run_selftests (int extended) - if (run_digest_selftests (extended)) - goto leave; - -- if (run_hmac_selftests (extended)) -+ if (run_mac_selftests (extended)) - goto leave; - - /* Run random tests before the pubkey tests because the latter diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch index 66abd59..adecbe4 100644 --- a/libgcrypt-1.8.3-fips-ctor.patch +++ b/libgcrypt-1.8.3-fips-ctor.patch @@ -50,7 +50,7 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c break; case GCRYCTL_SET_ENFORCED_FIPS_FLAG: -- if (!any_init_done) +- if (!_gcry_global_any_init_done) + if (fips_mode ()) { - /* Not yet initialized at all. Set the enforced fips mode flag */ diff --git a/libgcrypt-1.8.3-fips-enttest.patch b/libgcrypt-1.8.3-fips-enttest.patch index b6b09ba..34e54bf 100644 --- a/libgcrypt-1.8.3-fips-enttest.patch +++ b/libgcrypt-1.8.3-fips-enttest.patch @@ -2,7 +2,7 @@ diff -up libgcrypt-1.8.3/random/random-drbg.c.fips-enttest libgcrypt-1.8.3/rando --- libgcrypt-1.8.3/random/random-drbg.c.fips-enttest 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.3/random/random-drbg.c 2019-06-24 10:04:23.219547141 +0200 @@ -317,6 +317,7 @@ struct drbg_state_s - unsigned char *ctr_null; /* CTR mode zero buffer */ + gcry_cipher_hd_t ctr_handle; /* CTR mode cipher handle */ int seeded:1; /* DRBG fully seeded? */ int pr:1; /* Prediction resistance enabled? */ + int ent_primed:1; /* Previous entropy data primed? */ diff --git a/libgcrypt-1.8.4-tests-fipsmode.patch b/libgcrypt-1.8.4-tests-fipsmode.patch index 1442a0b..d6e29d1 100644 --- a/libgcrypt-1.8.4-tests-fipsmode.patch +++ b/libgcrypt-1.8.4-tests-fipsmode.patch @@ -2,7 +2,7 @@ diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basi --- libgcrypt-1.8.4/tests/basic.c.tests-fipsmode 2018-04-17 17:29:40.000000000 +0200 +++ libgcrypt-1.8.4/tests/basic.c 2019-02-12 13:30:48.935791024 +0100 @@ -6964,7 +6964,7 @@ check_ciphers (void) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0); + check_one_cipher (algos[i], GCRY_CIPHER_MODE_EAX, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0); - if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) @@ -10,7 +10,7 @@ diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basi check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0); if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN) check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0); -@@ -7010,11 +7010,17 @@ check_cipher_modes(void) +@@ -7010,12 +7010,18 @@ check_cipher_modes(void) check_cfb_cipher (); check_ofb_cipher (); check_ccm_cipher (); @@ -24,6 +24,7 @@ diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basi + check_ocb_cipher (); + } check_xts_cipher (); + check_eax_cipher (); - check_gost28147_cipher (); + if (!in_fips_mode) + { @@ -46,7 +47,7 @@ diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basi gcry_md_hd_t md; - /* First trigger a self-test. */ -- xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); +- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) fail ("not in operational state after self-test\n"); @@ -58,7 +59,7 @@ diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basi - { - /* Now run a self-test and to get back into - operational state. */ -- xgcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); +- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("did not reach operational after error " - "and self-test\n"); @@ -70,7 +71,7 @@ diff -up libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode libgcrypt-1.8.4/tests/ --- libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode 2019-02-12 11:31:44.859603883 +0100 +++ libgcrypt-1.8.4/tests/benchmark.c 2019-02-12 14:10:40.271999352 +0100 @@ -872,8 +872,10 @@ cipher_bench ( const char *algoname ) - || (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM)) + && algo != GCRY_CIPHER_CHACHA20) continue; - if (modes[modeidx].req_blocksize > 0 @@ -150,9 +151,9 @@ diff -up libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode libgcrypt-1.8.4/tests/ --- libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.4/tests/t-cv25519.c 2019-02-12 14:02:35.935705390 +0100 @@ -560,6 +560,9 @@ main (int argc, char **argv) - xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); - xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); - xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + /* Curve25519 isn't supported in fips mode */ + if (gcry_fips_mode_active()) + return 77; @@ -163,13 +164,13 @@ diff -up libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode libgcrypt-1.8.4/tests/t --- libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode 2017-11-23 19:19:54.000000000 +0100 +++ libgcrypt-1.8.4/tests/t-secmem.c 2019-02-12 11:51:02.462190538 +0100 @@ -174,7 +174,8 @@ main (int argc, char **argv) - xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); - xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); - xgcry_control (GCRYCTL_INIT_SECMEM, pool_size, 0); + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0)); - gcry_set_outofcore_handler (outofcore_handler, NULL); + if (!gcry_fips_mode_active ()) + gcry_set_outofcore_handler (outofcore_handler, NULL); - xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); /* Libgcrypt prints a warning when the first overflow is allocated; @@ -184,7 +185,8 @@ main (int argc, char **argv) diff --git a/libgcrypt-1.8.4-use-poll.patch b/libgcrypt-1.8.4-use-poll.patch index b96c6ce..d55b6a3 100644 --- a/libgcrypt-1.8.4-use-poll.patch +++ b/libgcrypt-1.8.4-use-poll.patch @@ -6,9 +6,9 @@ diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndli #include #include +#include - #if defined(__linux__) && defined(HAVE_SYSCALL) + #if defined(__linux__) || !defined(HAVE_GETENTROPY) + #ifdef HAVE_SYSCALL # include - #endif @@ -241,9 +242,8 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) @@ -18,8 +18,8 @@ diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndli int rc; + struct pollfd pfd; - /* If we have a modern Linux kernel, we first try to use the new - * getrandom syscall. That call guarantees that the kernel's + /* If we have a modern operating system, we first try to use the new + * getentropy function. That call guarantees that the kernel's @@ -300,36 +300,25 @@ _gcry_rndlinux_gather_random (void (*add any_need_entropy = 1; } diff --git a/libgcrypt-1.8.5-aes-perf.patch b/libgcrypt-1.8.5-aes-perf.patch deleted file mode 100644 index 268ce70..0000000 --- a/libgcrypt-1.8.5-aes-perf.patch +++ /dev/null @@ -1,8156 +0,0 @@ -diff -up libgcrypt-1.8.5/cipher/arcfour.c.aes-perf libgcrypt-1.8.5/cipher/arcfour.c ---- libgcrypt-1.8.5/cipher/arcfour.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/arcfour.c 2020-04-22 18:29:41.662862382 +0200 -@@ -184,10 +184,12 @@ do_arcfour_setkey (void *context, const - } - - static gcry_err_code_t --arcfour_setkey ( void *context, const byte *key, unsigned int keylen ) -+arcfour_setkey ( void *context, const byte *key, unsigned int keylen, -+ gcry_cipher_hd_t hd ) - { - ARCFOUR_context *ctx = (ARCFOUR_context *) context; - gcry_err_code_t rc = do_arcfour_setkey (ctx, key, keylen ); -+ (void)hd; - return rc; - } - -@@ -207,11 +209,11 @@ selftest(void) - static const byte ciphertext_1[] = - { 0xF1, 0x38, 0x29, 0xC9, 0xDE }; - -- arcfour_setkey( &ctx, key_1, sizeof(key_1)); -+ arcfour_setkey( &ctx, key_1, sizeof(key_1), NULL); - encrypt_stream( &ctx, scratch, plaintext_1, sizeof(plaintext_1)); - if ( memcmp (scratch, ciphertext_1, sizeof (ciphertext_1))) - return "Arcfour encryption test 1 failed."; -- arcfour_setkey( &ctx, key_1, sizeof(key_1)); -+ arcfour_setkey( &ctx, key_1, sizeof(key_1), NULL); - encrypt_stream(&ctx, scratch, scratch, sizeof(plaintext_1)); /* decrypt */ - if ( memcmp (scratch, plaintext_1, sizeof (plaintext_1))) - return "Arcfour decryption test 1 failed."; -diff -up libgcrypt-1.8.5/cipher/blowfish.c.aes-perf libgcrypt-1.8.5/cipher/blowfish.c ---- libgcrypt-1.8.5/cipher/blowfish.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/blowfish.c 2020-04-22 18:29:41.663862363 +0200 -@@ -37,6 +37,7 @@ - #include "g10lib.h" - #include "cipher.h" - #include "bufhelp.h" -+#include "cipher-internal.h" - #include "cipher-selftest.h" - - #define BLOWFISH_BLOCKSIZE 8 -@@ -67,7 +68,8 @@ typedef struct { - u32 p[BLOWFISH_ROUNDS+2]; - } BLOWFISH_context; - --static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen); -+static gcry_err_code_t bf_setkey (void *c, const byte *key, unsigned keylen, -+ gcry_cipher_hd_t hd); - static unsigned int encrypt_block (void *bc, byte *outbuf, const byte *inbuf); - static unsigned int decrypt_block (void *bc, byte *outbuf, const byte *inbuf); - -@@ -703,7 +705,7 @@ _gcry_blowfish_ctr_enc(void *context, un - /* Encrypt the counter. */ - do_encrypt_block(ctx, tmpbuf, ctr); - /* XOR the input with the encrypted counter and store in output. */ -- buf_xor(outbuf, tmpbuf, inbuf, BLOWFISH_BLOCKSIZE); -+ cipher_block_xor(outbuf, tmpbuf, inbuf, BLOWFISH_BLOCKSIZE); - outbuf += BLOWFISH_BLOCKSIZE; - inbuf += BLOWFISH_BLOCKSIZE; - /* Increment the counter. */ -@@ -771,7 +773,7 @@ _gcry_blowfish_cbc_dec(void *context, un - the intermediate result to SAVEBUF. */ - do_decrypt_block (ctx, savebuf, inbuf); - -- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOWFISH_BLOCKSIZE); -+ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOWFISH_BLOCKSIZE); - inbuf += BLOWFISH_BLOCKSIZE; - outbuf += BLOWFISH_BLOCKSIZE; - } -@@ -828,7 +830,7 @@ _gcry_blowfish_cfb_dec(void *context, un - for ( ;nblocks; nblocks-- ) - { - do_encrypt_block(ctx, iv, iv); -- buf_xor_n_copy(outbuf, iv, inbuf, BLOWFISH_BLOCKSIZE); -+ cipher_block_xor_n_copy(outbuf, iv, inbuf, BLOWFISH_BLOCKSIZE); - outbuf += BLOWFISH_BLOCKSIZE; - inbuf += BLOWFISH_BLOCKSIZE; - } -@@ -897,7 +899,7 @@ selftest(void) - const char *r; - - bf_setkey( (void *) &c, -- (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26 ); -+ (const unsigned char*)"abcdefghijklmnopqrstuvwxyz", 26, NULL ); - encrypt_block( (void *) &c, buffer, plain ); - if( memcmp( buffer, "\x32\x4E\xD0\xFE\xF4\x13\xA2\x03", 8 ) ) - return "Blowfish selftest failed (1)."; -@@ -905,7 +907,7 @@ selftest(void) - if( memcmp( buffer, plain, 8 ) ) - return "Blowfish selftest failed (2)."; - -- bf_setkey( (void *) &c, key3, 8 ); -+ bf_setkey( (void *) &c, key3, 8, NULL ); - encrypt_block( (void *) &c, buffer, plain3 ); - if( memcmp( buffer, cipher3, 8 ) ) - return "Blowfish selftest failed (3)."; -@@ -1095,10 +1097,12 @@ do_bf_setkey (BLOWFISH_context *c, const - - - static gcry_err_code_t --bf_setkey (void *context, const byte *key, unsigned keylen) -+bf_setkey (void *context, const byte *key, unsigned keylen, -+ gcry_cipher_hd_t hd) - { - BLOWFISH_context *c = (BLOWFISH_context *) context; - gcry_err_code_t rc = do_bf_setkey (c, key, keylen); -+ (void)hd; - return rc; - } - -diff -up libgcrypt-1.8.5/cipher/bufhelp.h.aes-perf libgcrypt-1.8.5/cipher/bufhelp.h ---- libgcrypt-1.8.5/cipher/bufhelp.h.aes-perf 2018-04-17 17:35:28.000000000 +0200 -+++ libgcrypt-1.8.5/cipher/bufhelp.h 2020-04-22 18:29:41.663862363 +0200 -@@ -450,7 +450,21 @@ static inline void buf_put_le64(void *_b - out->a = le_bswap64(val); - } - -- - #endif /*BUFHELP_UNALIGNED_ACCESS*/ - -+ -+/* Host-endian get/put macros */ -+#ifdef WORDS_BIGENDIAN -+# define buf_get_he32 buf_get_be32 -+# define buf_put_he32 buf_put_be32 -+# define buf_get_he64 buf_get_be64 -+# define buf_put_he64 buf_put_be64 -+#else -+# define buf_get_he32 buf_get_le32 -+# define buf_put_he32 buf_put_le32 -+# define buf_get_he64 buf_get_le64 -+# define buf_put_he64 buf_put_le64 -+#endif -+ -+ - #endif /*GCRYPT_BUFHELP_H*/ -diff -up libgcrypt-1.8.5/cipher/camellia-glue.c.aes-perf libgcrypt-1.8.5/cipher/camellia-glue.c ---- libgcrypt-1.8.5/cipher/camellia-glue.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/camellia-glue.c 2020-04-22 18:29:41.664862344 +0200 -@@ -204,7 +204,8 @@ extern void _gcry_camellia_aesni_avx2_oc - static const char *selftest(void); - - static gcry_err_code_t --camellia_setkey(void *c, const byte *key, unsigned keylen) -+camellia_setkey(void *c, const byte *key, unsigned keylen, -+ gcry_cipher_hd_t hd) - { - CAMELLIA_context *ctx=c; - static int initialized=0; -@@ -213,6 +214,8 @@ camellia_setkey(void *c, const byte *key - unsigned int hwf = _gcry_get_hw_features (); - #endif - -+ (void)hd; -+ - if(keylen!=16 && keylen!=24 && keylen!=32) - return GPG_ERR_INV_KEYLEN; - -@@ -427,7 +430,7 @@ _gcry_camellia_ctr_enc(void *context, un - /* Encrypt the counter. */ - Camellia_EncryptBlock(ctx->keybitlength, ctr, ctx->keytable, tmpbuf); - /* XOR the input with the encrypted counter and store in output. */ -- buf_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE); -+ cipher_block_xor(outbuf, tmpbuf, inbuf, CAMELLIA_BLOCK_SIZE); - outbuf += CAMELLIA_BLOCK_SIZE; - inbuf += CAMELLIA_BLOCK_SIZE; - /* Increment the counter. */ -@@ -520,7 +523,8 @@ _gcry_camellia_cbc_dec(void *context, un - the intermediate result to SAVEBUF. */ - Camellia_DecryptBlock(ctx->keybitlength, inbuf, ctx->keytable, savebuf); - -- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAMELLIA_BLOCK_SIZE); -+ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, -+ CAMELLIA_BLOCK_SIZE); - inbuf += CAMELLIA_BLOCK_SIZE; - outbuf += CAMELLIA_BLOCK_SIZE; - } -@@ -602,7 +606,7 @@ _gcry_camellia_cfb_dec(void *context, un - for ( ;nblocks; nblocks-- ) - { - Camellia_EncryptBlock(ctx->keybitlength, iv, ctx->keytable, iv); -- buf_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE); -+ cipher_block_xor_n_copy(outbuf, iv, inbuf, CAMELLIA_BLOCK_SIZE); - outbuf += CAMELLIA_BLOCK_SIZE; - inbuf += CAMELLIA_BLOCK_SIZE; - } -@@ -991,7 +995,7 @@ selftest(void) - 0x20,0xef,0x7c,0x91,0x9e,0x3a,0x75,0x09 - }; - -- camellia_setkey(&ctx,key_128,sizeof(key_128)); -+ camellia_setkey(&ctx,key_128,sizeof(key_128),NULL); - camellia_encrypt(&ctx,scratch,plaintext); - if(memcmp(scratch,ciphertext_128,sizeof(ciphertext_128))!=0) - return "CAMELLIA-128 test encryption failed."; -@@ -999,7 +1003,7 @@ selftest(void) - if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) - return "CAMELLIA-128 test decryption failed."; - -- camellia_setkey(&ctx,key_192,sizeof(key_192)); -+ camellia_setkey(&ctx,key_192,sizeof(key_192),NULL); - camellia_encrypt(&ctx,scratch,plaintext); - if(memcmp(scratch,ciphertext_192,sizeof(ciphertext_192))!=0) - return "CAMELLIA-192 test encryption failed."; -@@ -1007,7 +1011,7 @@ selftest(void) - if(memcmp(scratch,plaintext,sizeof(plaintext))!=0) - return "CAMELLIA-192 test decryption failed."; - -- camellia_setkey(&ctx,key_256,sizeof(key_256)); -+ camellia_setkey(&ctx,key_256,sizeof(key_256),NULL); - camellia_encrypt(&ctx,scratch,plaintext); - if(memcmp(scratch,ciphertext_256,sizeof(ciphertext_256))!=0) - return "CAMELLIA-256 test encryption failed."; -diff -up libgcrypt-1.8.5/cipher/cast5.c.aes-perf libgcrypt-1.8.5/cipher/cast5.c ---- libgcrypt-1.8.5/cipher/cast5.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cast5.c 2020-04-22 18:29:41.665862325 +0200 -@@ -44,6 +44,7 @@ - #include "cipher.h" - #include "bithelp.h" - #include "bufhelp.h" -+#include "cipher-internal.h" - #include "cipher-selftest.h" - - /* USE_AMD64_ASM indicates whether to use AMD64 assembly code. */ -@@ -72,7 +73,8 @@ typedef struct { - #endif - } CAST5_context; - --static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen); -+static gcry_err_code_t cast_setkey (void *c, const byte *key, unsigned keylen, -+ gcry_cipher_hd_t hd); - static unsigned int encrypt_block (void *c, byte *outbuf, const byte *inbuf); - static unsigned int decrypt_block (void *c, byte *outbuf, const byte *inbuf); - -@@ -671,7 +673,7 @@ _gcry_cast5_ctr_enc(void *context, unsig - /* Encrypt the counter. */ - do_encrypt_block(ctx, tmpbuf, ctr); - /* XOR the input with the encrypted counter and store in output. */ -- buf_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE); -+ cipher_block_xor(outbuf, tmpbuf, inbuf, CAST5_BLOCKSIZE); - outbuf += CAST5_BLOCKSIZE; - inbuf += CAST5_BLOCKSIZE; - /* Increment the counter. */ -@@ -739,7 +741,7 @@ _gcry_cast5_cbc_dec(void *context, unsig - the intermediate result to SAVEBUF. */ - do_decrypt_block (ctx, savebuf, inbuf); - -- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAST5_BLOCKSIZE); -+ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, CAST5_BLOCKSIZE); - inbuf += CAST5_BLOCKSIZE; - outbuf += CAST5_BLOCKSIZE; - } -@@ -795,7 +797,7 @@ _gcry_cast5_cfb_dec(void *context, unsig - for ( ;nblocks; nblocks-- ) - { - do_encrypt_block(ctx, iv, iv); -- buf_xor_n_copy(outbuf, iv, inbuf, CAST5_BLOCKSIZE); -+ cipher_block_xor_n_copy(outbuf, iv, inbuf, CAST5_BLOCKSIZE); - outbuf += CAST5_BLOCKSIZE; - inbuf += CAST5_BLOCKSIZE; - } -@@ -863,7 +865,7 @@ selftest(void) - byte buffer[8]; - const char *r; - -- cast_setkey( &c, key, 16 ); -+ cast_setkey( &c, key, 16, NULL ); - encrypt_block( &c, buffer, plain ); - if( memcmp( buffer, cipher, 8 ) ) - return "1"; -@@ -884,10 +886,10 @@ selftest(void) - 0x80,0xAC,0x05,0xB8,0xE8,0x3D,0x69,0x6E }; - - for(i=0; i < 1000000; i++ ) { -- cast_setkey( &c, b0, 16 ); -+ cast_setkey( &c, b0, 16, NULL ); - encrypt_block( &c, a0, a0 ); - encrypt_block( &c, a0+8, a0+8 ); -- cast_setkey( &c, a0, 16 ); -+ cast_setkey( &c, a0, 16, NULL ); - encrypt_block( &c, b0, b0 ); - encrypt_block( &c, b0+8, b0+8 ); - } -@@ -1029,10 +1031,12 @@ do_cast_setkey( CAST5_context *c, const - } - - static gcry_err_code_t --cast_setkey (void *context, const byte *key, unsigned keylen ) -+cast_setkey (void *context, const byte *key, unsigned keylen, -+ gcry_cipher_hd_t hd ) - { - CAST5_context *c = (CAST5_context *) context; - gcry_err_code_t rc = do_cast_setkey (c, key, keylen); -+ (void)hd; - return rc; - } - -diff -up libgcrypt-1.8.5/cipher/chacha20.c.aes-perf libgcrypt-1.8.5/cipher/chacha20.c ---- libgcrypt-1.8.5/cipher/chacha20.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/chacha20.c 2020-04-22 18:29:41.665862325 +0200 -@@ -419,10 +419,12 @@ chacha20_do_setkey (CHACHA20_context_t * - - - static gcry_err_code_t --chacha20_setkey (void *context, const byte * key, unsigned int keylen) -+chacha20_setkey (void *context, const byte *key, unsigned int keylen, -+ gcry_cipher_hd_t hd) - { - CHACHA20_context_t *ctx = (CHACHA20_context_t *) context; - gcry_err_code_t rc = chacha20_do_setkey (ctx, key, keylen); -+ (void)hd; - _gcry_burn_stack (4 + sizeof (void *) + 4 * sizeof (void *)); - return rc; - } -@@ -569,7 +571,7 @@ selftest (void) - /* 16-byte alignment required for amd64 implementation. */ - ctx = (CHACHA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15); - -- chacha20_setkey (ctx, key_1, sizeof key_1); -+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); - chacha20_setiv (ctx, nonce_1, sizeof nonce_1); - scratch[sizeof (scratch) - 1] = 0; - chacha20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1); -@@ -577,7 +579,7 @@ selftest (void) - return "ChaCha20 encryption test 1 failed."; - if (scratch[sizeof (scratch) - 1]) - return "ChaCha20 wrote too much."; -- chacha20_setkey (ctx, key_1, sizeof (key_1)); -+ chacha20_setkey (ctx, key_1, sizeof (key_1), NULL); - chacha20_setiv (ctx, nonce_1, sizeof nonce_1); - chacha20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1); - if (memcmp (scratch, plaintext_1, sizeof plaintext_1)) -@@ -585,12 +587,12 @@ selftest (void) - - for (i = 0; i < sizeof buf; i++) - buf[i] = i; -- chacha20_setkey (ctx, key_1, sizeof key_1); -+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); - chacha20_setiv (ctx, nonce_1, sizeof nonce_1); - /*encrypt */ - chacha20_encrypt_stream (ctx, buf, buf, sizeof buf); - /*decrypt */ -- chacha20_setkey (ctx, key_1, sizeof key_1); -+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); - chacha20_setiv (ctx, nonce_1, sizeof nonce_1); - chacha20_encrypt_stream (ctx, buf, buf, 1); - chacha20_encrypt_stream (ctx, buf + 1, buf + 1, (sizeof buf) - 1 - 1); -@@ -600,13 +602,13 @@ selftest (void) - if (buf[i] != (byte) i) - return "ChaCha20 encryption test 2 failed."; - -- chacha20_setkey (ctx, key_1, sizeof key_1); -+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); - chacha20_setiv (ctx, nonce_1, sizeof nonce_1); - /* encrypt */ - for (i = 0; i < sizeof buf; i++) - chacha20_encrypt_stream (ctx, &buf[i], &buf[i], 1); - /* decrypt */ -- chacha20_setkey (ctx, key_1, sizeof key_1); -+ chacha20_setkey (ctx, key_1, sizeof key_1, NULL); - chacha20_setiv (ctx, nonce_1, sizeof nonce_1); - chacha20_encrypt_stream (ctx, buf, buf, sizeof buf); - for (i = 0; i < sizeof buf; i++) -diff -up libgcrypt-1.8.5/cipher/cipher-aeswrap.c.aes-perf libgcrypt-1.8.5/cipher/cipher-aeswrap.c ---- libgcrypt-1.8.5/cipher/cipher-aeswrap.c.aes-perf 2018-04-17 17:49:00.000000000 +0200 -+++ libgcrypt-1.8.5/cipher/cipher-aeswrap.c 2020-04-22 18:29:41.665862325 +0200 -@@ -99,7 +99,7 @@ _gcry_cipher_aeswrap_encrypt (gcry_ciphe - break; - } - /* A := MSB_64(B) ^ t */ -- buf_xor(a, b, t, 8); -+ cipher_block_xor(a, b, t, 8); - /* R[i] := LSB_64(B) */ - memcpy (r+i*8, b+8, 8); - } -@@ -170,7 +170,7 @@ _gcry_cipher_aeswrap_decrypt (gcry_ciphe - for (i = n; i >= 1; i--) - { - /* B := AES_k^1( (A ^ t)| R[i] ) */ -- buf_xor(b, a, t, 8); -+ cipher_block_xor(b, a, t, 8); - memcpy (b+8, r+(i-1)*8, 8); - nburn = c->spec->decrypt (&c->context.c, b, b); - burn = nburn > burn ? nburn : burn; -diff -up libgcrypt-1.8.5/cipher/cipher.c.aes-perf libgcrypt-1.8.5/cipher/cipher.c ---- libgcrypt-1.8.5/cipher/cipher.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher.c 2020-04-22 18:29:41.666862306 +0200 -@@ -92,6 +92,8 @@ static gcry_cipher_spec_t *cipher_list[] - - - -+static void _gcry_cipher_setup_mode_ops(gcry_cipher_hd_t c, int mode); -+ - - static int - map_algo (int algo) -@@ -532,6 +534,7 @@ _gcry_cipher_open_internal (gcry_cipher_ - h->bulk.ctr_enc = _gcry_aes_ctr_enc; - h->bulk.ocb_crypt = _gcry_aes_ocb_crypt; - h->bulk.ocb_auth = _gcry_aes_ocb_auth; -+ h->bulk.xts_crypt = _gcry_aes_xts_crypt; - break; - #endif /*USE_AES*/ - #ifdef USE_BLOWFISH -@@ -592,6 +595,9 @@ _gcry_cipher_open_internal (gcry_cipher_ - break; - } - -+ /* Setup mode routines. */ -+ _gcry_cipher_setup_mode_ops(h, mode); -+ - /* Setup defaults depending on the mode. */ - switch (mode) - { -@@ -609,8 +615,7 @@ _gcry_cipher_open_internal (gcry_cipher_ - default: - break; - } -- -- } -+ } - } - - /* Done. */ -@@ -675,7 +680,7 @@ cipher_setkey (gcry_cipher_hd_t c, byte - } - } - -- rc = c->spec->setkey (&c->context.c, key, keylen); -+ rc = c->spec->setkey (&c->context.c, key, keylen, c); - if (!rc) - { - /* Duplicate initial context. */ -@@ -701,7 +706,7 @@ cipher_setkey (gcry_cipher_hd_t c, byte - case GCRY_CIPHER_MODE_XTS: - /* Setup tweak cipher with second part of XTS key. */ - rc = c->spec->setkey (c->u_mode.xts.tweak_context, key + keylen, -- keylen); -+ keylen, c); - if (!rc) - { - /* Duplicate initial tweak context. */ -@@ -872,85 +877,78 @@ do_ecb_decrypt (gcry_cipher_hd_t c, - } - - --/**************** -- * Encrypt INBUF to OUTBUF with the mode selected at open. -- * inbuf and outbuf may overlap or be the same. -- * Depending on the mode some constraints apply to INBUFLEN. -- */ - static gcry_err_code_t --cipher_encrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, -- const byte *inbuf, size_t inbuflen) -+do_stream_encrypt (gcry_cipher_hd_t c, -+ unsigned char *outbuf, size_t outbuflen, -+ const unsigned char *inbuf, size_t inbuflen) -+{ -+ (void)outbuflen; -+ c->spec->stencrypt (&c->context.c, outbuf, (void *)inbuf, inbuflen); -+ return 0; -+} -+ -+static gcry_err_code_t -+do_stream_decrypt (gcry_cipher_hd_t c, -+ unsigned char *outbuf, size_t outbuflen, -+ const unsigned char *inbuf, size_t inbuflen) -+{ -+ (void)outbuflen; -+ c->spec->stdecrypt (&c->context.c, outbuf, (void *)inbuf, inbuflen); -+ return 0; -+} -+ -+ -+static gcry_err_code_t -+do_encrypt_none_unknown (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, -+ const byte *inbuf, size_t inbuflen) - { - gcry_err_code_t rc; - -- if (c->mode != GCRY_CIPHER_MODE_NONE && !c->marks.key) -- { -- log_error ("cipher_encrypt: key not set\n"); -- return GPG_ERR_MISSING_KEY; -- } -+ (void)outbuflen; - - switch (c->mode) - { -- case GCRY_CIPHER_MODE_ECB: -- rc = do_ecb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_CBC: -- rc = _gcry_cipher_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_CFB: -- rc = _gcry_cipher_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -+ case GCRY_CIPHER_MODE_CMAC: -+ rc = GPG_ERR_INV_CIPHER_MODE; - break; - -- case GCRY_CIPHER_MODE_CFB8: -- rc = _gcry_cipher_cfb8_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -+ case GCRY_CIPHER_MODE_NONE: -+ if (fips_mode () || !_gcry_get_debug_flag (0)) -+ { -+ fips_signal_error ("cipher mode NONE used"); -+ rc = GPG_ERR_INV_CIPHER_MODE; -+ } -+ else -+ { -+ if (inbuf != outbuf) -+ memmove (outbuf, inbuf, inbuflen); -+ rc = 0; -+ } - break; - -- case GCRY_CIPHER_MODE_OFB: -- rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -+ default: -+ log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode ); -+ rc = GPG_ERR_INV_CIPHER_MODE; - break; -+ } - -- case GCRY_CIPHER_MODE_CTR: -- rc = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -+ return rc; -+} - -- case GCRY_CIPHER_MODE_AESWRAP: -- rc = _gcry_cipher_aeswrap_encrypt (c, outbuf, outbuflen, -- inbuf, inbuflen); -- break; -+static gcry_err_code_t -+do_decrypt_none_unknown (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, -+ const byte *inbuf, size_t inbuflen) -+{ -+ gcry_err_code_t rc; - -- case GCRY_CIPHER_MODE_CCM: -- rc = _gcry_cipher_ccm_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -+ (void)outbuflen; - -+ switch (c->mode) -+ { - case GCRY_CIPHER_MODE_CMAC: - rc = GPG_ERR_INV_CIPHER_MODE; - break; - -- case GCRY_CIPHER_MODE_GCM: -- rc = _gcry_cipher_gcm_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_POLY1305: -- rc = _gcry_cipher_poly1305_encrypt (c, outbuf, outbuflen, -- inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_OCB: -- rc = _gcry_cipher_ocb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_XTS: -- rc = _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 1); -- break; -- -- case GCRY_CIPHER_MODE_STREAM: -- c->spec->stencrypt (&c->context.c, -- outbuf, (byte*)/*arggg*/inbuf, inbuflen); -- rc = 0; -- break; -- - case GCRY_CIPHER_MODE_NONE: - if (fips_mode () || !_gcry_get_debug_flag (0)) - { -@@ -966,7 +964,7 @@ cipher_encrypt (gcry_cipher_hd_t c, byte - break; - - default: -- log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode ); -+ log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode ); - rc = GPG_ERR_INV_CIPHER_MODE; - break; - } -@@ -991,7 +989,13 @@ _gcry_cipher_encrypt (gcry_cipher_hd_t h - inlen = outsize; - } - -- rc = cipher_encrypt (h, out, outsize, in, inlen); -+ if (h->mode != GCRY_CIPHER_MODE_NONE && !h->marks.key) -+ { -+ log_error ("cipher_decrypt: key not set\n"); -+ return GPG_ERR_MISSING_KEY; -+ } -+ -+ rc = h->mode_ops.encrypt (h, out, outsize, in, inlen); - - /* Failsafe: Make sure that the plaintext will never make it into - OUT if the encryption returned an error. */ -@@ -1002,110 +1006,10 @@ _gcry_cipher_encrypt (gcry_cipher_hd_t h - } - - -- - /**************** -- * Decrypt INBUF to OUTBUF with the mode selected at open. -- * inbuf and outbuf may overlap or be the same. -- * Depending on the mode some some constraints apply to INBUFLEN. -+ * Decrypt IN and write it to OUT. If IN is NULL, in-place encryption has -+ * been requested. - */ --static gcry_err_code_t --cipher_decrypt (gcry_cipher_hd_t c, byte *outbuf, size_t outbuflen, -- const byte *inbuf, size_t inbuflen) --{ -- gcry_err_code_t rc; -- -- if (c->mode != GCRY_CIPHER_MODE_NONE && !c->marks.key) -- { -- log_error ("cipher_decrypt: key not set\n"); -- return GPG_ERR_MISSING_KEY; -- } -- -- switch (c->mode) -- { -- case GCRY_CIPHER_MODE_ECB: -- rc = do_ecb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_CBC: -- rc = _gcry_cipher_cbc_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_CFB: -- rc = _gcry_cipher_cfb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_CFB8: -- rc = _gcry_cipher_cfb8_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_OFB: -- rc = _gcry_cipher_ofb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_CTR: -- rc = _gcry_cipher_ctr_encrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_AESWRAP: -- rc = _gcry_cipher_aeswrap_decrypt (c, outbuf, outbuflen, -- inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_CCM: -- rc = _gcry_cipher_ccm_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_CMAC: -- rc = GPG_ERR_INV_CIPHER_MODE; -- break; -- -- case GCRY_CIPHER_MODE_GCM: -- rc = _gcry_cipher_gcm_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_POLY1305: -- rc = _gcry_cipher_poly1305_decrypt (c, outbuf, outbuflen, -- inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_OCB: -- rc = _gcry_cipher_ocb_decrypt (c, outbuf, outbuflen, inbuf, inbuflen); -- break; -- -- case GCRY_CIPHER_MODE_XTS: -- rc = _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 0); -- break; -- -- case GCRY_CIPHER_MODE_STREAM: -- c->spec->stdecrypt (&c->context.c, -- outbuf, (byte*)/*arggg*/inbuf, inbuflen); -- rc = 0; -- break; -- -- case GCRY_CIPHER_MODE_NONE: -- if (fips_mode () || !_gcry_get_debug_flag (0)) -- { -- fips_signal_error ("cipher mode NONE used"); -- rc = GPG_ERR_INV_CIPHER_MODE; -- } -- else -- { -- if (inbuf != outbuf) -- memmove (outbuf, inbuf, inbuflen); -- rc = 0; -- } -- break; -- -- default: -- log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode ); -- rc = GPG_ERR_INV_CIPHER_MODE; -- break; -- } -- -- return rc; --} -- -- - gcry_err_code_t - _gcry_cipher_decrypt (gcry_cipher_hd_t h, void *out, size_t outsize, - const void *in, size_t inlen) -@@ -1116,9 +1020,14 @@ _gcry_cipher_decrypt (gcry_cipher_hd_t h - inlen = outsize; - } - -- return cipher_decrypt (h, out, outsize, in, inlen); --} -+ if (h->mode != GCRY_CIPHER_MODE_NONE && !h->marks.key) -+ { -+ log_error ("cipher_decrypt: key not set\n"); -+ return GPG_ERR_MISSING_KEY; -+ } - -+ return h->mode_ops.decrypt (h, out, outsize, in, inlen); -+} - - - /**************** -@@ -1149,33 +1058,10 @@ _gcry_cipher_setkey (gcry_cipher_hd_t hd - gcry_err_code_t - _gcry_cipher_setiv (gcry_cipher_hd_t hd, const void *iv, size_t ivlen) - { -- gcry_err_code_t rc = 0; -- -- switch (hd->mode) -- { -- case GCRY_CIPHER_MODE_CCM: -- rc = _gcry_cipher_ccm_set_nonce (hd, iv, ivlen); -- break; -- -- case GCRY_CIPHER_MODE_GCM: -- rc = _gcry_cipher_gcm_setiv (hd, iv, ivlen); -- break; -- -- case GCRY_CIPHER_MODE_POLY1305: -- rc = _gcry_cipher_poly1305_setiv (hd, iv, ivlen); -- break; -- -- case GCRY_CIPHER_MODE_OCB: -- rc = _gcry_cipher_ocb_set_nonce (hd, iv, ivlen); -- break; -- -- default: -- rc = cipher_setiv (hd, iv, ivlen); -- break; -- } -- return rc; -+ return hd->mode_ops.setiv (hd, iv, ivlen); - } - -+ - /* Set counter for CTR mode. (CTR,CTRLEN) must denote a buffer of - block size length, or (NULL,0) to set the CTR to the all-zero - block. */ -@@ -1209,38 +1095,40 @@ _gcry_cipher_getctr (gcry_cipher_hd_t hd - return 0; - } - -+ - gcry_err_code_t - _gcry_cipher_authenticate (gcry_cipher_hd_t hd, const void *abuf, - size_t abuflen) - { - gcry_err_code_t rc; - -- switch (hd->mode) -+ if (hd->mode_ops.authenticate) - { -- case GCRY_CIPHER_MODE_CCM: -- rc = _gcry_cipher_ccm_authenticate (hd, abuf, abuflen); -- break; -- -- case GCRY_CIPHER_MODE_CMAC: -- rc = _gcry_cipher_cmac_authenticate (hd, abuf, abuflen); -- break; -+ rc = hd->mode_ops.authenticate (hd, abuf, abuflen); -+ } -+ else -+ { -+ log_error ("gcry_cipher_authenticate: invalid mode %d\n", hd->mode); -+ rc = GPG_ERR_INV_CIPHER_MODE; -+ } - -- case GCRY_CIPHER_MODE_GCM: -- rc = _gcry_cipher_gcm_authenticate (hd, abuf, abuflen); -- break; -+ return rc; -+} - -- case GCRY_CIPHER_MODE_POLY1305: -- rc = _gcry_cipher_poly1305_authenticate (hd, abuf, abuflen); -- break; - -- case GCRY_CIPHER_MODE_OCB: -- rc = _gcry_cipher_ocb_authenticate (hd, abuf, abuflen); -- break; -+gcry_err_code_t -+_gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen) -+{ -+ gcry_err_code_t rc; - -- default: -- log_error ("gcry_cipher_authenticate: invalid mode %d\n", hd->mode); -+ if (hd->mode_ops.get_tag) -+ { -+ rc = hd->mode_ops.get_tag (hd, outtag, taglen); -+ } -+ else -+ { -+ log_error ("gcry_cipher_gettag: invalid mode %d\n", hd->mode); - rc = GPG_ERR_INV_CIPHER_MODE; -- break; - } - - return rc; -@@ -1248,76 +1136,166 @@ _gcry_cipher_authenticate (gcry_cipher_h - - - gcry_err_code_t --_gcry_cipher_gettag (gcry_cipher_hd_t hd, void *outtag, size_t taglen) -+_gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen) - { - gcry_err_code_t rc; - -- switch (hd->mode) -+ if (hd->mode_ops.check_tag) - { -- case GCRY_CIPHER_MODE_CCM: -- rc = _gcry_cipher_ccm_get_tag (hd, outtag, taglen); -+ rc = hd->mode_ops.check_tag (hd, intag, taglen); -+ } -+ else -+ { -+ log_error ("gcry_cipher_checktag: invalid mode %d\n", hd->mode); -+ rc = GPG_ERR_INV_CIPHER_MODE; -+ } -+ -+ return rc; -+} -+ -+ -+ -+static void -+_gcry_cipher_setup_mode_ops(gcry_cipher_hd_t c, int mode) -+{ -+ /* Setup encryption and decryption routines. */ -+ switch (mode) -+ { -+ case GCRY_CIPHER_MODE_STREAM: -+ c->mode_ops.encrypt = do_stream_encrypt; -+ c->mode_ops.decrypt = do_stream_decrypt; - break; - -- case GCRY_CIPHER_MODE_CMAC: -- rc = _gcry_cipher_cmac_get_tag (hd, outtag, taglen); -+ case GCRY_CIPHER_MODE_ECB: -+ c->mode_ops.encrypt = do_ecb_encrypt; -+ c->mode_ops.decrypt = do_ecb_decrypt; -+ break; -+ -+ case GCRY_CIPHER_MODE_CBC: -+ c->mode_ops.encrypt = _gcry_cipher_cbc_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_cbc_decrypt; -+ break; -+ -+ case GCRY_CIPHER_MODE_CFB: -+ c->mode_ops.encrypt = _gcry_cipher_cfb_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_cfb_decrypt; -+ break; -+ -+ case GCRY_CIPHER_MODE_CFB8: -+ c->mode_ops.encrypt = _gcry_cipher_cfb8_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_cfb8_decrypt; -+ break; -+ -+ case GCRY_CIPHER_MODE_OFB: -+ c->mode_ops.encrypt = _gcry_cipher_ofb_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_ofb_encrypt; -+ break; -+ -+ case GCRY_CIPHER_MODE_CTR: -+ c->mode_ops.encrypt = _gcry_cipher_ctr_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_ctr_encrypt; -+ break; -+ -+ case GCRY_CIPHER_MODE_AESWRAP: -+ c->mode_ops.encrypt = _gcry_cipher_aeswrap_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_aeswrap_decrypt; -+ break; -+ -+ case GCRY_CIPHER_MODE_CCM: -+ c->mode_ops.encrypt = _gcry_cipher_ccm_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_ccm_decrypt; - break; - - case GCRY_CIPHER_MODE_GCM: -- rc = _gcry_cipher_gcm_get_tag (hd, outtag, taglen); -+ c->mode_ops.encrypt = _gcry_cipher_gcm_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_gcm_decrypt; - break; - - case GCRY_CIPHER_MODE_POLY1305: -- rc = _gcry_cipher_poly1305_get_tag (hd, outtag, taglen); -+ c->mode_ops.encrypt = _gcry_cipher_poly1305_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_poly1305_decrypt; - break; - - case GCRY_CIPHER_MODE_OCB: -- rc = _gcry_cipher_ocb_get_tag (hd, outtag, taglen); -+ c->mode_ops.encrypt = _gcry_cipher_ocb_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_ocb_decrypt; -+ break; -+ -+ case GCRY_CIPHER_MODE_XTS: -+ c->mode_ops.encrypt = _gcry_cipher_xts_encrypt; -+ c->mode_ops.decrypt = _gcry_cipher_xts_decrypt; - break; - - default: -- log_error ("gcry_cipher_gettag: invalid mode %d\n", hd->mode); -- rc = GPG_ERR_INV_CIPHER_MODE; -+ c->mode_ops.encrypt = do_encrypt_none_unknown; -+ c->mode_ops.decrypt = do_decrypt_none_unknown; - break; - } - -- return rc; --} -+ /* Setup IV setting routine. */ -+ switch (mode) -+ { -+ case GCRY_CIPHER_MODE_CCM: -+ c->mode_ops.setiv = _gcry_cipher_ccm_set_nonce; -+ break; -+ -+ case GCRY_CIPHER_MODE_GCM: -+ c->mode_ops.setiv = _gcry_cipher_gcm_setiv; -+ break; - -+ case GCRY_CIPHER_MODE_POLY1305: -+ c->mode_ops.setiv = _gcry_cipher_poly1305_setiv; -+ break; - --gcry_err_code_t --_gcry_cipher_checktag (gcry_cipher_hd_t hd, const void *intag, size_t taglen) --{ -- gcry_err_code_t rc; -+ case GCRY_CIPHER_MODE_OCB: -+ c->mode_ops.setiv = _gcry_cipher_ocb_set_nonce; -+ break; - -- switch (hd->mode) -+ default: -+ c->mode_ops.setiv = cipher_setiv; -+ break; -+ } -+ -+ -+ /* Setup authentication routines for AEAD modes. */ -+ switch (mode) - { - case GCRY_CIPHER_MODE_CCM: -- rc = _gcry_cipher_ccm_check_tag (hd, intag, taglen); -+ c->mode_ops.authenticate = _gcry_cipher_ccm_authenticate; -+ c->mode_ops.get_tag = _gcry_cipher_ccm_get_tag; -+ c->mode_ops.check_tag = _gcry_cipher_ccm_check_tag; - break; - - case GCRY_CIPHER_MODE_CMAC: -- rc = _gcry_cipher_cmac_check_tag (hd, intag, taglen); -+ c->mode_ops.authenticate = _gcry_cipher_cmac_authenticate; -+ c->mode_ops.get_tag = _gcry_cipher_cmac_get_tag; -+ c->mode_ops.check_tag = _gcry_cipher_cmac_check_tag; - break; - - case GCRY_CIPHER_MODE_GCM: -- rc = _gcry_cipher_gcm_check_tag (hd, intag, taglen); -+ c->mode_ops.authenticate = _gcry_cipher_gcm_authenticate; -+ c->mode_ops.get_tag = _gcry_cipher_gcm_get_tag; -+ c->mode_ops.check_tag = _gcry_cipher_gcm_check_tag; - break; - - case GCRY_CIPHER_MODE_POLY1305: -- rc = _gcry_cipher_poly1305_check_tag (hd, intag, taglen); -+ c->mode_ops.authenticate = _gcry_cipher_poly1305_authenticate; -+ c->mode_ops.get_tag = _gcry_cipher_poly1305_get_tag; -+ c->mode_ops.check_tag = _gcry_cipher_poly1305_check_tag; - break; - - case GCRY_CIPHER_MODE_OCB: -- rc = _gcry_cipher_ocb_check_tag (hd, intag, taglen); -+ c->mode_ops.authenticate = _gcry_cipher_ocb_authenticate; -+ c->mode_ops.get_tag = _gcry_cipher_ocb_get_tag; -+ c->mode_ops.check_tag = _gcry_cipher_ocb_check_tag; - break; - - default: -- log_error ("gcry_cipher_checktag: invalid mode %d\n", hd->mode); -- rc = GPG_ERR_INV_CIPHER_MODE; -+ c->mode_ops.authenticate = NULL; -+ c->mode_ops.get_tag = NULL; -+ c->mode_ops.check_tag = NULL; - break; - } -- -- return rc; - } - - -diff -up libgcrypt-1.8.5/cipher/cipher-cbc.c.aes-perf libgcrypt-1.8.5/cipher/cipher-cbc.c ---- libgcrypt-1.8.5/cipher/cipher-cbc.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-cbc.c 2020-04-22 18:29:41.666862306 +0200 -@@ -79,7 +79,7 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd - - for (n=0; n < nblocks; n++ ) - { -- buf_xor (outbuf, inbuf, ivp, blocksize); -+ cipher_block_xor (outbuf, inbuf, ivp, blocksize); - nburn = enc_fn ( &c->context.c, outbuf, outbuf ); - burn = nburn > burn ? nburn : burn; - ivp = outbuf; -@@ -116,7 +116,7 @@ _gcry_cipher_cbc_encrypt (gcry_cipher_hd - - nburn = enc_fn (&c->context.c, outbuf, outbuf); - burn = nburn > burn ? nburn : burn; -- buf_cpy (c->u_iv.iv, outbuf, blocksize); -+ cipher_block_cpy (c->u_iv.iv, outbuf, blocksize); - } - - if (burn > 0) -@@ -158,7 +158,7 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd - nblocks--; - if ((inbuflen % blocksize) == 0) - nblocks--; -- buf_cpy (c->lastiv, c->u_iv.iv, blocksize); -+ cipher_block_cpy (c->lastiv, c->u_iv.iv, blocksize); - } - - if (c->bulk.cbc_dec) -@@ -176,7 +176,8 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd - storage here because it is not used otherwise. */ - nburn = dec_fn ( &c->context.c, c->lastiv, inbuf ); - burn = nburn > burn ? nburn : burn; -- buf_xor_n_copy_2(outbuf, c->lastiv, c->u_iv.iv, inbuf, blocksize); -+ cipher_block_xor_n_copy_2 (outbuf, c->lastiv, c->u_iv.iv, inbuf, -+ blocksize); - inbuf += blocksize; - outbuf += blocksize; - } -@@ -191,7 +192,7 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd - else - restbytes = inbuflen % blocksize; - -- buf_cpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */ -+ cipher_block_cpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */ - buf_cpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */ - - nburn = dec_fn ( &c->context.c, outbuf, inbuf ); -@@ -203,7 +204,7 @@ _gcry_cipher_cbc_decrypt (gcry_cipher_hd - c->u_iv.iv[i] = outbuf[i]; - nburn = dec_fn (&c->context.c, outbuf, c->u_iv.iv); - burn = nburn > burn ? nburn : burn; -- buf_xor(outbuf, outbuf, c->lastiv, blocksize); -+ cipher_block_xor(outbuf, outbuf, c->lastiv, blocksize); - /* c->lastiv is now really lastlastiv, does this matter? */ - } - -diff -up libgcrypt-1.8.5/cipher/cipher-ccm.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ccm.c ---- libgcrypt-1.8.5/cipher/cipher-ccm.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-ccm.c 2020-04-22 18:29:41.666862306 +0200 -@@ -67,7 +67,8 @@ do_cbc_mac (gcry_cipher_hd_t c, const un - if (unused > 0) - { - /* Process one block from macbuf. */ -- buf_xor(c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.macbuf, blocksize); -+ cipher_block_xor(c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.macbuf, -+ blocksize); - set_burn (burn, enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv )); - - unused = 0; -@@ -86,7 +87,7 @@ do_cbc_mac (gcry_cipher_hd_t c, const un - { - while (inlen >= blocksize) - { -- buf_xor(c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); -+ cipher_block_xor(c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); - - set_burn (burn, enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv )); - -@@ -272,7 +273,7 @@ _gcry_cipher_ccm_tag (gcry_cipher_hd_t c - burn = do_cbc_mac (c, NULL, 0, 1); /* Perform final padding. */ - - /* Add S_0 */ -- buf_xor (c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.s0, 16); -+ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, c->u_mode.ccm.s0, 16); - - wipememory (c->u_ctr.ctr, 16); - wipememory (c->u_mode.ccm.s0, 16); -diff -up libgcrypt-1.8.5/cipher/cipher-cfb.c.aes-perf libgcrypt-1.8.5/cipher/cipher-cfb.c ---- libgcrypt-1.8.5/cipher/cipher-cfb.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-cfb.c 2020-04-22 18:29:41.667862287 +0200 -@@ -91,7 +91,7 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd - nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; - /* XOR the input with the IV and store input into IV. */ -- buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); -+ cipher_block_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); - outbuf += blocksize; - inbuf += blocksize; - inbuflen -= blocksize; -@@ -101,11 +101,11 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd - if ( inbuflen >= blocksize ) - { - /* Save the current IV and then encrypt the IV. */ -- buf_cpy( c->lastiv, c->u_iv.iv, blocksize ); -+ cipher_block_cpy( c->lastiv, c->u_iv.iv, blocksize ); - nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; - /* XOR the input with the IV and store input into IV */ -- buf_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); -+ cipher_block_xor_2dst(outbuf, c->u_iv.iv, inbuf, blocksize); - outbuf += blocksize; - inbuf += blocksize; - inbuflen -= blocksize; -@@ -113,7 +113,7 @@ _gcry_cipher_cfb_encrypt (gcry_cipher_hd - if ( inbuflen ) - { - /* Save the current IV and then encrypt the IV. */ -- buf_cpy( c->lastiv, c->u_iv.iv, blocksize ); -+ cipher_block_cpy( c->lastiv, c->u_iv.iv, blocksize ); - nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; - c->unused = blocksize; -@@ -193,7 +193,7 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd - nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; - /* XOR the input with the IV and store input into IV. */ -- buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); -+ cipher_block_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); - outbuf += blocksize; - inbuf += blocksize; - inbuflen -= blocksize; -@@ -203,11 +203,11 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd - if (inbuflen >= blocksize ) - { - /* Save the current IV and then encrypt the IV. */ -- buf_cpy ( c->lastiv, c->u_iv.iv, blocksize); -+ cipher_block_cpy ( c->lastiv, c->u_iv.iv, blocksize); - nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; - /* XOR the input with the IV and store input into IV */ -- buf_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); -+ cipher_block_xor_n_copy(outbuf, c->u_iv.iv, inbuf, blocksize); - outbuf += blocksize; - inbuf += blocksize; - inbuflen -= blocksize; -@@ -216,7 +216,7 @@ _gcry_cipher_cfb_decrypt (gcry_cipher_hd - if (inbuflen) - { - /* Save the current IV and then encrypt the IV. */ -- buf_cpy ( c->lastiv, c->u_iv.iv, blocksize ); -+ cipher_block_cpy ( c->lastiv, c->u_iv.iv, blocksize ); - nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; - c->unused = blocksize; -diff -up libgcrypt-1.8.5/cipher/cipher-cmac.c.aes-perf libgcrypt-1.8.5/cipher/cipher-cmac.c ---- libgcrypt-1.8.5/cipher/cipher-cmac.c.aes-perf 2020-04-22 18:29:41.643862745 +0200 -+++ libgcrypt-1.8.5/cipher/cipher-cmac.c 2020-04-22 18:29:41.667862287 +0200 -@@ -63,7 +63,7 @@ cmac_write (gcry_cipher_hd_t c, const by - for (; inlen && c->unused < blocksize; inlen--) - c->lastiv[c->unused++] = *inbuf++; - -- buf_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); -+ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); - set_burn (burn, enc_fn (&c->context.c, c->u_iv.iv, c->u_iv.iv)); - - c->unused = 0; -@@ -83,7 +83,7 @@ cmac_write (gcry_cipher_hd_t c, const by - else - while (inlen > blocksize) - { -- buf_xor (c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); -+ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, inbuf, blocksize); - set_burn (burn, enc_fn (&c->context.c, c->u_iv.iv, c->u_iv.iv)); - inlen -= blocksize; - inbuf += blocksize; -@@ -174,9 +174,9 @@ cmac_final (gcry_cipher_hd_t c) - c->lastiv[count++] = 0; - } - -- buf_xor (c->lastiv, c->lastiv, subkey, blocksize); -+ cipher_block_xor (c->lastiv, c->lastiv, subkey, blocksize); - -- buf_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); -+ cipher_block_xor (c->u_iv.iv, c->u_iv.iv, c->lastiv, blocksize); - burn = c->spec->encrypt (&c->context.c, c->u_iv.iv, c->u_iv.iv); - if (burn) - _gcry_burn_stack (burn + 4 * sizeof (void *)); -diff -up libgcrypt-1.8.5/cipher/cipher-ctr.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ctr.c ---- libgcrypt-1.8.5/cipher/cipher-ctr.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-ctr.c 2020-04-22 18:29:41.667862287 +0200 -@@ -81,24 +81,34 @@ _gcry_cipher_ctr_encrypt (gcry_cipher_hd - { - unsigned char tmp[MAX_BLOCKSIZE]; - -- do { -- nburn = enc_fn (&c->context.c, tmp, c->u_ctr.ctr); -- burn = nburn > burn ? nburn : burn; -- -- for (i = blocksize; i > 0; i--) -- { -- c->u_ctr.ctr[i-1]++; -- if (c->u_ctr.ctr[i-1] != 0) -- break; -- } -- -- n = blocksize < inbuflen ? blocksize : inbuflen; -- buf_xor(outbuf, inbuf, tmp, n); -- -- inbuflen -= n; -- outbuf += n; -- inbuf += n; -- } while (inbuflen); -+ do -+ { -+ nburn = enc_fn (&c->context.c, tmp, c->u_ctr.ctr); -+ burn = nburn > burn ? nburn : burn; -+ -+ for (i = blocksize; i > 0; i--) -+ { -+ c->u_ctr.ctr[i-1]++; -+ if (c->u_ctr.ctr[i-1] != 0) -+ break; -+ } -+ -+ if (inbuflen < blocksize) -+ break; -+ n = blocksize; -+ cipher_block_xor(outbuf, inbuf, tmp, blocksize); -+ -+ inbuflen -= n; -+ outbuf += n; -+ inbuf += n; -+ } -+ while (inbuflen); -+ -+ if (inbuflen) -+ { -+ n = inbuflen; -+ buf_xor(outbuf, inbuf, tmp, inbuflen); -+ } - - /* Save the unused bytes of the counter. */ - c->unused = blocksize - n; -diff -up libgcrypt-1.8.5/cipher/cipher-gcm.c.aes-perf libgcrypt-1.8.5/cipher/cipher-gcm.c ---- libgcrypt-1.8.5/cipher/cipher-gcm.c.aes-perf 2018-04-17 17:27:25.000000000 +0200 -+++ libgcrypt-1.8.5/cipher/cipher-gcm.c 2020-04-22 18:29:41.667862287 +0200 -@@ -150,7 +150,7 @@ do_ghash (unsigned char *result, const u - u32 A; - int i; - -- buf_xor (V, result, buf, 16); -+ cipher_block_xor (V, result, buf, 16); - V[0] = be_bswap64 (V[0]); - V[1] = be_bswap64 (V[1]); - -@@ -259,7 +259,7 @@ do_ghash (unsigned char *result, const u - u32 T[3]; - int i; - -- buf_xor (V, result, buf, 16); /* V is big-endian */ -+ cipher_block_xor (V, result, buf, 16); /* V is big-endian */ - - /* First round can be manually tweaked based on fact that 'tmp' is zero. */ - i = 15; -@@ -342,7 +342,7 @@ do_ghash (unsigned char *hsub, unsigned - #else - unsigned long T[4]; - -- buf_xor (V, result, buf, 16); -+ cipher_block_xor (V, result, buf, 16); - for (i = 0; i < 4; i++) - { - V[i] = (V[i] & 0x00ff00ff) << 8 | (V[i] & 0xff00ff00) >> 8; -@@ -358,7 +358,7 @@ do_ghash (unsigned char *hsub, unsigned - for (j = 0x80; j; j >>= 1) - { - if (hsub[i] & j) -- buf_xor (p, p, V, 16); -+ cipher_block_xor (p, p, V, 16); - if (bshift (V)) - V[0] ^= 0xe1000000; - } -@@ -598,7 +598,7 @@ gcm_ctr_encrypt (gcry_cipher_hd_t c, byt - } - - fix_ctr = 1; -- buf_cpy(ctr_copy, c->u_ctr.ctr, GCRY_GCM_BLOCK_LEN); -+ cipher_block_cpy(ctr_copy, c->u_ctr.ctr, GCRY_GCM_BLOCK_LEN); - } - } - -@@ -928,8 +928,8 @@ _gcry_cipher_gcm_tag (gcry_cipher_hd_t c - /* Add bitlengths to tag. */ - do_ghash_buf(c, c->u_mode.gcm.u_tag.tag, (byte*)bitlengths, - GCRY_GCM_BLOCK_LEN, 1); -- buf_xor (c->u_mode.gcm.u_tag.tag, c->u_mode.gcm.tagiv, -- c->u_mode.gcm.u_tag.tag, GCRY_GCM_BLOCK_LEN); -+ cipher_block_xor (c->u_mode.gcm.u_tag.tag, c->u_mode.gcm.tagiv, -+ c->u_mode.gcm.u_tag.tag, GCRY_GCM_BLOCK_LEN); - c->marks.tag = 1; - - wipememory (bitlengths, sizeof (bitlengths)); -diff -up libgcrypt-1.8.5/cipher/cipher-gcm-intel-pclmul.c.aes-perf libgcrypt-1.8.5/cipher/cipher-gcm-intel-pclmul.c ---- libgcrypt-1.8.5/cipher/cipher-gcm-intel-pclmul.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-gcm-intel-pclmul.c 2020-04-22 18:29:41.668862268 +0200 -@@ -248,7 +248,8 @@ static inline void gfmul_pclmul_aggr4(vo - void - _gcry_ghash_setup_intel_pclmul (gcry_cipher_hd_t c) - { -- u64 tmp[2]; -+ static const unsigned char be_mask[16] __attribute__ ((aligned (16))) = -+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; - #if defined(__x86_64__) && defined(__WIN64__) - char win64tmp[3 * 16]; - -@@ -262,15 +263,19 @@ _gcry_ghash_setup_intel_pclmul (gcry_cip - #endif - - /* Swap endianness of hsub. */ -- tmp[0] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 8); -- tmp[1] = buf_get_be64(c->u_mode.gcm.u_ghash_key.key + 0); -- buf_cpy (c->u_mode.gcm.u_ghash_key.key, tmp, GCRY_GCM_BLOCK_LEN); -+ asm volatile ("movdqu (%[key]), %%xmm0\n\t" -+ "pshufb %[be_mask], %%xmm0\n\t" -+ "movdqu %%xmm0, (%[key])\n\t" -+ : -+ : [key] "r" (c->u_mode.gcm.u_ghash_key.key), -+ [be_mask] "m" (*be_mask) -+ : "memory"); - - #ifdef __x86_64__ -- asm volatile ("movdqu %[h_1], %%xmm0\n\t" -- "movdqa %%xmm0, %%xmm1\n\t" -+ asm volatile ("movdqa %%xmm0, %%xmm1\n\t" -+ : - : -- : [h_1] "m" (*tmp)); -+ : "memory"); - - gfmul_pclmul (); /* H•H => H² */ - -@@ -324,8 +329,6 @@ _gcry_ghash_setup_intel_pclmul (gcry_cip - ::: "cc" ); - #endif - #endif -- -- wipememory (tmp, sizeof(tmp)); - } - - -diff -up libgcrypt-1.8.5/cipher/cipher-internal.h.aes-perf libgcrypt-1.8.5/cipher/cipher-internal.h ---- libgcrypt-1.8.5/cipher/cipher-internal.h.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-internal.h 2020-04-22 18:29:41.668862268 +0200 -@@ -121,6 +121,25 @@ struct gcry_cipher_handle - interface does not easily allow to retrieve this value. */ - int algo; - -+ /* A structure with function pointers for mode operations. */ -+ struct { -+ gcry_err_code_t (*encrypt)(gcry_cipher_hd_t c, -+ unsigned char *outbuf, size_t outbuflen, -+ const unsigned char *inbuf, size_t inbuflen); -+ gcry_err_code_t (*decrypt)(gcry_cipher_hd_t c, -+ unsigned char *outbuf, size_t outbuflen, -+ const unsigned char *inbuf, size_t inbuflen); -+ gcry_err_code_t (*setiv)(gcry_cipher_hd_t c, const unsigned char *iv, -+ size_t ivlen); -+ -+ gcry_err_code_t (*authenticate)(gcry_cipher_hd_t c, -+ const unsigned char *abuf, size_t abuflen); -+ gcry_err_code_t (*get_tag)(gcry_cipher_hd_t c, unsigned char *outtag, -+ size_t taglen); -+ gcry_err_code_t (*check_tag)(gcry_cipher_hd_t c, const unsigned char *intag, -+ size_t taglen); -+ } mode_ops; -+ - /* A structure with function pointers for bulk operations. Due to - limitations of the module system (we don't want to change the - API) we need to keep these function pointers here. The cipher -@@ -146,7 +165,7 @@ struct gcry_cipher_handle - const void *inbuf_arg, size_t nblocks, int encrypt); - size_t (*ocb_auth)(gcry_cipher_hd_t c, const void *abuf_arg, - size_t nblocks); -- void (*xts_crypt)(gcry_cipher_hd_t c, unsigned char *tweak, -+ void (*xts_crypt)(void *context, unsigned char *tweak, - void *outbuf_arg, const void *inbuf_arg, - size_t nblocks, int encrypt); - } bulk; -@@ -479,9 +498,12 @@ gcry_err_code_t _gcry_cipher_ocb_check_t - - - /*-- cipher-xts.c --*/ --gcry_err_code_t _gcry_cipher_xts_crypt -+gcry_err_code_t _gcry_cipher_xts_encrypt - /* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, -- const unsigned char *inbuf, size_t inbuflen, int encrypt); -+ const unsigned char *inbuf, size_t inbuflen); -+gcry_err_code_t _gcry_cipher_xts_decrypt -+/* */ (gcry_cipher_hd_t c, unsigned char *outbuf, size_t outbuflen, -+ const unsigned char *inbuf, size_t inbuflen); - - - /* Return the L-value for block N. Note: 'cipher_ocb.c' ensures that N -@@ -506,4 +528,145 @@ ocb_get_l (gcry_cipher_hd_t c, u64 n) - return c->u_mode.ocb.L[ntz]; - } - -+/* Optimized function for cipher block copying */ -+static inline void -+cipher_block_cpy(void *_dst, const void *_src, size_t blocksize) -+{ -+ byte *dst = _dst; -+ const byte *src = _src; -+ u64 s[2]; -+ -+ if (blocksize == 8) -+ { -+ buf_put_he64(dst + 0, buf_get_he64(src + 0)); -+ } -+ else /* blocksize == 16 */ -+ { -+ s[0] = buf_get_he64(src + 0); -+ s[1] = buf_get_he64(src + 8); -+ buf_put_he64(dst + 0, s[0]); -+ buf_put_he64(dst + 8, s[1]); -+ } -+} -+ -+ -+/* Optimized function for cipher block xoring */ -+static inline void -+cipher_block_xor(void *_dst, const void *_src1, const void *_src2, -+ size_t blocksize) -+{ -+ byte *dst = _dst; -+ const byte *src1 = _src1; -+ const byte *src2 = _src2; -+ u64 s1[2]; -+ u64 s2[2]; -+ -+ if (blocksize == 8) -+ { -+ buf_put_he64(dst + 0, buf_get_he64(src1 + 0) ^ buf_get_he64(src2 + 0)); -+ } -+ else /* blocksize == 16 */ -+ { -+ s1[0] = buf_get_he64(src1 + 0); -+ s1[1] = buf_get_he64(src1 + 8); -+ s2[0] = buf_get_he64(src2 + 0); -+ s2[1] = buf_get_he64(src2 + 8); -+ buf_put_he64(dst + 0, s1[0] ^ s2[0]); -+ buf_put_he64(dst + 8, s1[1] ^ s2[1]); -+ } -+} -+ -+ -+/* Optimized function for in-place cipher block xoring */ -+static inline void -+cipher_block_xor_1(void *_dst, const void *_src, size_t blocksize) -+{ -+ cipher_block_xor (_dst, _dst, _src, blocksize); -+} -+ -+ -+/* Optimized function for cipher block xoring with two destination cipher -+ blocks. Used mainly by CFB mode encryption. */ -+static inline void -+cipher_block_xor_2dst(void *_dst1, void *_dst2, const void *_src, -+ size_t blocksize) -+{ -+ byte *dst1 = _dst1; -+ byte *dst2 = _dst2; -+ const byte *src = _src; -+ u64 d2[2]; -+ u64 s[2]; -+ -+ if (blocksize == 8) -+ { -+ d2[0] = buf_get_he64(dst2 + 0) ^ buf_get_he64(src + 0); -+ buf_put_he64(dst2 + 0, d2[0]); -+ buf_put_he64(dst1 + 0, d2[0]); -+ } -+ else /* blocksize == 16 */ -+ { -+ s[0] = buf_get_he64(src + 0); -+ s[1] = buf_get_he64(src + 8); -+ d2[0] = buf_get_he64(dst2 + 0); -+ d2[1] = buf_get_he64(dst2 + 8); -+ d2[0] = d2[0] ^ s[0]; -+ d2[1] = d2[1] ^ s[1]; -+ buf_put_he64(dst2 + 0, d2[0]); -+ buf_put_he64(dst2 + 8, d2[1]); -+ buf_put_he64(dst1 + 0, d2[0]); -+ buf_put_he64(dst1 + 8, d2[1]); -+ } -+} -+ -+ -+/* Optimized function for combined cipher block xoring and copying. -+ Used by mainly CBC mode decryption. */ -+static inline void -+cipher_block_xor_n_copy_2(void *_dst_xor, const void *_src_xor, -+ void *_srcdst_cpy, const void *_src_cpy, -+ size_t blocksize) -+{ -+ byte *dst_xor = _dst_xor; -+ byte *srcdst_cpy = _srcdst_cpy; -+ const byte *src_xor = _src_xor; -+ const byte *src_cpy = _src_cpy; -+ u64 sc[2]; -+ u64 sx[2]; -+ u64 sdc[2]; -+ -+ if (blocksize == 8) -+ { -+ sc[0] = buf_get_he64(src_cpy + 0); -+ buf_put_he64(dst_xor + 0, -+ buf_get_he64(srcdst_cpy + 0) ^ buf_get_he64(src_xor + 0)); -+ buf_put_he64(srcdst_cpy + 0, sc[0]); -+ } -+ else /* blocksize == 16 */ -+ { -+ sc[0] = buf_get_he64(src_cpy + 0); -+ sc[1] = buf_get_he64(src_cpy + 8); -+ sx[0] = buf_get_he64(src_xor + 0); -+ sx[1] = buf_get_he64(src_xor + 8); -+ sdc[0] = buf_get_he64(srcdst_cpy + 0); -+ sdc[1] = buf_get_he64(srcdst_cpy + 8); -+ sx[0] ^= sdc[0]; -+ sx[1] ^= sdc[1]; -+ buf_put_he64(dst_xor + 0, sx[0]); -+ buf_put_he64(dst_xor + 8, sx[1]); -+ buf_put_he64(srcdst_cpy + 0, sc[0]); -+ buf_put_he64(srcdst_cpy + 8, sc[1]); -+ } -+} -+ -+ -+/* Optimized function for combined cipher block xoring and copying. -+ Used by mainly CFB mode decryption. */ -+static inline void -+cipher_block_xor_n_copy(void *_dst_xor, void *_srcdst_cpy, const void *_src, -+ size_t blocksize) -+{ -+ cipher_block_xor_n_copy_2(_dst_xor, _src, _srcdst_cpy, _src, blocksize); -+} -+ -+ - #endif /*G10_CIPHER_INTERNAL_H*/ -diff -up libgcrypt-1.8.5/cipher/cipher-ocb.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ocb.c ---- libgcrypt-1.8.5/cipher/cipher-ocb.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-ocb.c 2020-04-22 18:29:41.668862268 +0200 -@@ -82,7 +82,7 @@ static void - double_block_cpy (unsigned char *d, const unsigned char *s) - { - if (d != s) -- buf_cpy (d, s, OCB_BLOCK_LEN); -+ cipher_block_cpy (d, s, OCB_BLOCK_LEN); - double_block (d); - } - -@@ -181,8 +181,8 @@ _gcry_cipher_ocb_set_nonce (gcry_cipher_ - nburn = c->spec->encrypt (&c->context.c, ktop, ktop); - burn = nburn > burn ? nburn : burn; - /* Stretch = Ktop || (Ktop[1..64] xor Ktop[9..72]) */ -- buf_cpy (stretch, ktop, OCB_BLOCK_LEN); -- buf_xor (stretch + OCB_BLOCK_LEN, ktop, ktop + 1, 8); -+ cipher_block_cpy (stretch, ktop, OCB_BLOCK_LEN); -+ cipher_block_xor (stretch + OCB_BLOCK_LEN, ktop, ktop + 1, 8); - /* Offset_0 = Stretch[1+bottom..128+bottom] - (We use the IV field to store the offset) */ - bit_copy (c->u_iv.iv, stretch, bottom, OCB_BLOCK_LEN); -@@ -267,18 +267,18 @@ _gcry_cipher_ocb_authenticate (gcry_ciph - } - else - { -- buf_cpy (l_tmp, ocb_get_l (c, c->u_mode.ocb.aad_nblocks), -- OCB_BLOCK_LEN); -+ cipher_block_cpy (l_tmp, ocb_get_l (c, c->u_mode.ocb.aad_nblocks), -+ OCB_BLOCK_LEN); - } - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -- buf_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); - /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ -- buf_xor (l_tmp, c->u_mode.ocb.aad_offset, -- c->u_mode.ocb.aad_leftover, OCB_BLOCK_LEN); -+ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, -+ c->u_mode.ocb.aad_leftover, OCB_BLOCK_LEN); - nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); - burn = nburn > burn ? nburn : burn; -- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); - - c->u_mode.ocb.aad_nleftover = 0; - } -@@ -309,12 +309,13 @@ _gcry_cipher_ocb_authenticate (gcry_ciph - ocb_get_L_big(c, c->u_mode.ocb.aad_nblocks, l_tmp); - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -- buf_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l_tmp, OCB_BLOCK_LEN); - /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ -- buf_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, OCB_BLOCK_LEN); -+ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, -+ OCB_BLOCK_LEN); - nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); - burn = nburn > burn ? nburn : burn; -- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); - - abuf += OCB_BLOCK_LEN; - abuflen -= OCB_BLOCK_LEN; -@@ -349,14 +350,15 @@ _gcry_cipher_ocb_authenticate (gcry_ciph - gcry_assert(c->u_mode.ocb.aad_nblocks & table_size_mask); - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -- buf_xor_1 (c->u_mode.ocb.aad_offset, -- ocb_get_l (c, c->u_mode.ocb.aad_nblocks), -- OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, -+ ocb_get_l (c, c->u_mode.ocb.aad_nblocks), -+ OCB_BLOCK_LEN); - /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ -- buf_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, OCB_BLOCK_LEN); -+ cipher_block_xor (l_tmp, c->u_mode.ocb.aad_offset, abuf, -+ OCB_BLOCK_LEN); - nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); - burn = nburn > burn ? nburn : burn; -- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); - - abuf += OCB_BLOCK_LEN; - abuflen -= OCB_BLOCK_LEN; -@@ -397,18 +399,18 @@ ocb_aad_finalize (gcry_cipher_hd_t c) - if (c->u_mode.ocb.aad_nleftover) - { - /* Offset_* = Offset_m xor L_* */ -- buf_xor_1 (c->u_mode.ocb.aad_offset, -- c->u_mode.ocb.L_star, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, -+ c->u_mode.ocb.L_star, OCB_BLOCK_LEN); - /* CipherInput = (A_* || 1 || zeros(127-bitlen(A_*))) xor Offset_* */ - buf_cpy (l_tmp, c->u_mode.ocb.aad_leftover, c->u_mode.ocb.aad_nleftover); - memset (l_tmp + c->u_mode.ocb.aad_nleftover, 0, - OCB_BLOCK_LEN - c->u_mode.ocb.aad_nleftover); - l_tmp[c->u_mode.ocb.aad_nleftover] = 0x80; -- buf_xor_1 (l_tmp, c->u_mode.ocb.aad_offset, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (l_tmp, c->u_mode.ocb.aad_offset, OCB_BLOCK_LEN); - /* Sum = Sum_m xor ENCIPHER(K, CipherInput) */ - nburn = c->spec->encrypt (&c->context.c, l_tmp, l_tmp); - burn = nburn > burn ? nburn : burn; -- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp, OCB_BLOCK_LEN); - - c->u_mode.ocb.aad_nleftover = 0; - } -@@ -431,7 +433,7 @@ ocb_checksum (unsigned char *chksum, con - while (nblks > 0) - { - /* Checksum_i = Checksum_{i-1} xor P_i */ -- buf_xor_1(chksum, plainbuf, OCB_BLOCK_LEN); -+ cipher_block_xor_1(chksum, plainbuf, OCB_BLOCK_LEN); - - plainbuf += OCB_BLOCK_LEN; - nblks--; -@@ -491,12 +493,12 @@ ocb_crypt (gcry_cipher_hd_t c, int encry - } - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -- buf_xor_1 (c->u_iv.iv, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_iv.iv, l_tmp, OCB_BLOCK_LEN); - /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ -- buf_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); -+ cipher_block_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); - nburn = crypt_fn (&c->context.c, outbuf, outbuf); - burn = nburn > burn ? nburn : burn; -- buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); - - if (!encrypt) - { -@@ -551,14 +553,14 @@ ocb_crypt (gcry_cipher_hd_t c, int encry - gcry_assert(c->u_mode.ocb.data_nblocks & table_size_mask); - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -- buf_xor_1 (c->u_iv.iv, -- ocb_get_l (c, c->u_mode.ocb.data_nblocks), -- OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_iv.iv, -+ ocb_get_l (c, c->u_mode.ocb.data_nblocks), -+ OCB_BLOCK_LEN); - /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ -- buf_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); -+ cipher_block_xor (outbuf, c->u_iv.iv, inbuf, OCB_BLOCK_LEN); - nburn = crypt_fn (&c->context.c, outbuf, outbuf); - burn = nburn > burn ? nburn : burn; -- buf_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (outbuf, c->u_iv.iv, OCB_BLOCK_LEN); - - inbuf += OCB_BLOCK_LEN; - inbuflen -= OCB_BLOCK_LEN; -@@ -584,7 +586,7 @@ ocb_crypt (gcry_cipher_hd_t c, int encry - unsigned char pad[OCB_BLOCK_LEN]; - - /* Offset_* = Offset_m xor L_* */ -- buf_xor_1 (c->u_iv.iv, c->u_mode.ocb.L_star, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_iv.iv, c->u_mode.ocb.L_star, OCB_BLOCK_LEN); - /* Pad = ENCIPHER(K, Offset_*) */ - nburn = c->spec->encrypt (&c->context.c, pad, c->u_iv.iv); - burn = nburn > burn ? nburn : burn; -@@ -596,7 +598,7 @@ ocb_crypt (gcry_cipher_hd_t c, int encry - buf_cpy (l_tmp, inbuf, inbuflen); - memset (l_tmp + inbuflen, 0, OCB_BLOCK_LEN - inbuflen); - l_tmp[inbuflen] = 0x80; -- buf_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); - /* C_* = P_* xor Pad[1..bitlen(P_*)] */ - buf_xor (outbuf, inbuf, pad, inbuflen); - } -@@ -604,13 +606,13 @@ ocb_crypt (gcry_cipher_hd_t c, int encry - { - /* P_* = C_* xor Pad[1..bitlen(C_*)] */ - /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ -- buf_cpy (l_tmp, pad, OCB_BLOCK_LEN); -+ cipher_block_cpy (l_tmp, pad, OCB_BLOCK_LEN); - buf_cpy (l_tmp, inbuf, inbuflen); -- buf_xor_1 (l_tmp, pad, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (l_tmp, pad, OCB_BLOCK_LEN); - l_tmp[inbuflen] = 0x80; - buf_cpy (outbuf, l_tmp, inbuflen); - -- buf_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp, OCB_BLOCK_LEN); - } - } - -@@ -618,8 +620,10 @@ ocb_crypt (gcry_cipher_hd_t c, int encry - if (c->marks.finalize) - { - /* Tag = ENCIPHER(K, Checksum xor Offset xor L_$) xor HASH(K,A) */ -- buf_xor (c->u_mode.ocb.tag, c->u_ctr.ctr, c->u_iv.iv, OCB_BLOCK_LEN); -- buf_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.L_dollar, OCB_BLOCK_LEN); -+ cipher_block_xor (c->u_mode.ocb.tag, c->u_ctr.ctr, c->u_iv.iv, -+ OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.L_dollar, -+ OCB_BLOCK_LEN); - nburn = c->spec->encrypt (&c->context.c, - c->u_mode.ocb.tag, c->u_mode.ocb.tag); - burn = nburn > burn ? nburn : burn; -@@ -672,7 +676,8 @@ compute_tag_if_needed (gcry_cipher_hd_t - if (!c->marks.tag) - { - ocb_aad_finalize (c); -- buf_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.aad_sum, OCB_BLOCK_LEN); -+ cipher_block_xor_1 (c->u_mode.ocb.tag, c->u_mode.ocb.aad_sum, -+ OCB_BLOCK_LEN); - c->marks.tag = 1; - } - } -diff -up libgcrypt-1.8.5/cipher/cipher-ofb.c.aes-perf libgcrypt-1.8.5/cipher/cipher-ofb.c ---- libgcrypt-1.8.5/cipher/cipher-ofb.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-ofb.c 2020-04-22 18:29:41.668862268 +0200 -@@ -76,7 +76,7 @@ _gcry_cipher_ofb_encrypt (gcry_cipher_hd - /* Encrypt the IV (and save the current one). */ - nburn = enc_fn ( &c->context.c, c->u_iv.iv, c->u_iv.iv ); - burn = nburn > burn ? nburn : burn; -- buf_xor(outbuf, c->u_iv.iv, inbuf, blocksize); -+ cipher_block_xor(outbuf, c->u_iv.iv, inbuf, blocksize); - outbuf += blocksize; - inbuf += blocksize; - inbuflen -= blocksize; -diff -up libgcrypt-1.8.5/cipher/cipher-selftest.c.aes-perf libgcrypt-1.8.5/cipher/cipher-selftest.c ---- libgcrypt-1.8.5/cipher/cipher-selftest.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-selftest.c 2020-04-22 18:29:41.669862248 +0200 -@@ -105,7 +105,7 @@ _gcry_selftest_helper_cbc (const char *c - ciphertext = plaintext2 + nblocks * blocksize; - - /* Initialize ctx */ -- if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) -+ if (setkey_func (ctx, key, sizeof(key), NULL) != GPG_ERR_NO_ERROR) - { - xfree(mem); - return "setkey failed"; -@@ -228,7 +228,7 @@ _gcry_selftest_helper_cfb (const char *c - ciphertext = plaintext2 + nblocks * blocksize; - - /* Initialize ctx */ -- if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) -+ if (setkey_func (ctx, key, sizeof(key), NULL) != GPG_ERR_NO_ERROR) - { - xfree(mem); - return "setkey failed"; -@@ -351,7 +351,7 @@ _gcry_selftest_helper_ctr (const char *c - ciphertext2 = ciphertext + nblocks * blocksize; - - /* Initialize ctx */ -- if (setkey_func (ctx, key, sizeof(key)) != GPG_ERR_NO_ERROR) -+ if (setkey_func (ctx, key, sizeof(key), NULL) != GPG_ERR_NO_ERROR) - { - xfree(mem); - return "setkey failed"; -diff -up libgcrypt-1.8.5/cipher/cipher-xts.c.aes-perf libgcrypt-1.8.5/cipher/cipher-xts.c ---- libgcrypt-1.8.5/cipher/cipher-xts.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/cipher-xts.c 2020-04-22 18:29:41.669862248 +0200 -@@ -93,7 +93,8 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t - /* Use a bulk method if available. */ - if (nblocks && c->bulk.xts_crypt) - { -- c->bulk.xts_crypt (c, c->u_ctr.ctr, outbuf, inbuf, nblocks, encrypt); -+ c->bulk.xts_crypt (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks, -+ encrypt); - inbuf += nblocks * GCRY_XTS_BLOCK_LEN; - outbuf += nblocks * GCRY_XTS_BLOCK_LEN; - inbuflen -= nblocks * GCRY_XTS_BLOCK_LEN; -@@ -106,10 +107,10 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t - while (nblocks) - { - /* Xor-Encrypt/Decrypt-Xor block. */ -- buf_xor (tmp.x64, inbuf, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); -+ cipher_block_xor (tmp.x64, inbuf, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); - nburn = crypt_fn (&c->context.c, tmp.x1, tmp.x1); - burn = nburn > burn ? nburn : burn; -- buf_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); -+ cipher_block_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); - - outbuf += GCRY_XTS_BLOCK_LEN; - inbuf += GCRY_XTS_BLOCK_LEN; -@@ -132,10 +133,10 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t - xts_gfmul_byA (tmp.x1, c->u_ctr.ctr); - - /* Decrypt last block first. */ -- buf_xor (outbuf, inbuf, tmp.x64, GCRY_XTS_BLOCK_LEN); -+ cipher_block_xor (outbuf, inbuf, tmp.x64, GCRY_XTS_BLOCK_LEN); - nburn = crypt_fn (&c->context.c, outbuf, outbuf); - burn = nburn > burn ? nburn : burn; -- buf_xor (outbuf, outbuf, tmp.x64, GCRY_XTS_BLOCK_LEN); -+ cipher_block_xor (outbuf, outbuf, tmp.x64, GCRY_XTS_BLOCK_LEN); - - inbuflen -= GCRY_XTS_BLOCK_LEN; - inbuf += GCRY_XTS_BLOCK_LEN; -@@ -146,15 +147,15 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t - outbuf -= GCRY_XTS_BLOCK_LEN; - - /* Steal ciphertext from previous block. */ -- buf_cpy (tmp.x64, outbuf, GCRY_XTS_BLOCK_LEN); -+ cipher_block_cpy (tmp.x64, outbuf, GCRY_XTS_BLOCK_LEN); - buf_cpy (tmp.x64, inbuf, inbuflen); - buf_cpy (outbuf + GCRY_XTS_BLOCK_LEN, outbuf, inbuflen); - - /* Decrypt/Encrypt last block. */ -- buf_xor (tmp.x64, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); -+ cipher_block_xor (tmp.x64, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); - nburn = crypt_fn (&c->context.c, tmp.x1, tmp.x1); - burn = nburn > burn ? nburn : burn; -- buf_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); -+ cipher_block_xor (outbuf, tmp.x64, c->u_ctr.ctr, GCRY_XTS_BLOCK_LEN); - } - - /* Auto-increment data-unit sequence number */ -@@ -168,3 +169,21 @@ _gcry_cipher_xts_crypt (gcry_cipher_hd_t - - return 0; - } -+ -+ -+gcry_err_code_t -+_gcry_cipher_xts_encrypt (gcry_cipher_hd_t c, -+ unsigned char *outbuf, size_t outbuflen, -+ const unsigned char *inbuf, size_t inbuflen) -+{ -+ return _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 1); -+} -+ -+ -+gcry_err_code_t -+_gcry_cipher_xts_decrypt (gcry_cipher_hd_t c, -+ unsigned char *outbuf, size_t outbuflen, -+ const unsigned char *inbuf, size_t inbuflen) -+{ -+ return _gcry_cipher_xts_crypt (c, outbuf, outbuflen, inbuf, inbuflen, 0); -+} -diff -up libgcrypt-1.8.5/cipher/des.c.aes-perf libgcrypt-1.8.5/cipher/des.c ---- libgcrypt-1.8.5/cipher/des.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/des.c 2020-04-22 18:29:41.669862248 +0200 -@@ -119,6 +119,7 @@ - #include "g10lib.h" - #include "cipher.h" - #include "bufhelp.h" -+#include "cipher-internal.h" - #include "cipher-selftest.h" - - -@@ -197,7 +198,8 @@ static unsigned int do_tripledes_encrypt - static unsigned int do_tripledes_decrypt(void *context, byte *outbuf, - const byte *inbuf ); - static gcry_err_code_t do_tripledes_setkey(void *context, const byte *key, -- unsigned keylen); -+ unsigned keylen, -+ gcry_cipher_hd_t hd); - - static int initialized; - -@@ -940,7 +942,7 @@ _gcry_3des_ctr_enc(void *context, unsign - /* Encrypt the counter. */ - tripledes_ecb_encrypt (ctx, ctr, tmpbuf); - /* XOR the input with the encrypted counter and store in output. */ -- buf_xor(outbuf, tmpbuf, inbuf, DES_BLOCKSIZE); -+ cipher_block_xor(outbuf, tmpbuf, inbuf, DES_BLOCKSIZE); - outbuf += DES_BLOCKSIZE; - inbuf += DES_BLOCKSIZE; - /* Increment the counter. */ -@@ -996,7 +998,7 @@ _gcry_3des_cbc_dec(void *context, unsign - the intermediate result to SAVEBUF. */ - tripledes_ecb_decrypt (ctx, inbuf, savebuf); - -- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, DES_BLOCKSIZE); -+ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, DES_BLOCKSIZE); - inbuf += DES_BLOCKSIZE; - outbuf += DES_BLOCKSIZE; - } -@@ -1041,7 +1043,7 @@ _gcry_3des_cfb_dec(void *context, unsign - for ( ;nblocks; nblocks-- ) - { - tripledes_ecb_encrypt (ctx, iv, iv); -- buf_xor_n_copy(outbuf, iv, inbuf, DES_BLOCKSIZE); -+ cipher_block_xor_n_copy(outbuf, iv, inbuf, DES_BLOCKSIZE); - outbuf += DES_BLOCKSIZE; - inbuf += DES_BLOCKSIZE; - } -@@ -1086,7 +1088,8 @@ is_weak_key ( const byte *key ) - - /* Alternative setkey for selftests; need larger key than default. */ - static gcry_err_code_t --bulk_selftest_setkey (void *context, const byte *__key, unsigned __keylen) -+bulk_selftest_setkey (void *context, const byte *__key, unsigned __keylen, -+ gcry_cipher_hd_t hd) - { - static const unsigned char key[24] ATTR_ALIGNED_16 = { - 0x66,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F, -@@ -1094,10 +1097,11 @@ bulk_selftest_setkey (void *context, con - 0x18,0x2A,0x39,0x47,0x5E,0x6F,0x75,0x82 - }; - -+ (void)hd; - (void)__key; - (void)__keylen; - -- return do_tripledes_setkey(context, key, sizeof(key)); -+ return do_tripledes_setkey(context, key, sizeof(key), NULL); - } - - -@@ -1349,10 +1353,13 @@ selftest (void) - - - static gcry_err_code_t --do_tripledes_setkey ( void *context, const byte *key, unsigned keylen ) -+do_tripledes_setkey ( void *context, const byte *key, unsigned keylen, -+ gcry_cipher_hd_t hd ) - { - struct _tripledes_ctx *ctx = (struct _tripledes_ctx *) context; - -+ (void)hd; -+ - if( keylen != 24 ) - return GPG_ERR_INV_KEYLEN; - -@@ -1413,10 +1420,13 @@ do_tripledes_decrypt( void *context, byt - } - - static gcry_err_code_t --do_des_setkey (void *context, const byte *key, unsigned keylen) -+do_des_setkey (void *context, const byte *key, unsigned keylen, -+ gcry_cipher_hd_t hd) - { - struct _des_ctx *ctx = (struct _des_ctx *) context; - -+ (void)hd; -+ - if (keylen != 8) - return GPG_ERR_INV_KEYLEN; - -diff -up libgcrypt-1.8.5/cipher/gost28147.c.aes-perf libgcrypt-1.8.5/cipher/gost28147.c ---- libgcrypt-1.8.5/cipher/gost28147.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/gost28147.c 2020-04-22 18:29:41.669862248 +0200 -@@ -39,11 +39,14 @@ - #include "gost-sb.h" - - static gcry_err_code_t --gost_setkey (void *c, const byte *key, unsigned keylen) -+gost_setkey (void *c, const byte *key, unsigned keylen, -+ gcry_cipher_hd_t hd) - { - int i; - GOST28147_context *ctx = c; - -+ (void)hd; -+ - if (keylen != 256 / 8) - return GPG_ERR_INV_KEYLEN; - -diff -up libgcrypt-1.8.5/cipher/idea.c.aes-perf libgcrypt-1.8.5/cipher/idea.c ---- libgcrypt-1.8.5/cipher/idea.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/idea.c 2020-04-22 18:29:41.670862229 +0200 -@@ -258,10 +258,12 @@ do_setkey( IDEA_context *c, const byte * - } - - static gcry_err_code_t --idea_setkey (void *context, const byte *key, unsigned int keylen) -+idea_setkey (void *context, const byte *key, unsigned int keylen, -+ gcry_cipher_hd_t hd) - { - IDEA_context *ctx = context; - int rc = do_setkey (ctx, key, keylen); -+ (void)hd; - _gcry_burn_stack (23+6*sizeof(void*)); - return rc; - } -diff -up libgcrypt-1.8.5/cipher/Makefile.am.aes-perf libgcrypt-1.8.5/cipher/Makefile.am ---- libgcrypt-1.8.5/cipher/Makefile.am.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/Makefile.am 2020-04-22 18:29:41.670862229 +0200 -@@ -83,7 +83,8 @@ rijndael.c rijndael-internal.h rijndael- - rijndael-padlock.c rijndael-amd64.S rijndael-arm.S \ - rijndael-ssse3-amd64.c rijndael-ssse3-amd64-asm.S \ - rijndael-armv8-ce.c rijndael-armv8-aarch32-ce.S rijndael-armv8-aarch64-ce.S \ -- rijndael-aarch64.S \ -+ rijndael-aarch64.S rijndael-ppc.c rijndael-ppc9le.c \ -+ rijndael-ppc-common.h rijndael-ppc-functions.h \ - rmd160.c \ - rsa.c \ - salsa20.c salsa20-amd64.S salsa20-armv7-neon.S \ -@@ -128,3 +129,23 @@ tiger.o: $(srcdir)/tiger.c - - tiger.lo: $(srcdir)/tiger.c - `echo $(LTCOMPILE) -c $(srcdir)/tiger.c | $(o_flag_munging) ` -+ -+if ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS -+ppc_vcrypto_cflags = -maltivec -mvsx -mcrypto -+else -+ppc_vcrypto_cflags = -+endif -+ -+rijndael-ppc.o: $(srcdir)/rijndael-ppc.c Makefile -+ `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< ` -+ -+rijndael-ppc.lo: $(srcdir)/rijndael-ppc.c Makefile -+ `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< ` -+ -+rijndael-ppc9le.o: $(srcdir)/rijndael-ppc9le.c Makefile -+ `echo $(COMPILE) $(ppc_vcrypto_cflags) -c $< ` -+ -+rijndael-ppc9le.lo: $(srcdir)/rijndael-ppc9le.c Makefile -+ `echo $(LTCOMPILE) $(ppc_vcrypto_cflags) -c $< ` -+ -+ -diff -up libgcrypt-1.8.5/cipher/rfc2268.c.aes-perf libgcrypt-1.8.5/cipher/rfc2268.c ---- libgcrypt-1.8.5/cipher/rfc2268.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rfc2268.c 2020-04-22 18:29:41.670862229 +0200 -@@ -262,8 +262,10 @@ setkey_core (void *context, const unsign - } - - static gpg_err_code_t --do_setkey (void *context, const unsigned char *key, unsigned int keylen) -+do_setkey (void *context, const unsigned char *key, unsigned int keylen, -+ gcry_cipher_hd_t hd) - { -+ (void)hd; - return setkey_core (context, key, keylen, 1); - } - -diff -up libgcrypt-1.8.5/cipher/rijndael-aesni.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-aesni.c ---- libgcrypt-1.8.5/cipher/rijndael-aesni.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rijndael-aesni.c 2020-04-28 11:22:26.025519954 +0200 -@@ -327,8 +327,8 @@ _gcry_aes_aesni_do_setkey (RIJNDAEL_cont - - - /* Make a decryption key from an encryption key. */ --void --_gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx) -+static inline void -+do_aesni_prepare_decryption (RIJNDAEL_context *ctx) - { - /* The AES-NI decrypt instructions use the Equivalent Inverse - Cipher, thus we can't use the the standard decrypt key -@@ -338,8 +338,6 @@ _gcry_aes_aesni_prepare_decryption (RIJN - int rr; - int r; - -- aesni_prepare(); -- - #define DO_AESNI_AESIMC() \ - asm volatile ("movdqa %[ekey], %%xmm1\n\t" \ - /*"aesimc %%xmm1, %%xmm1\n\t"*/ \ -@@ -375,7 +373,13 @@ _gcry_aes_aesni_prepare_decryption (RIJN - dkey[r] = ekey[0]; - - #undef DO_AESNI_AESIMC -+} - -+void -+_gcry_aes_aesni_prepare_decryption (RIJNDAEL_context *ctx) -+{ -+ aesni_prepare(); -+ do_aesni_prepare_decryption (ctx); - aesni_cleanup(); - } - -@@ -1023,8 +1027,8 @@ _gcry_aes_aesni_encrypt (const RIJNDAEL_ - - - void --_gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -+_gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks) - { - aesni_prepare (); -@@ -1059,8 +1063,8 @@ _gcry_aes_aesni_cfb_enc (RIJNDAEL_contex - - - void --_gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -+_gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks, int cbc_mac) - { - aesni_prepare_2_6_variable; -@@ -1105,8 +1109,8 @@ _gcry_aes_aesni_cbc_enc (RIJNDAEL_contex - - - void --_gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *ctr, -+_gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, unsigned char *ctr, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks) - { - static const unsigned char be_mask[16] __attribute__ ((aligned (16))) = -@@ -1160,8 +1164,8 @@ _gcry_aes_aesni_decrypt (const RIJNDAEL_ - - - void --_gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -+_gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks) - { - aesni_prepare_2_6_variable; -@@ -1245,15 +1249,21 @@ _gcry_aes_aesni_cfb_dec (RIJNDAEL_contex - - - void --_gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -- size_t nblocks) -+_gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks) - { - aesni_prepare_2_6_variable; - - aesni_prepare (); - aesni_prepare_2_6(); - -+ if ( !ctx->decryption_prepared ) -+ { -+ do_aesni_prepare_decryption ( ctx ); -+ ctx->decryption_prepared = 1; -+ } -+ - asm volatile - ("movdqu %[iv], %%xmm5\n\t" /* use xmm5 as fast IV storage */ - : /* No output */ -@@ -1514,6 +1524,12 @@ aesni_ocb_dec (gcry_cipher_hd_t c, void - aesni_prepare (); - aesni_prepare_2_6 (); - -+ if ( !ctx->decryption_prepared ) -+ { -+ do_aesni_prepare_decryption ( ctx ); -+ ctx->decryption_prepared = 1; -+ } -+ - /* Preload Offset and Checksum */ - asm volatile ("movdqu %[iv], %%xmm5\n\t" - "movdqu %[ctr], %%xmm6\n\t" -@@ -1665,7 +1681,7 @@ aesni_ocb_dec (gcry_cipher_hd_t c, void - } - - --void -+size_t - _gcry_aes_aesni_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg, - const void *inbuf_arg, size_t nblocks, int encrypt) - { -@@ -1673,10 +1689,12 @@ _gcry_aes_aesni_ocb_crypt(gcry_cipher_hd - aesni_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); - else - aesni_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); -+ -+ return 0; - } - - --void -+size_t - _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, - size_t nblocks) - { -@@ -1810,7 +1828,306 @@ _gcry_aes_aesni_ocb_auth (gcry_cipher_hd - - aesni_cleanup (); - aesni_cleanup_2_6 (); -+ -+ return 0; - } - - -+static const u64 xts_gfmul_const[16] __attribute__ ((aligned (16))) = -+ { 0x87, 0x01 }; -+ -+ -+static void -+_gcry_aes_aesni_xts_enc (RIJNDAEL_context *ctx, unsigned char *tweak, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks) -+{ -+ aesni_prepare_2_6_variable; -+ -+ aesni_prepare (); -+ aesni_prepare_2_6 (); -+ -+ /* Preload Tweak */ -+ asm volatile ("movdqu %[tweak], %%xmm5\n\t" -+ "movdqa %[gfmul], %%xmm6\n\t" -+ : -+ : [tweak] "m" (*tweak), -+ [gfmul] "m" (*xts_gfmul_const) -+ : "memory" ); -+ -+ for ( ;nblocks >= 4; nblocks -= 4 ) -+ { -+ asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" -+ "movdqu %[inbuf0], %%xmm1\n\t" -+ "pxor %%xmm5, %%xmm1\n\t" -+ "movdqu %%xmm5, %[outbuf0]\n\t" -+ -+ "movdqa %%xmm4, %%xmm0\n\t" -+ "paddd %%xmm4, %%xmm4\n\t" -+ "psrad $31, %%xmm0\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm5\n\t" -+ : [outbuf0] "=m" (*(outbuf + 0 * 16)) -+ : [inbuf0] "m" (*(inbuf + 0 * 16)) -+ : "memory" ); -+ -+ asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" -+ "pxor %%xmm5, %%xmm2\n\t" -+ "movdqu %%xmm5, %[outbuf1]\n\t" -+ -+ "movdqa %%xmm4, %%xmm0\n\t" -+ "paddd %%xmm4, %%xmm4\n\t" -+ "psrad $31, %%xmm0\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm5\n\t" -+ : [outbuf1] "=m" (*(outbuf + 1 * 16)) -+ : [inbuf1] "m" (*(inbuf + 1 * 16)) -+ : "memory" ); -+ -+ asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" -+ "pxor %%xmm5, %%xmm3\n\t" -+ "movdqu %%xmm5, %[outbuf2]\n\t" -+ -+ "movdqa %%xmm4, %%xmm0\n\t" -+ "paddd %%xmm4, %%xmm4\n\t" -+ "psrad $31, %%xmm0\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm5\n\t" -+ : [outbuf2] "=m" (*(outbuf + 2 * 16)) -+ : [inbuf2] "m" (*(inbuf + 2 * 16)) -+ : "memory" ); -+ -+ asm volatile ("movdqa %%xmm4, %%xmm0\n\t" -+ "movdqu %[inbuf3], %%xmm4\n\t" -+ "pxor %%xmm5, %%xmm4\n\t" -+ "movdqu %%xmm5, %[outbuf3]\n\t" -+ -+ "psrad $31, %%xmm0\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm5\n\t" -+ : [outbuf3] "=m" (*(outbuf + 3 * 16)) -+ : [inbuf3] "m" (*(inbuf + 3 * 16)) -+ : "memory" ); -+ -+ do_aesni_enc_vec4 (ctx); -+ -+ asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm1\n\t" -+ "movdqu %[outbuf1], %%xmm0\n\t" -+ "movdqu %%xmm1, %[outbuf0]\n\t" -+ "movdqu %[outbuf2], %%xmm1\n\t" -+ "pxor %%xmm0, %%xmm2\n\t" -+ "movdqu %[outbuf3], %%xmm0\n\t" -+ "pxor %%xmm1, %%xmm3\n\t" -+ "pxor %%xmm0, %%xmm4\n\t" -+ "movdqu %%xmm2, %[outbuf1]\n\t" -+ "movdqu %%xmm3, %[outbuf2]\n\t" -+ "movdqu %%xmm4, %[outbuf3]\n\t" -+ : [outbuf0] "+m" (*(outbuf + 0 * 16)), -+ [outbuf1] "+m" (*(outbuf + 1 * 16)), -+ [outbuf2] "+m" (*(outbuf + 2 * 16)), -+ [outbuf3] "+m" (*(outbuf + 3 * 16)) -+ : -+ : "memory" ); -+ -+ outbuf += BLOCKSIZE * 4; -+ inbuf += BLOCKSIZE * 4; -+ } -+ -+ for ( ;nblocks; nblocks-- ) -+ { -+ asm volatile ("movdqu %[inbuf], %%xmm0\n\t" -+ "pxor %%xmm5, %%xmm0\n\t" -+ "movdqa %%xmm5, %%xmm4\n\t" -+ -+ "pshufd $0x13, %%xmm5, %%xmm1\n\t" -+ "psrad $31, %%xmm1\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm1\n\t" -+ "pxor %%xmm1, %%xmm5\n\t" -+ : -+ : [inbuf] "m" (*inbuf) -+ : "memory" ); -+ -+ do_aesni_enc (ctx); -+ -+ asm volatile ("pxor %%xmm4, %%xmm0\n\t" -+ "movdqu %%xmm0, %[outbuf]\n\t" -+ : [outbuf] "=m" (*outbuf) -+ : -+ : "memory" ); -+ -+ outbuf += BLOCKSIZE; -+ inbuf += BLOCKSIZE; -+ } -+ -+ asm volatile ("movdqu %%xmm5, %[tweak]\n\t" -+ : [tweak] "=m" (*tweak) -+ : -+ : "memory" ); -+ -+ aesni_cleanup (); -+ aesni_cleanup_2_6 (); -+} -+ -+ -+static void -+_gcry_aes_aesni_xts_dec (RIJNDAEL_context *ctx, unsigned char *tweak, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks) -+{ -+ aesni_prepare_2_6_variable; -+ -+ aesni_prepare (); -+ aesni_prepare_2_6 (); -+ -+ if ( !ctx->decryption_prepared ) -+ { -+ do_aesni_prepare_decryption ( ctx ); -+ ctx->decryption_prepared = 1; -+ } -+ -+ /* Preload Tweak */ -+ asm volatile ("movdqu %[tweak], %%xmm5\n\t" -+ "movdqa %[gfmul], %%xmm6\n\t" -+ : -+ : [tweak] "m" (*tweak), -+ [gfmul] "m" (*xts_gfmul_const) -+ : "memory" ); -+ -+ for ( ;nblocks >= 4; nblocks -= 4 ) -+ { -+ asm volatile ("pshufd $0x13, %%xmm5, %%xmm4\n\t" -+ "movdqu %[inbuf0], %%xmm1\n\t" -+ "pxor %%xmm5, %%xmm1\n\t" -+ "movdqu %%xmm5, %[outbuf0]\n\t" -+ -+ "movdqa %%xmm4, %%xmm0\n\t" -+ "paddd %%xmm4, %%xmm4\n\t" -+ "psrad $31, %%xmm0\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm5\n\t" -+ : [outbuf0] "=m" (*(outbuf + 0 * 16)) -+ : [inbuf0] "m" (*(inbuf + 0 * 16)) -+ : "memory" ); -+ -+ asm volatile ("movdqu %[inbuf1], %%xmm2\n\t" -+ "pxor %%xmm5, %%xmm2\n\t" -+ "movdqu %%xmm5, %[outbuf1]\n\t" -+ -+ "movdqa %%xmm4, %%xmm0\n\t" -+ "paddd %%xmm4, %%xmm4\n\t" -+ "psrad $31, %%xmm0\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm5\n\t" -+ : [outbuf1] "=m" (*(outbuf + 1 * 16)) -+ : [inbuf1] "m" (*(inbuf + 1 * 16)) -+ : "memory" ); -+ -+ asm volatile ("movdqu %[inbuf2], %%xmm3\n\t" -+ "pxor %%xmm5, %%xmm3\n\t" -+ "movdqu %%xmm5, %[outbuf2]\n\t" -+ -+ "movdqa %%xmm4, %%xmm0\n\t" -+ "paddd %%xmm4, %%xmm4\n\t" -+ "psrad $31, %%xmm0\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm5\n\t" -+ : [outbuf2] "=m" (*(outbuf + 2 * 16)) -+ : [inbuf2] "m" (*(inbuf + 2 * 16)) -+ : "memory" ); -+ -+ asm volatile ("movdqa %%xmm4, %%xmm0\n\t" -+ "movdqu %[inbuf3], %%xmm4\n\t" -+ "pxor %%xmm5, %%xmm4\n\t" -+ "movdqu %%xmm5, %[outbuf3]\n\t" -+ -+ "psrad $31, %%xmm0\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm5\n\t" -+ : [outbuf3] "=m" (*(outbuf + 3 * 16)) -+ : [inbuf3] "m" (*(inbuf + 3 * 16)) -+ : "memory" ); -+ -+ do_aesni_dec_vec4 (ctx); -+ -+ asm volatile ("movdqu %[outbuf0], %%xmm0\n\t" -+ "pxor %%xmm0, %%xmm1\n\t" -+ "movdqu %[outbuf1], %%xmm0\n\t" -+ "movdqu %%xmm1, %[outbuf0]\n\t" -+ "movdqu %[outbuf2], %%xmm1\n\t" -+ "pxor %%xmm0, %%xmm2\n\t" -+ "movdqu %[outbuf3], %%xmm0\n\t" -+ "pxor %%xmm1, %%xmm3\n\t" -+ "pxor %%xmm0, %%xmm4\n\t" -+ "movdqu %%xmm2, %[outbuf1]\n\t" -+ "movdqu %%xmm3, %[outbuf2]\n\t" -+ "movdqu %%xmm4, %[outbuf3]\n\t" -+ : [outbuf0] "+m" (*(outbuf + 0 * 16)), -+ [outbuf1] "+m" (*(outbuf + 1 * 16)), -+ [outbuf2] "+m" (*(outbuf + 2 * 16)), -+ [outbuf3] "+m" (*(outbuf + 3 * 16)) -+ : -+ : "memory" ); -+ -+ outbuf += BLOCKSIZE * 4; -+ inbuf += BLOCKSIZE * 4; -+ } -+ -+ for ( ;nblocks; nblocks-- ) -+ { -+ asm volatile ("movdqu %[inbuf], %%xmm0\n\t" -+ "pxor %%xmm5, %%xmm0\n\t" -+ "movdqa %%xmm5, %%xmm4\n\t" -+ -+ "pshufd $0x13, %%xmm5, %%xmm1\n\t" -+ "psrad $31, %%xmm1\n\t" -+ "paddq %%xmm5, %%xmm5\n\t" -+ "pand %%xmm6, %%xmm1\n\t" -+ "pxor %%xmm1, %%xmm5\n\t" -+ : -+ : [inbuf] "m" (*inbuf) -+ : "memory" ); -+ -+ do_aesni_dec (ctx); -+ -+ asm volatile ("pxor %%xmm4, %%xmm0\n\t" -+ "movdqu %%xmm0, %[outbuf]\n\t" -+ : [outbuf] "=m" (*outbuf) -+ : -+ : "memory" ); -+ -+ outbuf += BLOCKSIZE; -+ inbuf += BLOCKSIZE; -+ } -+ -+ asm volatile ("movdqu %%xmm5, %[tweak]\n\t" -+ : [tweak] "=m" (*tweak) -+ : -+ : "memory" ); -+ -+ aesni_cleanup (); -+ aesni_cleanup_2_6 (); -+} -+ -+ -+void -+_gcry_aes_aesni_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks, int encrypt) -+{ -+ if (encrypt) -+ _gcry_aes_aesni_xts_enc(ctx, tweak, outbuf, inbuf, nblocks); -+ else -+ _gcry_aes_aesni_xts_dec(ctx, tweak, outbuf, inbuf, nblocks); -+} -+ - #endif /* USE_AESNI */ -diff -up libgcrypt-1.8.5/cipher/rijndael-armv8-aarch32-ce.S.aes-perf libgcrypt-1.8.5/cipher/rijndael-armv8-aarch32-ce.S ---- libgcrypt-1.8.5/cipher/rijndael-armv8-aarch32-ce.S.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rijndael-armv8-aarch32-ce.S 2020-04-22 18:29:41.673862172 +0200 -@@ -1517,6 +1517,317 @@ _gcry_aes_ocb_auth_armv8_ce: - .size _gcry_aes_ocb_auth_armv8_ce,.-_gcry_aes_ocb_auth_armv8_ce; - - -+ -+/* -+ * void _gcry_aes_xts_enc_armv8_ce (const void *keysched, -+ * unsigned char *outbuf, -+ * const unsigned char *inbuf, -+ * unsigned char *iv, unsigned int nrounds); -+ */ -+ -+.align 3 -+.globl _gcry_aes_xts_enc_armv8_ce -+.type _gcry_aes_xts_enc_armv8_ce,%function; -+_gcry_aes_xts_enc_armv8_ce: -+ /* input: -+ * r0: keysched -+ * r1: outbuf -+ * r2: inbuf -+ * r3: iv -+ * %st+0: nblocks => r4 -+ * %st+4: nrounds => r5 -+ */ -+ -+ vpush {q4-q7} -+ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */ -+ ldr r4, [sp, #(104+0)] -+ ldr r5, [sp, #(104+4)] -+ cmp r4, #0 -+ beq .Lxts_enc_skip -+ -+ cmp r5, #12 -+ -+ vld1.8 {q0}, [r3] /* load tweak */ -+ mov r7, #0x87; -+ -+ aes_preload_keys(r0, r6); -+ -+ beq .Lxts_enc_entry_192 -+ bhi .Lxts_enc_entry_256 -+ -+#define CTR_XTS(bits, ...) \ -+ .Lxts_enc_entry_##bits: \ -+ cmp r4, #4; \ -+ blo .Lxts_enc_loop_##bits; \ -+ \ -+ .Lxts_enc_loop4_##bits: \ -+ sub r4, r4, #4; \ -+ veor q9, q9, q9; \ -+ \ -+ vld1.8 {q1-q2}, [r2]!; /* load plaintext */ \ -+ veor q1, q1, q0; \ -+ cmp r4, #4; \ -+ vmov.u32 d18[0], r7; \ -+ vst1.8 {q0}, [r1]!; /* store tweak0 to temp */ \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ \ -+ vld1.8 {q3-q4}, [r2]!; /* load plaintext */ \ -+ veor q2, q2, q0; \ -+ vst1.8 {q0}, [r1]!; /* store tweak1 to temp */ \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ \ -+ veor q3, q3, q0; \ -+ vst1.8 {q0}, [r1]!; /* store tweak2 to temp */ \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ \ -+ veor q4, q4, q0; \ -+ vst1.8 {q0}, [r1]; /* store tweak3 to temp */ \ -+ sub r1, r1, #48; \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ \ -+ do_aes_4_##bits(e, mc, q1, q2, q3, q4, ##__VA_ARGS__); \ -+ \ -+ vld1.8 {q8-q9}, [r1]!; /* load tweak from temp */ \ -+ veor q1, q1, q8; \ -+ veor q2, q2, q9; \ -+ vld1.8 {q8-q9}, [r1]; /* load tweak from temp */ \ -+ sub r1, r1, #32; \ -+ veor q3, q3, q8; \ -+ veor q4, q4, q9; \ -+ vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \ -+ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \ -+ \ -+ bhs .Lxts_enc_loop4_##bits; \ -+ cmp r4, #0; \ -+ beq .Lxts_enc_done; \ -+ \ -+ .Lxts_enc_loop_##bits: \ -+ \ -+ vld1.8 {q1}, [r2]!; /* load ciphertext */ \ -+ \ -+ veor q9, q9, q9; \ -+ veor q1, q1, q0; \ -+ vmov.u32 d18[0], r7; \ -+ vmov q2, q0; \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ subs r4, r4, #1; \ -+ \ -+ do_aes_one##bits(e, mc, q1, q1, ##__VA_ARGS__); \ -+ \ -+ veor q1, q1, q2; \ -+ vst1.8 {q1}, [r1]!; /* store plaintext */ \ -+ \ -+ bne .Lxts_enc_loop_##bits; \ -+ b .Lxts_enc_done; -+ -+ CTR_XTS(128re, r0, r6) -+ CTR_XTS(192, r0, r6) -+ CTR_XTS(256, r0, r6) -+ -+#undef CTR_XTS -+ -+.Lxts_enc_done: -+ vst1.8 {q0}, [r3] /* store tweak */ -+ -+ CLEAR_REG(q0) -+ CLEAR_REG(q1) -+ CLEAR_REG(q2) -+ CLEAR_REG(q3) -+ CLEAR_REG(q8) -+ CLEAR_REG(q9) -+ CLEAR_REG(q10) -+ CLEAR_REG(q11) -+ CLEAR_REG(q12) -+ CLEAR_REG(q13) -+ CLEAR_REG(q14) -+ -+.Lxts_enc_skip: -+ pop {r4-r12,lr} -+ vpop {q4-q7} -+ bx lr -+.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce; -+ -+ -+/* -+ * void _gcry_aes_xts_dec_armv8_ce (const void *keysched, -+ * unsigned char *outbuf, -+ * const unsigned char *inbuf, -+ * unsigned char *iv, unsigned int nrounds); -+ */ -+ -+.align 3 -+.globl _gcry_aes_xts_dec_armv8_ce -+.type _gcry_aes_xts_dec_armv8_ce,%function; -+_gcry_aes_xts_dec_armv8_ce: -+ /* input: -+ * r0: keysched -+ * r1: outbuf -+ * r2: inbuf -+ * r3: iv -+ * %st+0: nblocks => r4 -+ * %st+4: nrounds => r5 -+ */ -+ -+ vpush {q4-q7} -+ push {r4-r12,lr} /* 4*16 + 4*10 = 104b */ -+ ldr r4, [sp, #(104+0)] -+ ldr r5, [sp, #(104+4)] -+ cmp r4, #0 -+ beq .Lxts_dec_skip -+ -+ cmp r5, #12 -+ -+ vld1.8 {q0}, [r3] /* load tweak */ -+ mov r7, #0x87; -+ -+ aes_preload_keys(r0, r6); -+ -+ beq .Lxts_dec_entry_192 -+ bhi .Lxts_dec_entry_256 -+ -+#define CTR_XTS(bits, ...) \ -+ .Lxts_dec_entry_##bits: \ -+ cmp r4, #4; \ -+ blo .Lxts_dec_loop_##bits; \ -+ \ -+ .Lxts_dec_loop4_##bits: \ -+ sub r4, r4, #4; \ -+ veor q9, q9, q9; \ -+ \ -+ vld1.8 {q1-q2}, [r2]!; /* load plaintext */ \ -+ veor q1, q1, q0; \ -+ cmp r4, #4; \ -+ vmov.u32 d18[0], r7; \ -+ vst1.8 {q0}, [r1]!; /* store tweak0 to temp */ \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ \ -+ vld1.8 {q3-q4}, [r2]!; /* load plaintext */ \ -+ veor q2, q2, q0; \ -+ vst1.8 {q0}, [r1]!; /* store tweak1 to temp */ \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ \ -+ veor q3, q3, q0; \ -+ vst1.8 {q0}, [r1]!; /* store tweak2 to temp */ \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ \ -+ veor q4, q4, q0; \ -+ vst1.8 {q0}, [r1]; /* store tweak3 to temp */ \ -+ sub r1, r1, #48; \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ \ -+ do_aes_4_##bits(d, imc, q1, q2, q3, q4, ##__VA_ARGS__); \ -+ \ -+ vld1.8 {q8-q9}, [r1]!; /* load tweak from temp */ \ -+ veor q1, q1, q8; \ -+ veor q2, q2, q9; \ -+ vld1.8 {q8-q9}, [r1]; /* load tweak from temp */ \ -+ sub r1, r1, #32; \ -+ veor q3, q3, q8; \ -+ veor q4, q4, q9; \ -+ vst1.8 {q1-q2}, [r1]!; /* store plaintext */ \ -+ vst1.8 {q3-q4}, [r1]!; /* store plaintext */ \ -+ \ -+ bhs .Lxts_dec_loop4_##bits; \ -+ cmp r4, #0; \ -+ beq .Lxts_dec_done; \ -+ \ -+ .Lxts_dec_loop_##bits: \ -+ \ -+ vld1.8 {q1}, [r2]!; /* load ciphertext */ \ -+ \ -+ veor q9, q9, q9; \ -+ veor q1, q1, q0; \ -+ vmov.u32 d18[0], r7; \ -+ vmov q2, q0; \ -+ \ -+ vshr.s64 d16, d1, #63; \ -+ vshr.u64 d17, d0, #63; \ -+ vadd.u64 q0, q0, q0; \ -+ vand d16, d16, d18; \ -+ veor q0, q0, q8; \ -+ subs r4, r4, #1; \ -+ \ -+ do_aes_one##bits(d, imc, q1, q1, ##__VA_ARGS__); \ -+ \ -+ veor q1, q1, q2; \ -+ vst1.8 {q1}, [r1]!; /* store plaintext */ \ -+ \ -+ bne .Lxts_dec_loop_##bits; \ -+ b .Lxts_dec_done; -+ -+ CTR_XTS(128re, r0, r6) -+ CTR_XTS(192, r0, r6) -+ CTR_XTS(256, r0, r6) -+ -+#undef CTR_XTS -+ -+.Lxts_dec_done: -+ vst1.8 {q0}, [r3] /* store tweak */ -+ -+ CLEAR_REG(q0) -+ CLEAR_REG(q1) -+ CLEAR_REG(q2) -+ CLEAR_REG(q3) -+ CLEAR_REG(q8) -+ CLEAR_REG(q9) -+ CLEAR_REG(q10) -+ CLEAR_REG(q11) -+ CLEAR_REG(q12) -+ CLEAR_REG(q13) -+ CLEAR_REG(q14) -+ -+.Lxts_dec_skip: -+ pop {r4-r12,lr} -+ vpop {q4-q7} -+ bx lr -+.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce; -+ -+ - /* - * u32 _gcry_aes_sbox4_armv8_ce(u32 in4b); - */ -diff -up libgcrypt-1.8.5/cipher/rijndael-armv8-aarch64-ce.S.aes-perf libgcrypt-1.8.5/cipher/rijndael-armv8-aarch64-ce.S ---- libgcrypt-1.8.5/cipher/rijndael-armv8-aarch64-ce.S.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rijndael-armv8-aarch64-ce.S 2020-04-22 18:29:41.674862153 +0200 -@@ -1157,8 +1157,8 @@ _gcry_aes_ocb_auth_armv8_ce: - * w6: nrounds => w7 - * w7: blkn => w12 - */ -- mov x12, x7 -- mov x7, x6 -+ mov w12, w7 -+ mov w7, w6 - mov x6, x5 - mov x5, x4 - mov x4, x3 -@@ -1277,6 +1277,284 @@ _gcry_aes_ocb_auth_armv8_ce: - - - /* -+ * void _gcry_aes_xts_enc_armv8_ce (const void *keysched, -+ * unsigned char *outbuf, -+ * const unsigned char *inbuf, -+ * unsigned char *tweak, -+ * size_t nblocks, -+ * unsigned int nrounds); -+ */ -+ -+.align 3 -+.globl _gcry_aes_xts_enc_armv8_ce -+.type _gcry_aes_xts_enc_armv8_ce,%function; -+_gcry_aes_xts_enc_armv8_ce: -+ /* input: -+ * r0: keysched -+ * r1: outbuf -+ * r2: inbuf -+ * r3: tweak -+ * x4: nblocks -+ * w5: nrounds -+ */ -+ -+ cbz x4, .Lxts_enc_skip -+ -+ /* load tweak */ -+ ld1 {v0.16b}, [x3] -+ -+ /* load gfmul mask */ -+ mov x6, #0x87 -+ mov x7, #0x01 -+ mov v16.D[0], x6 -+ mov v16.D[1], x7 -+ -+ aes_preload_keys(x0, w5); -+ -+ b.eq .Lxts_enc_entry_192 -+ b.hi .Lxts_enc_entry_256 -+ -+#define XTS_ENC(bits) \ -+ .Lxts_enc_entry_##bits: \ -+ cmp x4, #4; \ -+ b.lo .Lxts_enc_loop_##bits; \ -+ \ -+ .Lxts_enc_loop4_##bits: \ -+ \ -+ ext v4.16b, v0.16b, v0.16b, #8; \ -+ \ -+ sshr v2.2d, v4.2d, #63; \ -+ add v5.2d, v0.2d, v0.2d; \ -+ and v2.16b, v2.16b, v16.16b; \ -+ add v4.2d, v4.2d, v4.2d; \ -+ eor v5.16b, v5.16b, v2.16b; \ -+ \ -+ sshr v2.2d, v4.2d, #63; \ -+ add v6.2d, v5.2d, v5.2d; \ -+ and v2.16b, v2.16b, v16.16b; \ -+ add v4.2d, v4.2d, v4.2d; \ -+ eor v6.16b, v6.16b, v2.16b; \ -+ \ -+ sshr v2.2d, v4.2d, #63; \ -+ add v7.2d, v6.2d, v6.2d; \ -+ and v2.16b, v2.16b, v16.16b; \ -+ add v4.2d, v4.2d, v4.2d; \ -+ eor v7.16b, v7.16b, v2.16b; \ -+ \ -+ sshr v2.2d, v4.2d, #63; \ -+ add v3.2d, v7.2d, v7.2d; \ -+ and v2.16b, v2.16b, v16.16b; \ -+ add v4.2d, v4.2d, v4.2d; \ -+ eor v3.16b, v3.16b, v2.16b; \ -+ ld1 {v1.16b-v2.16b}, [x2], #32; /* load plaintext */ \ -+ st1 {v3.16b}, [x3]; \ -+ sub x4, x4, #4; \ -+ eor v1.16b, v1.16b, v0.16b; \ -+ \ -+ ld1 {v3.16b-v4.16b}, [x2], #32; /* load plaintext */ \ -+ cmp x4, #4; \ -+ eor v2.16b, v2.16b, v5.16b; \ -+ eor v3.16b, v3.16b, v6.16b; \ -+ eor v4.16b, v4.16b, v7.16b; \ -+ \ -+ do_aes_4_##bits(e, mc, v1, v2, v3, v4); \ -+ \ -+ eor v1.16b, v1.16b, v0.16b; \ -+ ld1 {v0.16b}, [x3]; \ -+ eor v2.16b, v2.16b, v5.16b; \ -+ eor v3.16b, v3.16b, v6.16b; \ -+ eor v4.16b, v4.16b, v7.16b; \ -+ st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \ -+ \ -+ b.hs .Lxts_enc_loop4_##bits; \ -+ CLEAR_REG(v3); \ -+ CLEAR_REG(v4); \ -+ CLEAR_REG(v5); \ -+ CLEAR_REG(v6); \ -+ CLEAR_REG(v7); \ -+ cbz x4, .Lxts_enc_done; \ -+ \ -+ .Lxts_enc_loop_##bits: \ -+ \ -+ ld1 {v1.16b}, [x2], #16; /* load plaintext */ \ -+ ext v3.16b, v0.16b, v0.16b, #8; \ -+ mov v2.16b, v0.16b; \ -+ sshr v3.2d, v3.2d, #63; \ -+ add v0.2d, v0.2d, v0.2d; \ -+ and v3.16b, v3.16b, v16.16b; \ -+ eor v1.16b, v1.16b, v2.16b; \ -+ eor v0.16b, v0.16b, v3.16b; \ -+ sub x4, x4, #1; \ -+ \ -+ do_aes_one##bits(e, mc, v1, v1); \ -+ \ -+ eor v1.16b, v1.16b, v2.16b; \ -+ st1 {v1.16b}, [x1], #16; /* store ciphertext */ \ -+ \ -+ cbnz x4, .Lxts_enc_loop_##bits; \ -+ b .Lxts_enc_done; -+ -+ XTS_ENC(128) -+ XTS_ENC(192) -+ XTS_ENC(256) -+ -+#undef XTS_ENC -+ -+.Lxts_enc_done: -+ aes_clear_keys(w5) -+ -+ st1 {v0.16b}, [x3] /* store tweak */ -+ -+ CLEAR_REG(v0) -+ CLEAR_REG(v1) -+ CLEAR_REG(v2) -+ -+.Lxts_enc_skip: -+ ret -+ -+.size _gcry_aes_xts_enc_armv8_ce,.-_gcry_aes_xts_enc_armv8_ce; -+ -+ -+/* -+ * void _gcry_aes_xts_dec_armv8_ce (const void *keysched, -+ * unsigned char *outbuf, -+ * const unsigned char *inbuf, -+ * unsigned char *tweak, -+ * size_t nblocks, -+ * unsigned int nrounds); -+ */ -+ -+.align 3 -+.globl _gcry_aes_xts_dec_armv8_ce -+.type _gcry_aes_xts_dec_armv8_ce,%function; -+_gcry_aes_xts_dec_armv8_ce: -+ /* input: -+ * r0: keysched -+ * r1: outbuf -+ * r2: inbuf -+ * r3: tweak -+ * x4: nblocks -+ * w5: nrounds -+ */ -+ -+ cbz x4, .Lxts_dec_skip -+ -+ /* load tweak */ -+ ld1 {v0.16b}, [x3] -+ -+ /* load gfmul mask */ -+ mov x6, #0x87 -+ mov x7, #0x01 -+ mov v16.D[0], x6 -+ mov v16.D[1], x7 -+ -+ aes_preload_keys(x0, w5); -+ -+ b.eq .Lxts_dec_entry_192 -+ b.hi .Lxts_dec_entry_256 -+ -+#define XTS_DEC(bits) \ -+ .Lxts_dec_entry_##bits: \ -+ cmp x4, #4; \ -+ b.lo .Lxts_dec_loop_##bits; \ -+ \ -+ .Lxts_dec_loop4_##bits: \ -+ \ -+ ext v4.16b, v0.16b, v0.16b, #8; \ -+ \ -+ sshr v2.2d, v4.2d, #63; \ -+ add v5.2d, v0.2d, v0.2d; \ -+ and v2.16b, v2.16b, v16.16b; \ -+ add v4.2d, v4.2d, v4.2d; \ -+ eor v5.16b, v5.16b, v2.16b; \ -+ \ -+ sshr v2.2d, v4.2d, #63; \ -+ add v6.2d, v5.2d, v5.2d; \ -+ and v2.16b, v2.16b, v16.16b; \ -+ add v4.2d, v4.2d, v4.2d; \ -+ eor v6.16b, v6.16b, v2.16b; \ -+ \ -+ sshr v2.2d, v4.2d, #63; \ -+ add v7.2d, v6.2d, v6.2d; \ -+ and v2.16b, v2.16b, v16.16b; \ -+ add v4.2d, v4.2d, v4.2d; \ -+ eor v7.16b, v7.16b, v2.16b; \ -+ \ -+ sshr v2.2d, v4.2d, #63; \ -+ add v3.2d, v7.2d, v7.2d; \ -+ and v2.16b, v2.16b, v16.16b; \ -+ add v4.2d, v4.2d, v4.2d; \ -+ eor v3.16b, v3.16b, v2.16b; \ -+ ld1 {v1.16b-v2.16b}, [x2], #32; /* load plaintext */ \ -+ st1 {v3.16b}, [x3]; \ -+ sub x4, x4, #4; \ -+ eor v1.16b, v1.16b, v0.16b; \ -+ \ -+ ld1 {v3.16b-v4.16b}, [x2], #32; /* load plaintext */ \ -+ cmp x4, #4; \ -+ eor v2.16b, v2.16b, v5.16b; \ -+ eor v3.16b, v3.16b, v6.16b; \ -+ eor v4.16b, v4.16b, v7.16b; \ -+ \ -+ do_aes_4_##bits(d, imc, v1, v2, v3, v4); \ -+ \ -+ eor v1.16b, v1.16b, v0.16b; \ -+ ld1 {v0.16b}, [x3]; \ -+ eor v2.16b, v2.16b, v5.16b; \ -+ eor v3.16b, v3.16b, v6.16b; \ -+ eor v4.16b, v4.16b, v7.16b; \ -+ st1 {v1.16b-v4.16b}, [x1], #64; /* store plaintext */ \ -+ \ -+ b.hs .Lxts_dec_loop4_##bits; \ -+ CLEAR_REG(v3); \ -+ CLEAR_REG(v4); \ -+ CLEAR_REG(v5); \ -+ CLEAR_REG(v6); \ -+ CLEAR_REG(v7); \ -+ cbz x4, .Lxts_dec_done; \ -+ \ -+ .Lxts_dec_loop_##bits: \ -+ \ -+ ld1 {v1.16b}, [x2], #16; /* load plaintext */ \ -+ ext v3.16b, v0.16b, v0.16b, #8; \ -+ mov v2.16b, v0.16b; \ -+ sshr v3.2d, v3.2d, #63; \ -+ add v0.2d, v0.2d, v0.2d; \ -+ and v3.16b, v3.16b, v16.16b; \ -+ eor v1.16b, v1.16b, v2.16b; \ -+ eor v0.16b, v0.16b, v3.16b; \ -+ sub x4, x4, #1; \ -+ \ -+ do_aes_one##bits(d, imc, v1, v1); \ -+ \ -+ eor v1.16b, v1.16b, v2.16b; \ -+ st1 {v1.16b}, [x1], #16; /* store ciphertext */ \ -+ \ -+ cbnz x4, .Lxts_dec_loop_##bits; \ -+ b .Lxts_dec_done; -+ -+ XTS_DEC(128) -+ XTS_DEC(192) -+ XTS_DEC(256) -+ -+#undef XTS_DEC -+ -+.Lxts_dec_done: -+ aes_clear_keys(w5) -+ -+ st1 {v0.16b}, [x3] /* store tweak */ -+ -+ CLEAR_REG(v0) -+ CLEAR_REG(v1) -+ CLEAR_REG(v2) -+ -+.Lxts_dec_skip: -+ ret -+ -+.size _gcry_aes_xts_dec_armv8_ce,.-_gcry_aes_xts_dec_armv8_ce; -+ -+ -+/* - * u32 _gcry_aes_sbox4_armv8_ce(u32 in4b); - */ - .align 3 -diff -up libgcrypt-1.8.5/cipher/rijndael-armv8-ce.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-armv8-ce.c ---- libgcrypt-1.8.5/cipher/rijndael-armv8-ce.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rijndael-armv8-ce.c 2020-04-22 18:29:41.675862134 +0200 -@@ -101,6 +101,16 @@ extern void _gcry_aes_ocb_auth_armv8_ce - size_t nblocks, - unsigned int nrounds, - unsigned int blkn); -+extern void _gcry_aes_xts_enc_armv8_ce (const void *keysched, -+ unsigned char *outbuf, -+ const unsigned char *inbuf, -+ unsigned char *tweak, -+ size_t nblocks, unsigned int nrounds); -+extern void _gcry_aes_xts_dec_armv8_ce (const void *keysched, -+ unsigned char *outbuf, -+ const unsigned char *inbuf, -+ unsigned char *tweak, -+ size_t nblocks, unsigned int nrounds); - - typedef void (*ocb_crypt_fn_t) (const void *keysched, unsigned char *outbuf, - const unsigned char *inbuf, -@@ -108,6 +118,11 @@ typedef void (*ocb_crypt_fn_t) (const vo - unsigned char *L_table, size_t nblocks, - unsigned int nrounds, unsigned int blkn); - -+typedef void (*xts_crypt_fn_t) (const void *keysched, unsigned char *outbuf, -+ const unsigned char *inbuf, -+ unsigned char *tweak, size_t nblocks, -+ unsigned int nrounds); -+ - void - _gcry_aes_armv8_ce_setkey (RIJNDAEL_context *ctx, const byte *key) - { -@@ -269,8 +284,8 @@ _gcry_aes_armv8_ce_decrypt (const RIJNDA - } - - void --_gcry_aes_armv8_ce_cbc_enc (const RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -+_gcry_aes_armv8_ce_cbc_enc (const RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks, int cbc_mac) - { - const void *keysched = ctx->keyschenc32; -@@ -281,19 +296,25 @@ _gcry_aes_armv8_ce_cbc_enc (const RIJNDA - } - - void --_gcry_aes_armv8_ce_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -+_gcry_aes_armv8_ce_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks) - { - const void *keysched = ctx->keyschdec32; - unsigned int nrounds = ctx->rounds; - -+ if ( !ctx->decryption_prepared ) -+ { -+ _gcry_aes_armv8_ce_prepare_decryption ( ctx ); -+ ctx->decryption_prepared = 1; -+ } -+ - _gcry_aes_cbc_dec_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); - } - - void --_gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -+_gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks) - { - const void *keysched = ctx->keyschenc32; -@@ -303,8 +324,8 @@ _gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_con - } - - void --_gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -+_gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks) - { - const void *keysched = ctx->keyschenc32; -@@ -314,8 +335,8 @@ _gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_con - } - - void --_gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -+_gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, - size_t nblocks) - { - const void *keysched = ctx->keyschenc32; -@@ -324,7 +345,7 @@ _gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_con - _gcry_aes_ctr_enc_armv8_ce(keysched, outbuf, inbuf, iv, nblocks, nrounds); - } - --void -+size_t - _gcry_aes_armv8_ce_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, - const void *inbuf_arg, size_t nblocks, - int encrypt) -@@ -338,13 +359,21 @@ _gcry_aes_armv8_ce_ocb_crypt (gcry_ciphe - unsigned int nrounds = ctx->rounds; - u64 blkn = c->u_mode.ocb.data_nblocks; - -+ if ( !encrypt && !ctx->decryption_prepared ) -+ { -+ _gcry_aes_armv8_ce_prepare_decryption ( ctx ); -+ ctx->decryption_prepared = 1; -+ } -+ - c->u_mode.ocb.data_nblocks = blkn + nblocks; - - crypt_fn(keysched, outbuf, inbuf, c->u_iv.iv, c->u_ctr.ctr, - c->u_mode.ocb.L[0], nblocks, nrounds, (unsigned int)blkn); -+ -+ return 0; - } - --void -+size_t - _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, void *abuf_arg, - size_t nblocks) - { -@@ -359,6 +388,27 @@ _gcry_aes_armv8_ce_ocb_auth (gcry_cipher - _gcry_aes_ocb_auth_armv8_ce(keysched, abuf, c->u_mode.ocb.aad_offset, - c->u_mode.ocb.aad_sum, c->u_mode.ocb.L[0], - nblocks, nrounds, (unsigned int)blkn); -+ -+ return 0; -+} -+ -+void -+_gcry_aes_armv8_ce_xts_crypt (RIJNDAEL_context *ctx, unsigned char *tweak, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks, int encrypt) -+{ -+ const void *keysched = encrypt ? ctx->keyschenc32 : ctx->keyschdec32; -+ xts_crypt_fn_t crypt_fn = encrypt ? _gcry_aes_xts_enc_armv8_ce -+ : _gcry_aes_xts_dec_armv8_ce; -+ unsigned int nrounds = ctx->rounds; -+ -+ if ( !encrypt && !ctx->decryption_prepared ) -+ { -+ _gcry_aes_armv8_ce_prepare_decryption ( ctx ); -+ ctx->decryption_prepared = 1; -+ } -+ -+ crypt_fn(keysched, outbuf, inbuf, tweak, nblocks, nrounds); - } - - #endif /* USE_ARM_CE */ -diff -up libgcrypt-1.8.5/cipher/rijndael.c.aes-perf libgcrypt-1.8.5/cipher/rijndael.c ---- libgcrypt-1.8.5/cipher/rijndael.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rijndael.c 2020-04-22 18:29:41.676862114 +0200 -@@ -77,32 +77,29 @@ extern unsigned int _gcry_aes_aesni_encr - extern unsigned int _gcry_aes_aesni_decrypt (const RIJNDAEL_context *ctx, - unsigned char *dst, - const unsigned char *src); --extern void _gcry_aes_aesni_cfb_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_aesni_cbc_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks, -- int cbc_mac); --extern void _gcry_aes_aesni_ctr_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *ctr, size_t nblocks); --extern void _gcry_aes_aesni_cfb_dec (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_aesni_cbc_dec (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, -- const void *inbuf_arg, size_t nblocks, -- int encrypt); --extern void _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, -- size_t nblocks); -+extern void _gcry_aes_aesni_cfb_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_aesni_cbc_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, int cbc_mac); -+extern void _gcry_aes_aesni_ctr_enc (void *context, unsigned char *ctr, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_aesni_cfb_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_aesni_cbc_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern size_t _gcry_aes_aesni_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, -+ const void *inbuf_arg, size_t nblocks, -+ int encrypt); -+extern size_t _gcry_aes_aesni_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_aesni_xts_crypt (void *context, unsigned char *tweak, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, int encrypt); - #endif - - #ifdef USE_SSSE3 -@@ -116,32 +113,27 @@ extern unsigned int _gcry_aes_ssse3_encr - extern unsigned int _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, - unsigned char *dst, - const unsigned char *src); --extern void _gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks, -+extern void _gcry_aes_ssse3_cfb_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ssse3_cbc_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, - int cbc_mac); --extern void _gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *ctr, size_t nblocks); --extern void _gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_ssse3_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, -- const void *inbuf_arg, size_t nblocks, -- int encrypt); --extern void _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, -- size_t nblocks); -+extern void _gcry_aes_ssse3_ctr_enc (void *context, unsigned char *ctr, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ssse3_cfb_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ssse3_cbc_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern size_t _gcry_aes_ssse3_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, -+ const void *inbuf_arg, size_t nblocks, -+ int encrypt); -+extern size_t _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, -+ size_t nblocks); - #endif - - #ifdef USE_PADLOCK -@@ -180,34 +172,110 @@ extern unsigned int _gcry_aes_armv8_ce_d - unsigned char *dst, - const unsigned char *src); - --extern void _gcry_aes_armv8_ce_cfb_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_armv8_ce_cbc_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks, -+extern void _gcry_aes_armv8_ce_cfb_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_armv8_ce_cbc_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, - int cbc_mac); --extern void _gcry_aes_armv8_ce_ctr_enc (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *ctr, size_t nblocks); --extern void _gcry_aes_armv8_ce_cfb_dec (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_armv8_ce_cbc_dec (RIJNDAEL_context *ctx, -- unsigned char *outbuf, -- const unsigned char *inbuf, -- unsigned char *iv, size_t nblocks); --extern void _gcry_aes_armv8_ce_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, -- const void *inbuf_arg, size_t nblocks, -- int encrypt); --extern void _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, -- const void *abuf_arg, size_t nblocks); -+extern void _gcry_aes_armv8_ce_ctr_enc (void *context, unsigned char *ctr, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_armv8_ce_cfb_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_armv8_ce_cbc_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern size_t _gcry_aes_armv8_ce_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, -+ const void *inbuf_arg, size_t nblocks, -+ int encrypt); -+extern size_t _gcry_aes_armv8_ce_ocb_auth (gcry_cipher_hd_t c, -+ const void *abuf_arg, size_t nblocks); -+extern void _gcry_aes_armv8_ce_xts_crypt (void *context, unsigned char *tweak, -+ void *outbuf_arg, -+ const void *inbuf_arg, -+ size_t nblocks, int encrypt); - #endif /*USE_ARM_ASM*/ - -+#ifdef USE_PPC_CRYPTO -+/* PowerPC Crypto implementations of AES */ -+extern void _gcry_aes_ppc8_setkey(RIJNDAEL_context *ctx, const byte *key); -+extern void _gcry_aes_ppc8_prepare_decryption(RIJNDAEL_context *ctx); -+ -+extern unsigned int _gcry_aes_ppc8_encrypt(const RIJNDAEL_context *ctx, -+ unsigned char *dst, -+ const unsigned char *src); -+extern unsigned int _gcry_aes_ppc8_decrypt(const RIJNDAEL_context *ctx, -+ unsigned char *dst, -+ const unsigned char *src); -+ -+extern void _gcry_aes_ppc8_cfb_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ppc8_cbc_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, int cbc_mac); -+extern void _gcry_aes_ppc8_ctr_enc (void *context, unsigned char *ctr, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ppc8_cfb_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ppc8_cbc_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+ -+extern size_t _gcry_aes_ppc8_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, -+ const void *inbuf_arg, size_t nblocks, -+ int encrypt); -+extern size_t _gcry_aes_ppc8_ocb_auth (gcry_cipher_hd_t c, -+ const void *abuf_arg, size_t nblocks); -+ -+extern void _gcry_aes_ppc8_xts_crypt (void *context, unsigned char *tweak, -+ void *outbuf_arg, -+ const void *inbuf_arg, -+ size_t nblocks, int encrypt); -+#endif /*USE_PPC_CRYPTO*/ -+ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+/* Power9 little-endian crypto implementations of AES */ -+extern unsigned int _gcry_aes_ppc9le_encrypt(const RIJNDAEL_context *ctx, -+ unsigned char *dst, -+ const unsigned char *src); -+extern unsigned int _gcry_aes_ppc9le_decrypt(const RIJNDAEL_context *ctx, -+ unsigned char *dst, -+ const unsigned char *src); -+ -+extern void _gcry_aes_ppc9le_cfb_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ppc9le_cbc_enc (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, int cbc_mac); -+extern void _gcry_aes_ppc9le_ctr_enc (void *context, unsigned char *ctr, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ppc9le_cfb_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+extern void _gcry_aes_ppc9le_cbc_dec (void *context, unsigned char *iv, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks); -+ -+extern size_t _gcry_aes_ppc9le_ocb_crypt (gcry_cipher_hd_t c, void *outbuf_arg, -+ const void *inbuf_arg, size_t nblocks, -+ int encrypt); -+extern size_t _gcry_aes_ppc9le_ocb_auth (gcry_cipher_hd_t c, -+ const void *abuf_arg, size_t nblocks); -+ -+extern void _gcry_aes_ppc9le_xts_crypt (void *context, unsigned char *tweak, -+ void *outbuf_arg, -+ const void *inbuf_arg, -+ size_t nblocks, int encrypt); -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+ - static unsigned int do_encrypt (const RIJNDAEL_context *ctx, unsigned char *bx, - const unsigned char *ax); - static unsigned int do_decrypt (const RIJNDAEL_context *ctx, unsigned char *bx, -@@ -260,7 +328,8 @@ static void prefetch_dec(void) - - /* Perform the key setup. */ - static gcry_err_code_t --do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen) -+do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen, -+ gcry_cipher_hd_t hd) - { - static int initialized = 0; - static const char *selftest_failed = 0; -@@ -268,7 +337,7 @@ do_setkey (RIJNDAEL_context *ctx, const - int i,j, r, t, rconpointer = 0; - int KC; - #if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3) \ -- || defined(USE_ARM_CE) -+ || defined(USE_ARM_CE) || defined(USE_PPC_CRYPTO) - unsigned int hwfeatures; - #endif - -@@ -310,7 +379,7 @@ do_setkey (RIJNDAEL_context *ctx, const - ctx->rounds = rounds; - - #if defined(USE_AESNI) || defined(USE_PADLOCK) || defined(USE_SSSE3) \ -- || defined(USE_ARM_CE) -+ || defined(USE_ARM_CE) || defined(USE_PPC_CRYPTO) - hwfeatures = _gcry_get_hw_features (); - #endif - -@@ -327,6 +396,12 @@ do_setkey (RIJNDAEL_context *ctx, const - #ifdef USE_ARM_CE - ctx->use_arm_ce = 0; - #endif -+#ifdef USE_PPC_CRYPTO -+ ctx->use_ppc_crypto = 0; -+#endif -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ ctx->use_ppc9le_crypto = 0; -+#endif - - if (0) - { -@@ -340,6 +415,17 @@ do_setkey (RIJNDAEL_context *ctx, const - ctx->prefetch_enc_fn = NULL; - ctx->prefetch_dec_fn = NULL; - ctx->use_aesni = 1; -+ if (hd) -+ { -+ hd->bulk.cfb_enc = _gcry_aes_aesni_cfb_enc; -+ hd->bulk.cfb_dec = _gcry_aes_aesni_cfb_dec; -+ hd->bulk.cbc_enc = _gcry_aes_aesni_cbc_enc; -+ hd->bulk.cbc_dec = _gcry_aes_aesni_cbc_dec; -+ hd->bulk.ctr_enc = _gcry_aes_aesni_ctr_enc; -+ hd->bulk.ocb_crypt = _gcry_aes_aesni_ocb_crypt; -+ hd->bulk.ocb_auth = _gcry_aes_aesni_ocb_auth; -+ hd->bulk.xts_crypt = _gcry_aes_aesni_xts_crypt; -+ } - } - #endif - #ifdef USE_PADLOCK -@@ -361,6 +447,16 @@ do_setkey (RIJNDAEL_context *ctx, const - ctx->prefetch_enc_fn = NULL; - ctx->prefetch_dec_fn = NULL; - ctx->use_ssse3 = 1; -+ if (hd) -+ { -+ hd->bulk.cfb_enc = _gcry_aes_ssse3_cfb_enc; -+ hd->bulk.cfb_dec = _gcry_aes_ssse3_cfb_dec; -+ hd->bulk.cbc_enc = _gcry_aes_ssse3_cbc_enc; -+ hd->bulk.cbc_dec = _gcry_aes_ssse3_cbc_dec; -+ hd->bulk.ctr_enc = _gcry_aes_ssse3_ctr_enc; -+ hd->bulk.ocb_crypt = _gcry_aes_ssse3_ocb_crypt; -+ hd->bulk.ocb_auth = _gcry_aes_ssse3_ocb_auth; -+ } - } - #endif - #ifdef USE_ARM_CE -@@ -371,6 +467,60 @@ do_setkey (RIJNDAEL_context *ctx, const - ctx->prefetch_enc_fn = NULL; - ctx->prefetch_dec_fn = NULL; - ctx->use_arm_ce = 1; -+ if (hd) -+ { -+ hd->bulk.cfb_enc = _gcry_aes_armv8_ce_cfb_enc; -+ hd->bulk.cfb_dec = _gcry_aes_armv8_ce_cfb_dec; -+ hd->bulk.cbc_enc = _gcry_aes_armv8_ce_cbc_enc; -+ hd->bulk.cbc_dec = _gcry_aes_armv8_ce_cbc_dec; -+ hd->bulk.ctr_enc = _gcry_aes_armv8_ce_ctr_enc; -+ hd->bulk.ocb_crypt = _gcry_aes_armv8_ce_ocb_crypt; -+ hd->bulk.ocb_auth = _gcry_aes_armv8_ce_ocb_auth; -+ hd->bulk.xts_crypt = _gcry_aes_armv8_ce_xts_crypt; -+ } -+ } -+#endif -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if ((hwfeatures & HWF_PPC_VCRYPTO) && (hwfeatures & HWF_PPC_ARCH_3_00)) -+ { -+ ctx->encrypt_fn = _gcry_aes_ppc9le_encrypt; -+ ctx->decrypt_fn = _gcry_aes_ppc9le_decrypt; -+ ctx->prefetch_enc_fn = NULL; -+ ctx->prefetch_dec_fn = NULL; -+ ctx->use_ppc_crypto = 1; /* same key-setup as USE_PPC_CRYPTO */ -+ ctx->use_ppc9le_crypto = 1; -+ if (hd) -+ { -+ hd->bulk.cfb_enc = _gcry_aes_ppc9le_cfb_enc; -+ hd->bulk.cfb_dec = _gcry_aes_ppc9le_cfb_dec; -+ hd->bulk.cbc_enc = _gcry_aes_ppc9le_cbc_enc; -+ hd->bulk.cbc_dec = _gcry_aes_ppc9le_cbc_dec; -+ hd->bulk.ctr_enc = _gcry_aes_ppc9le_ctr_enc; -+ hd->bulk.ocb_crypt = _gcry_aes_ppc9le_ocb_crypt; -+ hd->bulk.ocb_auth = _gcry_aes_ppc9le_ocb_auth; -+ hd->bulk.xts_crypt = _gcry_aes_ppc9le_xts_crypt; -+ } -+ } -+#endif -+#ifdef USE_PPC_CRYPTO -+ else if (hwfeatures & HWF_PPC_VCRYPTO) -+ { -+ ctx->encrypt_fn = _gcry_aes_ppc8_encrypt; -+ ctx->decrypt_fn = _gcry_aes_ppc8_decrypt; -+ ctx->prefetch_enc_fn = NULL; -+ ctx->prefetch_dec_fn = NULL; -+ ctx->use_ppc_crypto = 1; -+ if (hd) -+ { -+ hd->bulk.cfb_enc = _gcry_aes_ppc8_cfb_enc; -+ hd->bulk.cfb_dec = _gcry_aes_ppc8_cfb_dec; -+ hd->bulk.cbc_enc = _gcry_aes_ppc8_cbc_enc; -+ hd->bulk.cbc_dec = _gcry_aes_ppc8_cbc_dec; -+ hd->bulk.ctr_enc = _gcry_aes_ppc8_ctr_enc; -+ hd->bulk.ocb_crypt = _gcry_aes_ppc8_ocb_crypt; -+ hd->bulk.ocb_auth = _gcry_aes_ppc8_ocb_auth; -+ hd->bulk.xts_crypt = _gcry_aes_ppc8_xts_crypt; -+ } - } - #endif - else -@@ -399,6 +549,10 @@ do_setkey (RIJNDAEL_context *ctx, const - else if (ctx->use_arm_ce) - _gcry_aes_armv8_ce_setkey (ctx, key); - #endif -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ _gcry_aes_ppc8_setkey (ctx, key); -+#endif - else - { - const byte *sbox = ((const byte *)encT) + 1; -@@ -503,10 +657,11 @@ do_setkey (RIJNDAEL_context *ctx, const - - - static gcry_err_code_t --rijndael_setkey (void *context, const byte *key, const unsigned keylen) -+rijndael_setkey (void *context, const byte *key, const unsigned keylen, -+ gcry_cipher_hd_t hd) - { - RIJNDAEL_context *ctx = context; -- return do_setkey (ctx, key, keylen); -+ return do_setkey (ctx, key, keylen, hd); - } - - -@@ -535,7 +690,19 @@ prepare_decryption( RIJNDAEL_context *ct - { - _gcry_aes_armv8_ce_prepare_decryption (ctx); - } --#endif /*USE_SSSE3*/ -+#endif /*USE_ARM_CE*/ -+#ifdef USE_ARM_CE -+ else if (ctx->use_arm_ce) -+ { -+ _gcry_aes_armv8_ce_prepare_decryption (ctx); -+ } -+#endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ _gcry_aes_ppc8_prepare_decryption (ctx); -+ } -+#endif - #ifdef USE_PADLOCK - else if (ctx->use_padlock) - { -@@ -790,42 +957,56 @@ _gcry_aes_cfb_enc (void *context, unsign - const unsigned char *inbuf = inbuf_arg; - unsigned int burn_depth = 0; - -- if (ctx->prefetch_enc_fn) -- ctx->prefetch_enc_fn(); -- - if (0) - ; - #ifdef USE_AESNI - else if (ctx->use_aesni) - { -- _gcry_aes_aesni_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_aesni_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_AESNI*/ - #ifdef USE_SSSE3 - else if (ctx->use_ssse3) - { -- _gcry_aes_ssse3_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_ssse3_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_SSSE3*/ - #ifdef USE_ARM_CE - else if (ctx->use_arm_ce) - { -- _gcry_aes_armv8_ce_cfb_enc (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_armv8_ce_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if (ctx->use_ppc9le_crypto) -+ { -+ _gcry_aes_ppc9le_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ _gcry_aes_ppc8_cfb_enc (ctx, iv, outbuf, inbuf, nblocks); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO*/ - else - { - rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; - -+ if (ctx->prefetch_enc_fn) -+ ctx->prefetch_enc_fn(); -+ - for ( ;nblocks; nblocks-- ) - { - /* Encrypt the IV. */ - burn_depth = encrypt_fn (ctx, iv, iv); - /* XOR the input with the IV and store input into IV. */ -- buf_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); -+ cipher_block_xor_2dst(outbuf, iv, inbuf, BLOCKSIZE); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } -@@ -851,41 +1032,55 @@ _gcry_aes_cbc_enc (void *context, unsign - unsigned char *last_iv; - unsigned int burn_depth = 0; - -- if (ctx->prefetch_enc_fn) -- ctx->prefetch_enc_fn(); -- - if (0) - ; - #ifdef USE_AESNI - else if (ctx->use_aesni) - { -- _gcry_aes_aesni_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac); -- burn_depth = 0; -+ _gcry_aes_aesni_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); -+ return; - } - #endif /*USE_AESNI*/ - #ifdef USE_SSSE3 - else if (ctx->use_ssse3) - { -- _gcry_aes_ssse3_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac); -- burn_depth = 0; -+ _gcry_aes_ssse3_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); -+ return; - } - #endif /*USE_SSSE3*/ - #ifdef USE_ARM_CE - else if (ctx->use_arm_ce) - { -- _gcry_aes_armv8_ce_cbc_enc (ctx, outbuf, inbuf, iv, nblocks, cbc_mac); -- burn_depth = 0; -+ _gcry_aes_armv8_ce_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); -+ return; - } - #endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if (ctx->use_ppc9le_crypto) -+ { -+ _gcry_aes_ppc9le_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ _gcry_aes_ppc8_cbc_enc (ctx, iv, outbuf, inbuf, nblocks, cbc_mac); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO*/ - else - { - rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; - -+ if (ctx->prefetch_enc_fn) -+ ctx->prefetch_enc_fn(); -+ - last_iv = iv; - - for ( ;nblocks; nblocks-- ) - { -- buf_xor(outbuf, inbuf, last_iv, BLOCKSIZE); -+ cipher_block_xor(outbuf, inbuf, last_iv, BLOCKSIZE); - - burn_depth = encrypt_fn (ctx, outbuf, outbuf); - -@@ -896,7 +1091,7 @@ _gcry_aes_cbc_enc (void *context, unsign - } - - if (last_iv != iv) -- buf_cpy (iv, last_iv, BLOCKSIZE); -+ cipher_block_cpy (iv, last_iv, BLOCKSIZE); - } - - if (burn_depth) -@@ -920,43 +1115,57 @@ _gcry_aes_ctr_enc (void *context, unsign - unsigned int burn_depth = 0; - int i; - -- if (ctx->prefetch_enc_fn) -- ctx->prefetch_enc_fn(); -- - if (0) - ; - #ifdef USE_AESNI - else if (ctx->use_aesni) - { -- _gcry_aes_aesni_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks); -- burn_depth = 0; -+ _gcry_aes_aesni_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_AESNI*/ - #ifdef USE_SSSE3 - else if (ctx->use_ssse3) - { -- _gcry_aes_ssse3_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks); -- burn_depth = 0; -+ _gcry_aes_ssse3_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_SSSE3*/ - #ifdef USE_ARM_CE - else if (ctx->use_arm_ce) - { -- _gcry_aes_armv8_ce_ctr_enc (ctx, outbuf, inbuf, ctr, nblocks); -- burn_depth = 0; -+ _gcry_aes_armv8_ce_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if (ctx->use_ppc9le_crypto) -+ { -+ _gcry_aes_ppc9le_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ _gcry_aes_ppc8_ctr_enc (ctx, ctr, outbuf, inbuf, nblocks); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO*/ - else - { - union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } tmp; - rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; - -+ if (ctx->prefetch_enc_fn) -+ ctx->prefetch_enc_fn(); -+ - for ( ;nblocks; nblocks-- ) - { - /* Encrypt the counter. */ - burn_depth = encrypt_fn (ctx, tmp.x1, ctr); - /* XOR the input with the encrypted counter and store in output. */ -- buf_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE); -+ cipher_block_xor(outbuf, tmp.x1, inbuf, BLOCKSIZE); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - /* Increment the counter. */ -@@ -1187,40 +1396,54 @@ _gcry_aes_cfb_dec (void *context, unsign - const unsigned char *inbuf = inbuf_arg; - unsigned int burn_depth = 0; - -- if (ctx->prefetch_enc_fn) -- ctx->prefetch_enc_fn(); -- - if (0) - ; - #ifdef USE_AESNI - else if (ctx->use_aesni) - { -- _gcry_aes_aesni_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_aesni_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_AESNI*/ - #ifdef USE_SSSE3 - else if (ctx->use_ssse3) - { -- _gcry_aes_ssse3_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_ssse3_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_SSSE3*/ - #ifdef USE_ARM_CE - else if (ctx->use_arm_ce) - { -- _gcry_aes_armv8_ce_cfb_dec (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_armv8_ce_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if (ctx->use_ppc9le_crypto) -+ { -+ _gcry_aes_ppc9le_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ _gcry_aes_ppc8_cfb_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO*/ - else - { - rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; - -+ if (ctx->prefetch_enc_fn) -+ ctx->prefetch_enc_fn(); -+ - for ( ;nblocks; nblocks-- ) - { - burn_depth = encrypt_fn (ctx, iv, iv); -- buf_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); -+ cipher_block_xor_n_copy(outbuf, iv, inbuf, BLOCKSIZE); - outbuf += BLOCKSIZE; - inbuf += BLOCKSIZE; - } -@@ -1245,39 +1468,53 @@ _gcry_aes_cbc_dec (void *context, unsign - const unsigned char *inbuf = inbuf_arg; - unsigned int burn_depth = 0; - -- check_decryption_preparation (ctx); -- -- if (ctx->prefetch_dec_fn) -- ctx->prefetch_dec_fn(); -- - if (0) - ; - #ifdef USE_AESNI - else if (ctx->use_aesni) - { -- _gcry_aes_aesni_cbc_dec (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_aesni_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_AESNI*/ - #ifdef USE_SSSE3 - else if (ctx->use_ssse3) - { -- _gcry_aes_ssse3_cbc_dec (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_ssse3_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_SSSE3*/ - #ifdef USE_ARM_CE - else if (ctx->use_arm_ce) - { -- _gcry_aes_armv8_ce_cbc_dec (ctx, outbuf, inbuf, iv, nblocks); -- burn_depth = 0; -+ _gcry_aes_armv8_ce_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; - } - #endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if (ctx->use_ppc9le_crypto) -+ { -+ _gcry_aes_ppc9le_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ _gcry_aes_ppc8_cbc_dec (ctx, iv, outbuf, inbuf, nblocks); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO*/ - else - { - unsigned char savebuf[BLOCKSIZE] ATTR_ALIGNED_16; - rijndael_cryptfn_t decrypt_fn = ctx->decrypt_fn; - -+ check_decryption_preparation (ctx); -+ -+ if (ctx->prefetch_dec_fn) -+ ctx->prefetch_dec_fn(); -+ - for ( ;nblocks; nblocks-- ) - { - /* INBUF is needed later and it may be identical to OUTBUF, so store -@@ -1285,7 +1522,7 @@ _gcry_aes_cbc_dec (void *context, unsign - - burn_depth = decrypt_fn (ctx, savebuf, inbuf); - -- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE); -+ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, BLOCKSIZE); - inbuf += BLOCKSIZE; - outbuf += BLOCKSIZE; - } -@@ -1309,62 +1546,61 @@ _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, - const unsigned char *inbuf = inbuf_arg; - unsigned int burn_depth = 0; - -- if (encrypt) -- { -- if (ctx->prefetch_enc_fn) -- ctx->prefetch_enc_fn(); -- } -- else -- { -- check_decryption_preparation (ctx); -- -- if (ctx->prefetch_dec_fn) -- ctx->prefetch_dec_fn(); -- } -- - if (0) - ; - #ifdef USE_AESNI - else if (ctx->use_aesni) - { -- _gcry_aes_aesni_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); -- burn_depth = 0; -+ return _gcry_aes_aesni_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); - } - #endif /*USE_AESNI*/ - #ifdef USE_SSSE3 - else if (ctx->use_ssse3) - { -- _gcry_aes_ssse3_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); -- burn_depth = 0; -+ return _gcry_aes_ssse3_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); - } - #endif /*USE_SSSE3*/ - #ifdef USE_ARM_CE - else if (ctx->use_arm_ce) - { -- _gcry_aes_armv8_ce_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); -- burn_depth = 0; -+ return _gcry_aes_armv8_ce_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); - } - #endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if (ctx->use_ppc9le_crypto) -+ { -+ return _gcry_aes_ppc9le_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); -+ } -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ return _gcry_aes_ppc8_ocb_crypt (c, outbuf, inbuf, nblocks, encrypt); -+ } -+#endif /*USE_PPC_CRYPTO*/ - else if (encrypt) - { - union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; - rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; - -+ if (ctx->prefetch_enc_fn) -+ ctx->prefetch_enc_fn(); -+ - for ( ;nblocks; nblocks-- ) - { - u64 i = ++c->u_mode.ocb.data_nblocks; - const unsigned char *l = ocb_get_l(c, i); - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -- buf_xor_1 (c->u_iv.iv, l, BLOCKSIZE); -- buf_cpy (l_tmp.x1, inbuf, BLOCKSIZE); -+ cipher_block_xor_1 (c->u_iv.iv, l, BLOCKSIZE); -+ cipher_block_cpy (l_tmp.x1, inbuf, BLOCKSIZE); - /* Checksum_i = Checksum_{i-1} xor P_i */ -- buf_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); -+ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); - /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ -- buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); -+ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); - burn_depth = encrypt_fn (ctx, l_tmp.x1, l_tmp.x1); -- buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); -- buf_cpy (outbuf, l_tmp.x1, BLOCKSIZE); -+ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); -+ cipher_block_cpy (outbuf, l_tmp.x1, BLOCKSIZE); - - inbuf += BLOCKSIZE; - outbuf += BLOCKSIZE; -@@ -1375,21 +1611,26 @@ _gcry_aes_ocb_crypt (gcry_cipher_hd_t c, - union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; - rijndael_cryptfn_t decrypt_fn = ctx->decrypt_fn; - -+ check_decryption_preparation (ctx); -+ -+ if (ctx->prefetch_dec_fn) -+ ctx->prefetch_dec_fn(); -+ - for ( ;nblocks; nblocks-- ) - { - u64 i = ++c->u_mode.ocb.data_nblocks; - const unsigned char *l = ocb_get_l(c, i); - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -- buf_xor_1 (c->u_iv.iv, l, BLOCKSIZE); -- buf_cpy (l_tmp.x1, inbuf, BLOCKSIZE); -+ cipher_block_xor_1 (c->u_iv.iv, l, BLOCKSIZE); -+ cipher_block_cpy (l_tmp.x1, inbuf, BLOCKSIZE); - /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ -- buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); -+ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); - burn_depth = decrypt_fn (ctx, l_tmp.x1, l_tmp.x1); -- buf_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); -+ cipher_block_xor_1 (l_tmp.x1, c->u_iv.iv, BLOCKSIZE); - /* Checksum_i = Checksum_{i-1} xor P_i */ -- buf_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); -- buf_cpy (outbuf, l_tmp.x1, BLOCKSIZE); -+ cipher_block_xor_1 (c->u_ctr.ctr, l_tmp.x1, BLOCKSIZE); -+ cipher_block_cpy (outbuf, l_tmp.x1, BLOCKSIZE); - - inbuf += BLOCKSIZE; - outbuf += BLOCKSIZE; -@@ -1411,48 +1652,58 @@ _gcry_aes_ocb_auth (gcry_cipher_hd_t c, - const unsigned char *abuf = abuf_arg; - unsigned int burn_depth = 0; - -- if (ctx->prefetch_enc_fn) -- ctx->prefetch_enc_fn(); -- - if (0) - ; - #ifdef USE_AESNI - else if (ctx->use_aesni) - { -- _gcry_aes_aesni_ocb_auth (c, abuf, nblocks); -- burn_depth = 0; -+ return _gcry_aes_aesni_ocb_auth (c, abuf, nblocks); - } - #endif /*USE_AESNI*/ - #ifdef USE_SSSE3 - else if (ctx->use_ssse3) - { -- _gcry_aes_ssse3_ocb_auth (c, abuf, nblocks); -- burn_depth = 0; -+ return _gcry_aes_ssse3_ocb_auth (c, abuf, nblocks); - } - #endif /*USE_SSSE3*/ - #ifdef USE_ARM_CE - else if (ctx->use_arm_ce) - { -- _gcry_aes_armv8_ce_ocb_auth (c, abuf, nblocks); -- burn_depth = 0; -+ return _gcry_aes_armv8_ce_ocb_auth (c, abuf, nblocks); - } - #endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if (ctx->use_ppc9le_crypto) -+ { -+ return _gcry_aes_ppc9le_ocb_auth (c, abuf, nblocks); -+ } -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ return _gcry_aes_ppc8_ocb_auth (c, abuf, nblocks); -+ } -+#endif /*USE_PPC_CRYPTO*/ - else - { - union { unsigned char x1[16] ATTR_ALIGNED_16; u32 x32[4]; } l_tmp; - rijndael_cryptfn_t encrypt_fn = ctx->encrypt_fn; - -+ if (ctx->prefetch_enc_fn) -+ ctx->prefetch_enc_fn(); -+ - for ( ;nblocks; nblocks-- ) - { - u64 i = ++c->u_mode.ocb.aad_nblocks; - const unsigned char *l = ocb_get_l(c, i); - - /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -- buf_xor_1 (c->u_mode.ocb.aad_offset, l, BLOCKSIZE); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_offset, l, BLOCKSIZE); - /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ -- buf_xor (l_tmp.x1, c->u_mode.ocb.aad_offset, abuf, BLOCKSIZE); -+ cipher_block_xor (l_tmp.x1, c->u_mode.ocb.aad_offset, abuf, -+ BLOCKSIZE); - burn_depth = encrypt_fn (ctx, l_tmp.x1, l_tmp.x1); -- buf_xor_1 (c->u_mode.ocb.aad_sum, l_tmp.x1, BLOCKSIZE); -+ cipher_block_xor_1 (c->u_mode.ocb.aad_sum, l_tmp.x1, BLOCKSIZE); - - abuf += BLOCKSIZE; - } -@@ -1467,6 +1718,106 @@ _gcry_aes_ocb_auth (gcry_cipher_hd_t c, - } - - -+/* Bulk encryption/decryption of complete blocks in XTS mode. */ -+void -+_gcry_aes_xts_crypt (void *context, unsigned char *tweak, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, int encrypt) -+{ -+ RIJNDAEL_context *ctx = context; -+ unsigned char *outbuf = outbuf_arg; -+ const unsigned char *inbuf = inbuf_arg; -+ unsigned int burn_depth = 0; -+ rijndael_cryptfn_t crypt_fn; -+ u64 tweak_lo, tweak_hi, tweak_next_lo, tweak_next_hi, tmp_lo, tmp_hi, carry; -+ -+ if (0) -+ ; -+#ifdef USE_AESNI -+ else if (ctx->use_aesni) -+ { -+ _gcry_aes_aesni_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); -+ return; -+ } -+#endif /*USE_AESNI*/ -+#ifdef USE_ARM_CE -+ else if (ctx->use_arm_ce) -+ { -+ _gcry_aes_armv8_ce_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); -+ return; -+ } -+#endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ else if (ctx->use_ppc9le_crypto) -+ { -+ _gcry_aes_ppc9le_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO_WITH_PPC9LE*/ -+#ifdef USE_PPC_CRYPTO -+ else if (ctx->use_ppc_crypto) -+ { -+ _gcry_aes_ppc8_xts_crypt (ctx, tweak, outbuf, inbuf, nblocks, encrypt); -+ return; -+ } -+#endif /*USE_PPC_CRYPTO*/ -+ else -+ { -+ if (encrypt) -+ { -+ if (ctx->prefetch_enc_fn) -+ ctx->prefetch_enc_fn(); -+ -+ crypt_fn = ctx->encrypt_fn; -+ } -+ else -+ { -+ check_decryption_preparation (ctx); -+ -+ if (ctx->prefetch_dec_fn) -+ ctx->prefetch_dec_fn(); -+ -+ crypt_fn = ctx->decrypt_fn; -+ } -+ -+ tweak_next_lo = buf_get_le64 (tweak + 0); -+ tweak_next_hi = buf_get_le64 (tweak + 8); -+ -+ while (nblocks) -+ { -+ tweak_lo = tweak_next_lo; -+ tweak_hi = tweak_next_hi; -+ -+ /* Xor-Encrypt/Decrypt-Xor block. */ -+ tmp_lo = buf_get_le64 (inbuf + 0) ^ tweak_lo; -+ tmp_hi = buf_get_le64 (inbuf + 8) ^ tweak_hi; -+ -+ buf_put_le64 (outbuf + 0, tmp_lo); -+ buf_put_le64 (outbuf + 8, tmp_hi); -+ -+ /* Generate next tweak. */ -+ carry = -(tweak_next_hi >> 63) & 0x87; -+ tweak_next_hi = (tweak_next_hi << 1) + (tweak_next_lo >> 63); -+ tweak_next_lo = (tweak_next_lo << 1) ^ carry; -+ -+ burn_depth = crypt_fn (ctx, outbuf, outbuf); -+ -+ buf_put_le64 (outbuf + 0, buf_get_le64 (outbuf + 0) ^ tweak_lo); -+ buf_put_le64 (outbuf + 8, buf_get_le64 (outbuf + 8) ^ tweak_hi); -+ -+ outbuf += GCRY_XTS_BLOCK_LEN; -+ inbuf += GCRY_XTS_BLOCK_LEN; -+ nblocks--; -+ } -+ -+ buf_put_le64 (tweak + 0, tweak_next_lo); -+ buf_put_le64 (tweak + 8, tweak_next_hi); -+ } -+ -+ if (burn_depth) -+ _gcry_burn_stack (burn_depth + 5 * sizeof(void *)); -+} -+ - - /* Run the self-tests for AES 128. Returns NULL on success. */ - static const char* -@@ -1522,7 +1873,7 @@ selftest_basic_128 (void) - if (!ctx) - return "failed to allocate memory"; - -- rijndael_setkey (ctx, key_128, sizeof (key_128)); -+ rijndael_setkey (ctx, key_128, sizeof (key_128), NULL); - rijndael_encrypt (ctx, scratch, plaintext_128); - if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128))) - { -@@ -1565,7 +1916,7 @@ selftest_basic_192 (void) - ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); - if (!ctx) - return "failed to allocate memory"; -- rijndael_setkey (ctx, key_192, sizeof(key_192)); -+ rijndael_setkey (ctx, key_192, sizeof(key_192), NULL); - rijndael_encrypt (ctx, scratch, plaintext_192); - if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192))) - { -@@ -1610,7 +1961,7 @@ selftest_basic_256 (void) - ctx = _gcry_cipher_selftest_alloc_ctx (sizeof *ctx, &ctxmem); - if (!ctx) - return "failed to allocate memory"; -- rijndael_setkey (ctx, key_256, sizeof(key_256)); -+ rijndael_setkey (ctx, key_256, sizeof(key_256), NULL); - rijndael_encrypt (ctx, scratch, plaintext_256); - if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256))) - { -diff -up libgcrypt-1.8.5/cipher/rijndael-internal.h.aes-perf libgcrypt-1.8.5/cipher/rijndael-internal.h ---- libgcrypt-1.8.5/cipher/rijndael-internal.h.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rijndael-internal.h 2020-04-22 18:29:41.676862114 +0200 -@@ -73,7 +73,7 @@ - # define USE_PADLOCK 1 - # endif - # endif --#endif /*ENABLE_PADLOCK_SUPPORT*/ -+#endif /* ENABLE_PADLOCK_SUPPORT */ - - /* USE_AESNI inidicates whether to compile with Intel AES-NI code. We - need the vector-size attribute which seems to be available since -@@ -102,6 +102,23 @@ - # endif - #endif /* ENABLE_ARM_CRYPTO_SUPPORT */ - -+/* USE_PPC_CRYPTO indicates whether to enable PowerPC vector crypto -+ * accelerated code. USE_PPC_CRYPTO_WITH_PPC9LE indicates whether to -+ * enable POWER9 optimized variant. */ -+#undef USE_PPC_CRYPTO -+#undef USE_PPC_CRYPTO_WITH_PPC9LE -+#ifdef ENABLE_PPC_CRYPTO_SUPPORT -+# if defined(HAVE_COMPATIBLE_CC_PPC_ALTIVEC) && \ -+ defined(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC) -+# if __GNUC__ >= 4 -+# define USE_PPC_CRYPTO 1 -+# if !defined(WORDS_BIGENDIAN) && defined(HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00) -+# define USE_PPC_CRYPTO_WITH_PPC9LE 1 -+# endif -+# endif -+# endif -+#endif /* ENABLE_PPC_CRYPTO_SUPPORT */ -+ - struct RIJNDAEL_context_s; - - typedef unsigned int (*rijndael_cryptfn_t)(const struct RIJNDAEL_context_s *ctx, -@@ -150,6 +167,12 @@ typedef struct RIJNDAEL_context_s - #ifdef USE_ARM_CE - unsigned int use_arm_ce:1; /* ARMv8 CE shall be used. */ - #endif /*USE_ARM_CE*/ -+#ifdef USE_PPC_CRYPTO -+ unsigned int use_ppc_crypto:1; /* PowerPC crypto shall be used. */ -+#endif /*USE_PPC_CRYPTO*/ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ unsigned int use_ppc9le_crypto:1; /* POWER9 LE crypto shall be used. */ -+#endif - rijndael_cryptfn_t encrypt_fn; - rijndael_cryptfn_t decrypt_fn; - rijndael_prefetchfn_t prefetch_enc_fn; -diff -up libgcrypt-1.8.5/cipher/rijndael-ppc9le.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-ppc9le.c ---- libgcrypt-1.8.5/cipher/rijndael-ppc9le.c.aes-perf 2020-04-22 18:29:41.677862096 +0200 -+++ libgcrypt-1.8.5/cipher/rijndael-ppc9le.c 2020-04-22 18:29:41.677862096 +0200 -@@ -0,0 +1,102 @@ -+/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation -+ * Copyright (C) 2019 Shawn Landden -+ * Copyright (C) 2019-2020 Jussi Kivilinna -+ * -+ * This file is part of Libgcrypt. -+ * -+ * Libgcrypt 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. -+ * -+ * Libgcrypt 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 program; if not, see . -+ * -+ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project, -+ * and Cryptogams by Andy Polyakov, and if made part of a release of either -+ * or both projects, is thereafter dual-licensed under the license said project -+ * is released under. -+ */ -+ -+#include -+ -+#include "rijndael-internal.h" -+#include "cipher-internal.h" -+#include "bufhelp.h" -+ -+#ifdef USE_PPC_CRYPTO_WITH_PPC9LE -+ -+#include "rijndael-ppc-common.h" -+ -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_load_be_const(void) -+{ -+ static const block vec_dummy = { 0 }; -+ return vec_dummy; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_be_swap(block vec, block be_bswap_const) -+{ -+ (void)be_bswap_const; -+ return vec; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_load_be_noswap(unsigned long offset, const void *ptr) -+{ -+ block vec; -+#if __GNUC__ >= 4 -+ if (__builtin_constant_p (offset) && offset == 0) -+ __asm__ volatile ("lxvb16x %x0,0,%1\n\t" -+ : "=wa" (vec) -+ : "r" ((uintptr_t)ptr) -+ : "memory"); -+ else -+#endif -+ __asm__ volatile ("lxvb16x %x0,%1,%2\n\t" -+ : "=wa" (vec) -+ : "r" (offset), "r" ((uintptr_t)ptr) -+ : "memory", "r0"); -+ return vec; -+} -+ -+static ASM_FUNC_ATTR_INLINE void -+asm_store_be_noswap(block vec, unsigned long offset, void *ptr) -+{ -+#if __GNUC__ >= 4 -+ if (__builtin_constant_p (offset) && offset == 0) -+ __asm__ volatile ("stxvb16x %x0,0,%1\n\t" -+ : -+ : "wa" (vec), "r" ((uintptr_t)ptr) -+ : "memory"); -+ else -+#endif -+ __asm__ volatile ("stxvb16x %x0,%1,%2\n\t" -+ : -+ : "wa" (vec), "r" (offset), "r" ((uintptr_t)ptr) -+ : "memory", "r0"); -+} -+ -+ -+#define GCRY_AES_PPC9LE 1 -+#define ENCRYPT_BLOCK_FUNC _gcry_aes_ppc9le_encrypt -+#define DECRYPT_BLOCK_FUNC _gcry_aes_ppc9le_decrypt -+#define CFB_ENC_FUNC _gcry_aes_ppc9le_cfb_enc -+#define CFB_DEC_FUNC _gcry_aes_ppc9le_cfb_dec -+#define CBC_ENC_FUNC _gcry_aes_ppc9le_cbc_enc -+#define CBC_DEC_FUNC _gcry_aes_ppc9le_cbc_dec -+#define CTR_ENC_FUNC _gcry_aes_ppc9le_ctr_enc -+#define OCB_CRYPT_FUNC _gcry_aes_ppc9le_ocb_crypt -+#define OCB_AUTH_FUNC _gcry_aes_ppc9le_ocb_auth -+#define XTS_CRYPT_FUNC _gcry_aes_ppc9le_xts_crypt -+ -+#include -+ -+#endif /* USE_PPC_CRYPTO */ -diff -up libgcrypt-1.8.5/cipher/rijndael-ppc.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-ppc.c ---- libgcrypt-1.8.5/cipher/rijndael-ppc.c.aes-perf 2020-04-22 18:29:41.677862096 +0200 -+++ libgcrypt-1.8.5/cipher/rijndael-ppc.c 2020-04-22 18:29:41.677862096 +0200 -@@ -0,0 +1,259 @@ -+/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation -+ * Copyright (C) 2019 Shawn Landden -+ * Copyright (C) 2019-2020 Jussi Kivilinna -+ * -+ * This file is part of Libgcrypt. -+ * -+ * Libgcrypt 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. -+ * -+ * Libgcrypt 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 program; if not, see . -+ * -+ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project, -+ * and Cryptogams by Andy Polyakov, and if made part of a release of either -+ * or both projects, is thereafter dual-licensed under the license said project -+ * is released under. -+ */ -+ -+#include -+ -+#include "rijndael-internal.h" -+#include "cipher-internal.h" -+#include "bufhelp.h" -+ -+#ifdef USE_PPC_CRYPTO -+ -+#include "rijndael-ppc-common.h" -+ -+ -+#ifdef WORDS_BIGENDIAN -+static const block vec_bswap32_const = -+ { 3, 2, 1, 0, 7, 6, 5, 4, 11, 10, 9, 8, 15, 14, 13, 12 }; -+#else -+static const block vec_bswap32_const_neg = -+ { ~3, ~2, ~1, ~0, ~7, ~6, ~5, ~4, ~11, ~10, ~9, ~8, ~15, ~14, ~13, ~12 }; -+#endif -+ -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_load_be_const(void) -+{ -+#ifndef WORDS_BIGENDIAN -+ return ALIGNED_LOAD (&vec_bswap32_const_neg, 0); -+#else -+ static const block vec_dummy = { 0 }; -+ return vec_dummy; -+#endif -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_be_swap(block vec, block be_bswap_const) -+{ -+ (void)be_bswap_const; -+#ifndef WORDS_BIGENDIAN -+ return asm_vperm1 (vec, be_bswap_const); -+#else -+ return vec; -+#endif -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_load_be_noswap(unsigned long offset, const void *ptr) -+{ -+ block vec; -+#if __GNUC__ >= 4 -+ if (__builtin_constant_p (offset) && offset == 0) -+ __asm__ volatile ("lxvw4x %x0,0,%1\n\t" -+ : "=wa" (vec) -+ : "r" ((uintptr_t)ptr) -+ : "memory"); -+ else -+#endif -+ __asm__ volatile ("lxvw4x %x0,%1,%2\n\t" -+ : "=wa" (vec) -+ : "r" (offset), "r" ((uintptr_t)ptr) -+ : "memory", "r0"); -+ /* NOTE: vec needs to be be-swapped using 'asm_be_swap' by caller */ -+ return vec; -+} -+ -+static ASM_FUNC_ATTR_INLINE void -+asm_store_be_noswap(block vec, unsigned long offset, void *ptr) -+{ -+ /* NOTE: vec be-swapped using 'asm_be_swap' by caller */ -+#if __GNUC__ >= 4 -+ if (__builtin_constant_p (offset) && offset == 0) -+ __asm__ volatile ("stxvw4x %x0,0,%1\n\t" -+ : -+ : "wa" (vec), "r" ((uintptr_t)ptr) -+ : "memory"); -+ else -+#endif -+ __asm__ volatile ("stxvw4x %x0,%1,%2\n\t" -+ : -+ : "wa" (vec), "r" (offset), "r" ((uintptr_t)ptr) -+ : "memory", "r0"); -+} -+ -+ -+static ASM_FUNC_ATTR_INLINE u32 -+_gcry_aes_sbox4_ppc8(u32 fourbytes) -+{ -+ union -+ { -+ PROPERLY_ALIGNED_TYPE dummy; -+ block data_vec; -+ u32 data32[4]; -+ } u; -+ -+ u.data32[0] = fourbytes; -+ u.data_vec = vec_sbox_be(u.data_vec); -+ return u.data32[0]; -+} -+ -+void -+_gcry_aes_ppc8_setkey (RIJNDAEL_context *ctx, const byte *key) -+{ -+ const block bige_const = asm_load_be_const(); -+ union -+ { -+ PROPERLY_ALIGNED_TYPE dummy; -+ byte data[MAXKC][4]; -+ u32 data32[MAXKC]; -+ } tkk[2]; -+ unsigned int rounds = ctx->rounds; -+ int KC = rounds - 6; -+ unsigned int keylen = KC * 4; -+ u128_t *ekey = (u128_t *)(void *)ctx->keyschenc; -+ unsigned int i, r, t; -+ byte rcon = 1; -+ int j; -+#define k tkk[0].data -+#define k_u32 tkk[0].data32 -+#define tk tkk[1].data -+#define tk_u32 tkk[1].data32 -+#define W (ctx->keyschenc) -+#define W_u32 (ctx->keyschenc32) -+ -+ for (i = 0; i < keylen; i++) -+ { -+ k[i >> 2][i & 3] = key[i]; -+ } -+ -+ for (j = KC-1; j >= 0; j--) -+ { -+ tk_u32[j] = k_u32[j]; -+ } -+ r = 0; -+ t = 0; -+ /* Copy values into round key array. */ -+ for (j = 0; (j < KC) && (r < rounds + 1); ) -+ { -+ for (; (j < KC) && (t < 4); j++, t++) -+ { -+ W_u32[r][t] = le_bswap32(tk_u32[j]); -+ } -+ if (t == 4) -+ { -+ r++; -+ t = 0; -+ } -+ } -+ while (r < rounds + 1) -+ { -+ tk_u32[0] ^= -+ le_bswap32( -+ _gcry_aes_sbox4_ppc8(rol(le_bswap32(tk_u32[KC - 1]), 24)) ^ rcon); -+ -+ if (KC != 8) -+ { -+ for (j = 1; j < KC; j++) -+ { -+ tk_u32[j] ^= tk_u32[j-1]; -+ } -+ } -+ else -+ { -+ for (j = 1; j < KC/2; j++) -+ { -+ tk_u32[j] ^= tk_u32[j-1]; -+ } -+ -+ tk_u32[KC/2] ^= -+ le_bswap32(_gcry_aes_sbox4_ppc8(le_bswap32(tk_u32[KC/2 - 1]))); -+ -+ for (j = KC/2 + 1; j < KC; j++) -+ { -+ tk_u32[j] ^= tk_u32[j-1]; -+ } -+ } -+ -+ /* Copy values into round key array. */ -+ for (j = 0; (j < KC) && (r < rounds + 1); ) -+ { -+ for (; (j < KC) && (t < 4); j++, t++) -+ { -+ W_u32[r][t] = le_bswap32(tk_u32[j]); -+ } -+ if (t == 4) -+ { -+ r++; -+ t = 0; -+ } -+ } -+ -+ rcon = (rcon << 1) ^ (-(rcon >> 7) & 0x1b); -+ } -+ -+ /* Store in big-endian order. */ -+ for (r = 0; r <= rounds; r++) -+ { -+#ifndef WORDS_BIGENDIAN -+ VEC_STORE_BE(ekey, r, ALIGNED_LOAD (ekey, r), bige_const); -+#else -+ block rvec = ALIGNED_LOAD (ekey, r); -+ ALIGNED_STORE (ekey, r, -+ vec_perm(rvec, rvec, vec_bswap32_const)); -+ (void)bige_const; -+#endif -+ } -+ -+#undef W -+#undef tk -+#undef k -+#undef W_u32 -+#undef tk_u32 -+#undef k_u32 -+ wipememory(&tkk, sizeof(tkk)); -+} -+ -+void -+_gcry_aes_ppc8_prepare_decryption (RIJNDAEL_context *ctx) -+{ -+ internal_aes_ppc_prepare_decryption (ctx); -+} -+ -+ -+#define GCRY_AES_PPC8 1 -+#define ENCRYPT_BLOCK_FUNC _gcry_aes_ppc8_encrypt -+#define DECRYPT_BLOCK_FUNC _gcry_aes_ppc8_decrypt -+#define CFB_ENC_FUNC _gcry_aes_ppc8_cfb_enc -+#define CFB_DEC_FUNC _gcry_aes_ppc8_cfb_dec -+#define CBC_ENC_FUNC _gcry_aes_ppc8_cbc_enc -+#define CBC_DEC_FUNC _gcry_aes_ppc8_cbc_dec -+#define CTR_ENC_FUNC _gcry_aes_ppc8_ctr_enc -+#define OCB_CRYPT_FUNC _gcry_aes_ppc8_ocb_crypt -+#define OCB_AUTH_FUNC _gcry_aes_ppc8_ocb_auth -+#define XTS_CRYPT_FUNC _gcry_aes_ppc8_xts_crypt -+ -+#include -+ -+#endif /* USE_PPC_CRYPTO */ -diff -up libgcrypt-1.8.5/cipher/rijndael-ppc-common.h.aes-perf libgcrypt-1.8.5/cipher/rijndael-ppc-common.h ---- libgcrypt-1.8.5/cipher/rijndael-ppc-common.h.aes-perf 2020-04-22 18:29:41.678862076 +0200 -+++ libgcrypt-1.8.5/cipher/rijndael-ppc-common.h 2020-04-22 18:29:41.678862076 +0200 -@@ -0,0 +1,342 @@ -+/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation -+ * Copyright (C) 2019 Shawn Landden -+ * Copyright (C) 2019-2020 Jussi Kivilinna -+ * -+ * This file is part of Libgcrypt. -+ * -+ * Libgcrypt 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. -+ * -+ * Libgcrypt 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 program; if not, see . -+ * -+ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project, -+ * and Cryptogams by Andy Polyakov, and if made part of a release of either -+ * or both projects, is thereafter dual-licensed under the license said project -+ * is released under. -+ */ -+ -+#ifndef G10_RIJNDAEL_PPC_COMMON_H -+#define G10_RIJNDAEL_PPC_COMMON_H -+ -+#include -+ -+ -+typedef vector unsigned char block; -+ -+typedef union -+{ -+ u32 data32[4]; -+} __attribute__((packed, aligned(1), may_alias)) u128_t; -+ -+ -+#define ALWAYS_INLINE inline __attribute__((always_inline)) -+#define NO_INLINE __attribute__((noinline)) -+#define NO_INSTRUMENT_FUNCTION __attribute__((no_instrument_function)) -+ -+#define ASM_FUNC_ATTR NO_INSTRUMENT_FUNCTION -+#define ASM_FUNC_ATTR_INLINE ASM_FUNC_ATTR ALWAYS_INLINE -+#define ASM_FUNC_ATTR_NOINLINE ASM_FUNC_ATTR NO_INLINE -+ -+ -+#define ALIGNED_LOAD(in_ptr, offs) \ -+ (asm_aligned_ld ((offs) * 16, (const void *)(in_ptr))) -+ -+#define ALIGNED_STORE(out_ptr, offs, vec) \ -+ (asm_aligned_st ((vec), (offs) * 16, (void *)(out_ptr))) -+ -+#define VEC_BE_SWAP(vec, bige_const) (asm_be_swap ((vec), (bige_const))) -+ -+#define VEC_LOAD_BE(in_ptr, offs, bige_const) \ -+ (asm_be_swap (asm_load_be_noswap ((offs) * 16, (const void *)(in_ptr)), \ -+ bige_const)) -+ -+#define VEC_LOAD_BE_NOSWAP(in_ptr, offs) \ -+ (asm_load_be_noswap ((offs) * 16, (const unsigned char *)(in_ptr))) -+ -+#define VEC_STORE_BE(out_ptr, offs, vec, bige_const) \ -+ (asm_store_be_noswap (asm_be_swap ((vec), (bige_const)), (offs) * 16, \ -+ (void *)(out_ptr))) -+ -+#define VEC_STORE_BE_NOSWAP(out_ptr, offs, vec) \ -+ (asm_store_be_noswap ((vec), (offs) * 16, (void *)(out_ptr))) -+ -+ -+#define ROUND_KEY_VARIABLES \ -+ block rkey0, rkeylast -+ -+#define PRELOAD_ROUND_KEYS(nrounds) \ -+ do { \ -+ rkey0 = ALIGNED_LOAD (rk, 0); \ -+ rkeylast = ALIGNED_LOAD (rk, nrounds); \ -+ } while (0) -+ -+#define AES_ENCRYPT(blk, nrounds) \ -+ do { \ -+ blk ^= rkey0; \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 1)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 2)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 3)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 4)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 5)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 6)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 7)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 8)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 9)); \ -+ if (nrounds >= 12) \ -+ { \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 10)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 11)); \ -+ if (rounds > 12) \ -+ { \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 12)); \ -+ blk = asm_cipher_be (blk, ALIGNED_LOAD (rk, 13)); \ -+ } \ -+ } \ -+ blk = asm_cipherlast_be (blk, rkeylast); \ -+ } while (0) -+ -+#define AES_DECRYPT(blk, nrounds) \ -+ do { \ -+ blk ^= rkey0; \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 1)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 2)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 3)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 4)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 5)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 6)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 7)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 8)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 9)); \ -+ if (nrounds >= 12) \ -+ { \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 10)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 11)); \ -+ if (rounds > 12) \ -+ { \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 12)); \ -+ blk = asm_ncipher_be (blk, ALIGNED_LOAD (rk, 13)); \ -+ } \ -+ } \ -+ blk = asm_ncipherlast_be (blk, rkeylast); \ -+ } while (0) -+ -+ -+#define ROUND_KEY_VARIABLES_ALL \ -+ block rkey0, rkey1, rkey2, rkey3, rkey4, rkey5, rkey6, rkey7, rkey8, \ -+ rkey9, rkey10, rkey11, rkey12, rkey13, rkeylast -+ -+#define PRELOAD_ROUND_KEYS_ALL(nrounds) \ -+ do { \ -+ rkey0 = ALIGNED_LOAD (rk, 0); \ -+ rkey1 = ALIGNED_LOAD (rk, 1); \ -+ rkey2 = ALIGNED_LOAD (rk, 2); \ -+ rkey3 = ALIGNED_LOAD (rk, 3); \ -+ rkey4 = ALIGNED_LOAD (rk, 4); \ -+ rkey5 = ALIGNED_LOAD (rk, 5); \ -+ rkey6 = ALIGNED_LOAD (rk, 6); \ -+ rkey7 = ALIGNED_LOAD (rk, 7); \ -+ rkey8 = ALIGNED_LOAD (rk, 8); \ -+ rkey9 = ALIGNED_LOAD (rk, 9); \ -+ if (nrounds >= 12) \ -+ { \ -+ rkey10 = ALIGNED_LOAD (rk, 10); \ -+ rkey11 = ALIGNED_LOAD (rk, 11); \ -+ if (rounds > 12) \ -+ { \ -+ rkey12 = ALIGNED_LOAD (rk, 12); \ -+ rkey13 = ALIGNED_LOAD (rk, 13); \ -+ } \ -+ } \ -+ rkeylast = ALIGNED_LOAD (rk, nrounds); \ -+ } while (0) -+ -+#define AES_ENCRYPT_ALL(blk, nrounds) \ -+ do { \ -+ blk ^= rkey0; \ -+ blk = asm_cipher_be (blk, rkey1); \ -+ blk = asm_cipher_be (blk, rkey2); \ -+ blk = asm_cipher_be (blk, rkey3); \ -+ blk = asm_cipher_be (blk, rkey4); \ -+ blk = asm_cipher_be (blk, rkey5); \ -+ blk = asm_cipher_be (blk, rkey6); \ -+ blk = asm_cipher_be (blk, rkey7); \ -+ blk = asm_cipher_be (blk, rkey8); \ -+ blk = asm_cipher_be (blk, rkey9); \ -+ if (nrounds >= 12) \ -+ { \ -+ blk = asm_cipher_be (blk, rkey10); \ -+ blk = asm_cipher_be (blk, rkey11); \ -+ if (rounds > 12) \ -+ { \ -+ blk = asm_cipher_be (blk, rkey12); \ -+ blk = asm_cipher_be (blk, rkey13); \ -+ } \ -+ } \ -+ blk = asm_cipherlast_be (blk, rkeylast); \ -+ } while (0) -+ -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_aligned_ld(unsigned long offset, const void *ptr) -+{ -+ block vec; -+#if __GNUC__ >= 4 -+ if (__builtin_constant_p (offset) && offset == 0) -+ __asm__ volatile ("lvx %0,0,%1\n\t" -+ : "=v" (vec) -+ : "r" ((uintptr_t)ptr) -+ : "memory"); -+ else -+#endif -+ __asm__ volatile ("lvx %0,%1,%2\n\t" -+ : "=v" (vec) -+ : "r" (offset), "r" ((uintptr_t)ptr) -+ : "memory", "r0"); -+ return vec; -+} -+ -+static ASM_FUNC_ATTR_INLINE void -+asm_aligned_st(block vec, unsigned long offset, void *ptr) -+{ -+#if __GNUC__ >= 4 -+ if (__builtin_constant_p (offset) && offset == 0) -+ __asm__ volatile ("stvx %0,0,%1\n\t" -+ : -+ : "v" (vec), "r" ((uintptr_t)ptr) -+ : "memory"); -+ else -+#endif -+ __asm__ volatile ("stvx %0,%1,%2\n\t" -+ : -+ : "v" (vec), "r" (offset), "r" ((uintptr_t)ptr) -+ : "memory", "r0"); -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_vperm1(block vec, block mask) -+{ -+ block o; -+ __asm__ volatile ("vperm %0,%1,%1,%2\n\t" -+ : "=v" (o) -+ : "v" (vec), "v" (mask)); -+ return o; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_add_uint128(block a, block b) -+{ -+ block res; -+ __asm__ volatile ("vadduqm %0,%1,%2\n\t" -+ : "=v" (res) -+ : "v" (a), "v" (b)); -+ return res; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_add_uint64(block a, block b) -+{ -+ block res; -+ __asm__ volatile ("vaddudm %0,%1,%2\n\t" -+ : "=v" (res) -+ : "v" (a), "v" (b)); -+ return res; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_sra_int64(block a, block b) -+{ -+ block res; -+ __asm__ volatile ("vsrad %0,%1,%2\n\t" -+ : "=v" (res) -+ : "v" (a), "v" (b)); -+ return res; -+} -+ -+static block -+asm_swap_uint64_halfs(block a) -+{ -+ block res; -+ __asm__ volatile ("xxswapd %x0, %x1" -+ : "=wa" (res) -+ : "wa" (a)); -+ return res; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_xor(block a, block b) -+{ -+ block res; -+ __asm__ volatile ("vxor %0,%1,%2\n\t" -+ : "=v" (res) -+ : "v" (a), "v" (b)); -+ return res; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_cipher_be(block b, block rk) -+{ -+ block o; -+ __asm__ volatile ("vcipher %0, %1, %2\n\t" -+ : "=v" (o) -+ : "v" (b), "v" (rk)); -+ return o; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_cipherlast_be(block b, block rk) -+{ -+ block o; -+ __asm__ volatile ("vcipherlast %0, %1, %2\n\t" -+ : "=v" (o) -+ : "v" (b), "v" (rk)); -+ return o; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_ncipher_be(block b, block rk) -+{ -+ block o; -+ __asm__ volatile ("vncipher %0, %1, %2\n\t" -+ : "=v" (o) -+ : "v" (b), "v" (rk)); -+ return o; -+} -+ -+static ASM_FUNC_ATTR_INLINE block -+asm_ncipherlast_be(block b, block rk) -+{ -+ block o; -+ __asm__ volatile ("vncipherlast %0, %1, %2\n\t" -+ : "=v" (o) -+ : "v" (b), "v" (rk)); -+ return o; -+} -+ -+ -+/* Make a decryption key from an encryption key. */ -+static ASM_FUNC_ATTR_INLINE void -+internal_aes_ppc_prepare_decryption (RIJNDAEL_context *ctx) -+{ -+ u128_t *ekey = (u128_t *)(void *)ctx->keyschenc; -+ u128_t *dkey = (u128_t *)(void *)ctx->keyschdec; -+ int rounds = ctx->rounds; -+ int rr; -+ int r; -+ -+ r = 0; -+ rr = rounds; -+ for (r = 0, rr = rounds; r <= rounds; r++, rr--) -+ { -+ ALIGNED_STORE (dkey, r, ALIGNED_LOAD (ekey, rr)); -+ } -+} -+ -+#endif /* G10_RIJNDAEL_PPC_COMMON_H */ -diff -up libgcrypt-1.8.5/cipher/rijndael-ppc-functions.h.aes-perf libgcrypt-1.8.5/cipher/rijndael-ppc-functions.h ---- libgcrypt-1.8.5/cipher/rijndael-ppc-functions.h.aes-perf 2020-04-22 18:29:41.679862057 +0200 -+++ libgcrypt-1.8.5/cipher/rijndael-ppc-functions.h 2020-04-22 18:29:41.679862057 +0200 -@@ -0,0 +1,2020 @@ -+/* Rijndael (AES) for GnuPG - PowerPC Vector Crypto AES implementation -+ * Copyright (C) 2019 Shawn Landden -+ * Copyright (C) 2019-2020 Jussi Kivilinna -+ * -+ * This file is part of Libgcrypt. -+ * -+ * Libgcrypt 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. -+ * -+ * Libgcrypt 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 program; if not, see . -+ * -+ * Alternatively, this code may be used in OpenSSL from The OpenSSL Project, -+ * and Cryptogams by Andy Polyakov, and if made part of a release of either -+ * or both projects, is thereafter dual-licensed under the license said project -+ * is released under. -+ */ -+ -+unsigned int ENCRYPT_BLOCK_FUNC (const RIJNDAEL_context *ctx, -+ unsigned char *out, -+ const unsigned char *in) -+{ -+ const block bige_const = asm_load_be_const(); -+ const u128_t *rk = (u128_t *)&ctx->keyschenc; -+ int rounds = ctx->rounds; -+ ROUND_KEY_VARIABLES; -+ block b; -+ -+ b = VEC_LOAD_BE (in, 0, bige_const); -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ -+ AES_ENCRYPT (b, rounds); -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ return 0; /* does not use stack */ -+} -+ -+ -+unsigned int DECRYPT_BLOCK_FUNC (const RIJNDAEL_context *ctx, -+ unsigned char *out, -+ const unsigned char *in) -+{ -+ const block bige_const = asm_load_be_const(); -+ const u128_t *rk = (u128_t *)&ctx->keyschdec; -+ int rounds = ctx->rounds; -+ ROUND_KEY_VARIABLES; -+ block b; -+ -+ b = VEC_LOAD_BE (in, 0, bige_const); -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ -+ AES_DECRYPT (b, rounds); -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ return 0; /* does not use stack */ -+} -+ -+ -+void CFB_ENC_FUNC (void *context, unsigned char *iv_arg, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks) -+{ -+ const block bige_const = asm_load_be_const(); -+ RIJNDAEL_context *ctx = context; -+ const u128_t *rk = (u128_t *)&ctx->keyschenc; -+ const u128_t *in = (const u128_t *)inbuf_arg; -+ u128_t *out = (u128_t *)outbuf_arg; -+ int rounds = ctx->rounds; -+ ROUND_KEY_VARIABLES_ALL; -+ block rkeylast_orig; -+ block iv; -+ -+ iv = VEC_LOAD_BE (iv_arg, 0, bige_const); -+ -+ PRELOAD_ROUND_KEYS_ALL (rounds); -+ rkeylast_orig = rkeylast; -+ -+ for (; nblocks >= 2; nblocks -= 2) -+ { -+ block in2, iv1; -+ -+ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in, 0, bige_const); -+ in2 = VEC_LOAD_BE (in + 1, 0, bige_const); -+ in += 2; -+ -+ AES_ENCRYPT_ALL (iv, rounds); -+ -+ iv1 = iv; -+ rkeylast = rkeylast_orig ^ in2; -+ -+ AES_ENCRYPT_ALL (iv, rounds); -+ -+ VEC_STORE_BE (out++, 0, iv1, bige_const); -+ VEC_STORE_BE (out++, 0, iv, bige_const); -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in++, 0, bige_const); -+ -+ AES_ENCRYPT_ALL (iv, rounds); -+ -+ VEC_STORE_BE (out++, 0, iv, bige_const); -+ } -+ -+ VEC_STORE_BE (iv_arg, 0, iv, bige_const); -+} -+ -+void CFB_DEC_FUNC (void *context, unsigned char *iv_arg, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks) -+{ -+ const block bige_const = asm_load_be_const(); -+ RIJNDAEL_context *ctx = context; -+ const u128_t *rk = (u128_t *)&ctx->keyschenc; -+ const u128_t *in = (const u128_t *)inbuf_arg; -+ u128_t *out = (u128_t *)outbuf_arg; -+ int rounds = ctx->rounds; -+ ROUND_KEY_VARIABLES; -+ block rkeylast_orig; -+ block iv, b, bin; -+ block in0, in1, in2, in3, in4, in5, in6, in7; -+ block b0, b1, b2, b3, b4, b5, b6, b7; -+ block rkey; -+ -+ iv = VEC_LOAD_BE (iv_arg, 0, bige_const); -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ rkeylast_orig = rkeylast; -+ -+ for (; nblocks >= 8; nblocks -= 8) -+ { -+ in0 = iv; -+ in1 = VEC_LOAD_BE_NOSWAP (in, 0); -+ in2 = VEC_LOAD_BE_NOSWAP (in, 1); -+ in3 = VEC_LOAD_BE_NOSWAP (in, 2); -+ in4 = VEC_LOAD_BE_NOSWAP (in, 3); -+ in1 = VEC_BE_SWAP (in1, bige_const); -+ in2 = VEC_BE_SWAP (in2, bige_const); -+ in5 = VEC_LOAD_BE_NOSWAP (in, 4); -+ in6 = VEC_LOAD_BE_NOSWAP (in, 5); -+ in3 = VEC_BE_SWAP (in3, bige_const); -+ in4 = VEC_BE_SWAP (in4, bige_const); -+ in7 = VEC_LOAD_BE_NOSWAP (in, 6); -+ iv = VEC_LOAD_BE_NOSWAP (in, 7); -+ in += 8; -+ in5 = VEC_BE_SWAP (in5, bige_const); -+ in6 = VEC_BE_SWAP (in6, bige_const); -+ b0 = asm_xor (rkey0, in0); -+ b1 = asm_xor (rkey0, in1); -+ in7 = VEC_BE_SWAP (in7, bige_const); -+ iv = VEC_BE_SWAP (iv, bige_const); -+ b2 = asm_xor (rkey0, in2); -+ b3 = asm_xor (rkey0, in3); -+ b4 = asm_xor (rkey0, in4); -+ b5 = asm_xor (rkey0, in5); -+ b6 = asm_xor (rkey0, in6); -+ b7 = asm_xor (rkey0, in7); -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); \ -+ b4 = asm_cipher_be (b4, rkey); \ -+ b5 = asm_cipher_be (b5, rkey); \ -+ b6 = asm_cipher_be (b6, rkey); \ -+ b7 = asm_cipher_be (b7, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ in1 = asm_xor (rkeylast, in1); -+ in2 = asm_xor (rkeylast, in2); -+ in3 = asm_xor (rkeylast, in3); -+ in4 = asm_xor (rkeylast, in4); -+ b0 = asm_cipherlast_be (b0, in1); -+ b1 = asm_cipherlast_be (b1, in2); -+ in5 = asm_xor (rkeylast, in5); -+ in6 = asm_xor (rkeylast, in6); -+ b2 = asm_cipherlast_be (b2, in3); -+ b3 = asm_cipherlast_be (b3, in4); -+ in7 = asm_xor (rkeylast, in7); -+ in0 = asm_xor (rkeylast, iv); -+ b0 = VEC_BE_SWAP (b0, bige_const); -+ b1 = VEC_BE_SWAP (b1, bige_const); -+ b4 = asm_cipherlast_be (b4, in5); -+ b5 = asm_cipherlast_be (b5, in6); -+ b2 = VEC_BE_SWAP (b2, bige_const); -+ b3 = VEC_BE_SWAP (b3, bige_const); -+ b6 = asm_cipherlast_be (b6, in7); -+ b7 = asm_cipherlast_be (b7, in0); -+ b4 = VEC_BE_SWAP (b4, bige_const); -+ b5 = VEC_BE_SWAP (b5, bige_const); -+ b6 = VEC_BE_SWAP (b6, bige_const); -+ b7 = VEC_BE_SWAP (b7, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 0, b0); -+ VEC_STORE_BE_NOSWAP (out, 1, b1); -+ VEC_STORE_BE_NOSWAP (out, 2, b2); -+ VEC_STORE_BE_NOSWAP (out, 3, b3); -+ VEC_STORE_BE_NOSWAP (out, 4, b4); -+ VEC_STORE_BE_NOSWAP (out, 5, b5); -+ VEC_STORE_BE_NOSWAP (out, 6, b6); -+ VEC_STORE_BE_NOSWAP (out, 7, b7); -+ out += 8; -+ } -+ -+ if (nblocks >= 4) -+ { -+ in0 = iv; -+ in1 = VEC_LOAD_BE (in, 0, bige_const); -+ in2 = VEC_LOAD_BE (in, 1, bige_const); -+ in3 = VEC_LOAD_BE (in, 2, bige_const); -+ iv = VEC_LOAD_BE (in, 3, bige_const); -+ -+ b0 = asm_xor (rkey0, in0); -+ b1 = asm_xor (rkey0, in1); -+ b2 = asm_xor (rkey0, in2); -+ b3 = asm_xor (rkey0, in3); -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ in1 = asm_xor (rkeylast, in1); -+ in2 = asm_xor (rkeylast, in2); -+ in3 = asm_xor (rkeylast, in3); -+ in0 = asm_xor (rkeylast, iv); -+ b0 = asm_cipherlast_be (b0, in1); -+ b1 = asm_cipherlast_be (b1, in2); -+ b2 = asm_cipherlast_be (b2, in3); -+ b3 = asm_cipherlast_be (b3, in0); -+ VEC_STORE_BE (out, 0, b0, bige_const); -+ VEC_STORE_BE (out, 1, b1, bige_const); -+ VEC_STORE_BE (out, 2, b2, bige_const); -+ VEC_STORE_BE (out, 3, b3, bige_const); -+ -+ in += 4; -+ out += 4; -+ nblocks -= 4; -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ bin = VEC_LOAD_BE (in, 0, bige_const); -+ rkeylast = rkeylast_orig ^ bin; -+ b = iv; -+ iv = bin; -+ -+ AES_ENCRYPT (b, rounds); -+ -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ out++; -+ in++; -+ } -+ -+ VEC_STORE_BE (iv_arg, 0, iv, bige_const); -+} -+ -+ -+void CBC_ENC_FUNC (void *context, unsigned char *iv_arg, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, int cbc_mac) -+{ -+ const block bige_const = asm_load_be_const(); -+ RIJNDAEL_context *ctx = context; -+ const u128_t *rk = (u128_t *)&ctx->keyschenc; -+ const u128_t *in = (const u128_t *)inbuf_arg; -+ byte *out = (byte *)outbuf_arg; -+ int rounds = ctx->rounds; -+ ROUND_KEY_VARIABLES_ALL; -+ block lastiv, b; -+ unsigned int outadd = -(!cbc_mac) & 16; -+ -+ lastiv = VEC_LOAD_BE (iv_arg, 0, bige_const); -+ -+ PRELOAD_ROUND_KEYS_ALL (rounds); -+ -+ for (; nblocks >= 2; nblocks -= 2) -+ { -+ block in2, lastiv1; -+ -+ b = lastiv ^ VEC_LOAD_BE (in, 0, bige_const); -+ in2 = VEC_LOAD_BE (in + 1, 0, bige_const); -+ in += 2; -+ -+ AES_ENCRYPT_ALL (b, rounds); -+ -+ lastiv1 = b; -+ b = lastiv1 ^ in2; -+ -+ AES_ENCRYPT_ALL (b, rounds); -+ -+ lastiv = b; -+ VEC_STORE_BE ((u128_t *)out, 0, lastiv1, bige_const); -+ out += outadd; -+ VEC_STORE_BE ((u128_t *)out, 0, lastiv, bige_const); -+ out += outadd; -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ b = lastiv ^ VEC_LOAD_BE (in++, 0, bige_const); -+ -+ AES_ENCRYPT_ALL (b, rounds); -+ -+ lastiv = b; -+ VEC_STORE_BE ((u128_t *)out, 0, b, bige_const); -+ out += outadd; -+ } -+ -+ VEC_STORE_BE (iv_arg, 0, lastiv, bige_const); -+} -+ -+void CBC_DEC_FUNC (void *context, unsigned char *iv_arg, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks) -+{ -+ const block bige_const = asm_load_be_const(); -+ RIJNDAEL_context *ctx = context; -+ const u128_t *rk = (u128_t *)&ctx->keyschdec; -+ const u128_t *in = (const u128_t *)inbuf_arg; -+ u128_t *out = (u128_t *)outbuf_arg; -+ int rounds = ctx->rounds; -+ ROUND_KEY_VARIABLES; -+ block rkeylast_orig; -+ block in0, in1, in2, in3, in4, in5, in6, in7; -+ block b0, b1, b2, b3, b4, b5, b6, b7; -+ block rkey; -+ block iv, b; -+ -+ if (!ctx->decryption_prepared) -+ { -+ internal_aes_ppc_prepare_decryption (ctx); -+ ctx->decryption_prepared = 1; -+ } -+ -+ iv = VEC_LOAD_BE (iv_arg, 0, bige_const); -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ rkeylast_orig = rkeylast; -+ -+ for (; nblocks >= 8; nblocks -= 8) -+ { -+ in0 = VEC_LOAD_BE_NOSWAP (in, 0); -+ in1 = VEC_LOAD_BE_NOSWAP (in, 1); -+ in2 = VEC_LOAD_BE_NOSWAP (in, 2); -+ in3 = VEC_LOAD_BE_NOSWAP (in, 3); -+ in0 = VEC_BE_SWAP (in0, bige_const); -+ in1 = VEC_BE_SWAP (in1, bige_const); -+ in4 = VEC_LOAD_BE_NOSWAP (in, 4); -+ in5 = VEC_LOAD_BE_NOSWAP (in, 5); -+ in2 = VEC_BE_SWAP (in2, bige_const); -+ in3 = VEC_BE_SWAP (in3, bige_const); -+ in6 = VEC_LOAD_BE_NOSWAP (in, 6); -+ in7 = VEC_LOAD_BE_NOSWAP (in, 7); -+ in += 8; -+ b0 = asm_xor (rkey0, in0); -+ b1 = asm_xor (rkey0, in1); -+ in4 = VEC_BE_SWAP (in4, bige_const); -+ in5 = VEC_BE_SWAP (in5, bige_const); -+ b2 = asm_xor (rkey0, in2); -+ b3 = asm_xor (rkey0, in3); -+ in6 = VEC_BE_SWAP (in6, bige_const); -+ in7 = VEC_BE_SWAP (in7, bige_const); -+ b4 = asm_xor (rkey0, in4); -+ b5 = asm_xor (rkey0, in5); -+ b6 = asm_xor (rkey0, in6); -+ b7 = asm_xor (rkey0, in7); -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_ncipher_be (b0, rkey); \ -+ b1 = asm_ncipher_be (b1, rkey); \ -+ b2 = asm_ncipher_be (b2, rkey); \ -+ b3 = asm_ncipher_be (b3, rkey); \ -+ b4 = asm_ncipher_be (b4, rkey); \ -+ b5 = asm_ncipher_be (b5, rkey); \ -+ b6 = asm_ncipher_be (b6, rkey); \ -+ b7 = asm_ncipher_be (b7, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ iv = asm_xor (rkeylast, iv); -+ in0 = asm_xor (rkeylast, in0); -+ in1 = asm_xor (rkeylast, in1); -+ in2 = asm_xor (rkeylast, in2); -+ b0 = asm_ncipherlast_be (b0, iv); -+ iv = in7; -+ b1 = asm_ncipherlast_be (b1, in0); -+ in3 = asm_xor (rkeylast, in3); -+ in4 = asm_xor (rkeylast, in4); -+ b2 = asm_ncipherlast_be (b2, in1); -+ b3 = asm_ncipherlast_be (b3, in2); -+ in5 = asm_xor (rkeylast, in5); -+ in6 = asm_xor (rkeylast, in6); -+ b0 = VEC_BE_SWAP (b0, bige_const); -+ b1 = VEC_BE_SWAP (b1, bige_const); -+ b4 = asm_ncipherlast_be (b4, in3); -+ b5 = asm_ncipherlast_be (b5, in4); -+ b2 = VEC_BE_SWAP (b2, bige_const); -+ b3 = VEC_BE_SWAP (b3, bige_const); -+ b6 = asm_ncipherlast_be (b6, in5); -+ b7 = asm_ncipherlast_be (b7, in6); -+ b4 = VEC_BE_SWAP (b4, bige_const); -+ b5 = VEC_BE_SWAP (b5, bige_const); -+ b6 = VEC_BE_SWAP (b6, bige_const); -+ b7 = VEC_BE_SWAP (b7, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 0, b0); -+ VEC_STORE_BE_NOSWAP (out, 1, b1); -+ VEC_STORE_BE_NOSWAP (out, 2, b2); -+ VEC_STORE_BE_NOSWAP (out, 3, b3); -+ VEC_STORE_BE_NOSWAP (out, 4, b4); -+ VEC_STORE_BE_NOSWAP (out, 5, b5); -+ VEC_STORE_BE_NOSWAP (out, 6, b6); -+ VEC_STORE_BE_NOSWAP (out, 7, b7); -+ out += 8; -+ } -+ -+ if (nblocks >= 4) -+ { -+ in0 = VEC_LOAD_BE (in, 0, bige_const); -+ in1 = VEC_LOAD_BE (in, 1, bige_const); -+ in2 = VEC_LOAD_BE (in, 2, bige_const); -+ in3 = VEC_LOAD_BE (in, 3, bige_const); -+ -+ b0 = asm_xor (rkey0, in0); -+ b1 = asm_xor (rkey0, in1); -+ b2 = asm_xor (rkey0, in2); -+ b3 = asm_xor (rkey0, in3); -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_ncipher_be (b0, rkey); \ -+ b1 = asm_ncipher_be (b1, rkey); \ -+ b2 = asm_ncipher_be (b2, rkey); \ -+ b3 = asm_ncipher_be (b3, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ iv = asm_xor (rkeylast, iv); -+ in0 = asm_xor (rkeylast, in0); -+ in1 = asm_xor (rkeylast, in1); -+ in2 = asm_xor (rkeylast, in2); -+ -+ b0 = asm_ncipherlast_be (b0, iv); -+ iv = in3; -+ b1 = asm_ncipherlast_be (b1, in0); -+ b2 = asm_ncipherlast_be (b2, in1); -+ b3 = asm_ncipherlast_be (b3, in2); -+ -+ VEC_STORE_BE (out, 0, b0, bige_const); -+ VEC_STORE_BE (out, 1, b1, bige_const); -+ VEC_STORE_BE (out, 2, b2, bige_const); -+ VEC_STORE_BE (out, 3, b3, bige_const); -+ -+ in += 4; -+ out += 4; -+ nblocks -= 4; -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ rkeylast = rkeylast_orig ^ iv; -+ -+ iv = VEC_LOAD_BE (in, 0, bige_const); -+ b = iv; -+ AES_DECRYPT (b, rounds); -+ -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ in++; -+ out++; -+ } -+ -+ VEC_STORE_BE (iv_arg, 0, iv, bige_const); -+} -+ -+ -+void CTR_ENC_FUNC (void *context, unsigned char *ctr_arg, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks) -+{ -+ static const unsigned char vec_one_const[16] = -+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; -+ const block bige_const = asm_load_be_const(); -+ RIJNDAEL_context *ctx = context; -+ const u128_t *rk = (u128_t *)&ctx->keyschenc; -+ const u128_t *in = (const u128_t *)inbuf_arg; -+ u128_t *out = (u128_t *)outbuf_arg; -+ int rounds = ctx->rounds; -+ ROUND_KEY_VARIABLES; -+ block rkeylast_orig; -+ block ctr, b, one; -+ -+ ctr = VEC_LOAD_BE (ctr_arg, 0, bige_const); -+ one = VEC_LOAD_BE (&vec_one_const, 0, bige_const); -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ rkeylast_orig = rkeylast; -+ -+ if (nblocks >= 4) -+ { -+ block in0, in1, in2, in3, in4, in5, in6, in7; -+ block b0, b1, b2, b3, b4, b5, b6, b7; -+ block two, three, four; -+ block rkey; -+ -+ two = asm_add_uint128 (one, one); -+ three = asm_add_uint128 (two, one); -+ four = asm_add_uint128 (two, two); -+ -+ for (; nblocks >= 8; nblocks -= 8) -+ { -+ b1 = asm_add_uint128 (ctr, one); -+ b2 = asm_add_uint128 (ctr, two); -+ b3 = asm_add_uint128 (ctr, three); -+ b4 = asm_add_uint128 (ctr, four); -+ b5 = asm_add_uint128 (b1, four); -+ b6 = asm_add_uint128 (b2, four); -+ b7 = asm_add_uint128 (b3, four); -+ b0 = asm_xor (rkey0, ctr); -+ rkey = ALIGNED_LOAD (rk, 1); -+ ctr = asm_add_uint128 (b4, four); -+ b1 = asm_xor (rkey0, b1); -+ b2 = asm_xor (rkey0, b2); -+ b3 = asm_xor (rkey0, b3); -+ b0 = asm_cipher_be (b0, rkey); -+ b1 = asm_cipher_be (b1, rkey); -+ b2 = asm_cipher_be (b2, rkey); -+ b3 = asm_cipher_be (b3, rkey); -+ b4 = asm_xor (rkey0, b4); -+ b5 = asm_xor (rkey0, b5); -+ b6 = asm_xor (rkey0, b6); -+ b7 = asm_xor (rkey0, b7); -+ b4 = asm_cipher_be (b4, rkey); -+ b5 = asm_cipher_be (b5, rkey); -+ b6 = asm_cipher_be (b6, rkey); -+ b7 = asm_cipher_be (b7, rkey); -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); \ -+ b4 = asm_cipher_be (b4, rkey); \ -+ b5 = asm_cipher_be (b5, rkey); \ -+ b6 = asm_cipher_be (b6, rkey); \ -+ b7 = asm_cipher_be (b7, rkey); -+ -+ in0 = VEC_LOAD_BE_NOSWAP (in, 0); -+ DO_ROUND(2); -+ in1 = VEC_LOAD_BE_NOSWAP (in, 1); -+ DO_ROUND(3); -+ in2 = VEC_LOAD_BE_NOSWAP (in, 2); -+ DO_ROUND(4); -+ in3 = VEC_LOAD_BE_NOSWAP (in, 3); -+ DO_ROUND(5); -+ in4 = VEC_LOAD_BE_NOSWAP (in, 4); -+ DO_ROUND(6); -+ in5 = VEC_LOAD_BE_NOSWAP (in, 5); -+ DO_ROUND(7); -+ in6 = VEC_LOAD_BE_NOSWAP (in, 6); -+ DO_ROUND(8); -+ in7 = VEC_LOAD_BE_NOSWAP (in, 7); -+ in += 8; -+ DO_ROUND(9); -+ -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ in0 = VEC_BE_SWAP (in0, bige_const); -+ in1 = VEC_BE_SWAP (in1, bige_const); -+ in2 = VEC_BE_SWAP (in2, bige_const); -+ in3 = VEC_BE_SWAP (in3, bige_const); -+ in4 = VEC_BE_SWAP (in4, bige_const); -+ in5 = VEC_BE_SWAP (in5, bige_const); -+ in6 = VEC_BE_SWAP (in6, bige_const); -+ in7 = VEC_BE_SWAP (in7, bige_const); -+ -+ in0 = asm_xor (rkeylast, in0); -+ in1 = asm_xor (rkeylast, in1); -+ in2 = asm_xor (rkeylast, in2); -+ in3 = asm_xor (rkeylast, in3); -+ b0 = asm_cipherlast_be (b0, in0); -+ b1 = asm_cipherlast_be (b1, in1); -+ in4 = asm_xor (rkeylast, in4); -+ in5 = asm_xor (rkeylast, in5); -+ b2 = asm_cipherlast_be (b2, in2); -+ b3 = asm_cipherlast_be (b3, in3); -+ in6 = asm_xor (rkeylast, in6); -+ in7 = asm_xor (rkeylast, in7); -+ b4 = asm_cipherlast_be (b4, in4); -+ b5 = asm_cipherlast_be (b5, in5); -+ b6 = asm_cipherlast_be (b6, in6); -+ b7 = asm_cipherlast_be (b7, in7); -+ -+ b0 = VEC_BE_SWAP (b0, bige_const); -+ b1 = VEC_BE_SWAP (b1, bige_const); -+ b2 = VEC_BE_SWAP (b2, bige_const); -+ b3 = VEC_BE_SWAP (b3, bige_const); -+ b4 = VEC_BE_SWAP (b4, bige_const); -+ b5 = VEC_BE_SWAP (b5, bige_const); -+ b6 = VEC_BE_SWAP (b6, bige_const); -+ b7 = VEC_BE_SWAP (b7, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 0, b0); -+ VEC_STORE_BE_NOSWAP (out, 1, b1); -+ VEC_STORE_BE_NOSWAP (out, 2, b2); -+ VEC_STORE_BE_NOSWAP (out, 3, b3); -+ VEC_STORE_BE_NOSWAP (out, 4, b4); -+ VEC_STORE_BE_NOSWAP (out, 5, b5); -+ VEC_STORE_BE_NOSWAP (out, 6, b6); -+ VEC_STORE_BE_NOSWAP (out, 7, b7); -+ out += 8; -+ } -+ -+ if (nblocks >= 4) -+ { -+ b1 = asm_add_uint128 (ctr, one); -+ b2 = asm_add_uint128 (ctr, two); -+ b3 = asm_add_uint128 (ctr, three); -+ b0 = asm_xor (rkey0, ctr); -+ ctr = asm_add_uint128 (ctr, four); -+ b1 = asm_xor (rkey0, b1); -+ b2 = asm_xor (rkey0, b2); -+ b3 = asm_xor (rkey0, b3); -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ -+ in0 = VEC_LOAD_BE (in, 0, bige_const); -+ in1 = VEC_LOAD_BE (in, 1, bige_const); -+ in2 = VEC_LOAD_BE (in, 2, bige_const); -+ in3 = VEC_LOAD_BE (in, 3, bige_const); -+ -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ in0 = asm_xor (rkeylast, in0); -+ in1 = asm_xor (rkeylast, in1); -+ in2 = asm_xor (rkeylast, in2); -+ in3 = asm_xor (rkeylast, in3); -+ -+ b0 = asm_cipherlast_be (b0, in0); -+ b1 = asm_cipherlast_be (b1, in1); -+ b2 = asm_cipherlast_be (b2, in2); -+ b3 = asm_cipherlast_be (b3, in3); -+ -+ VEC_STORE_BE (out, 0, b0, bige_const); -+ VEC_STORE_BE (out, 1, b1, bige_const); -+ VEC_STORE_BE (out, 2, b2, bige_const); -+ VEC_STORE_BE (out, 3, b3, bige_const); -+ -+ in += 4; -+ out += 4; -+ nblocks -= 4; -+ } -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ b = ctr; -+ ctr = asm_add_uint128 (ctr, one); -+ rkeylast = rkeylast_orig ^ VEC_LOAD_BE (in, 0, bige_const); -+ -+ AES_ENCRYPT (b, rounds); -+ -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ out++; -+ in++; -+ } -+ -+ VEC_STORE_BE (ctr_arg, 0, ctr, bige_const); -+} -+ -+ -+size_t OCB_CRYPT_FUNC (gcry_cipher_hd_t c, void *outbuf_arg, -+ const void *inbuf_arg, size_t nblocks, -+ int encrypt) -+{ -+ const block bige_const = asm_load_be_const(); -+ RIJNDAEL_context *ctx = (void *)&c->context.c; -+ const u128_t *in = (const u128_t *)inbuf_arg; -+ u128_t *out = (u128_t *)outbuf_arg; -+ int rounds = ctx->rounds; -+ u64 data_nblocks = c->u_mode.ocb.data_nblocks; -+ block l0, l1, l2, l; -+ block b0, b1, b2, b3, b4, b5, b6, b7, b; -+ block iv0, iv1, iv2, iv3, iv4, iv5, iv6, iv7; -+ block rkey, rkeylf; -+ block ctr, iv; -+ ROUND_KEY_VARIABLES; -+ -+ iv = VEC_LOAD_BE (c->u_iv.iv, 0, bige_const); -+ ctr = VEC_LOAD_BE (c->u_ctr.ctr, 0, bige_const); -+ -+ l0 = VEC_LOAD_BE (c->u_mode.ocb.L[0], 0, bige_const); -+ l1 = VEC_LOAD_BE (c->u_mode.ocb.L[1], 0, bige_const); -+ l2 = VEC_LOAD_BE (c->u_mode.ocb.L[2], 0, bige_const); -+ -+ if (encrypt) -+ { -+ const u128_t *rk = (u128_t *)&ctx->keyschenc; -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ -+ for (; nblocks >= 8 && data_nblocks % 8; nblocks--) -+ { -+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); -+ b = VEC_LOAD_BE (in, 0, bige_const); -+ -+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -+ iv ^= l; -+ /* Checksum_i = Checksum_{i-1} xor P_i */ -+ ctr ^= b; -+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ -+ b ^= iv; -+ AES_ENCRYPT (b, rounds); -+ b ^= iv; -+ -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ in += 1; -+ out += 1; -+ } -+ -+ for (; nblocks >= 8; nblocks -= 8) -+ { -+ b0 = VEC_LOAD_BE_NOSWAP (in, 0); -+ b1 = VEC_LOAD_BE_NOSWAP (in, 1); -+ b2 = VEC_LOAD_BE_NOSWAP (in, 2); -+ b3 = VEC_LOAD_BE_NOSWAP (in, 3); -+ b4 = VEC_LOAD_BE_NOSWAP (in, 4); -+ b5 = VEC_LOAD_BE_NOSWAP (in, 5); -+ b6 = VEC_LOAD_BE_NOSWAP (in, 6); -+ b7 = VEC_LOAD_BE_NOSWAP (in, 7); -+ in += 8; -+ l = VEC_LOAD_BE_NOSWAP (ocb_get_l (c, data_nblocks += 8), 0); -+ b0 = VEC_BE_SWAP(b0, bige_const); -+ b1 = VEC_BE_SWAP(b1, bige_const); -+ b2 = VEC_BE_SWAP(b2, bige_const); -+ b3 = VEC_BE_SWAP(b3, bige_const); -+ b4 = VEC_BE_SWAP(b4, bige_const); -+ b5 = VEC_BE_SWAP(b5, bige_const); -+ b6 = VEC_BE_SWAP(b6, bige_const); -+ b7 = VEC_BE_SWAP(b7, bige_const); -+ l = VEC_BE_SWAP(l, bige_const); -+ -+ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7; -+ -+ iv ^= rkey0; -+ -+ iv0 = iv ^ l0; -+ iv1 = iv ^ l0 ^ l1; -+ iv2 = iv ^ l1; -+ iv3 = iv ^ l1 ^ l2; -+ iv4 = iv ^ l1 ^ l2 ^ l0; -+ iv5 = iv ^ l2 ^ l0; -+ iv6 = iv ^ l2; -+ iv7 = iv ^ l2 ^ l; -+ -+ b0 ^= iv0; -+ b1 ^= iv1; -+ b2 ^= iv2; -+ b3 ^= iv3; -+ b4 ^= iv4; -+ b5 ^= iv5; -+ b6 ^= iv6; -+ b7 ^= iv7; -+ iv = iv7 ^ rkey0; -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); \ -+ b4 = asm_cipher_be (b4, rkey); \ -+ b5 = asm_cipher_be (b5, rkey); \ -+ b6 = asm_cipher_be (b6, rkey); \ -+ b7 = asm_cipher_be (b7, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ -+ rkeylf = asm_xor (rkeylast, rkey0); -+ -+ DO_ROUND(8); -+ -+ iv0 = asm_xor (rkeylf, iv0); -+ iv1 = asm_xor (rkeylf, iv1); -+ iv2 = asm_xor (rkeylf, iv2); -+ iv3 = asm_xor (rkeylf, iv3); -+ iv4 = asm_xor (rkeylf, iv4); -+ iv5 = asm_xor (rkeylf, iv5); -+ iv6 = asm_xor (rkeylf, iv6); -+ iv7 = asm_xor (rkeylf, iv7); -+ -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ b0 = asm_cipherlast_be (b0, iv0); -+ b1 = asm_cipherlast_be (b1, iv1); -+ b2 = asm_cipherlast_be (b2, iv2); -+ b3 = asm_cipherlast_be (b3, iv3); -+ b4 = asm_cipherlast_be (b4, iv4); -+ b5 = asm_cipherlast_be (b5, iv5); -+ b6 = asm_cipherlast_be (b6, iv6); -+ b7 = asm_cipherlast_be (b7, iv7); -+ -+ b0 = VEC_BE_SWAP (b0, bige_const); -+ b1 = VEC_BE_SWAP (b1, bige_const); -+ b2 = VEC_BE_SWAP (b2, bige_const); -+ b3 = VEC_BE_SWAP (b3, bige_const); -+ b4 = VEC_BE_SWAP (b4, bige_const); -+ b5 = VEC_BE_SWAP (b5, bige_const); -+ b6 = VEC_BE_SWAP (b6, bige_const); -+ b7 = VEC_BE_SWAP (b7, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 0, b0); -+ VEC_STORE_BE_NOSWAP (out, 1, b1); -+ VEC_STORE_BE_NOSWAP (out, 2, b2); -+ VEC_STORE_BE_NOSWAP (out, 3, b3); -+ VEC_STORE_BE_NOSWAP (out, 4, b4); -+ VEC_STORE_BE_NOSWAP (out, 5, b5); -+ VEC_STORE_BE_NOSWAP (out, 6, b6); -+ VEC_STORE_BE_NOSWAP (out, 7, b7); -+ out += 8; -+ } -+ -+ if (nblocks >= 4 && (data_nblocks % 4) == 0) -+ { -+ b0 = VEC_LOAD_BE (in, 0, bige_const); -+ b1 = VEC_LOAD_BE (in, 1, bige_const); -+ b2 = VEC_LOAD_BE (in, 2, bige_const); -+ b3 = VEC_LOAD_BE (in, 3, bige_const); -+ -+ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const); -+ -+ ctr ^= b0 ^ b1 ^ b2 ^ b3; -+ -+ iv ^= rkey0; -+ -+ iv0 = iv ^ l0; -+ iv1 = iv ^ l0 ^ l1; -+ iv2 = iv ^ l1; -+ iv3 = iv ^ l1 ^ l; -+ -+ b0 ^= iv0; -+ b1 ^= iv1; -+ b2 ^= iv2; -+ b3 ^= iv3; -+ iv = iv3 ^ rkey0; -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ rkey = rkeylast ^ rkey0; -+ b0 = asm_cipherlast_be (b0, rkey ^ iv0); -+ b1 = asm_cipherlast_be (b1, rkey ^ iv1); -+ b2 = asm_cipherlast_be (b2, rkey ^ iv2); -+ b3 = asm_cipherlast_be (b3, rkey ^ iv3); -+ -+ VEC_STORE_BE (out, 0, b0, bige_const); -+ VEC_STORE_BE (out, 1, b1, bige_const); -+ VEC_STORE_BE (out, 2, b2, bige_const); -+ VEC_STORE_BE (out, 3, b3, bige_const); -+ -+ in += 4; -+ out += 4; -+ nblocks -= 4; -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); -+ b = VEC_LOAD_BE (in, 0, bige_const); -+ -+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -+ iv ^= l; -+ /* Checksum_i = Checksum_{i-1} xor P_i */ -+ ctr ^= b; -+ /* C_i = Offset_i xor ENCIPHER(K, P_i xor Offset_i) */ -+ b ^= iv; -+ AES_ENCRYPT (b, rounds); -+ b ^= iv; -+ -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ in += 1; -+ out += 1; -+ } -+ } -+ else -+ { -+ const u128_t *rk = (u128_t *)&ctx->keyschdec; -+ -+ if (!ctx->decryption_prepared) -+ { -+ internal_aes_ppc_prepare_decryption (ctx); -+ ctx->decryption_prepared = 1; -+ } -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ -+ for (; nblocks >= 8 && data_nblocks % 8; nblocks--) -+ { -+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); -+ b = VEC_LOAD_BE (in, 0, bige_const); -+ -+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -+ iv ^= l; -+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ -+ b ^= iv; -+ AES_DECRYPT (b, rounds); -+ b ^= iv; -+ /* Checksum_i = Checksum_{i-1} xor P_i */ -+ ctr ^= b; -+ -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ in += 1; -+ out += 1; -+ } -+ -+ for (; nblocks >= 8; nblocks -= 8) -+ { -+ b0 = VEC_LOAD_BE_NOSWAP (in, 0); -+ b1 = VEC_LOAD_BE_NOSWAP (in, 1); -+ b2 = VEC_LOAD_BE_NOSWAP (in, 2); -+ b3 = VEC_LOAD_BE_NOSWAP (in, 3); -+ b4 = VEC_LOAD_BE_NOSWAP (in, 4); -+ b5 = VEC_LOAD_BE_NOSWAP (in, 5); -+ b6 = VEC_LOAD_BE_NOSWAP (in, 6); -+ b7 = VEC_LOAD_BE_NOSWAP (in, 7); -+ in += 8; -+ l = VEC_LOAD_BE_NOSWAP (ocb_get_l (c, data_nblocks += 8), 0); -+ b0 = VEC_BE_SWAP(b0, bige_const); -+ b1 = VEC_BE_SWAP(b1, bige_const); -+ b2 = VEC_BE_SWAP(b2, bige_const); -+ b3 = VEC_BE_SWAP(b3, bige_const); -+ b4 = VEC_BE_SWAP(b4, bige_const); -+ b5 = VEC_BE_SWAP(b5, bige_const); -+ b6 = VEC_BE_SWAP(b6, bige_const); -+ b7 = VEC_BE_SWAP(b7, bige_const); -+ l = VEC_BE_SWAP(l, bige_const); -+ -+ iv ^= rkey0; -+ -+ iv0 = iv ^ l0; -+ iv1 = iv ^ l0 ^ l1; -+ iv2 = iv ^ l1; -+ iv3 = iv ^ l1 ^ l2; -+ iv4 = iv ^ l1 ^ l2 ^ l0; -+ iv5 = iv ^ l2 ^ l0; -+ iv6 = iv ^ l2; -+ iv7 = iv ^ l2 ^ l; -+ -+ b0 ^= iv0; -+ b1 ^= iv1; -+ b2 ^= iv2; -+ b3 ^= iv3; -+ b4 ^= iv4; -+ b5 ^= iv5; -+ b6 ^= iv6; -+ b7 ^= iv7; -+ iv = iv7 ^ rkey0; -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_ncipher_be (b0, rkey); \ -+ b1 = asm_ncipher_be (b1, rkey); \ -+ b2 = asm_ncipher_be (b2, rkey); \ -+ b3 = asm_ncipher_be (b3, rkey); \ -+ b4 = asm_ncipher_be (b4, rkey); \ -+ b5 = asm_ncipher_be (b5, rkey); \ -+ b6 = asm_ncipher_be (b6, rkey); \ -+ b7 = asm_ncipher_be (b7, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ -+ rkeylf = asm_xor (rkeylast, rkey0); -+ -+ DO_ROUND(8); -+ -+ iv0 = asm_xor (rkeylf, iv0); -+ iv1 = asm_xor (rkeylf, iv1); -+ iv2 = asm_xor (rkeylf, iv2); -+ iv3 = asm_xor (rkeylf, iv3); -+ iv4 = asm_xor (rkeylf, iv4); -+ iv5 = asm_xor (rkeylf, iv5); -+ iv6 = asm_xor (rkeylf, iv6); -+ iv7 = asm_xor (rkeylf, iv7); -+ -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ b0 = asm_ncipherlast_be (b0, iv0); -+ b1 = asm_ncipherlast_be (b1, iv1); -+ b2 = asm_ncipherlast_be (b2, iv2); -+ b3 = asm_ncipherlast_be (b3, iv3); -+ b4 = asm_ncipherlast_be (b4, iv4); -+ b5 = asm_ncipherlast_be (b5, iv5); -+ b6 = asm_ncipherlast_be (b6, iv6); -+ b7 = asm_ncipherlast_be (b7, iv7); -+ -+ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7; -+ -+ b0 = VEC_BE_SWAP (b0, bige_const); -+ b1 = VEC_BE_SWAP (b1, bige_const); -+ b2 = VEC_BE_SWAP (b2, bige_const); -+ b3 = VEC_BE_SWAP (b3, bige_const); -+ b4 = VEC_BE_SWAP (b4, bige_const); -+ b5 = VEC_BE_SWAP (b5, bige_const); -+ b6 = VEC_BE_SWAP (b6, bige_const); -+ b7 = VEC_BE_SWAP (b7, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 0, b0); -+ VEC_STORE_BE_NOSWAP (out, 1, b1); -+ VEC_STORE_BE_NOSWAP (out, 2, b2); -+ VEC_STORE_BE_NOSWAP (out, 3, b3); -+ VEC_STORE_BE_NOSWAP (out, 4, b4); -+ VEC_STORE_BE_NOSWAP (out, 5, b5); -+ VEC_STORE_BE_NOSWAP (out, 6, b6); -+ VEC_STORE_BE_NOSWAP (out, 7, b7); -+ out += 8; -+ } -+ -+ if (nblocks >= 4 && (data_nblocks % 4) == 0) -+ { -+ b0 = VEC_LOAD_BE (in, 0, bige_const); -+ b1 = VEC_LOAD_BE (in, 1, bige_const); -+ b2 = VEC_LOAD_BE (in, 2, bige_const); -+ b3 = VEC_LOAD_BE (in, 3, bige_const); -+ -+ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const); -+ -+ iv ^= rkey0; -+ -+ iv0 = iv ^ l0; -+ iv1 = iv ^ l0 ^ l1; -+ iv2 = iv ^ l1; -+ iv3 = iv ^ l1 ^ l; -+ -+ b0 ^= iv0; -+ b1 ^= iv1; -+ b2 ^= iv2; -+ b3 ^= iv3; -+ iv = iv3 ^ rkey0; -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_ncipher_be (b0, rkey); \ -+ b1 = asm_ncipher_be (b1, rkey); \ -+ b2 = asm_ncipher_be (b2, rkey); \ -+ b3 = asm_ncipher_be (b3, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ rkey = rkeylast ^ rkey0; -+ b0 = asm_ncipherlast_be (b0, rkey ^ iv0); -+ b1 = asm_ncipherlast_be (b1, rkey ^ iv1); -+ b2 = asm_ncipherlast_be (b2, rkey ^ iv2); -+ b3 = asm_ncipherlast_be (b3, rkey ^ iv3); -+ -+ VEC_STORE_BE (out, 0, b0, bige_const); -+ VEC_STORE_BE (out, 1, b1, bige_const); -+ VEC_STORE_BE (out, 2, b2, bige_const); -+ VEC_STORE_BE (out, 3, b3, bige_const); -+ -+ ctr ^= b0 ^ b1 ^ b2 ^ b3; -+ -+ in += 4; -+ out += 4; -+ nblocks -= 4; -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); -+ b = VEC_LOAD_BE (in, 0, bige_const); -+ -+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -+ iv ^= l; -+ /* P_i = Offset_i xor DECIPHER(K, C_i xor Offset_i) */ -+ b ^= iv; -+ AES_DECRYPT (b, rounds); -+ b ^= iv; -+ /* Checksum_i = Checksum_{i-1} xor P_i */ -+ ctr ^= b; -+ -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ in += 1; -+ out += 1; -+ } -+ } -+ -+ VEC_STORE_BE (c->u_iv.iv, 0, iv, bige_const); -+ VEC_STORE_BE (c->u_ctr.ctr, 0, ctr, bige_const); -+ c->u_mode.ocb.data_nblocks = data_nblocks; -+ -+ return 0; -+} -+ -+size_t OCB_AUTH_FUNC (gcry_cipher_hd_t c, void *abuf_arg, size_t nblocks) -+{ -+ const block bige_const = asm_load_be_const(); -+ RIJNDAEL_context *ctx = (void *)&c->context.c; -+ const u128_t *rk = (u128_t *)&ctx->keyschenc; -+ const u128_t *abuf = (const u128_t *)abuf_arg; -+ int rounds = ctx->rounds; -+ u64 data_nblocks = c->u_mode.ocb.aad_nblocks; -+ block l0, l1, l2, l; -+ block b0, b1, b2, b3, b4, b5, b6, b7, b; -+ block iv0, iv1, iv2, iv3, iv4, iv5, iv6, iv7; -+ block rkey, frkey; -+ block ctr, iv; -+ ROUND_KEY_VARIABLES; -+ -+ iv = VEC_LOAD_BE (c->u_mode.ocb.aad_offset, 0, bige_const); -+ ctr = VEC_LOAD_BE (c->u_mode.ocb.aad_sum, 0, bige_const); -+ -+ l0 = VEC_LOAD_BE (c->u_mode.ocb.L[0], 0, bige_const); -+ l1 = VEC_LOAD_BE (c->u_mode.ocb.L[1], 0, bige_const); -+ l2 = VEC_LOAD_BE (c->u_mode.ocb.L[2], 0, bige_const); -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ -+ for (; nblocks >= 8 && data_nblocks % 8; nblocks--) -+ { -+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); -+ b = VEC_LOAD_BE (abuf, 0, bige_const); -+ -+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -+ iv ^= l; -+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ -+ b ^= iv; -+ AES_ENCRYPT (b, rounds); -+ ctr ^= b; -+ -+ abuf += 1; -+ } -+ -+ for (; nblocks >= 8; nblocks -= 8) -+ { -+ b0 = VEC_LOAD_BE (abuf, 0, bige_const); -+ b1 = VEC_LOAD_BE (abuf, 1, bige_const); -+ b2 = VEC_LOAD_BE (abuf, 2, bige_const); -+ b3 = VEC_LOAD_BE (abuf, 3, bige_const); -+ b4 = VEC_LOAD_BE (abuf, 4, bige_const); -+ b5 = VEC_LOAD_BE (abuf, 5, bige_const); -+ b6 = VEC_LOAD_BE (abuf, 6, bige_const); -+ b7 = VEC_LOAD_BE (abuf, 7, bige_const); -+ -+ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 8), 0, bige_const); -+ -+ frkey = rkey0; -+ iv ^= frkey; -+ -+ iv0 = iv ^ l0; -+ iv1 = iv ^ l0 ^ l1; -+ iv2 = iv ^ l1; -+ iv3 = iv ^ l1 ^ l2; -+ iv4 = iv ^ l1 ^ l2 ^ l0; -+ iv5 = iv ^ l2 ^ l0; -+ iv6 = iv ^ l2; -+ iv7 = iv ^ l2 ^ l; -+ -+ b0 ^= iv0; -+ b1 ^= iv1; -+ b2 ^= iv2; -+ b3 ^= iv3; -+ b4 ^= iv4; -+ b5 ^= iv5; -+ b6 ^= iv6; -+ b7 ^= iv7; -+ iv = iv7 ^ frkey; -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); \ -+ b4 = asm_cipher_be (b4, rkey); \ -+ b5 = asm_cipher_be (b5, rkey); \ -+ b6 = asm_cipher_be (b6, rkey); \ -+ b7 = asm_cipher_be (b7, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ rkey = rkeylast; -+ b0 = asm_cipherlast_be (b0, rkey); -+ b1 = asm_cipherlast_be (b1, rkey); -+ b2 = asm_cipherlast_be (b2, rkey); -+ b3 = asm_cipherlast_be (b3, rkey); -+ b4 = asm_cipherlast_be (b4, rkey); -+ b5 = asm_cipherlast_be (b5, rkey); -+ b6 = asm_cipherlast_be (b6, rkey); -+ b7 = asm_cipherlast_be (b7, rkey); -+ -+ ctr ^= b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7; -+ -+ abuf += 8; -+ } -+ -+ if (nblocks >= 4 && (data_nblocks % 4) == 0) -+ { -+ b0 = VEC_LOAD_BE (abuf, 0, bige_const); -+ b1 = VEC_LOAD_BE (abuf, 1, bige_const); -+ b2 = VEC_LOAD_BE (abuf, 2, bige_const); -+ b3 = VEC_LOAD_BE (abuf, 3, bige_const); -+ -+ l = VEC_LOAD_BE (ocb_get_l (c, data_nblocks += 4), 0, bige_const); -+ -+ frkey = rkey0; -+ iv ^= frkey; -+ -+ iv0 = iv ^ l0; -+ iv1 = iv ^ l0 ^ l1; -+ iv2 = iv ^ l1; -+ iv3 = iv ^ l1 ^ l; -+ -+ b0 ^= iv0; -+ b1 ^= iv1; -+ b2 ^= iv2; -+ b3 ^= iv3; -+ iv = iv3 ^ frkey; -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ rkey = rkeylast; -+ b0 = asm_cipherlast_be (b0, rkey); -+ b1 = asm_cipherlast_be (b1, rkey); -+ b2 = asm_cipherlast_be (b2, rkey); -+ b3 = asm_cipherlast_be (b3, rkey); -+ -+ ctr ^= b0 ^ b1 ^ b2 ^ b3; -+ -+ abuf += 4; -+ nblocks -= 4; -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ l = VEC_LOAD_BE (ocb_get_l (c, ++data_nblocks), 0, bige_const); -+ b = VEC_LOAD_BE (abuf, 0, bige_const); -+ -+ /* Offset_i = Offset_{i-1} xor L_{ntz(i)} */ -+ iv ^= l; -+ /* Sum_i = Sum_{i-1} xor ENCIPHER(K, A_i xor Offset_i) */ -+ b ^= iv; -+ AES_ENCRYPT (b, rounds); -+ ctr ^= b; -+ -+ abuf += 1; -+ } -+ -+ VEC_STORE_BE (c->u_mode.ocb.aad_offset, 0, iv, bige_const); -+ VEC_STORE_BE (c->u_mode.ocb.aad_sum, 0, ctr, bige_const); -+ c->u_mode.ocb.aad_nblocks = data_nblocks; -+ -+ return 0; -+} -+ -+ -+void XTS_CRYPT_FUNC (void *context, unsigned char *tweak_arg, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, int encrypt) -+{ -+#ifdef WORDS_BIGENDIAN -+ static const block vec_bswap128_const = -+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; -+#else -+ static const block vec_bswap128_const = -+ { ~15, ~14, ~13, ~12, ~11, ~10, ~9, ~8, ~7, ~6, ~5, ~4, ~3, ~2, ~1, ~0 }; -+#endif -+ static const unsigned char vec_tweak_const[16] = -+ { 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x87 }; -+ static const vector unsigned long long vec_shift63_const = -+ { 63, 63 }; -+ const block bige_const = asm_load_be_const(); -+ RIJNDAEL_context *ctx = context; -+ const u128_t *in = (const u128_t *)inbuf_arg; -+ u128_t *out = (u128_t *)outbuf_arg; -+ int rounds = ctx->rounds; -+ block tweak; -+ block b0, b1, b2, b3, b4, b5, b6, b7, b, rkey, rkeylf; -+ block tweak0, tweak1, tweak2, tweak3, tweak4, tweak5, tweak6, tweak7; -+ block tweak_const, bswap128_const, shift63_const; -+ ROUND_KEY_VARIABLES; -+ -+ tweak_const = VEC_LOAD_BE (&vec_tweak_const, 0, bige_const); -+ bswap128_const = ALIGNED_LOAD (&vec_bswap128_const, 0); -+ shift63_const = ALIGNED_LOAD (&vec_shift63_const, 0); -+ -+ tweak = VEC_LOAD_BE (tweak_arg, 0, bige_const); -+ tweak = asm_vperm1 (tweak, bswap128_const); -+ -+#define GEN_TWEAK(tout, tin) /* Generate next tweak. */ \ -+ do { \ -+ block tmp1, tmp2; \ -+ tmp1 = asm_swap_uint64_halfs(tin); \ -+ tmp2 = asm_add_uint64(tin, tin); \ -+ tmp1 = asm_sra_int64(tmp1, shift63_const) & tweak_const; \ -+ tout = asm_xor(tmp1, tmp2); \ -+ } while (0) -+ -+ if (encrypt) -+ { -+ const u128_t *rk = (u128_t *)&ctx->keyschenc; -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ -+ for (; nblocks >= 8; nblocks -= 8) -+ { -+ b0 = VEC_LOAD_BE_NOSWAP (in, 0); -+ b1 = VEC_LOAD_BE_NOSWAP (in, 1); -+ b2 = VEC_LOAD_BE_NOSWAP (in, 2); -+ b3 = VEC_LOAD_BE_NOSWAP (in, 3); -+ tweak0 = tweak; -+ GEN_TWEAK (tweak1, tweak0); -+ tweak0 = asm_vperm1 (tweak0, bswap128_const); -+ b4 = VEC_LOAD_BE_NOSWAP (in, 4); -+ b5 = VEC_LOAD_BE_NOSWAP (in, 5); -+ GEN_TWEAK (tweak2, tweak1); -+ tweak1 = asm_vperm1 (tweak1, bswap128_const); -+ b6 = VEC_LOAD_BE_NOSWAP (in, 6); -+ b7 = VEC_LOAD_BE_NOSWAP (in, 7); -+ in += 8; -+ -+ b0 = VEC_BE_SWAP(b0, bige_const); -+ b1 = VEC_BE_SWAP(b1, bige_const); -+ GEN_TWEAK (tweak3, tweak2); -+ tweak2 = asm_vperm1 (tweak2, bswap128_const); -+ GEN_TWEAK (tweak4, tweak3); -+ tweak3 = asm_vperm1 (tweak3, bswap128_const); -+ b2 = VEC_BE_SWAP(b2, bige_const); -+ b3 = VEC_BE_SWAP(b3, bige_const); -+ GEN_TWEAK (tweak5, tweak4); -+ tweak4 = asm_vperm1 (tweak4, bswap128_const); -+ GEN_TWEAK (tweak6, tweak5); -+ tweak5 = asm_vperm1 (tweak5, bswap128_const); -+ b4 = VEC_BE_SWAP(b4, bige_const); -+ b5 = VEC_BE_SWAP(b5, bige_const); -+ GEN_TWEAK (tweak7, tweak6); -+ tweak6 = asm_vperm1 (tweak6, bswap128_const); -+ GEN_TWEAK (tweak, tweak7); -+ tweak7 = asm_vperm1 (tweak7, bswap128_const); -+ b6 = VEC_BE_SWAP(b6, bige_const); -+ b7 = VEC_BE_SWAP(b7, bige_const); -+ -+ tweak0 = asm_xor (tweak0, rkey0); -+ tweak1 = asm_xor (tweak1, rkey0); -+ tweak2 = asm_xor (tweak2, rkey0); -+ tweak3 = asm_xor (tweak3, rkey0); -+ tweak4 = asm_xor (tweak4, rkey0); -+ tweak5 = asm_xor (tweak5, rkey0); -+ tweak6 = asm_xor (tweak6, rkey0); -+ tweak7 = asm_xor (tweak7, rkey0); -+ -+ b0 = asm_xor (b0, tweak0); -+ b1 = asm_xor (b1, tweak1); -+ b2 = asm_xor (b2, tweak2); -+ b3 = asm_xor (b3, tweak3); -+ b4 = asm_xor (b4, tweak4); -+ b5 = asm_xor (b5, tweak5); -+ b6 = asm_xor (b6, tweak6); -+ b7 = asm_xor (b7, tweak7); -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); \ -+ b4 = asm_cipher_be (b4, rkey); \ -+ b5 = asm_cipher_be (b5, rkey); \ -+ b6 = asm_cipher_be (b6, rkey); \ -+ b7 = asm_cipher_be (b7, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ -+ rkeylf = asm_xor (rkeylast, rkey0); -+ -+ DO_ROUND(8); -+ -+ tweak0 = asm_xor (tweak0, rkeylf); -+ tweak1 = asm_xor (tweak1, rkeylf); -+ tweak2 = asm_xor (tweak2, rkeylf); -+ tweak3 = asm_xor (tweak3, rkeylf); -+ tweak4 = asm_xor (tweak4, rkeylf); -+ tweak5 = asm_xor (tweak5, rkeylf); -+ tweak6 = asm_xor (tweak6, rkeylf); -+ tweak7 = asm_xor (tweak7, rkeylf); -+ -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ b0 = asm_cipherlast_be (b0, tweak0); -+ b1 = asm_cipherlast_be (b1, tweak1); -+ b2 = asm_cipherlast_be (b2, tweak2); -+ b3 = asm_cipherlast_be (b3, tweak3); -+ b0 = VEC_BE_SWAP (b0, bige_const); -+ b1 = VEC_BE_SWAP (b1, bige_const); -+ b4 = asm_cipherlast_be (b4, tweak4); -+ b5 = asm_cipherlast_be (b5, tweak5); -+ b2 = VEC_BE_SWAP (b2, bige_const); -+ b3 = VEC_BE_SWAP (b3, bige_const); -+ b6 = asm_cipherlast_be (b6, tweak6); -+ b7 = asm_cipherlast_be (b7, tweak7); -+ VEC_STORE_BE_NOSWAP (out, 0, b0); -+ VEC_STORE_BE_NOSWAP (out, 1, b1); -+ b4 = VEC_BE_SWAP (b4, bige_const); -+ b5 = VEC_BE_SWAP (b5, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 2, b2); -+ VEC_STORE_BE_NOSWAP (out, 3, b3); -+ b6 = VEC_BE_SWAP (b6, bige_const); -+ b7 = VEC_BE_SWAP (b7, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 4, b4); -+ VEC_STORE_BE_NOSWAP (out, 5, b5); -+ VEC_STORE_BE_NOSWAP (out, 6, b6); -+ VEC_STORE_BE_NOSWAP (out, 7, b7); -+ out += 8; -+ } -+ -+ if (nblocks >= 4) -+ { -+ tweak0 = tweak; -+ GEN_TWEAK (tweak1, tweak0); -+ GEN_TWEAK (tweak2, tweak1); -+ GEN_TWEAK (tweak3, tweak2); -+ GEN_TWEAK (tweak, tweak3); -+ -+ b0 = VEC_LOAD_BE (in, 0, bige_const); -+ b1 = VEC_LOAD_BE (in, 1, bige_const); -+ b2 = VEC_LOAD_BE (in, 2, bige_const); -+ b3 = VEC_LOAD_BE (in, 3, bige_const); -+ -+ tweak0 = asm_vperm1 (tweak0, bswap128_const); -+ tweak1 = asm_vperm1 (tweak1, bswap128_const); -+ tweak2 = asm_vperm1 (tweak2, bswap128_const); -+ tweak3 = asm_vperm1 (tweak3, bswap128_const); -+ -+ b0 ^= tweak0 ^ rkey0; -+ b1 ^= tweak1 ^ rkey0; -+ b2 ^= tweak2 ^ rkey0; -+ b3 ^= tweak3 ^ rkey0; -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_cipher_be (b0, rkey); \ -+ b1 = asm_cipher_be (b1, rkey); \ -+ b2 = asm_cipher_be (b2, rkey); \ -+ b3 = asm_cipher_be (b3, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ rkey = rkeylast; -+ b0 = asm_cipherlast_be (b0, rkey ^ tweak0); -+ b1 = asm_cipherlast_be (b1, rkey ^ tweak1); -+ b2 = asm_cipherlast_be (b2, rkey ^ tweak2); -+ b3 = asm_cipherlast_be (b3, rkey ^ tweak3); -+ -+ VEC_STORE_BE (out, 0, b0, bige_const); -+ VEC_STORE_BE (out, 1, b1, bige_const); -+ VEC_STORE_BE (out, 2, b2, bige_const); -+ VEC_STORE_BE (out, 3, b3, bige_const); -+ -+ in += 4; -+ out += 4; -+ nblocks -= 4; -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ tweak0 = asm_vperm1 (tweak, bswap128_const); -+ -+ /* Xor-Encrypt/Decrypt-Xor block. */ -+ b = VEC_LOAD_BE (in, 0, bige_const) ^ tweak0; -+ -+ /* Generate next tweak. */ -+ GEN_TWEAK (tweak, tweak); -+ -+ AES_ENCRYPT (b, rounds); -+ -+ b ^= tweak0; -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ in++; -+ out++; -+ } -+ } -+ else -+ { -+ const u128_t *rk = (u128_t *)&ctx->keyschdec; -+ -+ if (!ctx->decryption_prepared) -+ { -+ internal_aes_ppc_prepare_decryption (ctx); -+ ctx->decryption_prepared = 1; -+ } -+ -+ PRELOAD_ROUND_KEYS (rounds); -+ -+ for (; nblocks >= 8; nblocks -= 8) -+ { -+ b0 = VEC_LOAD_BE_NOSWAP (in, 0); -+ b1 = VEC_LOAD_BE_NOSWAP (in, 1); -+ b2 = VEC_LOAD_BE_NOSWAP (in, 2); -+ b3 = VEC_LOAD_BE_NOSWAP (in, 3); -+ tweak0 = tweak; -+ GEN_TWEAK (tweak1, tweak0); -+ tweak0 = asm_vperm1 (tweak0, bswap128_const); -+ b4 = VEC_LOAD_BE_NOSWAP (in, 4); -+ b5 = VEC_LOAD_BE_NOSWAP (in, 5); -+ GEN_TWEAK (tweak2, tweak1); -+ tweak1 = asm_vperm1 (tweak1, bswap128_const); -+ b6 = VEC_LOAD_BE_NOSWAP (in, 6); -+ b7 = VEC_LOAD_BE_NOSWAP (in, 7); -+ in += 8; -+ -+ b0 = VEC_BE_SWAP(b0, bige_const); -+ b1 = VEC_BE_SWAP(b1, bige_const); -+ GEN_TWEAK (tweak3, tweak2); -+ tweak2 = asm_vperm1 (tweak2, bswap128_const); -+ GEN_TWEAK (tweak4, tweak3); -+ tweak3 = asm_vperm1 (tweak3, bswap128_const); -+ b2 = VEC_BE_SWAP(b2, bige_const); -+ b3 = VEC_BE_SWAP(b3, bige_const); -+ GEN_TWEAK (tweak5, tweak4); -+ tweak4 = asm_vperm1 (tweak4, bswap128_const); -+ GEN_TWEAK (tweak6, tweak5); -+ tweak5 = asm_vperm1 (tweak5, bswap128_const); -+ b4 = VEC_BE_SWAP(b4, bige_const); -+ b5 = VEC_BE_SWAP(b5, bige_const); -+ GEN_TWEAK (tweak7, tweak6); -+ tweak6 = asm_vperm1 (tweak6, bswap128_const); -+ GEN_TWEAK (tweak, tweak7); -+ tweak7 = asm_vperm1 (tweak7, bswap128_const); -+ b6 = VEC_BE_SWAP(b6, bige_const); -+ b7 = VEC_BE_SWAP(b7, bige_const); -+ -+ tweak0 = asm_xor (tweak0, rkey0); -+ tweak1 = asm_xor (tweak1, rkey0); -+ tweak2 = asm_xor (tweak2, rkey0); -+ tweak3 = asm_xor (tweak3, rkey0); -+ tweak4 = asm_xor (tweak4, rkey0); -+ tweak5 = asm_xor (tweak5, rkey0); -+ tweak6 = asm_xor (tweak6, rkey0); -+ tweak7 = asm_xor (tweak7, rkey0); -+ -+ b0 = asm_xor (b0, tweak0); -+ b1 = asm_xor (b1, tweak1); -+ b2 = asm_xor (b2, tweak2); -+ b3 = asm_xor (b3, tweak3); -+ b4 = asm_xor (b4, tweak4); -+ b5 = asm_xor (b5, tweak5); -+ b6 = asm_xor (b6, tweak6); -+ b7 = asm_xor (b7, tweak7); -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_ncipher_be (b0, rkey); \ -+ b1 = asm_ncipher_be (b1, rkey); \ -+ b2 = asm_ncipher_be (b2, rkey); \ -+ b3 = asm_ncipher_be (b3, rkey); \ -+ b4 = asm_ncipher_be (b4, rkey); \ -+ b5 = asm_ncipher_be (b5, rkey); \ -+ b6 = asm_ncipher_be (b6, rkey); \ -+ b7 = asm_ncipher_be (b7, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ -+ rkeylf = asm_xor (rkeylast, rkey0); -+ -+ DO_ROUND(8); -+ -+ tweak0 = asm_xor (tweak0, rkeylf); -+ tweak1 = asm_xor (tweak1, rkeylf); -+ tweak2 = asm_xor (tweak2, rkeylf); -+ tweak3 = asm_xor (tweak3, rkeylf); -+ tweak4 = asm_xor (tweak4, rkeylf); -+ tweak5 = asm_xor (tweak5, rkeylf); -+ tweak6 = asm_xor (tweak6, rkeylf); -+ tweak7 = asm_xor (tweak7, rkeylf); -+ -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ b0 = asm_ncipherlast_be (b0, tweak0); -+ b1 = asm_ncipherlast_be (b1, tweak1); -+ b2 = asm_ncipherlast_be (b2, tweak2); -+ b3 = asm_ncipherlast_be (b3, tweak3); -+ b0 = VEC_BE_SWAP (b0, bige_const); -+ b1 = VEC_BE_SWAP (b1, bige_const); -+ b4 = asm_ncipherlast_be (b4, tweak4); -+ b5 = asm_ncipherlast_be (b5, tweak5); -+ b2 = VEC_BE_SWAP (b2, bige_const); -+ b3 = VEC_BE_SWAP (b3, bige_const); -+ b6 = asm_ncipherlast_be (b6, tweak6); -+ b7 = asm_ncipherlast_be (b7, tweak7); -+ VEC_STORE_BE_NOSWAP (out, 0, b0); -+ VEC_STORE_BE_NOSWAP (out, 1, b1); -+ b4 = VEC_BE_SWAP (b4, bige_const); -+ b5 = VEC_BE_SWAP (b5, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 2, b2); -+ VEC_STORE_BE_NOSWAP (out, 3, b3); -+ b6 = VEC_BE_SWAP (b6, bige_const); -+ b7 = VEC_BE_SWAP (b7, bige_const); -+ VEC_STORE_BE_NOSWAP (out, 4, b4); -+ VEC_STORE_BE_NOSWAP (out, 5, b5); -+ VEC_STORE_BE_NOSWAP (out, 6, b6); -+ VEC_STORE_BE_NOSWAP (out, 7, b7); -+ out += 8; -+ } -+ -+ if (nblocks >= 4) -+ { -+ tweak0 = tweak; -+ GEN_TWEAK (tweak1, tweak0); -+ GEN_TWEAK (tweak2, tweak1); -+ GEN_TWEAK (tweak3, tweak2); -+ GEN_TWEAK (tweak, tweak3); -+ -+ b0 = VEC_LOAD_BE (in, 0, bige_const); -+ b1 = VEC_LOAD_BE (in, 1, bige_const); -+ b2 = VEC_LOAD_BE (in, 2, bige_const); -+ b3 = VEC_LOAD_BE (in, 3, bige_const); -+ -+ tweak0 = asm_vperm1 (tweak0, bswap128_const); -+ tweak1 = asm_vperm1 (tweak1, bswap128_const); -+ tweak2 = asm_vperm1 (tweak2, bswap128_const); -+ tweak3 = asm_vperm1 (tweak3, bswap128_const); -+ -+ b0 ^= tweak0 ^ rkey0; -+ b1 ^= tweak1 ^ rkey0; -+ b2 ^= tweak2 ^ rkey0; -+ b3 ^= tweak3 ^ rkey0; -+ -+#define DO_ROUND(r) \ -+ rkey = ALIGNED_LOAD (rk, r); \ -+ b0 = asm_ncipher_be (b0, rkey); \ -+ b1 = asm_ncipher_be (b1, rkey); \ -+ b2 = asm_ncipher_be (b2, rkey); \ -+ b3 = asm_ncipher_be (b3, rkey); -+ -+ DO_ROUND(1); -+ DO_ROUND(2); -+ DO_ROUND(3); -+ DO_ROUND(4); -+ DO_ROUND(5); -+ DO_ROUND(6); -+ DO_ROUND(7); -+ DO_ROUND(8); -+ DO_ROUND(9); -+ if (rounds >= 12) -+ { -+ DO_ROUND(10); -+ DO_ROUND(11); -+ if (rounds > 12) -+ { -+ DO_ROUND(12); -+ DO_ROUND(13); -+ } -+ } -+ -+#undef DO_ROUND -+ -+ rkey = rkeylast; -+ b0 = asm_ncipherlast_be (b0, rkey ^ tweak0); -+ b1 = asm_ncipherlast_be (b1, rkey ^ tweak1); -+ b2 = asm_ncipherlast_be (b2, rkey ^ tweak2); -+ b3 = asm_ncipherlast_be (b3, rkey ^ tweak3); -+ -+ VEC_STORE_BE (out, 0, b0, bige_const); -+ VEC_STORE_BE (out, 1, b1, bige_const); -+ VEC_STORE_BE (out, 2, b2, bige_const); -+ VEC_STORE_BE (out, 3, b3, bige_const); -+ -+ in += 4; -+ out += 4; -+ nblocks -= 4; -+ } -+ -+ for (; nblocks; nblocks--) -+ { -+ tweak0 = asm_vperm1 (tweak, bswap128_const); -+ -+ /* Xor-Encrypt/Decrypt-Xor block. */ -+ b = VEC_LOAD_BE (in, 0, bige_const) ^ tweak0; -+ -+ /* Generate next tweak. */ -+ GEN_TWEAK (tweak, tweak); -+ -+ AES_DECRYPT (b, rounds); -+ -+ b ^= tweak0; -+ VEC_STORE_BE (out, 0, b, bige_const); -+ -+ in++; -+ out++; -+ } -+ } -+ -+ tweak = asm_vperm1 (tweak, bswap128_const); -+ VEC_STORE_BE (tweak_arg, 0, tweak, bige_const); -+ -+#undef GEN_TWEAK -+} -diff -up libgcrypt-1.8.5/cipher/rijndael-ssse3-amd64.c.aes-perf libgcrypt-1.8.5/cipher/rijndael-ssse3-amd64.c ---- libgcrypt-1.8.5/cipher/rijndael-ssse3-amd64.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/rijndael-ssse3-amd64.c 2020-04-22 18:29:41.679862057 +0200 -@@ -208,11 +208,11 @@ _gcry_aes_ssse3_do_setkey (RIJNDAEL_cont - - - /* Make a decryption key from an encryption key. */ --void --_gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx) -+static inline void -+do_ssse3_prepare_decryption (RIJNDAEL_context *ctx, -+ byte ssse3_state[SSSE3_STATE_SIZE]) - { - unsigned int keybits = (ctx->rounds - 10) * 32 + 128; -- byte ssse3_state[SSSE3_STATE_SIZE]; - - vpaes_ssse3_prepare(); - -@@ -237,6 +237,14 @@ _gcry_aes_ssse3_prepare_decryption (RIJN - vpaes_ssse3_cleanup(); - } - -+void -+_gcry_aes_ssse3_prepare_decryption (RIJNDAEL_context *ctx) -+{ -+ byte ssse3_state[SSSE3_STATE_SIZE]; -+ -+ do_ssse3_prepare_decryption(ctx, ssse3_state); -+} -+ - - /* Encrypt one block using the Intel SSSE3 instructions. Block is input - * and output through SSE register xmm0. */ -@@ -295,9 +303,9 @@ _gcry_aes_ssse3_encrypt (const RIJNDAEL_ - - - void --_gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -- size_t nblocks) -+_gcry_aes_ssse3_cfb_enc (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks) - { - unsigned int nrounds = ctx->rounds; - byte ssse3_state[SSSE3_STATE_SIZE]; -@@ -334,9 +342,9 @@ _gcry_aes_ssse3_cfb_enc (RIJNDAEL_contex - - - void --_gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -- size_t nblocks, int cbc_mac) -+_gcry_aes_ssse3_cbc_enc (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks, int cbc_mac) - { - unsigned int nrounds = ctx->rounds; - byte ssse3_state[SSSE3_STATE_SIZE]; -@@ -379,9 +387,9 @@ _gcry_aes_ssse3_cbc_enc (RIJNDAEL_contex - - - void --_gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *ctr, -- size_t nblocks) -+_gcry_aes_ssse3_ctr_enc (RIJNDAEL_context *ctx, unsigned char *ctr, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks) - { - static const unsigned char be_mask[16] __attribute__ ((aligned (16))) = - { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 }; -@@ -447,7 +455,7 @@ _gcry_aes_ssse3_ctr_enc (RIJNDAEL_contex - - unsigned int - _gcry_aes_ssse3_decrypt (const RIJNDAEL_context *ctx, unsigned char *dst, -- const unsigned char *src) -+ const unsigned char *src) - { - unsigned int nrounds = ctx->rounds; - byte ssse3_state[SSSE3_STATE_SIZE]; -@@ -468,9 +476,9 @@ _gcry_aes_ssse3_decrypt (const RIJNDAEL_ - - - void --_gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -- size_t nblocks) -+_gcry_aes_ssse3_cfb_dec (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks) - { - unsigned int nrounds = ctx->rounds; - byte ssse3_state[SSSE3_STATE_SIZE]; -@@ -508,13 +516,19 @@ _gcry_aes_ssse3_cfb_dec (RIJNDAEL_contex - - - void --_gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *outbuf, -- const unsigned char *inbuf, unsigned char *iv, -- size_t nblocks) -+_gcry_aes_ssse3_cbc_dec (RIJNDAEL_context *ctx, unsigned char *iv, -+ unsigned char *outbuf, const unsigned char *inbuf, -+ size_t nblocks) - { - unsigned int nrounds = ctx->rounds; - byte ssse3_state[SSSE3_STATE_SIZE]; - -+ if ( !ctx->decryption_prepared ) -+ { -+ do_ssse3_prepare_decryption ( ctx, ssse3_state ); -+ ctx->decryption_prepared = 1; -+ } -+ - vpaes_ssse3_prepare_dec (); - - asm volatile ("movdqu %[iv], %%xmm7\n\t" /* use xmm7 as fast IV storage */ -@@ -626,6 +640,12 @@ ssse3_ocb_dec (gcry_cipher_hd_t c, void - unsigned int nrounds = ctx->rounds; - byte ssse3_state[SSSE3_STATE_SIZE]; - -+ if ( !ctx->decryption_prepared ) -+ { -+ do_ssse3_prepare_decryption ( ctx, ssse3_state ); -+ ctx->decryption_prepared = 1; -+ } -+ - vpaes_ssse3_prepare_dec (); - - /* Preload Offset and Checksum */ -@@ -679,7 +699,7 @@ ssse3_ocb_dec (gcry_cipher_hd_t c, void - } - - --void -+size_t - _gcry_aes_ssse3_ocb_crypt(gcry_cipher_hd_t c, void *outbuf_arg, - const void *inbuf_arg, size_t nblocks, int encrypt) - { -@@ -687,10 +707,12 @@ _gcry_aes_ssse3_ocb_crypt(gcry_cipher_hd - ssse3_ocb_enc(c, outbuf_arg, inbuf_arg, nblocks); - else - ssse3_ocb_dec(c, outbuf_arg, inbuf_arg, nblocks); -+ -+ return 0; - } - - --void -+size_t - _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, - size_t nblocks) - { -@@ -746,6 +768,8 @@ _gcry_aes_ssse3_ocb_auth (gcry_cipher_hd - : "memory" ); - - vpaes_ssse3_cleanup (); -+ -+ return 0; - } - - #endif /* USE_SSSE3 */ -diff -up libgcrypt-1.8.5/cipher/salsa20.c.aes-perf libgcrypt-1.8.5/cipher/salsa20.c ---- libgcrypt-1.8.5/cipher/salsa20.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/salsa20.c 2020-04-22 18:29:41.679862057 +0200 -@@ -366,10 +366,12 @@ salsa20_do_setkey (SALSA20_context_t *ct - - - static gcry_err_code_t --salsa20_setkey (void *context, const byte *key, unsigned int keylen) -+salsa20_setkey (void *context, const byte *key, unsigned int keylen, -+ gcry_cipher_hd_t hd) - { - SALSA20_context_t *ctx = (SALSA20_context_t *)context; - gcry_err_code_t rc = salsa20_do_setkey (ctx, key, keylen); -+ (void)hd; - _gcry_burn_stack (4 + sizeof (void *) + 4 * sizeof (void *)); - return rc; - } -@@ -522,7 +524,7 @@ selftest (void) - /* 16-byte alignment required for amd64 implementation. */ - ctx = (SALSA20_context_t *)((uintptr_t)(ctxbuf + 15) & ~(uintptr_t)15); - -- salsa20_setkey (ctx, key_1, sizeof key_1); -+ salsa20_setkey (ctx, key_1, sizeof key_1, NULL); - salsa20_setiv (ctx, nonce_1, sizeof nonce_1); - scratch[8] = 0; - salsa20_encrypt_stream (ctx, scratch, plaintext_1, sizeof plaintext_1); -@@ -530,7 +532,7 @@ selftest (void) - return "Salsa20 encryption test 1 failed."; - if (scratch[8]) - return "Salsa20 wrote too much."; -- salsa20_setkey( ctx, key_1, sizeof(key_1)); -+ salsa20_setkey( ctx, key_1, sizeof(key_1), NULL); - salsa20_setiv (ctx, nonce_1, sizeof nonce_1); - salsa20_encrypt_stream (ctx, scratch, scratch, sizeof plaintext_1); - if (memcmp (scratch, plaintext_1, sizeof plaintext_1)) -@@ -538,12 +540,12 @@ selftest (void) - - for (i = 0; i < sizeof buf; i++) - buf[i] = i; -- salsa20_setkey (ctx, key_1, sizeof key_1); -+ salsa20_setkey (ctx, key_1, sizeof key_1, NULL); - salsa20_setiv (ctx, nonce_1, sizeof nonce_1); - /*encrypt*/ - salsa20_encrypt_stream (ctx, buf, buf, sizeof buf); - /*decrypt*/ -- salsa20_setkey (ctx, key_1, sizeof key_1); -+ salsa20_setkey (ctx, key_1, sizeof key_1, NULL); - salsa20_setiv (ctx, nonce_1, sizeof nonce_1); - salsa20_encrypt_stream (ctx, buf, buf, 1); - salsa20_encrypt_stream (ctx, buf+1, buf+1, (sizeof buf)-1-1); -diff -up libgcrypt-1.8.5/cipher/seed.c.aes-perf libgcrypt-1.8.5/cipher/seed.c ---- libgcrypt-1.8.5/cipher/seed.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/seed.c 2020-04-22 18:29:41.680862038 +0200 -@@ -309,11 +309,12 @@ do_setkey (SEED_context *ctx, const byte - } - - static gcry_err_code_t --seed_setkey (void *context, const byte *key, const unsigned keylen) -+seed_setkey (void *context, const byte *key, const unsigned keylen, -+ gcry_cipher_hd_t hd) - { - SEED_context *ctx = context; -- - int rc = do_setkey (ctx, key, keylen); -+ (void)hd; - _gcry_burn_stack (4*6 + sizeof(void*)*2 + sizeof(int)*2); - return rc; - } -@@ -446,7 +447,7 @@ selftest (void) - 0x22, 0x6B, 0xC3, 0x14, 0x2C, 0xD4, 0x0D, 0x4A, - }; - -- seed_setkey (&ctx, key, sizeof(key)); -+ seed_setkey (&ctx, key, sizeof(key), NULL); - seed_encrypt (&ctx, scratch, plaintext); - if (memcmp (scratch, ciphertext, sizeof (ciphertext))) - return "SEED test encryption failed."; -diff -up libgcrypt-1.8.5/cipher/serpent.c.aes-perf libgcrypt-1.8.5/cipher/serpent.c ---- libgcrypt-1.8.5/cipher/serpent.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/serpent.c 2020-04-22 18:29:41.680862038 +0200 -@@ -748,13 +748,16 @@ serpent_setkey_internal (serpent_context - /* Initialize CTX with the key KEY of KEY_LENGTH bytes. */ - static gcry_err_code_t - serpent_setkey (void *ctx, -- const byte *key, unsigned int key_length) -+ const byte *key, unsigned int key_length, -+ gcry_cipher_hd_t hd) - { - serpent_context_t *context = ctx; - static const char *serpent_test_ret; - static int serpent_init_done; - gcry_err_code_t ret = GPG_ERR_NO_ERROR; - -+ (void)hd; -+ - if (! serpent_init_done) - { - /* Execute a self-test the first time, Serpent is used. */ -@@ -999,7 +1002,7 @@ _gcry_serpent_ctr_enc(void *context, uns - /* Encrypt the counter. */ - serpent_encrypt_internal(ctx, ctr, tmpbuf); - /* XOR the input with the encrypted counter and store in output. */ -- buf_xor(outbuf, tmpbuf, inbuf, sizeof(serpent_block_t)); -+ cipher_block_xor(outbuf, tmpbuf, inbuf, sizeof(serpent_block_t)); - outbuf += sizeof(serpent_block_t); - inbuf += sizeof(serpent_block_t); - /* Increment the counter. */ -@@ -1114,7 +1117,8 @@ _gcry_serpent_cbc_dec(void *context, uns - the intermediate result to SAVEBUF. */ - serpent_decrypt_internal (ctx, inbuf, savebuf); - -- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, sizeof(serpent_block_t)); -+ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, -+ sizeof(serpent_block_t)); - inbuf += sizeof(serpent_block_t); - outbuf += sizeof(serpent_block_t); - } -@@ -1218,7 +1222,7 @@ _gcry_serpent_cfb_dec(void *context, uns - for ( ;nblocks; nblocks-- ) - { - serpent_encrypt_internal(ctx, iv, iv); -- buf_xor_n_copy(outbuf, iv, inbuf, sizeof(serpent_block_t)); -+ cipher_block_xor_n_copy(outbuf, iv, inbuf, sizeof(serpent_block_t)); - outbuf += sizeof(serpent_block_t); - inbuf += sizeof(serpent_block_t); - } -diff -up libgcrypt-1.8.5/cipher/twofish.c.aes-perf libgcrypt-1.8.5/cipher/twofish.c ---- libgcrypt-1.8.5/cipher/twofish.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/twofish.c 2020-04-22 18:29:41.680862038 +0200 -@@ -734,12 +734,15 @@ do_twofish_setkey (TWOFISH_context *ctx, - } - - static gcry_err_code_t --twofish_setkey (void *context, const byte *key, unsigned int keylen) -+twofish_setkey (void *context, const byte *key, unsigned int keylen, -+ gcry_cipher_hd_t hd) - { - TWOFISH_context *ctx = context; - unsigned int hwfeatures = _gcry_get_hw_features (); - int rc; - -+ (void)hd; -+ - rc = do_twofish_setkey (ctx, key, keylen); - - #ifdef USE_AVX2 -@@ -1245,7 +1248,7 @@ _gcry_twofish_ctr_enc(void *context, uns - burn_stack_depth = burn; - - /* XOR the input with the encrypted counter and store in output. */ -- buf_xor(outbuf, tmpbuf, inbuf, TWOFISH_BLOCKSIZE); -+ cipher_block_xor(outbuf, tmpbuf, inbuf, TWOFISH_BLOCKSIZE); - outbuf += TWOFISH_BLOCKSIZE; - inbuf += TWOFISH_BLOCKSIZE; - /* Increment the counter. */ -@@ -1327,7 +1330,7 @@ _gcry_twofish_cbc_dec(void *context, uns - if (burn > burn_stack_depth) - burn_stack_depth = burn; - -- buf_xor_n_copy_2(outbuf, savebuf, iv, inbuf, TWOFISH_BLOCKSIZE); -+ cipher_block_xor_n_copy_2(outbuf, savebuf, iv, inbuf, TWOFISH_BLOCKSIZE); - inbuf += TWOFISH_BLOCKSIZE; - outbuf += TWOFISH_BLOCKSIZE; - } -@@ -1399,7 +1402,7 @@ _gcry_twofish_cfb_dec(void *context, uns - if (burn > burn_stack_depth) - burn_stack_depth = burn; - -- buf_xor_n_copy(outbuf, iv, inbuf, TWOFISH_BLOCKSIZE); -+ cipher_block_xor_n_copy(outbuf, iv, inbuf, TWOFISH_BLOCKSIZE); - outbuf += TWOFISH_BLOCKSIZE; - inbuf += TWOFISH_BLOCKSIZE; - } -@@ -1710,7 +1713,7 @@ selftest (void) - 0x05, 0x93, 0x1C, 0xB6, 0xD4, 0x08, 0xE7, 0xFA - }; - -- twofish_setkey (&ctx, key, sizeof(key)); -+ twofish_setkey (&ctx, key, sizeof(key), NULL); - twofish_encrypt (&ctx, scratch, plaintext); - if (memcmp (scratch, ciphertext, sizeof (ciphertext))) - return "Twofish-128 test encryption failed."; -@@ -1718,7 +1721,7 @@ selftest (void) - if (memcmp (scratch, plaintext, sizeof (plaintext))) - return "Twofish-128 test decryption failed."; - -- twofish_setkey (&ctx, key_256, sizeof(key_256)); -+ twofish_setkey (&ctx, key_256, sizeof(key_256), NULL); - twofish_encrypt (&ctx, scratch, plaintext_256); - if (memcmp (scratch, ciphertext_256, sizeof (ciphertext_256))) - return "Twofish-256 test encryption failed."; -@@ -1800,13 +1803,13 @@ main() - /* Encryption test. */ - for (i = 0; i < 125; i++) - { -- twofish_setkey (&ctx, buffer[0], sizeof (buffer[0])); -+ twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]), NULL); - for (j = 0; j < 1000; j++) - twofish_encrypt (&ctx, buffer[2], buffer[2]); -- twofish_setkey (&ctx, buffer[1], sizeof (buffer[1])); -+ twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]), NULL); - for (j = 0; j < 1000; j++) - twofish_encrypt (&ctx, buffer[3], buffer[3]); -- twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2); -+ twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2, NULL); - for (j = 0; j < 1000; j++) { - twofish_encrypt (&ctx, buffer[0], buffer[0]); - twofish_encrypt (&ctx, buffer[1], buffer[1]); -@@ -1818,15 +1821,15 @@ main() - /* Decryption test. */ - for (i = 0; i < 125; i++) - { -- twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2); -+ twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2, NULL); - for (j = 0; j < 1000; j++) { - twofish_decrypt (&ctx, buffer[0], buffer[0]); - twofish_decrypt (&ctx, buffer[1], buffer[1]); - } -- twofish_setkey (&ctx, buffer[1], sizeof (buffer[1])); -+ twofish_setkey (&ctx, buffer[1], sizeof (buffer[1]), NULL); - for (j = 0; j < 1000; j++) - twofish_decrypt (&ctx, buffer[3], buffer[3]); -- twofish_setkey (&ctx, buffer[0], sizeof (buffer[0])); -+ twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]), NULL); - for (j = 0; j < 1000; j++) - twofish_decrypt (&ctx, buffer[2], buffer[2]); - } -diff -up libgcrypt-1.8.5/configure.ac.aes-perf libgcrypt-1.8.5/configure.ac ---- libgcrypt-1.8.5/configure.ac.aes-perf 2020-04-22 18:29:41.655862516 +0200 -+++ libgcrypt-1.8.5/configure.ac 2020-04-22 18:29:41.681862019 +0200 -@@ -649,6 +649,14 @@ AC_ARG_ENABLE(arm-crypto-support, - armcryptosupport=$enableval,armcryptosupport=yes) - AC_MSG_RESULT($armcryptosupport) - -+# Implementation of the --disable-ppc-crypto-support switch. -+AC_MSG_CHECKING([whether PPC crypto support is requested]) -+AC_ARG_ENABLE(ppc-crypto-support, -+ AC_HELP_STRING([--disable-ppc-crypto-support], -+ [Disable support for the PPC crypto instructions introduced in POWER 8 (PowerISA 2.07)]), -+ ppccryptosupport=$enableval,ppccryptosupport=yes) -+AC_MSG_RESULT($ppccryptosupport) -+ - # Implementation of the --disable-O-flag-munging switch. - AC_MSG_CHECKING([whether a -O flag munging is requested]) - AC_ARG_ENABLE([O-flag-munging], -@@ -1196,6 +1204,9 @@ if test "$mpi_cpu_arch" != "arm" ; then - fi - fi - -+if test "$mpi_cpu_arch" != "ppc"; then -+ ppccryptosupport="n/a" -+fi - - ############################################# - #### #### -@@ -1722,6 +1733,113 @@ if test "$gcry_cv_gcc_inline_asm_aarch64 - fi - - -+# -+# Check whether PowerPC AltiVec/VSX intrinsics -+# -+AC_CACHE_CHECK([whether compiler supports PowerPC AltiVec/VSX intrinsics], -+ [gcry_cv_cc_ppc_altivec], -+ [if test "$mpi_cpu_arch" != "ppc" ; then -+ gcry_cv_cc_ppc_altivec="n/a" -+ else -+ gcry_cv_cc_ppc_altivec=no -+ AC_COMPILE_IFELSE([AC_LANG_SOURCE( -+ [[#include -+ typedef vector unsigned char block; -+ block fn(block in) -+ { -+ block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0)); -+ return vec_cipher_be (t, in); -+ } -+ ]])], -+ [gcry_cv_cc_ppc_altivec=yes]) -+ fi]) -+if test "$gcry_cv_cc_ppc_altivec" = "yes" ; then -+ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC,1, -+ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics]) -+fi -+ -+_gcc_cflags_save=$CFLAGS -+CFLAGS="$CFLAGS -maltivec -mvsx -mcrypto" -+ -+if test "$gcry_cv_cc_ppc_altivec" = "no" && -+ test "$mpi_cpu_arch" = "ppc" ; then -+ AC_CACHE_CHECK([whether compiler supports PowerPC AltiVec/VSX/crypto intrinsics with extra GCC flags], -+ [gcry_cv_cc_ppc_altivec_cflags], -+ [gcry_cv_cc_ppc_altivec_cflags=no -+ AC_COMPILE_IFELSE([AC_LANG_SOURCE( -+ [[#include -+ typedef vector unsigned char block; -+ block fn(block in) -+ { -+ block t = vec_perm (in, in, vec_vsx_ld (0, (unsigned char*)0)); -+ return vec_cipher_be (t, in); -+ }]])], -+ [gcry_cv_cc_ppc_altivec_cflags=yes])]) -+ if test "$gcry_cv_cc_ppc_altivec_cflags" = "yes" ; then -+ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC,1, -+ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics]) -+ AC_DEFINE(HAVE_COMPATIBLE_CC_PPC_ALTIVEC_WITH_CFLAGS,1, -+ [Defined if underlying compiler supports PowerPC AltiVec/VSX/crypto intrinsics with extra GCC flags]) -+ fi -+fi -+ -+AM_CONDITIONAL(ENABLE_PPC_VCRYPTO_EXTRA_CFLAGS, -+ test "$gcry_cv_cc_ppc_altivec_cflags" = "yes") -+ -+# Restore flags. -+CFLAGS=$_gcc_cflags_save; -+ -+ -+# -+# Check whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions -+# -+AC_CACHE_CHECK([whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto instructions], -+ [gcry_cv_gcc_inline_asm_ppc_altivec], -+ [if test "$mpi_cpu_arch" != "ppc" ; then -+ gcry_cv_gcc_inline_asm_ppc_altivec="n/a" -+ else -+ gcry_cv_gcc_inline_asm_ppc_altivec=no -+ AC_COMPILE_IFELSE([AC_LANG_SOURCE( -+ [[__asm__(".globl testfn;\n" -+ "testfn:\n" -+ "stvx %v31,%r12,%r0;\n" -+ "lvx %v20,%r12,%r0;\n" -+ "vcipher %v0, %v1, %v22;\n" -+ "lxvw4x %vs32, %r0, %r1;\n" -+ "vadduwm %v0, %v1, %v22;\n" -+ ); -+ ]])], -+ [gcry_cv_gcc_inline_asm_ppc_altivec=yes]) -+ fi]) -+if test "$gcry_cv_gcc_inline_asm_ppc_altivec" = "yes" ; then -+ AC_DEFINE(HAVE_GCC_INLINE_ASM_PPC_ALTIVEC,1, -+ [Defined if inline assembler supports PowerPC AltiVec/VSX/crypto instructions]) -+fi -+ -+ -+# -+# Check whether GCC inline assembler supports PowerISA 3.00 instructions -+# -+AC_CACHE_CHECK([whether GCC inline assembler supports PowerISA 3.00 instructions], -+ [gcry_cv_gcc_inline_asm_ppc_arch_3_00], -+ [if test "$mpi_cpu_arch" != "ppc" ; then -+ gcry_cv_gcc_inline_asm_ppc_arch_3_00="n/a" -+ else -+ gcry_cv_gcc_inline_asm_ppc_arch_3_00=no -+ AC_COMPILE_IFELSE([AC_LANG_SOURCE( -+ [[__asm__(".globl testfn;\n" -+ "testfn:\n" -+ "stxvb16x %r1,%v12,%v30;\n" -+ ); -+ ]])], -+ [gcry_cv_gcc_inline_asm_ppc_arch_3_00=yes]) -+ fi]) -+if test "$gcry_cv_gcc_inline_asm_ppc_arch_3_00" = "yes" ; then -+ AC_DEFINE(HAVE_GCC_INLINE_ASM_PPC_ARCH_3_00,1, -+ [Defined if inline assembler supports PowerISA 3.00 instructions]) -+fi -+ -+ - ####################################### - #### Checks for library functions. #### - ####################################### -@@ -1999,6 +2117,10 @@ if test x"$armcryptosupport" = xyes ; th - AC_DEFINE(ENABLE_ARM_CRYPTO_SUPPORT,1, - [Enable support for ARMv8 Crypto Extension instructions.]) - fi -+if test x"$ppccryptosupport" = xyes ; then -+ AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1, -+ [Enable support for POWER 8 (PowerISA 2.07) crypto extension.]) -+fi - if test x"$jentsupport" = xyes ; then - AC_DEFINE(ENABLE_JENT_SUPPORT, 1, - [Enable support for the jitter entropy collector.]) -@@ -2106,6 +2228,21 @@ if test "$found" = "1" ; then - GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-ce.lo" - GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-armv8-aarch64-ce.lo" - ;; -+ powerpc64le-*-*) -+ # Build with the crypto extension implementation -+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo" -+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc9le.lo" -+ ;; -+ powerpc64-*-*) -+ # Big-Endian. -+ # Build with the crypto extension implementation -+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo" -+ ;; -+ powerpc-*-*) -+ # Big-Endian. -+ # Build with the crypto extension implementation -+ GCRYPT_CIPHERS="$GCRYPT_CIPHERS rijndael-ppc.lo" -+ ;; - esac - - case "$mpi_cpu_arch" in -@@ -2555,6 +2692,7 @@ case "$mpi_cpu_arch" in - ;; - ppc) - AC_DEFINE(HAVE_CPU_ARCH_PPC, 1, [Defined for PPC platforms]) -+ GCRYPT_HWF_MODULES="hwf-ppc.lo" - ;; - arm) - AC_DEFINE(HAVE_CPU_ARCH_ARM, 1, [Defined for ARM platforms]) -@@ -2653,6 +2791,7 @@ GCRY_MSG_SHOW([Try using Intel AVX: - GCRY_MSG_SHOW([Try using Intel AVX2: ],[$avx2support]) - GCRY_MSG_SHOW([Try using ARM NEON: ],[$neonsupport]) - GCRY_MSG_SHOW([Try using ARMv8 crypto: ],[$armcryptosupport]) -+GCRY_MSG_SHOW([Try using PPC crypto: ],[$ppccryptosupport]) - GCRY_MSG_SHOW([],[]) - - if test "x${gpg_config_script_warn}" != x; then -diff -up libgcrypt-1.8.5/src/cipher.h.aes-perf libgcrypt-1.8.5/src/cipher.h ---- libgcrypt-1.8.5/src/cipher.h.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/src/cipher.h 2020-04-22 18:29:41.681862019 +0200 -@@ -158,6 +158,9 @@ size_t _gcry_aes_ocb_crypt (gcry_cipher_ - const void *inbuf_arg, size_t nblocks, int encrypt); - size_t _gcry_aes_ocb_auth (gcry_cipher_hd_t c, const void *abuf_arg, - size_t nblocks); -+void _gcry_aes_xts_crypt (void *context, unsigned char *tweak, -+ void *outbuf_arg, const void *inbuf_arg, -+ size_t nblocks, int encrypt); - - /*-- blowfish.c --*/ - void _gcry_blowfish_cfb_dec (void *context, unsigned char *iv, -diff -up libgcrypt-1.8.5/src/cipher-proto.h.aes-perf libgcrypt-1.8.5/src/cipher-proto.h ---- libgcrypt-1.8.5/src/cipher-proto.h.aes-perf 2020-04-22 18:29:41.643862745 +0200 -+++ libgcrypt-1.8.5/src/cipher-proto.h 2020-04-22 18:29:41.681862019 +0200 -@@ -132,7 +132,8 @@ typedef struct gcry_pk_spec - /* Type for the cipher_setkey function. */ - typedef gcry_err_code_t (*gcry_cipher_setkey_t) (void *c, - const unsigned char *key, -- unsigned keylen); -+ unsigned keylen, -+ gcry_cipher_hd_t hd); - - /* Type for the cipher_encrypt function. */ - typedef unsigned int (*gcry_cipher_encrypt_t) (void *c, -diff -up libgcrypt-1.8.5/src/g10lib.h.aes-perf libgcrypt-1.8.5/src/g10lib.h ---- libgcrypt-1.8.5/src/g10lib.h.aes-perf 2020-04-22 18:29:41.660862420 +0200 -+++ libgcrypt-1.8.5/src/g10lib.h 2020-04-22 18:50:46.990661309 +0200 -@@ -233,7 +233,9 @@ char **_gcry_strtokenize (const char *st - - #define HWF_INTEL_RDTSC (1 << 20) - -- -+#define HWF_PPC_VCRYPTO (1 << 22) -+#define HWF_PPC_ARCH_3_00 (1 << 23) -+#define HWF_PPC_ARCH_2_07 (1 << 24) - - gpg_err_code_t _gcry_disable_hw_feature (const char *name); - void _gcry_detect_hw_features (void); -diff -up libgcrypt-1.8.5/src/hwf-common.h.aes-perf libgcrypt-1.8.5/src/hwf-common.h ---- libgcrypt-1.8.5/src/hwf-common.h.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/src/hwf-common.h 2020-04-22 18:29:41.682862000 +0200 -@@ -22,6 +22,6 @@ - - unsigned int _gcry_hwf_detect_x86 (void); - unsigned int _gcry_hwf_detect_arm (void); -- -+unsigned int _gcry_hwf_detect_ppc (void); - - #endif /*HWF_COMMON_H*/ -diff -up libgcrypt-1.8.5/src/hwfeatures.c.aes-perf libgcrypt-1.8.5/src/hwfeatures.c ---- libgcrypt-1.8.5/src/hwfeatures.c.aes-perf 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/src/hwfeatures.c 2020-04-22 18:51:48.326487879 +0200 -@@ -42,6 +42,7 @@ static struct - const char *desc; - } hwflist[] = - { -+#if defined(HAVE_CPU_ARCH_X86) - { HWF_PADLOCK_RNG, "padlock-rng" }, - { HWF_PADLOCK_AES, "padlock-aes" }, - { HWF_PADLOCK_SHA, "padlock-sha" }, -@@ -58,11 +59,17 @@ static struct - { HWF_INTEL_AVX2, "intel-avx2" }, - { HWF_INTEL_FAST_VPGATHER, "intel-fast-vpgather" }, - { HWF_INTEL_RDTSC, "intel-rdtsc" }, -+#elif defined(HAVE_CPU_ARCH_ARM) - { HWF_ARM_NEON, "arm-neon" }, - { HWF_ARM_AES, "arm-aes" }, - { HWF_ARM_SHA1, "arm-sha1" }, - { HWF_ARM_SHA2, "arm-sha2" }, -- { HWF_ARM_PMULL, "arm-pmull" } -+ { HWF_ARM_PMULL, "arm-pmull" }, -+#elif defined(HAVE_CPU_ARCH_PPC) -+ { HWF_PPC_VCRYPTO, "ppc-vcrypto" }, -+ { HWF_PPC_ARCH_3_00, "ppc-arch_3_00" }, -+ { HWF_PPC_ARCH_2_07, "ppc-arch_2_07" }, -+#endif - }; - - /* A bit vector with the hardware features which shall not be used. -@@ -207,12 +214,14 @@ _gcry_detect_hw_features (void) - { - hw_features = _gcry_hwf_detect_x86 (); - } --#endif /* HAVE_CPU_ARCH_X86 */ --#if defined (HAVE_CPU_ARCH_ARM) -+#elif defined (HAVE_CPU_ARCH_ARM) - { - hw_features = _gcry_hwf_detect_arm (); - } --#endif /* HAVE_CPU_ARCH_ARM */ -- -+#elif defined (HAVE_CPU_ARCH_PPC) -+ { -+ hw_features = _gcry_hwf_detect_ppc (); -+ } -+#endif - hw_features &= ~disabled_hw_features; - } -diff -up libgcrypt-1.8.5/src/hwf-ppc.c.aes-perf libgcrypt-1.8.5/src/hwf-ppc.c ---- libgcrypt-1.8.5/src/hwf-ppc.c.aes-perf 2020-04-22 18:29:41.682862000 +0200 -+++ libgcrypt-1.8.5/src/hwf-ppc.c 2020-04-22 18:50:21.396150974 +0200 -@@ -0,0 +1,243 @@ -+/* hwf-ppc.c - Detect hardware features - PPC part -+ * Copyright (C) 2013,2019 Jussi Kivilinna -+ * Copyright (C) 2019 Shawn Landden -+ * -+ * This file is part of Libgcrypt. -+ * -+ * Libgcrypt 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. -+ * -+ * Libgcrypt 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 program; if not, see . -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if defined(HAVE_SYS_AUXV_H) && (defined(HAVE_GETAUXVAL) || \ -+ defined(HAVE_ELF_AUX_INFO)) -+#include -+#endif -+ -+#include "g10lib.h" -+#include "hwf-common.h" -+ -+#if !defined (__powerpc__) && !defined (__powerpc64__) -+# error Module build for wrong CPU. -+#endif -+ -+ -+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_ELF_AUX_INFO) && \ -+ !defined(HAVE_GETAUXVAL) && defined(AT_HWCAP) -+#define HAVE_GETAUXVAL -+static unsigned long getauxval(unsigned long type) -+{ -+ unsigned long auxval = 0; -+ int err; -+ -+ /* FreeBSD provides 'elf_aux_info' function that does the same as -+ * 'getauxval' on Linux. */ -+ -+ err = elf_aux_info (type, &auxval, sizeof(auxval)); -+ if (err) -+ { -+ errno = err; -+ auxval = 0; -+ } -+ -+ return auxval; -+} -+#endif -+ -+ -+#undef HAS_SYS_AT_HWCAP -+#if defined(__linux__) || \ -+ (defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL)) -+#define HAS_SYS_AT_HWCAP 1 -+ -+struct feature_map_s -+ { -+ unsigned int hwcap_flag; -+ unsigned int hwcap2_flag; -+ unsigned int hwf_flag; -+ }; -+ -+#if defined(__powerpc__) || defined(__powerpc64__) -+ -+/* Note: These macros have same values on Linux and FreeBSD. */ -+#ifndef AT_HWCAP -+# define AT_HWCAP 16 -+#endif -+#ifndef AT_HWCAP2 -+# define AT_HWCAP2 26 -+#endif -+ -+#ifndef PPC_FEATURE2_ARCH_2_07 -+# define PPC_FEATURE2_ARCH_2_07 0x80000000 -+#endif -+#ifndef PPC_FEATURE2_VEC_CRYPTO -+# define PPC_FEATURE2_VEC_CRYPTO 0x02000000 -+#endif -+#ifndef PPC_FEATURE2_ARCH_3_00 -+# define PPC_FEATURE2_ARCH_3_00 0x00800000 -+#endif -+ -+static const struct feature_map_s ppc_features[] = -+ { -+ { 0, PPC_FEATURE2_ARCH_2_07, HWF_PPC_ARCH_2_07 }, -+#ifdef ENABLE_PPC_CRYPTO_SUPPORT -+ { 0, PPC_FEATURE2_VEC_CRYPTO, HWF_PPC_VCRYPTO }, -+#endif -+ { 0, PPC_FEATURE2_ARCH_3_00, HWF_PPC_ARCH_3_00 }, -+ }; -+#endif -+ -+static int -+get_hwcap(unsigned int *hwcap, unsigned int *hwcap2) -+{ -+ struct { unsigned long a_type; unsigned long a_val; } auxv; -+ FILE *f; -+ int err = -1; -+ static int hwcap_initialized = 0; -+ static unsigned int stored_hwcap = 0; -+ static unsigned int stored_hwcap2 = 0; -+ -+ if (hwcap_initialized) -+ { -+ *hwcap = stored_hwcap; -+ *hwcap2 = stored_hwcap2; -+ return 0; -+ } -+ -+#if 0 // TODO: configure.ac detection for __builtin_cpu_supports -+ // TODO: move to 'detect_ppc_builtin_cpu_supports' -+#if defined(__GLIBC__) && defined(__GNUC__) && __GNUC__ >= 6 -+ /* __builtin_cpu_supports returns 0 if glibc support doesn't exist, so -+ * we can only trust positive results. */ -+#ifdef ENABLE_PPC_CRYPTO_SUPPORT -+ if (__builtin_cpu_supports("vcrypto")) /* TODO: Configure.ac */ -+ { -+ stored_hwcap2 |= PPC_FEATURE2_VEC_CRYPTO; -+ hwcap_initialized = 1; -+ } -+#endif -+ -+ if (__builtin_cpu_supports("arch_3_00")) /* TODO: Configure.ac */ -+ { -+ stored_hwcap2 |= PPC_FEATURE2_ARCH_3_00; -+ hwcap_initialized = 1; -+ } -+#endif -+#endif -+ -+#if defined(HAVE_SYS_AUXV_H) && defined(HAVE_GETAUXVAL) -+ errno = 0; -+ auxv.a_val = getauxval (AT_HWCAP); -+ if (errno == 0) -+ { -+ stored_hwcap |= auxv.a_val; -+ hwcap_initialized = 1; -+ } -+ -+ if (AT_HWCAP2 >= 0) -+ { -+ errno = 0; -+ auxv.a_val = getauxval (AT_HWCAP2); -+ if (errno == 0) -+ { -+ stored_hwcap2 |= auxv.a_val; -+ hwcap_initialized = 1; -+ } -+ } -+ -+ if (hwcap_initialized && (stored_hwcap || stored_hwcap2)) -+ { -+ *hwcap = stored_hwcap; -+ *hwcap2 = stored_hwcap2; -+ return 0; -+ } -+#endif -+ -+ f = fopen("/proc/self/auxv", "r"); -+ if (!f) -+ { -+ *hwcap = stored_hwcap; -+ *hwcap2 = stored_hwcap2; -+ return -1; -+ } -+ -+ while (fread(&auxv, sizeof(auxv), 1, f) > 0) -+ { -+ if (auxv.a_type == AT_HWCAP) -+ { -+ stored_hwcap |= auxv.a_val; -+ hwcap_initialized = 1; -+ } -+ -+ if (auxv.a_type == AT_HWCAP2) -+ { -+ stored_hwcap2 |= auxv.a_val; -+ hwcap_initialized = 1; -+ } -+ } -+ -+ if (hwcap_initialized) -+ err = 0; -+ -+ fclose(f); -+ -+ *hwcap = stored_hwcap; -+ *hwcap2 = stored_hwcap2; -+ return err; -+} -+ -+static unsigned int -+detect_ppc_at_hwcap(void) -+{ -+ unsigned int hwcap; -+ unsigned int hwcap2; -+ unsigned int features = 0; -+ unsigned int i; -+ -+ if (get_hwcap(&hwcap, &hwcap2) < 0) -+ return features; -+ -+ for (i = 0; i < DIM(ppc_features); i++) -+ { -+ if (hwcap & ppc_features[i].hwcap_flag) -+ features |= ppc_features[i].hwf_flag; -+ -+ if (hwcap2 & ppc_features[i].hwcap2_flag) -+ features |= ppc_features[i].hwf_flag; -+ } -+ -+ return features; -+} -+ -+#endif -+ -+unsigned int -+_gcry_hwf_detect_ppc (void) -+{ -+ unsigned int ret = 0; -+ unsigned int broken_hwfs = 0; -+ -+#if defined (HAS_SYS_AT_HWCAP) -+ ret |= detect_ppc_at_hwcap (); -+#endif -+ -+ ret &= ~broken_hwfs; -+ -+ return ret; -+} -diff -up libgcrypt-1.8.5/src/Makefile.am.aes-perf libgcrypt-1.8.5/src/Makefile.am ---- libgcrypt-1.8.5/src/Makefile.am.aes-perf 2018-11-14 14:16:40.000000000 +0100 -+++ libgcrypt-1.8.5/src/Makefile.am 2020-04-22 18:29:41.683861981 +0200 -@@ -66,7 +66,7 @@ libgcrypt_la_SOURCES = \ - hmac256.c hmac256.h context.c context.h \ - ec-context.h - --EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c -+EXTRA_libgcrypt_la_SOURCES = hwf-x86.c hwf-arm.c hwf-ppc.c - gcrypt_hwf_modules = @GCRYPT_HWF_MODULES@ - - diff --git a/libgcrypt-1.8.5-fips-module.patch b/libgcrypt-1.8.5-fips-module.patch index 60b9ce2..8ffe465 100644 --- a/libgcrypt-1.8.5-fips-module.patch +++ b/libgcrypt-1.8.5-fips-module.patch @@ -23,7 +23,7 @@ diff -up libgcrypt-1.8.5/src/fips.c.fips-module libgcrypt-1.8.5/src/fips.c - actually used. The file itself may be empty. */ - if ( !access (FIPS_FORCE_FILE, F_OK) ) - { -- gcry_assert (!no_fips_mode_required); +- gcry_assert (!_gcry_no_fips_mode_required); - goto leave; - } - @@ -42,7 +42,7 @@ diff -up libgcrypt-1.8.5/src/fips.c.fips-module libgcrypt-1.8.5/src/fips.c - { - /* System is in fips mode. */ - fclose (fp); -- gcry_assert (!no_fips_mode_required); +- gcry_assert (!_gcry_no_fips_mode_required); - goto leave; - } - fclose (fp); @@ -65,7 +65,7 @@ diff -up libgcrypt-1.8.5/src/fips.c.fips-module libgcrypt-1.8.5/src/fips.c - } - /* Fips not not requested, set flag. */ - no_fips_mode_required = 1; + _gcry_no_fips_mode_required = 1; diff -up libgcrypt-1.8.5/src/g10lib.h.fips-module libgcrypt-1.8.5/src/g10lib.h --- libgcrypt-1.8.5/src/g10lib.h.fips-module 2020-04-20 19:07:45.918919759 +0200 @@ -77,9 +77,9 @@ diff -up libgcrypt-1.8.5/src/g10lib.h.fips-module libgcrypt-1.8.5/src/g10lib.h +/* The name of the file used to force libgcrypt into fips mode. */ +#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" + - void _gcry_initialize_fips_mode (int force); + extern int _gcry_no_fips_mode_required; - int _gcry_fips_mode (void); + void _gcry_initialize_fips_mode (int force); diff -up libgcrypt-1.8.5/src/global.c.fips-module libgcrypt-1.8.5/src/global.c --- libgcrypt-1.8.5/src/global.c.fips-module 2020-04-20 19:07:45.919919741 +0200 +++ libgcrypt-1.8.5/src/global.c 2020-04-20 19:07:45.950919149 +0200 diff --git a/libgcrypt-1.8.5-getrandom.patch b/libgcrypt-1.8.5-getrandom.patch index ff2ef3b..1779dc1 100644 --- a/libgcrypt-1.8.5-getrandom.patch +++ b/libgcrypt-1.8.5-getrandom.patch @@ -154,13 +154,13 @@ diff -up libgcrypt-1.8.5/random/rndlinux.c.getrandom libgcrypt-1.8.5/random/rndl --- libgcrypt-1.8.5/random/rndlinux.c.getrandom 2020-04-20 15:01:50.159848963 +0200 +++ libgcrypt-1.8.5/random/rndlinux.c 2020-04-20 16:14:21.901610921 +0200 @@ -35,6 +35,7 @@ - #include - #if defined(__linux__) && defined(HAVE_SYSCALL) + #if defined(__linux__) || !defined(HAVE_GETENTROPY) + #ifdef HAVE_SYSCALL # include +# include - #endif - - #include "types.h" + # ifdef __NR_getrandom + # define getentropy(buf,buflen) syscall (__NR_getrandom, buf, buflen, 0) + # endif @@ -147,12 +148,12 @@ _gcry_rndlinux_gather_random (void (*add if (!add) { @@ -216,25 +216,17 @@ diff -up libgcrypt-1.8.5/random/rndlinux.c.getrandom libgcrypt-1.8.5/random/rndl { if (fd_random == -1) { -@@ -255,6 +272,7 @@ _gcry_rndlinux_gather_random (void (*add - * syscall and not a new device and thus we are not able to use - * select(2) to have a timeout. */ - #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ if (fd == -2) - { - long ret; - size_t nbytes; @@ -270,9 +288,7 @@ _gcry_rndlinux_gather_random (void (*add _gcry_post_syscall (); } while (ret == -1 && errno == EINTR); - if (ret == -1 && errno == ENOSYS) -- ; /* The syscall is not supported - fallback to pulling from fd. */ +- ; /* getentropy is not supported - fallback to pulling from fd. */ - else + if (1) - { /* The syscall is supported. Some sanity checks. */ + { /* getentropy is supported. Some sanity checks. */ if (ret == -1) - log_fatal ("unexpected error from getrandom: %s\n", + log_fatal ("unexpected error from getentropy: %s\n", diff -up libgcrypt-1.8.5/src/g10lib.h.getrandom libgcrypt-1.8.5/src/g10lib.h --- libgcrypt-1.8.5/src/g10lib.h.getrandom 2020-04-20 15:08:16.528538580 +0200 +++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 15:08:28.641309399 +0200 diff --git a/libgcrypt-1.8.5-intel-cet.patch b/libgcrypt-1.8.5-intel-cet.patch deleted file mode 100644 index f58084e..0000000 --- a/libgcrypt-1.8.5-intel-cet.patch +++ /dev/null @@ -1,348 +0,0 @@ -diff -up libgcrypt-1.8.5/cipher/camellia-aesni-avx2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/camellia-aesni-avx2-amd64.S ---- libgcrypt-1.8.5/cipher/camellia-aesni-avx2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/camellia-aesni-avx2-amd64.S 2020-01-23 15:36:44.148972045 +0100 -@@ -18,8 +18,9 @@ - * License along with this program; if not, see . - */ - --#ifdef __x86_64 - #include -+ -+#ifdef __x86_64 - #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ - defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \ - defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX2_SUPPORT) -diff -up libgcrypt-1.8.5/cipher/camellia-aesni-avx-amd64.S.intel-cet libgcrypt-1.8.5/cipher/camellia-aesni-avx-amd64.S ---- libgcrypt-1.8.5/cipher/camellia-aesni-avx-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/camellia-aesni-avx-amd64.S 2020-01-23 15:36:44.145972088 +0100 -@@ -18,8 +18,9 @@ - * License along with this program; if not, see . - */ - --#ifdef __x86_64 - #include -+ -+#ifdef __x86_64 - #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ - defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && \ - defined(ENABLE_AESNI_SUPPORT) && defined(ENABLE_AVX_SUPPORT) -diff -up libgcrypt-1.8.5/cipher/chacha20-avx2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/chacha20-avx2-amd64.S ---- libgcrypt-1.8.5/cipher/chacha20-avx2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/chacha20-avx2-amd64.S 2020-01-23 15:36:16.780250066 +0100 -@@ -48,6 +48,9 @@ - .globl _gcry_chacha20_amd64_avx2_blocks - ELF(.type _gcry_chacha20_amd64_avx2_blocks,@function;) - _gcry_chacha20_amd64_avx2_blocks: -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - .Lchacha_blocks_avx2_local: - vzeroupper - pushq %rbx -diff -up libgcrypt-1.8.5/cipher/chacha20-sse2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/chacha20-sse2-amd64.S ---- libgcrypt-1.8.5/cipher/chacha20-sse2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/chacha20-sse2-amd64.S 2020-01-23 15:36:16.783250095 +0100 -@@ -41,6 +41,9 @@ - .globl _gcry_chacha20_amd64_sse2_blocks - ELF(.type _gcry_chacha20_amd64_sse2_blocks,@function;) - _gcry_chacha20_amd64_sse2_blocks: -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - .Lchacha_blocks_sse2_local: - pushq %rbx - pushq %rbp -diff -up libgcrypt-1.8.5/cipher/poly1305-avx2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/poly1305-avx2-amd64.S ---- libgcrypt-1.8.5/cipher/poly1305-avx2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/poly1305-avx2-amd64.S 2020-01-23 15:36:16.784250105 +0100 -@@ -43,6 +43,9 @@ - .globl _gcry_poly1305_amd64_avx2_init_ext - ELF(.type _gcry_poly1305_amd64_avx2_init_ext,@function;) - _gcry_poly1305_amd64_avx2_init_ext: -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - .Lpoly1305_init_ext_avx2_local: - xor %edx, %edx - vzeroupper -@@ -406,6 +409,9 @@ ELF(.size _gcry_poly1305_amd64_avx2_init - .globl _gcry_poly1305_amd64_avx2_blocks - ELF(.type _gcry_poly1305_amd64_avx2_blocks,@function;) - _gcry_poly1305_amd64_avx2_blocks: -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - .Lpoly1305_blocks_avx2_local: - vzeroupper - pushq %rbp -@@ -732,6 +738,9 @@ ELF(.size _gcry_poly1305_amd64_avx2_bloc - .globl _gcry_poly1305_amd64_avx2_finish_ext - ELF(.type _gcry_poly1305_amd64_avx2_finish_ext,@function;) - _gcry_poly1305_amd64_avx2_finish_ext: -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - .Lpoly1305_finish_ext_avx2_local: - vzeroupper - pushq %rbp -diff -up libgcrypt-1.8.5/cipher/poly1305-sse2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/poly1305-sse2-amd64.S ---- libgcrypt-1.8.5/cipher/poly1305-sse2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/poly1305-sse2-amd64.S 2020-01-23 15:36:16.787250134 +0100 -@@ -42,6 +42,9 @@ - .globl _gcry_poly1305_amd64_sse2_init_ext - ELF(.type _gcry_poly1305_amd64_sse2_init_ext,@function;) - _gcry_poly1305_amd64_sse2_init_ext: -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - .Lpoly1305_init_ext_x86_local: - xor %edx, %edx - pushq %r12 -@@ -288,6 +291,9 @@ ELF(.size _gcry_poly1305_amd64_sse2_init - .globl _gcry_poly1305_amd64_sse2_finish_ext - ELF(.type _gcry_poly1305_amd64_sse2_finish_ext,@function;) - _gcry_poly1305_amd64_sse2_finish_ext: -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - .Lpoly1305_finish_ext_x86_local: - pushq %rbp - movq %rsp, %rbp -@@ -439,6 +445,9 @@ ELF(.size _gcry_poly1305_amd64_sse2_fini - .globl _gcry_poly1305_amd64_sse2_blocks - ELF(.type _gcry_poly1305_amd64_sse2_blocks,@function;) - _gcry_poly1305_amd64_sse2_blocks: -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - .Lpoly1305_blocks_x86_local: - pushq %rbp - movq %rsp, %rbp -diff -up libgcrypt-1.8.5/cipher/serpent-avx2-amd64.S.intel-cet libgcrypt-1.8.5/cipher/serpent-avx2-amd64.S ---- libgcrypt-1.8.5/cipher/serpent-avx2-amd64.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/cipher/serpent-avx2-amd64.S 2020-01-23 15:36:44.151972003 +0100 -@@ -18,8 +18,9 @@ - * License along with this program; if not, see . - */ - --#ifdef __x86_64 - #include -+ -+#ifdef __x86_64 - #if (defined(HAVE_COMPATIBLE_GCC_AMD64_PLATFORM_AS) || \ - defined(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS)) && defined(USE_SERPENT) && \ - defined(ENABLE_AVX2_SUPPORT) -diff -up libgcrypt-1.8.5/configure.ac.intel-cet libgcrypt-1.8.5/configure.ac ---- libgcrypt-1.8.5/configure.ac.intel-cet 2019-08-29 15:00:08.000000000 +0200 -+++ libgcrypt-1.8.5/configure.ac 2020-01-23 15:35:28.147774463 +0100 -@@ -95,6 +95,12 @@ AH_TOP([ - AH_BOTTOM([ - #define _GCRYPT_IN_LIBGCRYPT 1 - -+/* Add .note.gnu.property section for Intel CET in assembler sources -+ when CET is enabled. */ -+#if defined(__ASSEMBLER__) && defined(__CET__) -+# include -+#endif -+ - /* If the configure check for endianness has been disabled, get it from - OS macros. This is intended for making fat binary builds on OS X. */ - #ifdef DISABLED_ENDIAN_CHECK -diff -up libgcrypt-1.8.5/mpi/config.links.intel-cet libgcrypt-1.8.5/mpi/config.links ---- libgcrypt-1.8.5/mpi/config.links.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/mpi/config.links 2020-01-23 15:35:46.398952954 +0100 -@@ -382,6 +382,16 @@ if test x"$mpi_cpu_arch" = x ; then - mpi_cpu_arch="unknown" - fi - -+# Add .note.gnu.property section for Intel CET in assembler sources -+# when CET is enabled. */ -+if test x"$mpi_cpu_arch" = xx86 ; then -+ cat <> ./mpi/asm-syntax.h -+ -+#if defined(__ASSEMBLER__) && defined(__CET__) -+# include -+#endif -+EOF -+fi - - # Make sysdep.h - echo '/* created by config.links - do not edit */' >./mpi/sysdep.h -diff -up libgcrypt-1.8.5/mpi/i386/mpih-add1.S.intel-cet libgcrypt-1.8.5/mpi/i386/mpih-add1.S ---- libgcrypt-1.8.5/mpi/i386/mpih-add1.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/mpi/i386/mpih-add1.S 2020-01-23 15:37:40.470175379 +0100 -@@ -52,6 +52,10 @@ C_SYMBOL_NAME(_gcry_mpih_add_n:) - movl 20(%esp),%edx /* s2_ptr */ - movl 24(%esp),%ecx /* size */ - -+#if defined __CET__ && (__CET__ & 1) != 0 -+ pushl %ebx -+#endif -+ - movl %ecx,%eax - shrl $3,%ecx /* compute count for unrolled loop */ - negl %eax -@@ -63,6 +67,9 @@ C_SYMBOL_NAME(_gcry_mpih_add_n:) - subl %eax,%esi /* ... by a constant when we ... */ - subl %eax,%edx /* ... enter the loop */ - shrl $2,%eax /* restore previous value */ -+#if defined __CET__ && (__CET__ & 1) != 0 -+ leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */ -+#endif - #ifdef PIC - /* Calculate start address in loop for PIC. Due to limitations in some - assemblers, Loop-L0-3 cannot be put into the leal */ -@@ -75,29 +82,53 @@ L0: leal (%eax,%eax,8),%eax - /* Calculate start address in loop for non-PIC. */ - leal (Loop - 3)(%eax,%eax,8),%eax - #endif -+#if defined __CET__ && (__CET__ & 1) != 0 -+ addl %ebx,%eax /* Adjust for endbr32 */ -+#endif - jmp *%eax /* jump into loop */ - ALIGN (3) - Loop: movl (%esi),%eax - adcl (%edx),%eax - movl %eax,(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 4(%esi),%eax - adcl 4(%edx),%eax - movl %eax,4(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 8(%esi),%eax - adcl 8(%edx),%eax - movl %eax,8(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 12(%esi),%eax - adcl 12(%edx),%eax - movl %eax,12(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 16(%esi),%eax - adcl 16(%edx),%eax - movl %eax,16(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 20(%esi),%eax - adcl 20(%edx),%eax - movl %eax,20(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 24(%esi),%eax - adcl 24(%edx),%eax - movl %eax,24(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 28(%esi),%eax - adcl 28(%edx),%eax - movl %eax,28(%edi) -@@ -110,6 +141,10 @@ Loop: movl (%esi),%eax - sbbl %eax,%eax - negl %eax - -+#if defined __CET__ && (__CET__ & 1) != 0 -+ popl %ebx -+#endif -+ - popl %esi - popl %edi - ret -diff -up libgcrypt-1.8.5/mpi/i386/mpih-sub1.S.intel-cet libgcrypt-1.8.5/mpi/i386/mpih-sub1.S ---- libgcrypt-1.8.5/mpi/i386/mpih-sub1.S.intel-cet 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/mpi/i386/mpih-sub1.S 2020-01-23 15:37:40.472175351 +0100 -@@ -53,6 +53,10 @@ C_SYMBOL_NAME(_gcry_mpih_sub_n:) - movl 20(%esp),%edx /* s2_ptr */ - movl 24(%esp),%ecx /* size */ - -+#if defined __CET__ && (__CET__ & 1) != 0 -+ pushl %ebx -+#endif -+ - movl %ecx,%eax - shrl $3,%ecx /* compute count for unrolled loop */ - negl %eax -@@ -64,6 +68,9 @@ C_SYMBOL_NAME(_gcry_mpih_sub_n:) - subl %eax,%esi /* ... by a constant when we ... */ - subl %eax,%edx /* ... enter the loop */ - shrl $2,%eax /* restore previous value */ -+#if defined __CET__ && (__CET__ & 1) != 0 -+ leal -4(,%eax,4),%ebx /* Count for 4-byte endbr32 */ -+#endif - #ifdef PIC - /* Calculate start address in loop for PIC. Due to limitations in some - assemblers, Loop-L0-3 cannot be put into the leal */ -@@ -76,29 +83,53 @@ L0: leal (%eax,%eax,8),%eax - /* Calculate start address in loop for non-PIC. */ - leal (Loop - 3)(%eax,%eax,8),%eax - #endif -+#if defined __CET__ && (__CET__ & 1) != 0 -+ addl %ebx,%eax /* Adjust for endbr32 */ -+#endif - jmp *%eax /* jump into loop */ - ALIGN (3) - Loop: movl (%esi),%eax - sbbl (%edx),%eax - movl %eax,(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 4(%esi),%eax - sbbl 4(%edx),%eax - movl %eax,4(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 8(%esi),%eax - sbbl 8(%edx),%eax - movl %eax,8(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 12(%esi),%eax - sbbl 12(%edx),%eax - movl %eax,12(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 16(%esi),%eax - sbbl 16(%edx),%eax - movl %eax,16(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 20(%esi),%eax - sbbl 20(%edx),%eax - movl %eax,20(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 24(%esi),%eax - sbbl 24(%edx),%eax - movl %eax,24(%edi) -+#ifdef _CET_ENDBR -+ _CET_ENDBR -+#endif - movl 28(%esi),%eax - sbbl 28(%edx),%eax - movl %eax,28(%edi) -@@ -111,6 +142,10 @@ Loop: movl (%esi),%eax - sbbl %eax,%eax - negl %eax - -+#if defined __CET__ && (__CET__ & 1) != 0 -+ popl %ebx -+#endif -+ - popl %esi - popl %edi - ret diff --git a/libgcrypt-1.8.5-use-fipscheck.patch b/libgcrypt-1.8.5-use-fipscheck.patch index 298ec4c..46145d8 100644 --- a/libgcrypt-1.8.5-use-fipscheck.patch +++ b/libgcrypt-1.8.5-use-fipscheck.patch @@ -75,15 +75,3 @@ diff -up libgcrypt-1.8.5/src/fips.c.use-fipscheck libgcrypt-1.8.5/src/fips.c p = strrchr (fname, '/'); if (p) p++; -diff -up libgcrypt-1.8.5/src/Makefile.am.use-fipscheck libgcrypt-1.8.5/src/Makefile.am ---- libgcrypt-1.8.5/src/Makefile.am.use-fipscheck 2020-04-23 10:18:36.237764702 +0200 -+++ libgcrypt-1.8.5/src/Makefile.am 2020-04-23 10:19:03.186247455 +0200 -@@ -125,7 +125,7 @@ libgcrypt_la_LIBADD = $(gcrypt_res) \ - ../cipher/libcipher.la \ - ../random/librandom.la \ - ../mpi/libmpi.la \ -- ../compat/libcompat.la $(GPG_ERROR_LIBS) -+ ../compat/libcompat.la $(GPG_ERROR_LIBS) -ldl - - - dumpsexp_SOURCES = dumpsexp.c diff --git a/libgcrypt.spec b/libgcrypt.spec index 803c618..65c4c9b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.8.7 +Version: 1.9.0 Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -40,18 +40,12 @@ Patch18: libgcrypt-1.8.3-fips-ctor.patch Patch22: libgcrypt-1.7.3-fips-reqs.patch # Do not try to open /dev/urandom if getrandom() works Patch24: libgcrypt-1.8.5-getrandom.patch -# CMAC selftest for FIPS POST -Patch25: libgcrypt-1.8.3-cmac-selftest.patch # Continuous FIPS entropy test Patch26: libgcrypt-1.8.3-fips-enttest.patch # Disable non-approved FIPS hashes in the enforced FIPS mode Patch27: libgcrypt-1.8.3-md-fips-enforce.patch -# Intel CET support, in upstream master -Patch28: libgcrypt-1.8.5-intel-cet.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch -# Backported AES performance improvements -Patch31: libgcrypt-1.8.5-aes-perf.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -98,12 +92,9 @@ applications using libgcrypt. %patch18 -p1 -b .fips-ctor %patch22 -p1 -b .fips-reqs %patch24 -p1 -b .getrandom -%patch25 -p1 -b .cmac-selftest %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce -%patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module -%patch31 -p1 -b .aes-perf cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -213,6 +204,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Jan 20 2021 Jakub Jelen - 1.9.0-1 +- New upstream release (#1917878) + * Tue Nov 24 2020 Jakub Jelen - 1.8.7-1 - new upstream release (#1891123) diff --git a/sources b/sources index b46a259..69b2536 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.8.7-hobbled.tar.xz) = e9655f5387f08d18dcfcef3bce737aa7bb0242a5ebcb2be0dd2892fad3761496e3e51b283b61e8537b30b157a3ef5657a5bf4288c7d3aec94982b0c6da749876 +SHA512 (libgcrypt-1.9.0-hobbled.tar.xz) = d4ea9a1b732b05f605f0c99dd2b1e9747539bf2b6a8ff2fad7ab5350888f68b7f0b94bdd9253356ec9c8e6d3b87b5c76bc8dc4fbb3950acd8354b691f1f2ad3e diff --git a/t-mpi-point.c b/t-mpi-point.c index 2a8c36c..9a6190e 100644 --- a/t-mpi-point.c +++ b/t-mpi-point.c @@ -1188,11 +1188,11 @@ main (int argc, char **argv) if (!gcry_check_version (GCRYPT_VERSION)) die ("version mismatch\n"); - xgcry_control (GCRYCTL_DISABLE_SECMEM, 0); - xgcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); if (debug) - xgcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); - xgcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); set_get_point (); context_alloc (); From e12a03494690ed17d13ee81d78f4e1d8e7b0a083 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 26 Jan 2021 12:54:20 +0100 Subject: [PATCH 150/214] Unbreak builds on non-intel architectures --- libgcrypt-1.9.0-kdf-missing-terminator.patch | 31 ++++++++++++++++++++ libgcrypt.spec | 3 ++ 2 files changed, 34 insertions(+) create mode 100644 libgcrypt-1.9.0-kdf-missing-terminator.patch diff --git a/libgcrypt-1.9.0-kdf-missing-terminator.patch b/libgcrypt-1.9.0-kdf-missing-terminator.patch new file mode 100644 index 0000000..1d60f3f --- /dev/null +++ b/libgcrypt-1.9.0-kdf-missing-terminator.patch @@ -0,0 +1,31 @@ +From: Jussi Kivilinna +Date: Tue, 19 Jan 2021 18:04:30 +0000 (+0200) +Subject: kdf: add missing null-terminator for self-test test-vector array +X-Git-Url: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff_plain;h=c6425a5537294dfe2beaafc9105f7af4ceac677f + +kdf: add missing null-terminator for self-test test-vector array + +* cipher/kdf.c (selftest_pbkdf2): Add null-terminator to TV array. +-- + +This was causing kdf self-test to fail on s390x builds. + +GnuPG-bug-id: 5254 +Signed-off-by: Jussi Kivilinna +--- + +diff --git a/cipher/kdf.c b/cipher/kdf.c +index 3d707bd0..b916a3f8 100644 +--- a/cipher/kdf.c ++++ b/cipher/kdf.c +@@ -452,7 +452,8 @@ selftest_pbkdf2 (int extended, selftest_report_func_t report) + "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf" + "\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c\x4e\x2a\x1f\xb8\xdd\x53\xe1" + "\xc6\x35\x51\x8c\x7d\xac\x47\xe9" +- } ++ }, ++ { NULL } + }; + const char *what; + const char *errtxt; + diff --git a/libgcrypt.spec b/libgcrypt.spec index 65c4c9b..3cc62db 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -46,6 +46,8 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch +# Missing terminator in the kdf vectors causing s390x builds failing +Patch31: libgcrypt-1.9.0-kdf-missing-terminator.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -95,6 +97,7 @@ applications using libgcrypt. %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module +%patch31 -p1 -b .kdf-terminator cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ From 93ba00ab6ffe91bb52a03bc4a9ddfdf6756afacf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 29 Jan 2021 14:11:06 +0100 Subject: [PATCH 151/214] libgcrypt-1.9.1-1 --- .gitignore | 1 + ecc-curves.c | 28 +++++++++++++--- libgcrypt-1.7.3-fips-reqs.patch | 35 -------------------- libgcrypt-1.8.4-fips-keygen.patch | 9 +++-- libgcrypt-1.8.4-tests-fipsmode.patch | 2 +- libgcrypt-1.8.4-use-poll.patch | 6 ++-- libgcrypt-1.9.0-kdf-missing-terminator.patch | 31 ----------------- libgcrypt.spec | 11 +++--- sources | 2 +- 9 files changed, 37 insertions(+), 88 deletions(-) delete mode 100644 libgcrypt-1.7.3-fips-reqs.patch delete mode 100644 libgcrypt-1.9.0-kdf-missing-terminator.patch diff --git a/.gitignore b/.gitignore index fed427b..0288827 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.6-hobbled.tar.xz /libgcrypt-1.8.7-hobbled.tar.xz /libgcrypt-1.9.0-hobbled.tar.xz +/libgcrypt-1.9.1-hobbled.tar.xz diff --git a/ecc-curves.c b/ecc-curves.c index 4242117..a974bcf 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -1064,13 +1064,18 @@ mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags, if ((n+7)/8 != len) { - if ((n+7)/8 < len && ec->dialect == ECC_DIALECT_ED25519) + if (ec->dialect == ECC_DIALECT_ED25519) { /* * GnuPG (<= 2.2) or OpenPGP implementations with no * SOS support may remove zeros at the beginning. * Recover those zeros. */ + /* + * Also, GnuPG (<= 2.2) may add additional zero at + * the beginning, when private key is moved from + * OpenPGP to gpg-agent. Remove such a zero-prefix. + */ const unsigned char *buf; unsigned char *value; @@ -1078,13 +1083,26 @@ mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags, if (!buf) return GPG_ERR_INV_OBJ; - value = xtrycalloc_secure (1, len); + value = xtrymalloc_secure (len); if (!value) return gpg_err_code_from_syserror (); - memset (value, 0, len - (n+7)/8); - memcpy (value + len - (n+7)/8, buf, (n+7)/8); - mpi_set_opaque (ec->d, value, len); + if ((n+7)/8 < len) + /* Recover zeros. */ + { + memset (value, 0, len - (n+7)/8); + memcpy (value + len - (n+7)/8, buf, (n+7)/8); + } + else if ((n+7)/8 == len + 1) + /* Remove a zero. */ + memcpy (value, buf+1, len); + else + { + xfree (value); + return GPG_ERR_INV_OBJ; + } + + mpi_set_opaque (ec->d, value, len*8); } else { diff --git a/libgcrypt-1.7.3-fips-reqs.patch b/libgcrypt-1.7.3-fips-reqs.patch deleted file mode 100644 index ef7f765..0000000 --- a/libgcrypt-1.7.3-fips-reqs.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff -up libgcrypt-1.7.3/src/visibility.c.fips-reqs libgcrypt-1.7.3/src/visibility.c ---- libgcrypt-1.7.3/src/visibility.c.fips-reqs 2016-03-23 12:59:34.000000000 +0100 -+++ libgcrypt-1.7.3/src/visibility.c 2016-11-22 16:29:36.992042480 +0100 -@@ -1288,6 +1288,8 @@ gcry_kdf_derive (const void *passphrase, - unsigned long iterations, - size_t keysize, void *keybuffer) - { -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); - return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, - salt, saltlen, iterations, - keysize, keybuffer)); -@@ -1343,6 +1345,13 @@ void - gcry_mpi_randomize (gcry_mpi_t w, - unsigned int nbits, enum gcry_random_level level) - { -+ if (!fips_is_operational ()) -+ { -+ (void)fips_not_operational (); -+ fips_signal_fatal_error ("called in non-operational state"); -+ fips_noreturn (); -+ } -+ - _gcry_mpi_randomize (w, nbits, level); - } - -@@ -1368,6 +1377,8 @@ gcry_prime_generate (gcry_mpi_t *prime, - gcry_random_level_t random_level, - unsigned int flags) - { -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); - return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits, - factors, cb_func, cb_arg, - random_level, flags)); diff --git a/libgcrypt-1.8.4-fips-keygen.patch b/libgcrypt-1.8.4-fips-keygen.patch index 9d3a647..a3e241f 100644 --- a/libgcrypt-1.8.4-fips-keygen.patch +++ b/libgcrypt-1.8.4-fips-keygen.patch @@ -1,16 +1,15 @@ diff -up libgcrypt-1.8.4/cipher/dsa.c.fips-keygen libgcrypt-1.8.4/cipher/dsa.c --- libgcrypt-1.8.4/cipher/dsa.c.fips-keygen 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.4/cipher/dsa.c 2019-02-12 14:29:25.629513989 +0100 -@@ -457,11 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un +@@ -457,13 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un &prime_q, &prime_p, r_counter, r_seed, r_seedlen); - else -- ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, + else if (!domain->p || !domain->q) -+ ec = _gcry_generate_fips186_3_prime (nbits, qbits, -+ initial_seed.seed, -+ initial_seed.seedlen, + ec = _gcry_generate_fips186_3_prime (nbits, qbits, + initial_seed.seed, + initial_seed.seedlen, &prime_q, &prime_p, r_counter, r_seed, r_seedlen, NULL); diff --git a/libgcrypt-1.8.4-tests-fipsmode.patch b/libgcrypt-1.8.4-tests-fipsmode.patch index d6e29d1..a415d18 100644 --- a/libgcrypt-1.8.4-tests-fipsmode.patch +++ b/libgcrypt-1.8.4-tests-fipsmode.patch @@ -142,7 +142,7 @@ diff -up libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode libgcrypt-1.8.4/tests/pub " (use-fips186)" " (transient-key)" " (derive-parms" -- " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", +- " (seed #f770a4598ff756931fc529764513b103ce57d85f4ad8c5cf297c9b4d48241c5b#))))", + " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", 0, 1); if (rc) diff --git a/libgcrypt-1.8.4-use-poll.patch b/libgcrypt-1.8.4-use-poll.patch index d55b6a3..01dcf82 100644 --- a/libgcrypt-1.8.4-use-poll.patch +++ b/libgcrypt-1.8.4-use-poll.patch @@ -6,9 +6,9 @@ diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndli #include #include +#include - #if defined(__linux__) || !defined(HAVE_GETENTROPY) - #ifdef HAVE_SYSCALL - # include + #if defined(__APPLE__) && defined(__MACH__) + extern int getentropy (void *buf, size_t buflen) __attribute__ ((weak_import)); + #define HAVE_GETENTROPY @@ -241,9 +242,8 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) diff --git a/libgcrypt-1.9.0-kdf-missing-terminator.patch b/libgcrypt-1.9.0-kdf-missing-terminator.patch deleted file mode 100644 index 1d60f3f..0000000 --- a/libgcrypt-1.9.0-kdf-missing-terminator.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Jussi Kivilinna -Date: Tue, 19 Jan 2021 18:04:30 +0000 (+0200) -Subject: kdf: add missing null-terminator for self-test test-vector array -X-Git-Url: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff_plain;h=c6425a5537294dfe2beaafc9105f7af4ceac677f - -kdf: add missing null-terminator for self-test test-vector array - -* cipher/kdf.c (selftest_pbkdf2): Add null-terminator to TV array. --- - -This was causing kdf self-test to fail on s390x builds. - -GnuPG-bug-id: 5254 -Signed-off-by: Jussi Kivilinna ---- - -diff --git a/cipher/kdf.c b/cipher/kdf.c -index 3d707bd0..b916a3f8 100644 ---- a/cipher/kdf.c -+++ b/cipher/kdf.c -@@ -452,7 +452,8 @@ selftest_pbkdf2 (int extended, selftest_report_func_t report) - "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf" - "\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c\x4e\x2a\x1f\xb8\xdd\x53\xe1" - "\xc6\x35\x51\x8c\x7d\xac\x47\xe9" -- } -+ }, -+ { NULL } - }; - const char *what; - const char *errtxt; - diff --git a/libgcrypt.spec b/libgcrypt.spec index 3cc62db..971a4b1 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.9.0 +Version: 1.9.1 Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -36,8 +36,6 @@ Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch Patch14: libgcrypt-1.7.3-ecc-test-fix.patch # Run the FIPS mode initialization in the shared library constructor Patch18: libgcrypt-1.8.3-fips-ctor.patch -# Block some operations if in FIPS non-operational state -Patch22: libgcrypt-1.7.3-fips-reqs.patch # Do not try to open /dev/urandom if getrandom() works Patch24: libgcrypt-1.8.5-getrandom.patch # Continuous FIPS entropy test @@ -46,8 +44,6 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch -# Missing terminator in the kdf vectors causing s390x builds failing -Patch31: libgcrypt-1.9.0-kdf-missing-terminator.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -92,12 +88,10 @@ applications using libgcrypt. %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix %patch18 -p1 -b .fips-ctor -%patch22 -p1 -b .fips-reqs %patch24 -p1 -b .getrandom %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module -%patch31 -p1 -b .kdf-terminator cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -207,6 +201,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Fri Jan 29 2021 Jakub Jelen - 1.9.1-1 +- New upstream release (#1922156, #1922097) + * Wed Jan 20 2021 Jakub Jelen - 1.9.0-1 - New upstream release (#1917878) diff --git a/sources b/sources index 69b2536..3fb2e74 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.0-hobbled.tar.xz) = d4ea9a1b732b05f605f0c99dd2b1e9747539bf2b6a8ff2fad7ab5350888f68b7f0b94bdd9253356ec9c8e6d3b87b5c76bc8dc4fbb3950acd8354b691f1f2ad3e +SHA512 (libgcrypt-1.9.1-hobbled.tar.xz) = 87c474c7b5054d7d6c75ca0d2458b2be197d7b8131b1e0a2017f391287a9e7bca666a9ac743c24210df869839518294c0091858245c96d10c5856f2473f35943 From af59e404ea6d424994d28f56e5067c555a5c6a98 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 17 Feb 2021 13:01:13 +0100 Subject: [PATCH 152/214] libgcrypt-1.9.2-1 --- .gitignore | 1 + libgcrypt-1.8.4-use-poll.patch | 4 ++-- libgcrypt.spec | 5 ++++- sources | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 0288827..9fe7a79 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.7-hobbled.tar.xz /libgcrypt-1.9.0-hobbled.tar.xz /libgcrypt-1.9.1-hobbled.tar.xz +/libgcrypt-1.9.2-hobbled.tar.xz diff --git a/libgcrypt-1.8.4-use-poll.patch b/libgcrypt-1.8.4-use-poll.patch index 01dcf82..8032992 100644 --- a/libgcrypt-1.8.4-use-poll.patch +++ b/libgcrypt-1.8.4-use-poll.patch @@ -7,8 +7,8 @@ diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndli #include +#include #if defined(__APPLE__) && defined(__MACH__) - extern int getentropy (void *buf, size_t buflen) __attribute__ ((weak_import)); - #define HAVE_GETENTROPY + #include + #ifdef __MAC_10_11 @@ -241,9 +242,8 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) diff --git a/libgcrypt.spec b/libgcrypt.spec index 971a4b1..470bf62 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.9.1 +Version: 1.9.2 Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -201,6 +201,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Feb 17 2021 Jakub Jelen - 1.9.2-1 +- New upstream release (#1929630) + * Fri Jan 29 2021 Jakub Jelen - 1.9.1-1 - New upstream release (#1922156, #1922097) diff --git a/sources b/sources index 3fb2e74..9ebeb2d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.1-hobbled.tar.xz) = 87c474c7b5054d7d6c75ca0d2458b2be197d7b8131b1e0a2017f391287a9e7bca666a9ac743c24210df869839518294c0091858245c96d10c5856f2473f35943 +SHA512 (libgcrypt-1.9.2-hobbled.tar.xz) = b89f1e2ea76a6efb5e503264b4ebd843f410e188cf4fad4da4607ae77b247349f031e1e8e4340f4d3d0b03197f110e14dcca9d693f8971c086f6d8be3de403e6 From 713d2850dd617b21469c65af6de98f1e1fcc57bf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 29 Mar 2021 19:45:10 +0200 Subject: [PATCH 153/214] Fix OCB tag creation on s390x --- libgcrypt-1.9.2-s390x-ocb.patch | 253 ++++++++++++++++++++++++++++++++ libgcrypt.spec | 3 + 2 files changed, 256 insertions(+) create mode 100644 libgcrypt-1.9.2-s390x-ocb.patch diff --git a/libgcrypt-1.9.2-s390x-ocb.patch b/libgcrypt-1.9.2-s390x-ocb.patch new file mode 100644 index 0000000..e7ff8e3 --- /dev/null +++ b/libgcrypt-1.9.2-s390x-ocb.patch @@ -0,0 +1,253 @@ +From 56da81ac47209dc41af08a129f5e0c15538261b2 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Thu, 25 Mar 2021 19:33:44 +0200 +Subject: [PATCH 1/3] tests/basic: add decryption check to + check_ocb_cipher_checksum + +* tests/basic.c (check_ocb_cipher_checksum): Add decryption. +-- + +GnuPG-bug-id: T5356 +Signed-off-by: Jussi Kivilinna +--- + tests/basic.c | 32 +++++++++++++++++++++++++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/tests/basic.c b/tests/basic.c +index 9a7e33cc..b39b901a 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -6800,9 +6800,10 @@ check_ocb_cipher_checksum (int algo, int keylen) + const size_t buflen = 128 * 16; + unsigned char *inbuf, *outbuf; + gpg_error_t err = 0; +- gcry_cipher_hd_t hde, hde2; ++ gcry_cipher_hd_t hde, hde2, hdd; + unsigned char tag[16]; + unsigned char tag2[16]; ++ unsigned char tag3[16]; + int i; + + inbuf = xmalloc(buflen); +@@ -6833,6 +6834,8 @@ check_ocb_cipher_checksum (int algo, int keylen) + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) + err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); ++ if (!err) ++ err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); + if (err) + { + fail ("cipher-ocb, gcry_cipher_open failed (checksum, algo %d): %s\n", +@@ -6843,24 +6846,30 @@ check_ocb_cipher_checksum (int algo, int keylen) + err = gcry_cipher_setkey (hde, key, keylen); + if (!err) + err = gcry_cipher_setkey (hde2, key, keylen); ++ if (!err) ++ err = gcry_cipher_setkey (hdd, key, keylen); + if (err) + { + fail ("cipher-ocb, gcry_cipher_setkey failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); ++ gcry_cipher_close (hdd); + goto out_free; + } + + err = gcry_cipher_setiv (hde, nonce, 12); + if (!err) + err = gcry_cipher_setiv (hde2, nonce, 12); ++ if (!err) ++ err = gcry_cipher_setiv (hdd, nonce, 12); + if (err) + { + fail ("cipher-ocb, gcry_cipher_setiv failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); ++ gcry_cipher_close (hdd); + goto out_free; + } + +@@ -6876,6 +6885,14 @@ check_ocb_cipher_checksum (int algo, int keylen) + if (!err) + err = gcry_cipher_encrypt (hde2, outbuf + i, 16, inbuf + i, 16); + } ++ if (!err) ++ { ++ err = gcry_cipher_final (hdd); ++ } ++ if (!err) ++ { ++ err = gcry_cipher_decrypt (hdd, outbuf, buflen, outbuf, buflen); ++ } + + if (err) + { +@@ -6883,6 +6900,7 @@ check_ocb_cipher_checksum (int algo, int keylen) + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); ++ gcry_cipher_close (hdd); + goto out_free; + } + +@@ -6899,14 +6917,26 @@ check_ocb_cipher_checksum (int algo, int keylen) + fail ("cipher_ocb, gcry_cipher_gettag failed (checksum2, algo %d): %s\n", + algo, gpg_strerror (err)); + } ++ err = gcry_cipher_gettag (hdd, tag3, 16); ++ if (err) ++ { ++ fail ("cipher_ocb, gcry_cipher_gettag failed (checksum3, algo %d): %s\n", ++ algo, gpg_strerror (err)); ++ } + if (memcmp (tag, tag2, 16)) + { + mismatch (tag, 16, tag2, 16); + fail ("cipher-ocb, encrypt tag mismatch (checksum, algo %d)\n", algo); + } ++ if (memcmp (tag, tag3, 16)) ++ { ++ mismatch (tag, 16, tag3, 16); ++ fail ("cipher-ocb, decrypt tag mismatch (checksum, algo %d)\n", algo); ++ } + + gcry_cipher_close (hde); + gcry_cipher_close (hde2); ++ gcry_cipher_close (hdd); + + out_free: + xfree(inbuf); +-- +2.27.0 + +From 21c273cecfd58408b8d3287f5bc8c246c3010313 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Thu, 25 Mar 2021 19:43:41 +0200 +Subject: [PATCH 2/3] tests/basic: OCB large buffer check: make input buffer + non-repeatable + +* tests/basic.c (check_ocb_cipher_largebuf_split): Use SHA1 to +initialize input buffer. +(check_ocb_cipher): Update largebuf test vectors. +-- + +GnuPG-bug-id: T5356 +Signed-off-by: Jussi Kivilinna +--- + tests/basic.c | 36 +++++++++++++++++++++++------------- + 1 file changed, 23 insertions(+), 13 deletions(-) + +diff --git a/tests/basic.c b/tests/basic.c +index b39b901a..f9ada8ef 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -6630,8 +6630,18 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, + return; + } + +- for (i = 0; i < buflen; i++) +- inbuf[i] = (unsigned int)(i + 181081) * 5039U; ++ for (i = 0; i < buflen; i += 16) ++ { ++ unsigned char hash[20]; ++ unsigned char ctr[4]; ++ ++ ctr[0] = (i >> 0) & 0xff; ++ ctr[1] = (i >> 8) & 0xff; ++ ctr[2] = (i >> 16) & 0xff; ++ ctr[3] = (i >> 24) & 0xff; ++ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, ctr, sizeof(ctr)); ++ memcpy(inbuf + i, hash, 16); ++ } + + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) +@@ -7200,27 +7210,27 @@ check_ocb_cipher (void) + + /* Check large buffer encryption/decryption. */ + check_ocb_cipher_largebuf(GCRY_CIPHER_AES, 16, +- "\xc1\x5b\xf1\x80\xa4\xd5\xea\xfd\xae\x17\xa6\xcd\x6b\x10\xa8\xea"); ++ "\x4a\x00\x7f\x8d\xbe\x38\x32\x48\xb2\x2f\x7f\x27\xd8\x15\x7f\xb0"); + check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32, +- "\x2b\xb7\x25\x6b\x77\xc7\xfb\x21\x5c\xc9\x6c\x36\x17\x1a\x1a\xd5"); ++ "\xec\xc5\xe9\x2b\x24\x91\xba\x64\xbc\xe3\x62\xb6\x83\x20\xad\xbd"); + check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16, +- "\xe0\xae\x3f\x29\x3a\xee\xd8\xe3\xf2\x20\xc1\xa2\xd8\x72\x12\xd9"); ++ "\xd5\xbd\x76\xec\x75\x4a\xab\x6c\x13\xec\x87\x95\x11\xd4\xf0\x3d"); + check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24, +- "\xd7\x98\x71\xcf\x19\x5c\xa3\x3d\x6c\xfc\xc9\xbe\x9f\x13\x6b\xbd"); ++ "\xde\xdd\x6b\xbf\xce\x15\x01\x39\x7c\xc5\x69\x19\x72\xa2\x67\x23"); + check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32, +- "\x03\xf6\xec\x1a\x0e\xae\x66\x24\x2b\xba\x26\x0f\xb3\xb3\x1f\xb9"); ++ "\x0c\xf3\xd5\x82\x20\x73\xee\x0f\xbd\x6b\x32\x38\xf9\x10\xef\xe5"); + check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16, +- "\x1c\xf9\xc7\xfc\x3a\x32\xac\xc7\x5e\x0a\xc2\x5c\x90\xd6\xf6\xf9"); ++ "\x54\x87\x68\xb6\x17\xe6\xd7\xa6\x76\x0d\x7e\x9f\x57\x8b\xec\x88"); + check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32, +- "\x53\x02\xc8\x0d\x4e\x9a\x44\x9e\x43\xd4\xaa\x06\x30\x93\xcc\x16"); ++ "\x0b\xc3\x93\x52\xfa\x97\x22\xe6\x88\x6e\x29\x4d\x77\x35\x48\x84"); + check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16, +- "\xd3\x64\xac\x40\x48\x88\x77\xe2\x41\x26\x4c\xde\x21\x29\x21\x8d"); ++ "\x7e\x49\x3b\xd6\xde\x6e\x9e\x53\x67\xcd\x00\xad\xc9\xd9\xa5\xbc"); + check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24, +- "\x99\xeb\x35\xb0\x62\x4e\x7b\xf1\x5e\x9f\xed\x32\x78\x90\x0b\xd0"); ++ "\x1e\x33\x0e\x06\xc8\x27\x6a\x0b\x41\x5e\x93\xae\x39\xf4\x50\x12"); + check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32, +- "\x71\x66\x2f\x68\xbf\xdd\xcc\xb1\xbf\x81\x56\x5f\x01\x73\xeb\x44"); ++ "\x6b\x4c\x3f\x8f\x77\x75\xf2\x4d\xaf\xde\x2c\x5f\x1a\x80\xb8\x4d"); + check_ocb_cipher_largebuf(GCRY_CIPHER_SM4, 16, +- "\x2c\x0b\x31\x0b\xf4\x71\x9b\x01\xf4\x18\x5d\xf1\xe9\x3d\xed\x6b"); ++ "\x3c\x32\x54\x5d\xc5\x17\xa1\x16\x3f\x8e\xc7\x1d\x8d\x8b\x2d\xb0"); + + /* Check that the AAD data is correctly buffered. */ + check_ocb_cipher_splitaad (); +-- +2.27.0 + +From 68bb0ddc5504c9c0f3f52259a4085bb2fc1a02ad Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Thu, 25 Mar 2021 19:52:23 +0200 +Subject: [PATCH 3/3] rijndael-s390x: fix checksum calculation in OCB + decryption + +* cipher/rijndael-s390x.c (aes_s390x_ocb_dec): Calculate checksum +after decryption instead of inlining. +-- + +OCB decryption was missing checksum inlining in 64 block loop. + +GnuPG-bug-id: T5356 +Signed-off-by: Jussi Kivilinna +--- + cipher/rijndael-s390x.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/cipher/rijndael-s390x.c b/cipher/rijndael-s390x.c +index aea65c5a..c3da9fb2 100644 +--- a/cipher/rijndael-s390x.c ++++ b/cipher/rijndael-s390x.c +@@ -777,9 +777,7 @@ aes_s390x_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, + OCB_INPUT_4((n) + 12); + + #define OCB_OUTPUT(n) \ +- cipher_block_xor_1 (&blocks[n], outbuf + (n) * BLOCKSIZE, BLOCKSIZE); \ +- cipher_block_xor_1 (c->u_ctr.ctr, &blocks[n], BLOCKSIZE); \ +- cipher_block_cpy (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE); ++ cipher_block_xor_1 (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE); + + #define OCB_OUTPUT_4(n) \ + OCB_OUTPUT((n) + 0); OCB_OUTPUT((n) + 1); OCB_OUTPUT((n) + 2); \ +@@ -895,6 +893,8 @@ aes_s390x_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, + if (max_blocks_used) + wipememory (&blocks, max_blocks_used * BLOCKSIZE); + ++ aes_s390x_ocb_checksum (c->u_ctr.ctr, outbuf_arg, nblocks_arg); ++ + return 0; + } + +-- +2.27.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index 470bf62..d854c4a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -44,6 +44,8 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch +# Unbreak gnupg2 build on s390x: https://dev.gnupg.org/T5356 +Patch31: libgcrypt-1.9.2-s390x-ocb.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -92,6 +94,7 @@ applications using libgcrypt. %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module +%patch31 -p1 -b .s390x-ocb cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ From 643055c06da6b5f5d720aba61a57827bab556995 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 29 Mar 2021 19:47:55 +0200 Subject: [PATCH 154/214] libgcrypt-1.9.2-2 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index d854c4a..e93314f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.2 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -204,6 +204,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Mon Mar 29 2021 Jakub Jelen - 1.9.2-2 +- Fix OCB tag creation on s390x (failing gnupg2 tests) + * Wed Feb 17 2021 Jakub Jelen - 1.9.2-1 - New upstream release (#1929630) From 2e2a35ecb333567f912ce2460ff3b27d2b22927f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 15 Apr 2021 10:58:31 +0200 Subject: [PATCH 155/214] Fix coverity reports --- libgcrypt-1.9.2-coverity.patch | 55 ++++++++++++++++++++++++++++++++++ libgcrypt.spec | 3 ++ 2 files changed, 58 insertions(+) create mode 100644 libgcrypt-1.9.2-coverity.patch diff --git a/libgcrypt-1.9.2-coverity.patch b/libgcrypt-1.9.2-coverity.patch new file mode 100644 index 0000000..6673081 --- /dev/null +++ b/libgcrypt-1.9.2-coverity.patch @@ -0,0 +1,55 @@ +commit a8d6c6c1b258548260748eefba0532fd35c8ce47 +Author: NIIBE Yutaka +Date: Thu Apr 15 16:08:24 2021 +0900 + + cipher: Fix memory leaks for EdDSA. + + * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Free the point Q. + (_gcry_ecc_eddsa_verify): Avoid memory leaks for points and MPIs. + + -- + + GnuPG-bug-id: 5385 + Co-authored-by: Jakub Jelen + Signed-off-by: NIIBE Yutaka + +diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c +index 2a1a8907..8b32545a 100644 +--- a/cipher/ecc-eddsa.c ++++ b/cipher/ecc-eddsa.c +@@ -641,7 +641,10 @@ _gcry_ecc_eddsa_genkey (mpi_ec_t ec, int flags) + ec->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8); + rc = _gcry_ecc_eddsa_compute_h_d (&hash_d, ec); + if (rc) +- goto leave; ++ { ++ point_free (&Q); ++ goto leave; ++ } + + _gcry_mpi_set_buffer (a, hash_d, b, 0); + xfree (hash_d); +@@ -991,11 +994,6 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec, + if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in)) + return GPG_ERR_INV_DATA; + +- point_init (&Ia); +- point_init (&Ib); +- h = mpi_new (0); +- s = mpi_new (0); +- + b = (ec->nbits+7)/8; + + if (ec->nbits == 255) +@@ -1005,6 +1003,11 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec, + else + return GPG_ERR_NOT_IMPLEMENTED; + ++ point_init (&Ia); ++ point_init (&Ib); ++ h = mpi_new (0); ++ s = mpi_new (0); ++ + /* Encode and check the public key. */ + rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0, + &encpk, &encpklen); diff --git a/libgcrypt.spec b/libgcrypt.spec index e93314f..99c21cb 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -46,6 +46,8 @@ Patch27: libgcrypt-1.8.3-md-fips-enforce.patch Patch30: libgcrypt-1.8.5-fips-module.patch # Unbreak gnupg2 build on s390x: https://dev.gnupg.org/T5356 Patch31: libgcrypt-1.9.2-s390x-ocb.patch +# Coverity reported issues https://dev.gnupg.org/T5385 +Patch32: libgcrypt-1.9.2-coverity.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -95,6 +97,7 @@ applications using libgcrypt. %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module %patch31 -p1 -b .s390x-ocb +%patch32 -p1 -b .coverity cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ From a8c423ec7b73afeab9f832791a871bd0e327896d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 15 Apr 2021 10:59:36 +0200 Subject: [PATCH 156/214] libgcrypt-1.9.2-3 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 99c21cb..ed7666d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.2 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -207,6 +207,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Apr 15 2021 Jakub Jelen - 1.9.2-3 +- Fix issues reported by coverity + * Mon Mar 29 2021 Jakub Jelen - 1.9.2-2 - Fix OCB tag creation on s390x (failing gnupg2 tests) From e8a3eea4344c56843ef6f1844b549bb63059b6a4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Apr 2021 11:35:10 +0200 Subject: [PATCH 157/214] libgcrypt-1.9.3-1 --- hobble-libgcrypt | 1 + keygrip.c | 341 ++++++++++++++++++++++++++++++++ libgcrypt-1.9.2-coverity.patch | 55 ------ libgcrypt-1.9.2-s390x-ocb.patch | 253 ------------------------ libgcrypt.spec | 16 +- 5 files changed, 349 insertions(+), 317 deletions(-) create mode 100644 keygrip.c delete mode 100644 libgcrypt-1.9.2-coverity.patch delete mode 100644 libgcrypt-1.9.2-s390x-ocb.patch diff --git a/hobble-libgcrypt b/hobble-libgcrypt index cc53cc1..3c76f73 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -9,3 +9,4 @@ set -e -x rm -f cipher/ecc-curves.c rm -f tests/curves.c rm -f tests/t-mpi-point.c +rm -f tests/keygrip.c diff --git a/keygrip.c b/keygrip.c new file mode 100644 index 0000000..56fbba8 --- /dev/null +++ b/keygrip.c @@ -0,0 +1,341 @@ +/* keygrip.c - verifies that keygrips are calculated as expected + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt 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. + * + * Libgcrypt 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 program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#define PGM "keygrip" +#include "t-common.h" + +static int repetitions; + + + +static void +print_hex (const char *text, const void *buf, size_t n) +{ + const unsigned char *p = buf; + + fputs (text, stdout); + for (; n; n--, p++) + printf ("%02X", *p); + putchar ('\n'); +} + + + + +static struct +{ + int algo; + const char *key; + const unsigned char grip[20]; +} key_grips[] = + { + { + GCRY_PK_RSA, + "(private-key" + " (rsa" + " (n #00B6B509596A9ECABC939212F891E656A626BA07DA8521A9CAD4C08E640C04052FBB87F424EF1A0275A48A9299AC9DB69ABE3D0124E6C756B1F7DFB9B842D6251AEA6EE85390495CADA73D671537FCE5850A932F32BAB60AB1AC1F852C1F83C625E7A7D70CDA9EF16D5C8E47739D77DF59261ABE8454807FF441E143FBD37F8545#)" + " (e #010001#)" + " (d #077AD3DE284245F4806A1B82B79E616FBDE821C82D691A65665E57B5FAD3F34E67F401E7BD2E28699E89D9C496CF821945AE83AC7A1231176A196BA6027E77D85789055D50404A7A2A95B1512F91F190BBAEF730ED550D227D512F89C0CDB31AC06FA9A19503DDF6B66D0B42B9691BFD6140EC1720FFC48AE00C34796DC899E5#)" + " (p #00D586C78E5F1B4BF2E7CD7A04CA091911706F19788B93E44EE20AAF462E8363E98A72253ED845CCBF2481BB351E8557C85BCFFF0DABDBFF8E26A79A0938096F27#)" + " (q #00DB0CDF60F26F2A296C88D6BF9F8E5BE45C0DDD713C96CC73EBCB48B061740943F21D2A93D6E42A7211E7F02A95DCED6C390A67AD21ECF739AE8A0CA46FF2EBB3#)" + " (u #33149195F16912DB20A48D020DBC3B9E3881B39D722BF79378F6340F43148A6E9FC5F53E2853B7387BA4443BA53A52FCA8173DE6E85B42F9783D4A7817D0680B#)))", + "\x32\xCF\xFA\x85\xB1\x79\x1F\xBB\x26\x14\xE9\x1A\xFD\xF3\xAF\xE3\x32\x08\x2E\x25" + }, + { + GCRY_PK_DSA, + " (public-key" + " (dsa" + " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" + " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" + " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" + " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)))", + "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" + + }, + { + GCRY_PK_DSA, + "(private-key" + " (dsa" + " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" + " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" + " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" + " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)" + " (x #0087F9E91BFBCC1163DE71ED86D557708E32F8ADDE#)))", + "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa(flags param)" + " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" + " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)" + " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" + " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" + " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa(flags param)" + " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" + " (curve \"NIST P-256\")" + " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" + " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" + " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa" + " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" + " (curve \"NIST P-256\")" + " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" + " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" + " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa" + " (curve secp256r1)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve secp256r1)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { /* Ed25519 standard */ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Ed25519)" + " (q #04" + " 1CC662926E7EFF4982B7FB8B928E61CD74CCDD85277CC57196C3AD20B611085F" + " 47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)" + " ))", + "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8" + "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1" + }, + { /* Ed25519+EdDSA */ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Ed25519)(flags eddsa)" + " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" + " ))", + "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" + "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" + }, + { /* Ed25519+EdDSA (with compression prefix) */ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Ed25519)(flags eddsa)" + " (q #40" + " 773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" + " ))", + "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" + "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" + }, + { /* Ed25519+EdDSA (same but uncompressed)*/ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Ed25519)(flags eddsa)" + " (q #04" + " 629ad237d1ed04dcd4abe1711dd699a1cf51b1584c4de7a4ef8b8a640180b26f" + " 5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)" + " ))", + "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" + "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" + }, + { /* Cv25519 */ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Curve25519)(flags djb-tweak)" + " (q #40" + " 918C1733127F6BF2646FAE3D081A18AE77111C903B906310B077505EFFF12740#)" + " ))", + "\x0F\x89\xA5\x65\xD3\xEA\x18\x7C\xE8\x39" + "\x33\x23\x98\xF5\xD4\x80\x67\x7D\xF4\x9C" + }, + { /* Random key */ + GCRY_PK_RSA, + "(shadowed-private-key" + " (rsa" + " (n #00B493C79928398DA9D99AC0E949FE6EB62F683CB974FFFBFBC01066F5C9A89B" + " D3DC48EAD7C65F36EA943C2B2C865C26C4884FF9EDFDA8C99C855B737D77EEF6" + " B85DBC0CCEC0E900C1F89A6893A2A93E8B31028469B6927CEB2F08687E547C68" + " 6B0A2F7E50A194FF7AB7637E03DE0912EF7F6E5F1EC37625BD1620CCC2E7A564" + " 31E168CDAFBD1D9E61AE47A69A6FA03EF22F844528A710B2392F262B95A3078C" + " F321DC8325F92A5691EF69F34FD0DE0B22C79D29DC87723FCADE463829E8E5F7" + " D196D73D6C9C180F6A6A0DDBF7B9D8F7FA293C36163B12199EF6A1A95CAE4051" + " E3069C522CC6C4A7110F663A5DAD20F66C13A1674D050088208FAE4F33B3AB51" + " 03#)" + " (e #00010001#)" + " (shadowed t1-v1" + " (#D2760001240102000005000123350000# OPENPGP.1)" + ")))", + "\xE5\x6E\xE6\xEE\x5A\x2F\xDC\x3E\x98\x9D" + "\xFE\x49\xDA\xF5\x67\x43\xE3\x27\x28\x33" + } + }; + + +static void +check (void) +{ + unsigned char buf[20]; + unsigned char *ret; + gcry_error_t err; + gcry_sexp_t sexp; + unsigned int i; + int repn; + + for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++) + { + if (gcry_pk_test_algo (key_grips[i].algo)) + { + if (verbose) + fprintf (stderr, "algo %d not available; test skipped\n", + key_grips[i].algo); + continue; + } + err = gcry_sexp_sscan (&sexp, NULL, key_grips[i].key, + strlen (key_grips[i].key)); + if (err) + die ("scanning data %d failed: %s\n", i, gpg_strerror (err)); + + if (debug) + info ("check(%d): s-exp='%s'\n", i, key_grips[i].key); + + for (repn=0; repn < repetitions; repn++) + { + ret = gcry_pk_get_keygrip (sexp, buf); + if (!ret) + die ("gcry_pk_get_keygrip failed for %d\n", i); + + if ( memcmp (key_grips[i].grip, buf, sizeof (buf)) ) + { + print_hex ("keygrip: ", buf, sizeof buf); + die ("keygrip for %d does not match\n", i); + } + else if (debug && !repn) + print_hex ("keygrip: ", buf, sizeof buf); + } + + gcry_sexp_release (sexp); + } +} + + + +static void +progress_handler (void *cb_data, const char *what, int printchar, + int current, int total) +{ + (void)cb_data; + (void)what; + (void)current; + (void)total; + + putchar (printchar); +} + +int +main (int argc, char **argv) +{ + int last_argc = -1; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose = 1; + debug = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--repetitions")) + { + argc--; argv++; + if (argc) + { + repetitions = atoi(*argv); + argc--; argv++; + } + } + } + + if (repetitions < 1) + repetitions = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_set_progress_handler (progress_handler, NULL); + + xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + if (debug) + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); + + check (); + + return 0; +} diff --git a/libgcrypt-1.9.2-coverity.patch b/libgcrypt-1.9.2-coverity.patch deleted file mode 100644 index 6673081..0000000 --- a/libgcrypt-1.9.2-coverity.patch +++ /dev/null @@ -1,55 +0,0 @@ -commit a8d6c6c1b258548260748eefba0532fd35c8ce47 -Author: NIIBE Yutaka -Date: Thu Apr 15 16:08:24 2021 +0900 - - cipher: Fix memory leaks for EdDSA. - - * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Free the point Q. - (_gcry_ecc_eddsa_verify): Avoid memory leaks for points and MPIs. - - -- - - GnuPG-bug-id: 5385 - Co-authored-by: Jakub Jelen - Signed-off-by: NIIBE Yutaka - -diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c -index 2a1a8907..8b32545a 100644 ---- a/cipher/ecc-eddsa.c -+++ b/cipher/ecc-eddsa.c -@@ -641,7 +641,10 @@ _gcry_ecc_eddsa_genkey (mpi_ec_t ec, int flags) - ec->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8); - rc = _gcry_ecc_eddsa_compute_h_d (&hash_d, ec); - if (rc) -- goto leave; -+ { -+ point_free (&Q); -+ goto leave; -+ } - - _gcry_mpi_set_buffer (a, hash_d, b, 0); - xfree (hash_d); -@@ -991,11 +994,6 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec, - if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in)) - return GPG_ERR_INV_DATA; - -- point_init (&Ia); -- point_init (&Ib); -- h = mpi_new (0); -- s = mpi_new (0); -- - b = (ec->nbits+7)/8; - - if (ec->nbits == 255) -@@ -1005,6 +1003,11 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec, - else - return GPG_ERR_NOT_IMPLEMENTED; - -+ point_init (&Ia); -+ point_init (&Ib); -+ h = mpi_new (0); -+ s = mpi_new (0); -+ - /* Encode and check the public key. */ - rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0, - &encpk, &encpklen); diff --git a/libgcrypt-1.9.2-s390x-ocb.patch b/libgcrypt-1.9.2-s390x-ocb.patch deleted file mode 100644 index e7ff8e3..0000000 --- a/libgcrypt-1.9.2-s390x-ocb.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 56da81ac47209dc41af08a129f5e0c15538261b2 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Thu, 25 Mar 2021 19:33:44 +0200 -Subject: [PATCH 1/3] tests/basic: add decryption check to - check_ocb_cipher_checksum - -* tests/basic.c (check_ocb_cipher_checksum): Add decryption. --- - -GnuPG-bug-id: T5356 -Signed-off-by: Jussi Kivilinna ---- - tests/basic.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/tests/basic.c b/tests/basic.c -index 9a7e33cc..b39b901a 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -6800,9 +6800,10 @@ check_ocb_cipher_checksum (int algo, int keylen) - const size_t buflen = 128 * 16; - unsigned char *inbuf, *outbuf; - gpg_error_t err = 0; -- gcry_cipher_hd_t hde, hde2; -+ gcry_cipher_hd_t hde, hde2, hdd; - unsigned char tag[16]; - unsigned char tag2[16]; -+ unsigned char tag3[16]; - int i; - - inbuf = xmalloc(buflen); -@@ -6833,6 +6834,8 @@ check_ocb_cipher_checksum (int algo, int keylen) - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); -+ if (!err) -+ err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); - if (err) - { - fail ("cipher-ocb, gcry_cipher_open failed (checksum, algo %d): %s\n", -@@ -6843,24 +6846,30 @@ check_ocb_cipher_checksum (int algo, int keylen) - err = gcry_cipher_setkey (hde, key, keylen); - if (!err) - err = gcry_cipher_setkey (hde2, key, keylen); -+ if (!err) -+ err = gcry_cipher_setkey (hdd, key, keylen); - if (err) - { - fail ("cipher-ocb, gcry_cipher_setkey failed (checksum, algo %d): %s\n", - algo, gpg_strerror (err)); - gcry_cipher_close (hde); - gcry_cipher_close (hde2); -+ gcry_cipher_close (hdd); - goto out_free; - } - - err = gcry_cipher_setiv (hde, nonce, 12); - if (!err) - err = gcry_cipher_setiv (hde2, nonce, 12); -+ if (!err) -+ err = gcry_cipher_setiv (hdd, nonce, 12); - if (err) - { - fail ("cipher-ocb, gcry_cipher_setiv failed (checksum, algo %d): %s\n", - algo, gpg_strerror (err)); - gcry_cipher_close (hde); - gcry_cipher_close (hde2); -+ gcry_cipher_close (hdd); - goto out_free; - } - -@@ -6876,6 +6885,14 @@ check_ocb_cipher_checksum (int algo, int keylen) - if (!err) - err = gcry_cipher_encrypt (hde2, outbuf + i, 16, inbuf + i, 16); - } -+ if (!err) -+ { -+ err = gcry_cipher_final (hdd); -+ } -+ if (!err) -+ { -+ err = gcry_cipher_decrypt (hdd, outbuf, buflen, outbuf, buflen); -+ } - - if (err) - { -@@ -6883,6 +6900,7 @@ check_ocb_cipher_checksum (int algo, int keylen) - algo, gpg_strerror (err)); - gcry_cipher_close (hde); - gcry_cipher_close (hde2); -+ gcry_cipher_close (hdd); - goto out_free; - } - -@@ -6899,14 +6917,26 @@ check_ocb_cipher_checksum (int algo, int keylen) - fail ("cipher_ocb, gcry_cipher_gettag failed (checksum2, algo %d): %s\n", - algo, gpg_strerror (err)); - } -+ err = gcry_cipher_gettag (hdd, tag3, 16); -+ if (err) -+ { -+ fail ("cipher_ocb, gcry_cipher_gettag failed (checksum3, algo %d): %s\n", -+ algo, gpg_strerror (err)); -+ } - if (memcmp (tag, tag2, 16)) - { - mismatch (tag, 16, tag2, 16); - fail ("cipher-ocb, encrypt tag mismatch (checksum, algo %d)\n", algo); - } -+ if (memcmp (tag, tag3, 16)) -+ { -+ mismatch (tag, 16, tag3, 16); -+ fail ("cipher-ocb, decrypt tag mismatch (checksum, algo %d)\n", algo); -+ } - - gcry_cipher_close (hde); - gcry_cipher_close (hde2); -+ gcry_cipher_close (hdd); - - out_free: - xfree(inbuf); --- -2.27.0 - -From 21c273cecfd58408b8d3287f5bc8c246c3010313 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Thu, 25 Mar 2021 19:43:41 +0200 -Subject: [PATCH 2/3] tests/basic: OCB large buffer check: make input buffer - non-repeatable - -* tests/basic.c (check_ocb_cipher_largebuf_split): Use SHA1 to -initialize input buffer. -(check_ocb_cipher): Update largebuf test vectors. --- - -GnuPG-bug-id: T5356 -Signed-off-by: Jussi Kivilinna ---- - tests/basic.c | 36 +++++++++++++++++++++++------------- - 1 file changed, 23 insertions(+), 13 deletions(-) - -diff --git a/tests/basic.c b/tests/basic.c -index b39b901a..f9ada8ef 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -6630,8 +6630,18 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, - return; - } - -- for (i = 0; i < buflen; i++) -- inbuf[i] = (unsigned int)(i + 181081) * 5039U; -+ for (i = 0; i < buflen; i += 16) -+ { -+ unsigned char hash[20]; -+ unsigned char ctr[4]; -+ -+ ctr[0] = (i >> 0) & 0xff; -+ ctr[1] = (i >> 8) & 0xff; -+ ctr[2] = (i >> 16) & 0xff; -+ ctr[3] = (i >> 24) & 0xff; -+ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, ctr, sizeof(ctr)); -+ memcpy(inbuf + i, hash, 16); -+ } - - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) -@@ -7200,27 +7210,27 @@ check_ocb_cipher (void) - - /* Check large buffer encryption/decryption. */ - check_ocb_cipher_largebuf(GCRY_CIPHER_AES, 16, -- "\xc1\x5b\xf1\x80\xa4\xd5\xea\xfd\xae\x17\xa6\xcd\x6b\x10\xa8\xea"); -+ "\x4a\x00\x7f\x8d\xbe\x38\x32\x48\xb2\x2f\x7f\x27\xd8\x15\x7f\xb0"); - check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32, -- "\x2b\xb7\x25\x6b\x77\xc7\xfb\x21\x5c\xc9\x6c\x36\x17\x1a\x1a\xd5"); -+ "\xec\xc5\xe9\x2b\x24\x91\xba\x64\xbc\xe3\x62\xb6\x83\x20\xad\xbd"); - check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16, -- "\xe0\xae\x3f\x29\x3a\xee\xd8\xe3\xf2\x20\xc1\xa2\xd8\x72\x12\xd9"); -+ "\xd5\xbd\x76\xec\x75\x4a\xab\x6c\x13\xec\x87\x95\x11\xd4\xf0\x3d"); - check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24, -- "\xd7\x98\x71\xcf\x19\x5c\xa3\x3d\x6c\xfc\xc9\xbe\x9f\x13\x6b\xbd"); -+ "\xde\xdd\x6b\xbf\xce\x15\x01\x39\x7c\xc5\x69\x19\x72\xa2\x67\x23"); - check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32, -- "\x03\xf6\xec\x1a\x0e\xae\x66\x24\x2b\xba\x26\x0f\xb3\xb3\x1f\xb9"); -+ "\x0c\xf3\xd5\x82\x20\x73\xee\x0f\xbd\x6b\x32\x38\xf9\x10\xef\xe5"); - check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16, -- "\x1c\xf9\xc7\xfc\x3a\x32\xac\xc7\x5e\x0a\xc2\x5c\x90\xd6\xf6\xf9"); -+ "\x54\x87\x68\xb6\x17\xe6\xd7\xa6\x76\x0d\x7e\x9f\x57\x8b\xec\x88"); - check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32, -- "\x53\x02\xc8\x0d\x4e\x9a\x44\x9e\x43\xd4\xaa\x06\x30\x93\xcc\x16"); -+ "\x0b\xc3\x93\x52\xfa\x97\x22\xe6\x88\x6e\x29\x4d\x77\x35\x48\x84"); - check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16, -- "\xd3\x64\xac\x40\x48\x88\x77\xe2\x41\x26\x4c\xde\x21\x29\x21\x8d"); -+ "\x7e\x49\x3b\xd6\xde\x6e\x9e\x53\x67\xcd\x00\xad\xc9\xd9\xa5\xbc"); - check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24, -- "\x99\xeb\x35\xb0\x62\x4e\x7b\xf1\x5e\x9f\xed\x32\x78\x90\x0b\xd0"); -+ "\x1e\x33\x0e\x06\xc8\x27\x6a\x0b\x41\x5e\x93\xae\x39\xf4\x50\x12"); - check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32, -- "\x71\x66\x2f\x68\xbf\xdd\xcc\xb1\xbf\x81\x56\x5f\x01\x73\xeb\x44"); -+ "\x6b\x4c\x3f\x8f\x77\x75\xf2\x4d\xaf\xde\x2c\x5f\x1a\x80\xb8\x4d"); - check_ocb_cipher_largebuf(GCRY_CIPHER_SM4, 16, -- "\x2c\x0b\x31\x0b\xf4\x71\x9b\x01\xf4\x18\x5d\xf1\xe9\x3d\xed\x6b"); -+ "\x3c\x32\x54\x5d\xc5\x17\xa1\x16\x3f\x8e\xc7\x1d\x8d\x8b\x2d\xb0"); - - /* Check that the AAD data is correctly buffered. */ - check_ocb_cipher_splitaad (); --- -2.27.0 - -From 68bb0ddc5504c9c0f3f52259a4085bb2fc1a02ad Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Thu, 25 Mar 2021 19:52:23 +0200 -Subject: [PATCH 3/3] rijndael-s390x: fix checksum calculation in OCB - decryption - -* cipher/rijndael-s390x.c (aes_s390x_ocb_dec): Calculate checksum -after decryption instead of inlining. --- - -OCB decryption was missing checksum inlining in 64 block loop. - -GnuPG-bug-id: T5356 -Signed-off-by: Jussi Kivilinna ---- - cipher/rijndael-s390x.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/cipher/rijndael-s390x.c b/cipher/rijndael-s390x.c -index aea65c5a..c3da9fb2 100644 ---- a/cipher/rijndael-s390x.c -+++ b/cipher/rijndael-s390x.c -@@ -777,9 +777,7 @@ aes_s390x_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, - OCB_INPUT_4((n) + 12); - - #define OCB_OUTPUT(n) \ -- cipher_block_xor_1 (&blocks[n], outbuf + (n) * BLOCKSIZE, BLOCKSIZE); \ -- cipher_block_xor_1 (c->u_ctr.ctr, &blocks[n], BLOCKSIZE); \ -- cipher_block_cpy (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE); -+ cipher_block_xor_1 (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE); - - #define OCB_OUTPUT_4(n) \ - OCB_OUTPUT((n) + 0); OCB_OUTPUT((n) + 1); OCB_OUTPUT((n) + 2); \ -@@ -895,6 +893,8 @@ aes_s390x_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, - if (max_blocks_used) - wipememory (&blocks, max_blocks_used * BLOCKSIZE); - -+ aes_s390x_ocb_checksum (c->u_ctr.ctr, outbuf_arg, nblocks_arg); -+ - return 0; - } - --- -2.27.0 - diff --git a/libgcrypt.spec b/libgcrypt.spec index ed7666d..6868655 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.9.2 -Release: 3%{?dist} +Version: 1.9.3 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -19,6 +19,7 @@ Source4: ecc-curves.c Source5: curves.c Source6: t-mpi-point.c Source7: random.conf +Source8: keygrip.c # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump Patch2: libgcrypt-1.8.5-use-fipscheck.patch @@ -44,10 +45,6 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch -# Unbreak gnupg2 build on s390x: https://dev.gnupg.org/T5356 -Patch31: libgcrypt-1.9.2-s390x-ocb.patch -# Coverity reported issues https://dev.gnupg.org/T5385 -Patch32: libgcrypt-1.9.2-coverity.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -96,11 +93,9 @@ applications using libgcrypt. %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module -%patch31 -p1 -b .s390x-ocb -%patch32 -p1 -b .coverity cp %{SOURCE4} cipher/ -cp %{SOURCE5} %{SOURCE6} tests/ +cp %{SOURCE5} %{SOURCE6} %{SOURCE8} tests/ %build # This package has a configure test which uses ASMs, but does not link the @@ -207,6 +202,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Apr 20 2021 Jakub Jelen - 1.9.3-1 +- New upstream release (#1951325) + * Thu Apr 15 2021 Jakub Jelen - 1.9.2-3 - Fix issues reported by coverity From 7f23c523ef2056aa95c01404dfcc8d6a8ee73d69 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Apr 2021 11:38:50 +0200 Subject: [PATCH 158/214] forgotten sources --- .gitignore | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9fe7a79..69b0cfb 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.9.0-hobbled.tar.xz /libgcrypt-1.9.1-hobbled.tar.xz /libgcrypt-1.9.2-hobbled.tar.xz +/libgcrypt-1.9.3-hobbled.tar.xz diff --git a/sources b/sources index 9ebeb2d..cbff218 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.2-hobbled.tar.xz) = b89f1e2ea76a6efb5e503264b4ebd843f410e188cf4fad4da4607ae77b247349f031e1e8e4340f4d3d0b03197f110e14dcca9d693f8971c086f6d8be3de403e6 +SHA512 (libgcrypt-1.9.3-hobbled.tar.xz) = c469bbfbcb87b31133e431da5bb4764824ccc4509d26fb6da200d50455282f4ca84fd51e86ae32d57d859ae5509104479a3b575f9ee9094707fa23f1ab5e68c1 From b9da031d089079959adf7eaab6668681783a8873 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Apr 2021 11:48:05 +0200 Subject: [PATCH 159/214] Reupload sources without bogus build artifacts --- libgcrypt.spec | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6868655..6aac689 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -7,6 +7,7 @@ Source0: libgcrypt-%{version}-hobbled.tar.xz # cipher support. We have to remove it in the tarball we ship with # the hobble-libgcrypt script. # (We replace it with RH approved ECC in Source4-5) +# rm -rf libgcrypt-x.y.z # make sure there are no leftover files # tar -xf libgcrypt-x.y.z.tar.bz2 # pushd libgcrypt-x.y.z && ../hobble-libgcrypt && popd # tar -cvJf libgcrypt-x.y.z-hobbled.tar.xz libgcrypt-x.y.z diff --git a/sources b/sources index cbff218..84854e4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.3-hobbled.tar.xz) = c469bbfbcb87b31133e431da5bb4764824ccc4509d26fb6da200d50455282f4ca84fd51e86ae32d57d859ae5509104479a3b575f9ee9094707fa23f1ab5e68c1 +SHA512 (libgcrypt-1.9.3-hobbled.tar.xz) = 5c6f3ee57ec496af6d82000979a79d220a5b9be7a3a9d064d727ff7e54cf107e5b398d9ec8d822594a7fe53bc0d4324e96a5b41d55a77f103109620b88c61f1a From ca49edafdd5ce709b72cc68b435c78a46d34143a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 27 Apr 2021 20:32:31 +0200 Subject: [PATCH 160/214] Restore Intel CET support after upstream release (#1954049) --- libgcrypt-1.8.5-intel-cet.patch | 34 +++++++++++++++++++++++++++++++++ libgcrypt.spec | 3 +++ 2 files changed, 37 insertions(+) create mode 100644 libgcrypt-1.8.5-intel-cet.patch diff --git a/libgcrypt-1.8.5-intel-cet.patch b/libgcrypt-1.8.5-intel-cet.patch new file mode 100644 index 0000000..a19d2f1 --- /dev/null +++ b/libgcrypt-1.8.5-intel-cet.patch @@ -0,0 +1,34 @@ +From b04c0a86b19856071c29d2a6285f3240c606ee7a Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 27 Apr 2021 09:08:41 -0700 +Subject: [PATCH] Always include in cipher assembly codes + +* cipher/poly1305-s390x.S: Always include . + +When Intel CET is enabled, we need to include in assembly codes +to mark Intel CET support even if it is empty. We should always include + in cipher assembly codes so that they will be marked for +Intel CET support when compiling for x86-64 and i686. + +Signed-off-by: H.J. Lu +--- + cipher/poly1305-s390x.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cipher/poly1305-s390x.S b/cipher/poly1305-s390x.S +index 844245f6..28bed560 100644 +--- a/cipher/poly1305-s390x.S ++++ b/cipher/poly1305-s390x.S +@@ -18,8 +18,8 @@ + * License along with this program; if not, see . + */ + +-#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9 + #include ++#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9 + #if defined(HAVE_GCC_INLINE_ASM_S390X) + + #include "asm-poly1305-s390x.h" +-- +GitLab + diff --git a/libgcrypt.spec b/libgcrypt.spec index 6aac689..c7f8e15 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -44,6 +44,8 @@ Patch24: libgcrypt-1.8.5-getrandom.patch Patch26: libgcrypt-1.8.3-fips-enttest.patch # Disable non-approved FIPS hashes in the enforced FIPS mode Patch27: libgcrypt-1.8.3-md-fips-enforce.patch +# Missing Intel CET support in the library (#1954049) +Patch28: libgcrypt-1.8.5-intel-cet.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch @@ -93,6 +95,7 @@ applications using libgcrypt. %patch24 -p1 -b .getrandom %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce +%patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module cp %{SOURCE4} cipher/ From ecb230f86117ffb00d77262e08b26796f3e4921a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 28 Apr 2021 09:12:52 +0200 Subject: [PATCH 161/214] libgcrypt-1.9.3-2 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index c7f8e15..ca19c19 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.3 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -206,6 +206,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Apr 28 2021 Jakub Jelen - 1.9.3-2 +- Restore the CET protection (#1954049) + * Tue Apr 20 2021 Jakub Jelen - 1.9.3-1 - New upstream release (#1951325) From b67b214174440014c8f035fcaefd0b57d420d9b0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 15 Jun 2021 13:34:41 +0200 Subject: [PATCH 162/214] Fix for CVE-2021-33560 (#1970098]) --- libgcrypt-1.9.3-CVE-2021-33560.patch | 100 +++++++++++++++++++++++++++ libgcrypt.spec | 3 + 2 files changed, 103 insertions(+) create mode 100644 libgcrypt-1.9.3-CVE-2021-33560.patch diff --git a/libgcrypt-1.9.3-CVE-2021-33560.patch b/libgcrypt-1.9.3-CVE-2021-33560.patch new file mode 100644 index 0000000..2161840 --- /dev/null +++ b/libgcrypt-1.9.3-CVE-2021-33560.patch @@ -0,0 +1,100 @@ +commit 3462280f2e23e16adf3ed5176e0f2413d8861320 +Author: NIIBE Yutaka +Date: Fri May 21 11:15:07 2021 +0900 + + cipher: Fix ElGamal encryption for other implementations. + + * cipher/elgamal.c (gen_k): Remove support of smaller K. + (do_encrypt): Never use smaller K. + (sign): Folllow the change of gen_k. + + -- + + Cherry-pick master commit of: + 632d80ef30e13de6926d503aa697f92b5dbfbc5e + + This change basically reverts encryption changes in two commits: + + 74386120dad6b3da62db37f7044267c8ef34689b + 78531373a342aeb847950f404343a05e36022065 + + Use of smaller K for ephemeral key in ElGamal encryption is only good, + when we can guarantee that recipient's key is generated by our + implementation (or compatible). + + For detail, please see: + + Luca De Feo, Bertram Poettering, Alessandro Sorniotti, + "On the (in)security of ElGamal in OpenPGP"; + in the proceedings of CCS'2021. + + CVE-id: CVE-2021-33560 + GnuPG-bug-id: 5328 + Suggested-by: Luca De Feo, Bertram Poettering, Alessandro Sorniotti + Signed-off-by: NIIBE Yutaka + +diff --git a/cipher/elgamal.c b/cipher/elgamal.c +index 9835122f..eead4502 100644 +--- a/cipher/elgamal.c ++++ b/cipher/elgamal.c +@@ -66,7 +66,7 @@ static const char *elg_names[] = + + + static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie); +-static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k); ++static gcry_mpi_t gen_k (gcry_mpi_t p); + static gcry_err_code_t generate (ELG_secret_key *sk, unsigned nbits, + gcry_mpi_t **factors); + static int check_secret_key (ELG_secret_key *sk); +@@ -189,11 +189,10 @@ test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie ) + + /**************** + * Generate a random secret exponent k from prime p, so that k is +- * relatively prime to p-1. With SMALL_K set, k will be selected for +- * better encryption performance - this must never be used signing! ++ * relatively prime to p-1. + */ + static gcry_mpi_t +-gen_k( gcry_mpi_t p, int small_k ) ++gen_k( gcry_mpi_t p ) + { + gcry_mpi_t k = mpi_alloc_secure( 0 ); + gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) ); +@@ -202,18 +201,7 @@ gen_k( gcry_mpi_t p, int small_k ) + unsigned int nbits, nbytes; + char *rndbuf = NULL; + +- if (small_k) +- { +- /* Using a k much lesser than p is sufficient for encryption and +- * it greatly improves the encryption performance. We use +- * Wiener's table and add a large safety margin. */ +- nbits = wiener_map( orig_nbits ) * 3 / 2; +- if( nbits >= orig_nbits ) +- BUG(); +- } +- else +- nbits = orig_nbits; +- ++ nbits = orig_nbits; + + nbytes = (nbits+7)/8; + if( DBG_CIPHER ) +@@ -492,7 +480,7 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey ) + * error code. + */ + +- k = gen_k( pkey->p, 1 ); ++ k = gen_k( pkey->p ); + mpi_powm (a, pkey->g, k, pkey->p); + + /* b = (y^k * input) mod p +@@ -608,7 +596,7 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey ) + * + */ + mpi_sub_ui(p_1, p_1, 1); +- k = gen_k( skey->p, 0 /* no small K ! */ ); ++ k = gen_k( skey->p ); + mpi_powm( a, skey->g, k, skey->p ); + mpi_mul(t, skey->x, a ); + mpi_subm(t, input, t, p_1 ); diff --git a/libgcrypt.spec b/libgcrypt.spec index ca19c19..2eb80a0 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -48,6 +48,8 @@ Patch27: libgcrypt-1.8.3-md-fips-enforce.patch Patch28: libgcrypt-1.8.5-intel-cet.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch +# Fix for CVE-2021-33560 +Patch31: libgcrypt-1.9.3-CVE-2021-33560.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -97,6 +99,7 @@ applications using libgcrypt. %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module +%patch31 -p1 -b .CVE-2021-33560 cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} %{SOURCE8} tests/ From 0fd2314056ad4eeb59e0b445c1f4f9ca5e44d72b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 15 Jun 2021 13:35:35 +0200 Subject: [PATCH 163/214] libgcrypt-1.9.3-3 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 2eb80a0..3106772 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.3 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -209,6 +209,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Jun 15 2021 Jakub Jelen - 1.9.3-3 +- Fix for CVE-2021-33560 (#1970098) + * Wed Apr 28 2021 Jakub Jelen - 1.9.3-2 - Restore the CET protection (#1954049) From dcaae6dd48a041eb5abdc953a0edb6ab0453e62a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 9 Jul 2021 09:46:38 +0200 Subject: [PATCH 164/214] Skip the x448 test in FIPS mode --- libgcrypt-1.8.4-tests-fipsmode.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libgcrypt-1.8.4-tests-fipsmode.patch b/libgcrypt-1.8.4-tests-fipsmode.patch index a415d18..fa235f8 100644 --- a/libgcrypt-1.8.4-tests-fipsmode.patch +++ b/libgcrypt-1.8.4-tests-fipsmode.patch @@ -160,6 +160,19 @@ diff -up libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode libgcrypt-1.8.4/tests/ start_timer (); check_cv25519 (); +diff -up libgcrypt-1.8.4/tests/t-x448.c.tests-fipsmode libgcrypt-1.8.4/tests/t-x448.c +--- libgcrypt-1.8.4/tests/t-x448.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/tests/t-x448.c 2019-02-12 14:02:35.935705390 +0100 +@@ -560,6 +560,9 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); ++ /* x448 isn't supported in fips mode */ ++ if (gcry_fips_mode_active()) ++ return 77; + + start_timer (); + check_x448 (); diff -up libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode libgcrypt-1.8.4/tests/t-secmem.c --- libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode 2017-11-23 19:19:54.000000000 +0100 +++ libgcrypt-1.8.4/tests/t-secmem.c 2019-02-12 11:51:02.462190538 +0100 From af286f213cd486a2391838c1c5f95c70e7e9481d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 22 Jul 2021 11:25:34 +0000 Subject: [PATCH 165/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3106772..5b0e0aa 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.3 -Release: 3%{?dist} +Release: 4%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -209,6 +209,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Jul 22 2021 Fedora Release Engineering - 1.9.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Tue Jun 15 2021 Jakub Jelen - 1.9.3-3 - Fix for CVE-2021-33560 (#1970098) From 21fe8b5f7138176ed66a55bbc631bb1d405201a9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 13 Jul 2021 22:56:49 +0200 Subject: [PATCH 166/214] Aggregate FIPS test patches for upstream submission and backport whats already in --- libgcrypt-1.7.3-ecc-test-fix.patch | 122 -- libgcrypt-1.8.3-fips-ctor.patch | 13 + libgcrypt-1.8.3-md-fips-enforce.patch | 19 + libgcrypt-1.8.4-tests-fipsmode.patch | 198 --- libgcrypt-1.9.3-fips-tests.patch | 1804 +++++++++++++++++++++++++ libgcrypt.spec | 5 +- 6 files changed, 1837 insertions(+), 324 deletions(-) delete mode 100644 libgcrypt-1.7.3-ecc-test-fix.patch delete mode 100644 libgcrypt-1.8.4-tests-fipsmode.patch create mode 100644 libgcrypt-1.9.3-fips-tests.patch diff --git a/libgcrypt-1.7.3-ecc-test-fix.patch b/libgcrypt-1.7.3-ecc-test-fix.patch deleted file mode 100644 index 8ce7aa9..0000000 --- a/libgcrypt-1.7.3-ecc-test-fix.patch +++ /dev/null @@ -1,122 +0,0 @@ -diff -up libgcrypt-1.7.3/tests/benchmark.c.eccfix libgcrypt-1.7.3/tests/benchmark.c ---- libgcrypt-1.7.3/tests/benchmark.c.eccfix 2016-07-14 11:19:17.000000000 +0200 -+++ libgcrypt-1.7.3/tests/benchmark.c 2016-11-22 16:21:00.109004197 +0100 -@@ -1412,7 +1412,7 @@ ecc_bench (int iterations, int print_hea - { - #if USE_ECC - gpg_error_t err; -- const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", -+ const char *p_sizes[] = { "224", "256", "384", "521", "Ed25519", - "gost256", "gost512" }; - int testno; - -diff -up libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix libgcrypt-1.7.3/tests/dsa-rfc6979.c ---- libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix 2016-02-18 09:38:03.000000000 +0100 -+++ libgcrypt-1.7.3/tests/dsa-rfc6979.c 2016-11-22 16:22:11.804674008 +0100 -@@ -210,16 +210,6 @@ check_dsa_rfc6979 (void) - " ))" - }, - { -- "ECDSA, 192 bits (prime field)", -- "(private-key" -- " (ecdsa" -- " (curve \"NIST P-192\")" -- " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" -- " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" -- " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" -- " ))" -- }, -- { - "ECDSA, 224 bits (prime field)", - "(private-key" - " (ecdsa" -@@ -443,89 +433,6 @@ check_dsa_rfc6979 (void) - "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1" - }, - { -- "ECDSA, 192 bits (prime field)", -- "With SHA-1, message = \"sample\"", -- "sha1", "sample", -- "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", -- "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", -- "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-224, message = \"sample\"", -- "sha224", "sample", -- "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8", -- "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", -- "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-256, message = \"sample\"", -- "sha256", "sample", -- "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", -- "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", -- "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-384, message = \"sample\"", -- "sha384", "sample", -- "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311", -- "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", -- "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-512, message = \"sample\"", -- "sha512", "sample", -- "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", -- "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", -- "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-1, message = \"test\"", -- "sha1", "test", -- "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", -- "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", -- "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-224, message = \"test\"", -- "sha224", "test", -- "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE", -- "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", -- "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-256, message = \"test\"", -- "sha256", "test", -- "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", -- "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", -- "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-384, message = \"test\"", -- "sha384", "test", -- "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693", -- "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", -- "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-512, message = \"test\"", -- "sha512", "test", -- "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", -- "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", -- "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290" -- }, -- -- -- -- { - "ECDSA, 224 bits (prime field)", - "With SHA-1, message = \"sample\"", - "sha1", "sample", diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch index adecbe4..a5d3467 100644 --- a/libgcrypt-1.8.3-fips-ctor.patch +++ b/libgcrypt-1.8.3-fips-ctor.patch @@ -58,3 +58,16 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c _gcry_set_preferred_rng_type (0); _gcry_set_enforced_fips_mode (); } +diff --git a/tests/t-secmem.c b/tests/t-secmem.c +index 2b769134..1d33bbfd 100644 +--- a/tests/t-secmem.c ++++ b/tests/t-secmem.c +@@ -54,7 +54,7 @@ test_secmem (void) + + /* Allocating another 2k should fail for the default 16k pool. */ + b = gcry_malloc_secure (chunk_size*4); +- if (b) ++ if (b && !gcry_fips_mode_active ()) + fail ("allocation did not fail as expected\n"); + + for (i=0; i < DIM(a); i++) diff --git a/libgcrypt-1.8.3-md-fips-enforce.patch b/libgcrypt-1.8.3-md-fips-enforce.patch index eed7fa5..3b730a1 100644 --- a/libgcrypt-1.8.3-md-fips-enforce.patch +++ b/libgcrypt-1.8.3-md-fips-enforce.patch @@ -16,3 +16,22 @@ diff -up libgcrypt-1.8.3/cipher/md.c.fips-enforce libgcrypt-1.8.3/cipher/md.c err = GPG_ERR_DIGEST_ALGO; } } +diff --git a/tests/t-kdf.c b/tests/t-kdf.c +index 7a48e98a..48309b9a 100644 +--- a/tests/t-kdf.c ++++ b/tests/t-kdf.c +@@ -1104,6 +1104,13 @@ check_pbkdf2 (void) + GCRY_KDF_PBKDF2, tv[tvidx].hashalgo, + tv[tvidx].salt, tv[tvidx].saltlen, + tv[tvidx].c, tv[tvidx].dklen, outbuf); ++ if (gcry_fips_mode_active() && tvidx > 6) ++ { ++ if (!err) ++ fail ("pbkdf2 test %d unexpectedly passed in FIPS mode: %s\n", ++ tvidx, gpg_strerror (err)); ++ continue; ++ } + if (err) + fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); + else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) + diff --git a/libgcrypt-1.8.4-tests-fipsmode.patch b/libgcrypt-1.8.4-tests-fipsmode.patch deleted file mode 100644 index fa235f8..0000000 --- a/libgcrypt-1.8.4-tests-fipsmode.patch +++ /dev/null @@ -1,198 +0,0 @@ -diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basic.c ---- libgcrypt-1.8.4/tests/basic.c.tests-fipsmode 2018-04-17 17:29:40.000000000 +0200 -+++ libgcrypt-1.8.4/tests/basic.c 2019-02-12 13:30:48.935791024 +0100 -@@ -6964,7 +6964,7 @@ check_ciphers (void) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_EAX, 0); - if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0); -- if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) -+ if (!in_fips_mode && gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0); - if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0); -@@ -7010,12 +7010,18 @@ check_cipher_modes(void) - check_cfb_cipher (); - check_ofb_cipher (); - check_ccm_cipher (); -- check_gcm_cipher (); -- check_poly1305_cipher (); -- check_ocb_cipher (); -+ if (!in_fips_mode) -+ { -+ check_gcm_cipher (); -+ check_poly1305_cipher (); -+ check_ocb_cipher (); -+ } - check_xts_cipher (); - check_eax_cipher (); -- check_gost28147_cipher (); -+ if (!in_fips_mode) -+ { -+ check_gost28147_cipher (); -+ } - check_stream_cipher (); - check_stream_cipher_large_block (); - -@@ -10001,7 +10007,7 @@ check_mac (void) - show_mac_not_available (algos[i].algo); - continue; - } -- if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode) -+ if ((algos[i].algo == GCRY_MAC_GMAC_AES || gcry_mac_test_algo (algos[i].algo)) && in_fips_mode) - { - if (verbose) - fprintf (stderr, " algorithm %d not available in fips mode\n", -@@ -11095,8 +11101,6 @@ main (int argc, char **argv) - /* If we are in fips mode do some more tests. */ - gcry_md_hd_t md; - -- /* First trigger a self-test. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("not in operational state after self-test\n"); - -@@ -11121,15 +11125,6 @@ main (int argc, char **argv) - gcry_md_close (md); - if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("expected error state but still in operational state\n"); -- else -- { -- /* Now run a self-test and to get back into -- operational state. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); -- if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) -- fail ("did not reach operational after error " -- "and self-test\n"); -- } - } - } - -diff -up libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode libgcrypt-1.8.4/tests/benchmark.c ---- libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode 2019-02-12 11:31:44.859603883 +0100 -+++ libgcrypt-1.8.4/tests/benchmark.c 2019-02-12 14:10:40.271999352 +0100 -@@ -872,8 +872,10 @@ cipher_bench ( const char *algoname ) - && algo != GCRY_CIPHER_CHACHA20) - continue; - -- if (modes[modeidx].req_blocksize > 0 -- && blklen != modes[modeidx].req_blocksize) -+ if ((modes[modeidx].req_blocksize > 0 -+ && blklen != modes[modeidx].req_blocksize) -+ || (in_fips_mode -+ && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM)) - { - printf (" %7s %7s", "-", "-" ); - continue; -diff -up libgcrypt-1.8.4/tests/bench-slope.c.tests-fipsmode libgcrypt-1.8.4/tests/bench-slope.c ---- libgcrypt-1.8.4/tests/bench-slope.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/tests/bench-slope.c 2019-02-12 14:14:33.618763325 +0100 -@@ -1338,7 +1338,7 @@ cipher_bench_one (int algo, struct bench - return; - - /* GCM has restrictions for block-size */ -- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) -+ if (mode.mode == GCRY_CIPHER_MODE_GCM && (gcry_fips_mode_active () || blklen != GCRY_GCM_BLOCK_LEN)) - return; - - /* XTS has restrictions for block-size */ -diff -up libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode libgcrypt-1.8.4/tests/pubkey.c ---- libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/tests/pubkey.c 2019-02-12 13:52:25.658746415 +0100 -@@ -504,15 +504,30 @@ get_dsa_key_with_domain_new (gcry_sexp_t - rc = gcry_sexp_new - (&key_spec, - "(genkey (dsa (transient-key)(domain" -- "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" -- "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" -- "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" -- "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" -- "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" -- "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" -- "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" -- "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" -- "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" -+ " (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" -+ " 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" -+ " 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" -+ " 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" -+ " 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" -+ " eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" -+ " 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" -+ " 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" -+ " 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" -+ " 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" -+ " 2c8d7469db02e24d592394a7dba069e9#)" -+ " (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" -+ " 7441a0a5#)" -+ " (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" -+ " 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" -+ " ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" -+ " 0df242b75b414df372121e53a553f222f836b000f016485b" -+ " 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" -+ " 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" -+ " 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" -+ " ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" -+ " 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" -+ " 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" -+ " 45f322f82e4e85ca3ab85591b3c2a966#)" - ")))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); -@@ -595,7 +610,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ - " (use-fips186)" - " (transient-key)" - " (derive-parms" -- " (seed #f770a4598ff756931fc529764513b103ce57d85f4ad8c5cf297c9b4d48241c5b#))))", -+ " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", - 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); -diff -up libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode libgcrypt-1.8.4/tests/t-cv25519.c ---- libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/tests/t-cv25519.c 2019-02-12 14:02:35.935705390 +0100 -@@ -560,6 +560,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); -+ /* Curve25519 isn't supported in fips mode */ -+ if (gcry_fips_mode_active()) -+ return 77; - - start_timer (); - check_cv25519 (); -diff -up libgcrypt-1.8.4/tests/t-x448.c.tests-fipsmode libgcrypt-1.8.4/tests/t-x448.c ---- libgcrypt-1.8.4/tests/t-x448.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/tests/t-x448.c 2019-02-12 14:02:35.935705390 +0100 -@@ -560,6 +560,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); -+ /* x448 isn't supported in fips mode */ -+ if (gcry_fips_mode_active()) -+ return 77; - - start_timer (); - check_x448 (); -diff -up libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode libgcrypt-1.8.4/tests/t-secmem.c ---- libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode 2017-11-23 19:19:54.000000000 +0100 -+++ libgcrypt-1.8.4/tests/t-secmem.c 2019-02-12 11:51:02.462190538 +0100 -@@ -174,7 +174,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0)); -- gcry_set_outofcore_handler (outofcore_handler, NULL); -+ if (!gcry_fips_mode_active ()) -+ gcry_set_outofcore_handler (outofcore_handler, NULL); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - - /* Libgcrypt prints a warning when the first overflow is allocated; -@@ -184,7 +185,8 @@ main (int argc, char **argv) - - - test_secmem (); -- test_secmem_overflow (); -+ if (!gcry_fips_mode_active ()) -+ test_secmem_overflow (); - /* FIXME: We need to improve the tests, for example by registering - * our own log handler and comparing the output of - * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */ diff --git a/libgcrypt-1.9.3-fips-tests.patch b/libgcrypt-1.9.3-fips-tests.patch new file mode 100644 index 0000000..1ddc64f --- /dev/null +++ b/libgcrypt-1.9.3-fips-tests.patch @@ -0,0 +1,1804 @@ +commit 57cf83834bc00a7431378aabda692bf700e4876c +Author: Jussi Kivilinna +Date: Sat Apr 17 17:06:40 2021 +0300 + + tests/bench-slope: add ECC benchmarking + + * tests/bench-slope.c (bench_print_result_nsec_per_iteration): New. + (bench_print_header_nsec_per_iteration): New. + (kdf_bench_one, kdf_bench): Use new print helper functions. + [USE_ECC]: New ECC benchmarks. + (ecc_bench): New. + (print_help): Add 'ecc' option. + (main): Add ECC benchmarks. + -- + + Signed-off-by: Jussi Kivilinna + +diff --git a/tests/bench-slope.c b/tests/bench-slope.c +index c8647b6b..9b4a139a 100644 +--- a/tests/bench-slope.c ++++ b/tests/bench-slope.c +@@ -783,6 +783,54 @@ bench_print_result (double nsecs_per_byte) + bench_print_result_std (nsecs_per_byte); + } + ++static void ++bench_print_result_nsec_per_iteration (double nsecs_per_iteration) ++{ ++ double cycles_per_iteration; ++ char nsecpiter_buf[16]; ++ char cpiter_buf[16]; ++ char mhz_buf[16]; ++ ++ strcpy(cpiter_buf, csv_mode ? "" : "-"); ++ strcpy(mhz_buf, csv_mode ? "" : "-"); ++ ++ double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); ++ ++ /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ ++ if (bench_ghz > 0.0) ++ { ++ cycles_per_iteration = nsecs_per_iteration * bench_ghz; ++ double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); ++ double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); ++ } ++ ++ if (csv_mode) ++ { ++ if (auto_ghz) ++ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", ++ current_section_name, ++ current_algo_name ? current_algo_name : "", ++ current_mode_name ? current_mode_name : "", ++ nsecpiter_buf, ++ cpiter_buf, ++ mhz_buf); ++ else ++ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", ++ current_section_name, ++ current_algo_name ? current_algo_name : "", ++ current_mode_name ? current_mode_name : "", ++ nsecpiter_buf, ++ cpiter_buf); ++ } ++ else ++ { ++ if (auto_ghz) ++ printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); ++ else ++ printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); ++ } ++} ++ + static void + bench_print_section (const char *section_name, const char *print_name) + { +@@ -819,6 +867,28 @@ bench_print_header (int algo_width, const char *algo_name) + } + } + ++static void ++bench_print_header_nsec_per_iteration (int algo_width, const char *algo_name) ++{ ++ if (csv_mode) ++ { ++ gcry_free (current_algo_name); ++ current_algo_name = gcry_xstrdup (algo_name); ++ } ++ else ++ { ++ if (algo_width < 0) ++ printf (" %-*s | ", -algo_width, algo_name); ++ else ++ printf (" %-*s | ", algo_width, algo_name); ++ ++ if (auto_ghz) ++ printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); ++ else ++ printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); ++ } ++} ++ + static void + bench_print_algo (int algo_width, const char *algo_name) + { +@@ -1991,11 +2061,7 @@ kdf_bench_one (int algo, int subalgo) + struct bench_kdf_mode mode = { &kdf_ops }; + struct bench_obj obj = { 0 }; + double nsecs_per_iteration; +- double cycles_per_iteration; + char algo_name[32]; +- char nsecpiter_buf[16]; +- char cpiter_buf[16]; +- char mhz_buf[16]; + + mode.algo = algo; + mode.subalgo = subalgo; +@@ -2030,45 +2096,7 @@ kdf_bench_one (int algo, int subalgo) + obj.priv = &mode; + + nsecs_per_iteration = do_slope_benchmark (&obj); +- +- strcpy(cpiter_buf, csv_mode ? "" : "-"); +- strcpy(mhz_buf, csv_mode ? "" : "-"); +- +- double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); +- +- /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ +- if (bench_ghz > 0.0) +- { +- cycles_per_iteration = nsecs_per_iteration * bench_ghz; +- double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); +- double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); +- } +- +- if (csv_mode) +- { +- if (auto_ghz) +- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", +- current_section_name, +- current_algo_name ? current_algo_name : "", +- current_mode_name ? current_mode_name : "", +- nsecpiter_buf, +- cpiter_buf, +- mhz_buf); +- else +- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", +- current_section_name, +- current_algo_name ? current_algo_name : "", +- current_mode_name ? current_mode_name : "", +- nsecpiter_buf, +- cpiter_buf); +- } +- else +- { +- if (auto_ghz) +- printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); +- else +- printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); +- } ++ bench_print_result_nsec_per_iteration (nsecs_per_iteration); + } + + void +@@ -2079,14 +2107,7 @@ kdf_bench (char **argv, int argc) + + bench_print_section ("kdf", "KDF"); + +- if (!csv_mode) +- { +- printf (" %-*s | ", 24, ""); +- if (auto_ghz) +- printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); +- else +- printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); +- } ++ bench_print_header_nsec_per_iteration (24, ""); + + if (argv && argc) + { +@@ -2116,13 +2137,571 @@ kdf_bench (char **argv, int argc) + } + + ++/************************************************************ ECC benchmarks. */ ++ ++#if USE_ECC ++enum bench_ecc_algo ++{ ++ ECC_ALGO_ED25519 = 0, ++ ECC_ALGO_ED448, ++ ECC_ALGO_NIST_P192, ++ ECC_ALGO_NIST_P224, ++ ECC_ALGO_NIST_P256, ++ ECC_ALGO_NIST_P384, ++ ECC_ALGO_NIST_P521, ++ ECC_ALGO_SECP256K1, ++ __MAX_ECC_ALGO ++}; ++ ++enum bench_ecc_operation ++{ ++ ECC_OPER_MULT = 0, ++ ECC_OPER_KEYGEN, ++ ECC_OPER_SIGN, ++ ECC_OPER_VERIFY, ++ __MAX_ECC_OPER ++}; ++ ++struct bench_ecc_oper ++{ ++ enum bench_ecc_operation oper; ++ const char *name; ++ struct bench_ops *ops; ++ ++ enum bench_ecc_algo algo; ++}; ++ ++struct bench_ecc_mult_hd ++{ ++ gcry_ctx_t ec; ++ gcry_mpi_t k, x, y; ++ gcry_mpi_point_t G, Q; ++}; ++ ++struct bench_ecc_hd ++{ ++ gcry_sexp_t key_spec; ++ gcry_sexp_t data; ++ gcry_sexp_t pub_key; ++ gcry_sexp_t sec_key; ++ gcry_sexp_t sig; ++}; ++ ++ ++static const char * ++ecc_algo_name (int algo) ++{ ++ switch (algo) ++ { ++ case ECC_ALGO_ED25519: ++ return "Ed25519"; ++ case ECC_ALGO_ED448: ++ return "Ed448"; ++ case ECC_ALGO_NIST_P192: ++ return "NIST-P192"; ++ case ECC_ALGO_NIST_P224: ++ return "NIST-P224"; ++ case ECC_ALGO_NIST_P256: ++ return "NIST-P256"; ++ case ECC_ALGO_NIST_P384: ++ return "NIST-P384"; ++ case ECC_ALGO_NIST_P521: ++ return "NIST-P521"; ++ case ECC_ALGO_SECP256K1: ++ return "secp256k1"; ++ default: ++ return NULL; ++ } ++} ++ ++static const char * ++ecc_algo_curve (int algo) ++{ ++ switch (algo) ++ { ++ case ECC_ALGO_ED25519: ++ return "Ed25519"; ++ case ECC_ALGO_ED448: ++ return "Ed448"; ++ case ECC_ALGO_NIST_P192: ++ return "NIST P-192"; ++ case ECC_ALGO_NIST_P224: ++ return "NIST P-224"; ++ case ECC_ALGO_NIST_P256: ++ return "NIST P-256"; ++ case ECC_ALGO_NIST_P384: ++ return "NIST P-384"; ++ case ECC_ALGO_NIST_P521: ++ return "NIST P-521"; ++ case ECC_ALGO_SECP256K1: ++ return "secp256k1"; ++ default: ++ return NULL; ++ } ++} ++ ++static int ++ecc_nbits (int algo) ++{ ++ switch (algo) ++ { ++ case ECC_ALGO_ED25519: ++ return 255; ++ case ECC_ALGO_ED448: ++ return 448; ++ case ECC_ALGO_NIST_P192: ++ return 192; ++ case ECC_ALGO_NIST_P224: ++ return 224; ++ case ECC_ALGO_NIST_P256: ++ return 256; ++ case ECC_ALGO_NIST_P384: ++ return 384; ++ case ECC_ALGO_NIST_P521: ++ return 521; ++ case ECC_ALGO_SECP256K1: ++ return 256; ++ default: ++ return 0; ++ } ++} ++ ++static int ++ecc_map_name (const char *name) ++{ ++ int i; ++ ++ for (i = 0; i < __MAX_ECC_ALGO; i++) ++ { ++ if (strcmp(ecc_algo_name(i), name) == 0) ++ { ++ return i; ++ } ++ } ++ ++ return -1; ++} ++ ++ ++static int ++bench_ecc_mult_init (struct bench_obj *obj) ++{ ++ struct bench_ecc_oper *oper = obj->priv; ++ struct bench_ecc_mult_hd *hd; ++ int p_size = ecc_nbits (oper->algo); ++ gpg_error_t err; ++ gcry_mpi_t p; ++ ++ obj->min_bufsize = 1; ++ obj->max_bufsize = 4; ++ obj->step_size = 1; ++ obj->num_measure_repetitions = ++ num_measurement_repetitions / obj->max_bufsize; ++ ++ while (obj->num_measure_repetitions == 0) ++ { ++ if (obj->max_bufsize == 2) ++ { ++ obj->num_measure_repetitions = 2; ++ } ++ else ++ { ++ obj->max_bufsize--; ++ obj->num_measure_repetitions = ++ num_measurement_repetitions / obj->max_bufsize; ++ } ++ } ++ ++ hd = calloc (1, sizeof(*hd)); ++ if (!hd) ++ return -1; ++ ++ err = gcry_mpi_ec_new (&hd->ec, NULL, ecc_algo_curve(oper->algo)); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_mpi_ec_new failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ hd->G = gcry_mpi_ec_get_point ("g", hd->ec, 1); ++ hd->Q = gcry_mpi_point_new (0); ++ hd->x = gcry_mpi_new (0); ++ hd->y = gcry_mpi_new (0); ++ hd->k = gcry_mpi_new (p_size); ++ gcry_mpi_randomize (hd->k, p_size, GCRY_WEAK_RANDOM); ++ p = gcry_mpi_ec_get_mpi ("p", hd->ec, 1); ++ gcry_mpi_mod (hd->k, hd->k, p); ++ gcry_mpi_release (p); ++ ++ obj->hd = hd; ++ return 0; ++} ++ ++static void ++bench_ecc_mult_free (struct bench_obj *obj) ++{ ++ struct bench_ecc_mult_hd *hd = obj->hd; ++ ++ gcry_mpi_release (hd->k); ++ gcry_mpi_release (hd->y); ++ gcry_mpi_release (hd->x); ++ gcry_mpi_point_release (hd->Q); ++ gcry_mpi_point_release (hd->G); ++ gcry_ctx_release (hd->ec); ++ free (hd); ++ obj->hd = NULL; ++} ++ ++static void ++bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) ++{ ++ struct bench_ecc_mult_hd *hd = obj->hd; ++ size_t i; ++ ++ (void)buf; ++ ++ for (i = 0; i < num_iter; i++) ++ { ++ gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec); ++ if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec)) ++ { ++ fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n"); ++ exit (1); ++ } ++ } ++} ++ ++ ++static int ++bench_ecc_init (struct bench_obj *obj) ++{ ++ struct bench_ecc_oper *oper = obj->priv; ++ struct bench_ecc_hd *hd; ++ int p_size = ecc_nbits (oper->algo); ++ gpg_error_t err; ++ gcry_mpi_t x; ++ ++ obj->min_bufsize = 1; ++ obj->max_bufsize = 4; ++ obj->step_size = 1; ++ obj->num_measure_repetitions = ++ num_measurement_repetitions / obj->max_bufsize; ++ ++ while (obj->num_measure_repetitions == 0) ++ { ++ if (obj->max_bufsize == 2) ++ { ++ obj->num_measure_repetitions = 2; ++ } ++ else ++ { ++ obj->max_bufsize--; ++ obj->num_measure_repetitions = ++ num_measurement_repetitions / obj->max_bufsize; ++ } ++ } ++ ++ hd = calloc (1, sizeof(*hd)); ++ if (!hd) ++ return -1; ++ ++ x = gcry_mpi_new (p_size); ++ gcry_mpi_randomize (x, p_size, GCRY_WEAK_RANDOM); ++ ++ switch (oper->algo) ++ { ++ default: ++ return -1; ++ ++ case ECC_ALGO_ED25519: ++ err = gcry_sexp_build (&hd->key_spec, NULL, ++ "(genkey (ecdsa (curve \"Ed25519\")" ++ "(flags eddsa)))"); ++ if (err) ++ break; ++ err = gcry_sexp_build (&hd->data, NULL, ++ "(data (flags eddsa)(hash-algo sha512)" ++ " (value %m))", x); ++ break; ++ ++ case ECC_ALGO_ED448: ++ err = gcry_sexp_build (&hd->key_spec, NULL, ++ "(genkey (ecdsa (curve \"Ed448\")" ++ "(flags eddsa)))"); ++ if (err) ++ break; ++ err = gcry_sexp_build (&hd->data, NULL, ++ "(data (flags eddsa)(hash-algo shake256)" ++ " (value %m))", x); ++ break; ++ ++ case ECC_ALGO_NIST_P192: ++ case ECC_ALGO_NIST_P224: ++ case ECC_ALGO_NIST_P256: ++ case ECC_ALGO_NIST_P384: ++ case ECC_ALGO_NIST_P521: ++ err = gcry_sexp_build (&hd->key_spec, NULL, ++ "(genkey (ECDSA (nbits %d)))", p_size); ++ if (err) ++ break; ++ err = gcry_sexp_build (&hd->data, NULL, ++ "(data (flags raw) (value %m))", x); ++ break; ++ } ++ ++ gcry_mpi_release (x); ++ ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_sexp_build failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ ++ obj->hd = hd; ++ return 0; ++} ++ ++static void ++bench_ecc_free (struct bench_obj *obj) ++{ ++ struct bench_ecc_hd *hd = obj->hd; ++ ++ gcry_sexp_release (hd->sig); ++ gcry_sexp_release (hd->pub_key); ++ gcry_sexp_release (hd->sec_key); ++ gcry_sexp_release (hd->data); ++ gcry_sexp_release (hd->key_spec); ++ free (hd); ++ obj->hd = NULL; ++} ++ ++static void ++bench_ecc_keygen (struct bench_ecc_hd *hd) ++{ ++ gcry_sexp_t key_pair; ++ gpg_error_t err; ++ ++ err = gcry_pk_genkey (&key_pair, hd->key_spec); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_pk_genkey failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ ++ hd->pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); ++ if (!hd->pub_key) ++ { ++ fprintf (stderr, PGM ": public part missing in key\n"); ++ exit (1); ++ } ++ hd->sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); ++ if (!hd->sec_key) ++ { ++ fprintf (stderr, PGM ": private part missing in key\n"); ++ exit (1); ++ } ++ ++ gcry_sexp_release (key_pair); ++} ++ ++static void ++bench_ecc_keygen_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) ++{ ++ struct bench_ecc_hd *hd = obj->hd; ++ size_t i; ++ ++ (void)buf; ++ ++ for (i = 0; i < num_iter; i++) ++ { ++ bench_ecc_keygen (hd); ++ gcry_sexp_release (hd->pub_key); ++ gcry_sexp_release (hd->sec_key); ++ } ++ ++ hd->pub_key = NULL; ++ hd->sec_key = NULL; ++} ++ ++static void ++bench_ecc_sign_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) ++{ ++ struct bench_ecc_hd *hd = obj->hd; ++ gpg_error_t err; ++ size_t i; ++ ++ (void)buf; ++ ++ bench_ecc_keygen (hd); ++ ++ for (i = 0; i < num_iter; i++) ++ { ++ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ gcry_sexp_release (hd->sig); ++ } ++ ++ gcry_sexp_release (hd->pub_key); ++ gcry_sexp_release (hd->sec_key); ++ hd->sig = NULL; ++ hd->pub_key = NULL; ++ hd->sec_key = NULL; ++} ++ ++static void ++bench_ecc_verify_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) ++{ ++ struct bench_ecc_hd *hd = obj->hd; ++ gpg_error_t err; ++ int i; ++ ++ (void)buf; ++ ++ bench_ecc_keygen (hd); ++ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ ++ for (i = 0; i < num_iter; i++) ++ { ++ err = gcry_pk_verify (hd->sig, hd->data, hd->pub_key); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_pk_verify failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ } ++ ++ gcry_sexp_release (hd->sig); ++ gcry_sexp_release (hd->pub_key); ++ gcry_sexp_release (hd->sec_key); ++ hd->sig = NULL; ++ hd->pub_key = NULL; ++ hd->sec_key = NULL; ++} ++ ++ ++static struct bench_ops ecc_mult_ops = { ++ &bench_ecc_mult_init, ++ &bench_ecc_mult_free, ++ &bench_ecc_mult_do_bench ++}; ++ ++static struct bench_ops ecc_keygen_ops = { ++ &bench_ecc_init, ++ &bench_ecc_free, ++ &bench_ecc_keygen_do_bench ++}; ++ ++static struct bench_ops ecc_sign_ops = { ++ &bench_ecc_init, ++ &bench_ecc_free, ++ &bench_ecc_sign_do_bench ++}; ++ ++static struct bench_ops ecc_verify_ops = { ++ &bench_ecc_init, ++ &bench_ecc_free, ++ &bench_ecc_verify_do_bench ++}; ++ ++ ++static struct bench_ecc_oper ecc_operations[] = { ++ { ECC_OPER_MULT, "mult", &ecc_mult_ops }, ++ { ECC_OPER_KEYGEN, "keygen", &ecc_keygen_ops }, ++ { ECC_OPER_SIGN, "sign", &ecc_sign_ops }, ++ { ECC_OPER_VERIFY, "verify", &ecc_verify_ops }, ++ { 0, NULL, NULL } ++}; ++ ++ ++static void ++cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper) ++{ ++ struct bench_ecc_oper oper = *poper; ++ struct bench_obj obj = { 0 }; ++ double result; ++ ++ if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT) ++ return; ++ ++ oper.algo = algo; ++ ++ bench_print_mode (14, oper.name); ++ ++ obj.ops = oper.ops; ++ obj.priv = &oper; ++ ++ result = do_slope_benchmark (&obj); ++ bench_print_result_nsec_per_iteration (result); ++} ++ ++ ++static void ++_ecc_bench (int algo) ++{ ++ const char *algo_name; ++ int i; ++ ++ algo_name = ecc_algo_name (algo); ++ ++ bench_print_header_nsec_per_iteration (14, algo_name); ++ ++ for (i = 0; ecc_operations[i].name; i++) ++ cipher_ecc_one (algo, &ecc_operations[i]); ++ ++ bench_print_footer (14); ++} ++#endif ++ ++ ++void ++ecc_bench (char **argv, int argc) ++{ ++#if USE_ECC ++ int i, algo; ++ ++ bench_print_section ("ecc", "ECC"); ++ ++ if (argv && argc) ++ { ++ for (i = 0; i < argc; i++) ++ { ++ algo = ecc_map_name (argv[i]); ++ if (algo >= 0) ++ _ecc_bench (algo); ++ } ++ } ++ else ++ { ++ for (i = 0; i < __MAX_ECC_ALGO; i++) ++ _ecc_bench (i); ++ } ++#else ++ (void)argv; ++ (void)argc; ++#endif ++} ++ + /************************************************************** Main program. */ + + void + print_help (void) + { + static const char *help_lines[] = { +- "usage: bench-slope [options] [hash|mac|cipher|kdf [algonames]]", ++ "usage: bench-slope [options] [hash|mac|cipher|kdf|ecc [algonames]]", + "", + " options:", + " --cpu-mhz Set CPU speed for calculating cycles", +@@ -2304,6 +2883,7 @@ main (int argc, char **argv) + mac_bench (NULL, 0); + cipher_bench (NULL, 0); + kdf_bench (NULL, 0); ++ ecc_bench (NULL, 0); + } + else if (!strcmp (*argv, "hash")) + { +@@ -2337,6 +2917,14 @@ main (int argc, char **argv) + warm_up_cpu (); + kdf_bench ((argc == 0) ? NULL : argv, argc); + } ++ else if (!strcmp (*argv, "ecc")) ++ { ++ argc--; ++ argv++; ++ ++ warm_up_cpu (); ++ ecc_bench ((argc == 0) ? NULL : argv, argc); ++ } + else + { + fprintf (stderr, PGM ": unknown argument: %s\n", *argv); + +commit 9911069388e762d2a85bc2a11ca6cfcc4c895e4f +Author: Jussi Kivilinna +Date: Wed Jun 16 20:27:01 2021 +0300 + + bench-slope: add X25519 and X448 scalar multiplication + + * tests/bench-slope.c (ECC_ALGO_X25519, ECC_ALGO_X448): New. + (ecc_algo_name, ecc_algo_curve, ecc_nbits): Add X25519 and X448. + (bench_ecc_mult_do_bench): Pass Y as NULL to ec_get_affine with + X25519 and X448. + (cipher_ecc_one): Run only multiplication bench for X25519 and X448. + -- + + Signed-off-by: Jussi Kivilinna + +diff --git a/tests/bench-slope.c b/tests/bench-slope.c +index 9b4a139a..35272094 100644 +--- a/tests/bench-slope.c ++++ b/tests/bench-slope.c +@@ -2144,6 +2144,8 @@ enum bench_ecc_algo + { + ECC_ALGO_ED25519 = 0, + ECC_ALGO_ED448, ++ ECC_ALGO_X25519, ++ ECC_ALGO_X448, + ECC_ALGO_NIST_P192, + ECC_ALGO_NIST_P224, + ECC_ALGO_NIST_P256, +@@ -2197,6 +2199,10 @@ ecc_algo_name (int algo) + return "Ed25519"; + case ECC_ALGO_ED448: + return "Ed448"; ++ case ECC_ALGO_X25519: ++ return "X25519"; ++ case ECC_ALGO_X448: ++ return "X448"; + case ECC_ALGO_NIST_P192: + return "NIST-P192"; + case ECC_ALGO_NIST_P224: +@@ -2223,6 +2229,10 @@ ecc_algo_curve (int algo) + return "Ed25519"; + case ECC_ALGO_ED448: + return "Ed448"; ++ case ECC_ALGO_X25519: ++ return "Curve25519"; ++ case ECC_ALGO_X448: ++ return "X448"; + case ECC_ALGO_NIST_P192: + return "NIST P-192"; + case ECC_ALGO_NIST_P224: +@@ -2249,6 +2259,10 @@ ecc_nbits (int algo) + return 255; + case ECC_ALGO_ED448: + return 448; ++ case ECC_ALGO_X25519: ++ return 255; ++ case ECC_ALGO_X448: ++ return 448; + case ECC_ALGO_NIST_P192: + return 192; + case ECC_ALGO_NIST_P224: +@@ -2355,15 +2369,26 @@ bench_ecc_mult_free (struct bench_obj *obj) + static void + bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) + { ++ struct bench_ecc_oper *oper = obj->priv; + struct bench_ecc_mult_hd *hd = obj->hd; ++ gcry_mpi_t y; + size_t i; + + (void)buf; + ++ if (oper->algo == ECC_ALGO_X25519 || oper->algo == ECC_ALGO_X448) ++ { ++ y = NULL; ++ } ++ else ++ { ++ y = hd->y; ++ } ++ + for (i = 0; i < num_iter; i++) + { + gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec); +- if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec)) ++ if (gcry_mpi_ec_get_affine (hd->x, y, hd->Q, hd->ec)) + { + fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n"); + exit (1); +@@ -2634,7 +2659,8 @@ cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper) + struct bench_obj obj = { 0 }; + double result; + +- if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT) ++ if ((algo == ECC_ALGO_X25519 || algo == ECC_ALGO_X448 || ++ algo == ECC_ALGO_SECP256K1) && oper.oper != ECC_OPER_MULT) + return; + + oper.algo = algo; + + +From bd49a4fa915b8a078c341b35f5a51fcb2a004c35 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 12 Jul 2021 21:35:18 +0200 +Subject: [PATCH 1/8] mac: Disable AES GMAC in FIPS mode + +* cipher/mac-gmac.c (_gcry_mac_type_spec_gmac_aes): Remove FIPS flag +-- +The GMAC does not work in FIPS mode until libgcrypt will have internal +IV generator. + +Signed-off-by: Jakub Jelen +--- + cipher/mac-gmac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cipher/mac-gmac.c b/cipher/mac-gmac.c +index e04c6d1e..1d59d085 100644 +--- a/cipher/mac-gmac.c ++++ b/cipher/mac-gmac.c +@@ -157,7 +157,7 @@ static gcry_mac_spec_ops_t gmac_ops = { + + #if USE_AES + gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = { +- GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES", ++ GCRY_MAC_GMAC_AES, {0, 0}, "GMAC_AES", + &gmac_ops + }; + #endif +-- +2.31.1 + + +From fd0e1c3e7f6062579869d345875d6ef823706e56 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 12 Jul 2021 21:36:34 +0200 +Subject: [PATCH 2/8] tests: Do not expect GCM work in FIPS + +* tests/basic.c (check_one_cipher_core): Expect GCM ciphers to fail in + FIPS mode + (check_cipher_modes): Skip GCM ciphers tests as they fail quite late + in gcry_cipher_gettag(). +-- + +Signed-off-by: Jakub Jelen +--- + tests/basic.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/tests/basic.c b/tests/basic.c +index 0572c46e..d7b7f496 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -9510,6 +9510,13 @@ check_one_cipher_core (int algo, int mode, int flags, + + clutter_vector_registers(); + err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain); ++ if (in_fips_mode && mode == GCRY_CIPHER_MODE_GCM) ++ { ++ if (!err) ++ fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt is expected to " ++ "fail in FIPS mode: %s\n", pass, algo, mode, gpg_strerror (err)); ++ goto err_out_free; ++ } + if (err) + { + fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", +@@ -10257,7 +10264,12 @@ check_cipher_modes(void) + check_cfb_cipher (); + check_ofb_cipher (); + check_ccm_cipher (); +- check_gcm_cipher (); ++ if (!in_fips_mode) ++ { ++ /* This will have to go through modifications as the GCM fails in fips ++ * as late as in gcry_cipher_gettag, but we want to allow it in the end */ ++ check_gcm_cipher (); ++ } + check_poly1305_cipher (); + check_ocb_cipher (); + check_xts_cipher (); +-- +2.31.1 + + +From ccbb1694693080822858e2065cf88ab43ec03fbc Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 09:18:52 +0200 +Subject: [PATCH 3/8] tests: Skip unsupported mechanisms in FIPS mode + +* tests/bench-slope.c (cipher_bench_one): Skip GCM mode in FIPS mode + (ecc_algo_fips_allowed): New function + (_ecc_bench): Skip algorithms disabled in FIPS mode + (main): Check for FIPS mode +* tests/benchmark.c (cipher_bench): Skip GCM in FIPS mode +-- +In FIPS mode, not all the curves are allowed. This is already checked in +other parts of the code base, but not in the benchmark test. + +Signed-off-by: Jakub Jelen +--- + tests/bench-slope.c | 33 +++++++++++++++++++++++++++++++-- + tests/benchmark.c | 4 ++++ + 2 files changed, 35 insertions(+), 2 deletions(-) + +diff --git a/tests/bench-slope.c b/tests/bench-slope.c +index 35272094..5bdb391e 100644 +--- a/tests/bench-slope.c ++++ b/tests/bench-slope.c +@@ -70,6 +70,7 @@ static double bench_ghz; + /* Current accuracy of auto-detected CPU Ghz. */ + static double bench_ghz_diff; + ++static int in_fips_mode = 0; + + /*************************************** Default parameters for measurements. */ + +@@ -1642,8 +1643,8 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode) + if (mode.mode == GCRY_CIPHER_MODE_CCM && blklen != GCRY_CCM_BLOCK_LEN) + return; + +- /* GCM has restrictions for block-size */ +- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) ++ /* GCM has restrictions for block-size; not allowed in FIPS mode */ ++ if (mode.mode == GCRY_CIPHER_MODE_GCM && (in_fips_mode || blklen != GCRY_GCM_BLOCK_LEN)) + return; + + /* XTS has restrictions for block-size */ +@@ -2190,6 +2191,27 @@ struct bench_ecc_hd + }; + + ++static int ++ecc_algo_fips_allowed (int algo) ++{ ++ switch (algo) ++ { ++ case ECC_ALGO_NIST_P224: ++ case ECC_ALGO_NIST_P256: ++ case ECC_ALGO_NIST_P384: ++ case ECC_ALGO_NIST_P521: ++ return 1; ++ case ECC_ALGO_SECP256K1: ++ case ECC_ALGO_ED25519: ++ case ECC_ALGO_ED448: ++ case ECC_ALGO_X25519: ++ case ECC_ALGO_X448: ++ case ECC_ALGO_NIST_P192: ++ default: ++ return 0; ++ } ++} ++ + static const char * + ecc_algo_name (int algo) + { +@@ -2681,6 +2703,10 @@ _ecc_bench (int algo) + const char *algo_name; + int i; + ++ /* Skip not allowed mechanisms */ ++ if (!ecc_algo_fips_allowed(algo)) ++ return; ++ + algo_name = ecc_algo_name (algo); + + bench_print_header_nsec_per_iteration (14, algo_name); +@@ -2899,6 +2925,9 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; ++ + if (in_regression_test) + fputs ("Note: " PGM " running in quick regression test mode.\n", stdout); + +diff --git a/tests/benchmark.c b/tests/benchmark.c +index 605b50c6..24141371 100644 +--- a/tests/benchmark.c ++++ b/tests/benchmark.c +@@ -943,6 +943,10 @@ cipher_bench ( const char *algoname ) + && algo != GCRY_CIPHER_CHACHA20) + continue; + ++ /* GCM is not available in FIPS mode */ ++ if (in_fips_mode && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM) ++ continue; ++ + if (modes[modeidx].req_blocksize > 0 + && blklen != modes[modeidx].req_blocksize) + { +-- +2.31.1 + + +From 744baa85722da10d7374c6eca6b08b8197819ab6 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 09:20:18 +0200 +Subject: [PATCH 4/8] tests: Expect curves 25519/448 to fail in FIPS mode + +* tests/t-cv25519.c (test_cv_hl): Expect the operation to fail in FIPS + mode. + (test_cv_x25519, test_it): Ditto. + (main) Detect FIPS mode. +* tests/t-ed25519.c (one_test): Expect the operation to fail in FIPS + mode. + (main) Detect FIPS mode. +* tests/t-ed448.c (one_test): Expect the operation to fail in FIPS + mode. + (main) Detect FIPS mode. +* tests/t-x448.c (test_cv_hl): Expect the operation to fail in FIPS + mode. + (test_cv_x448, test_cv): Ditto. + (main) Detect FIPS mode. +-- +The ed25519, ed448, cv25519 and cv448 curves are not available in FIPS +mode. Some of the tests already skipped these, but it is always better +to make sure thy are failing, rather than just skipping these. + +Signed-off-by: Jakub Jelen +--- + tests/t-cv25519.c | 37 +++++++++++++++++++++++++++++++++++-- + tests/t-ed25519.c | 18 ++++++++++++++---- + tests/t-ed448.c | 18 ++++++++++++++---- + tests/t-x448.c | 41 +++++++++++++++++++++++++++++++++++++---- + 4 files changed, 100 insertions(+), 14 deletions(-) + +diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c +index 0de50a02..b4126f4c 100644 +--- a/tests/t-cv25519.c ++++ b/tests/t-cv25519.c +@@ -33,6 +33,7 @@ + #include "t-common.h" + #define N_TESTS 18 + ++static int in_fips_mode = 0; + + static void + print_mpi (const char *text, gcry_mpi_t a) +@@ -188,7 +189,17 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, + xfree (buffer); + buffer = NULL; + +- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) ++ err = gcry_pk_encrypt (&s_result, s_data, s_pk); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_pk_encrypt failed for test %d: %s", testno, + gpg_strerror (err)); + +@@ -281,7 +292,17 @@ test_cv_x25519 (int testno, const char *k_str, const char *u_str, + goto leave; + } + +- if ((err = gcry_ecc_mul_point (algo, result, scalar, point))) ++ err = gcry_ecc_mul_point (algo, result, scalar, point); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_ecc_mul_point failed for test %d: %s", testno, + gpg_strerror (err)); + +@@ -335,6 +356,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) + info ("Running test %d: iteration=%d\n", testno, iter); + + gcry_mpi_ec_new (&ctx, NULL, "Curve25519"); ++ if (in_fips_mode) ++ { ++ if (ctx) ++ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ return; ++ } + Q = gcry_mpi_point_new (0); + + if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32) +@@ -640,6 +670,9 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; ++ + start_timer (); + check_cv25519 (); + stop_timer (); +diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c +index a5271c25..567bc797 100644 +--- a/tests/t-ed25519.c ++++ b/tests/t-ed25519.c +@@ -36,6 +36,7 @@ + static int sign_with_pk; + static int no_verify; + static int custom_data_file; ++static int in_fips_mode = 0; + + + static void +@@ -271,7 +272,17 @@ one_test (int testno, const char *sk, const char *pk, + goto leave; + } + +- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) ++ err = gcry_pk_sign (&s_sig, s_msg, s_sk); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); + if (debug) + show_sexp ("sig=", s_sig); +@@ -481,9 +492,8 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + +- /* Ed25519 isn't supported in fips mode */ +- if (gcry_fips_mode_active()) +- return 77; ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; + + start_timer (); + check_ed25519 (fname); +diff --git a/tests/t-ed448.c b/tests/t-ed448.c +index 1f445ffc..f38cd10c 100644 +--- a/tests/t-ed448.c ++++ b/tests/t-ed448.c +@@ -36,6 +36,7 @@ + static int sign_with_pk; + static int no_verify; + static int custom_data_file; ++static int in_fips_mode = 0; + + + static void +@@ -302,7 +303,17 @@ one_test (int testno, int ph, const char *sk, const char *pk, + } + } + +- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) ++ err = gcry_pk_sign (&s_sig, s_msg, s_sk); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); + if (debug) + show_sexp ("sig=", s_sig); +@@ -521,9 +532,8 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + +- /* Ed448 isn't supported in fips mode */ +- if (gcry_fips_mode_active()) +- return 77; ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; + + start_timer (); + check_ed448 (fname); +diff --git a/tests/t-x448.c b/tests/t-x448.c +index 5c3cbeb9..cc4b10fc 100644 +--- a/tests/t-x448.c ++++ b/tests/t-x448.c +@@ -34,6 +34,7 @@ + #include "t-common.h" + #define N_TESTS 9 + ++static int in_fips_mode = 0; + + static void + print_mpi (const char *text, gcry_mpi_t a) +@@ -179,8 +180,18 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, + xfree (buffer); + buffer = NULL; + +- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) +- fail ("gcry_pk_encrypt failed for test %d: %s", testno, ++ err = gcry_pk_encrypt (&s_result, s_data, s_pk); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) ++ fail ("gcry_pk_encrypt goto leavefailed for test %d: %s", testno, + gpg_strerror (err)); + + s_tmp = gcry_sexp_find_token (s_result, "s", 0); +@@ -257,7 +268,17 @@ test_cv_x448 (int testno, const char *k_str, const char *u_str, + goto leave; + } + +- if ((err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point))) ++ err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point); ++ if (in_fips_mode) ++ { ++ if (err != GPG_ERR_NOT_SUPPORTED) ++ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d: %s", ++ testno, gpg_strerror (err)); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_ecc_mul_point failed for test %d: %s", testno, + gpg_strerror (err)); + +@@ -296,7 +317,7 @@ test_cv (int testno, const char *k_str, const char *u_str, + static void + test_it (int testno, const char *k_str, int iter, const char *result_str) + { +- gcry_ctx_t ctx; ++ gcry_ctx_t ctx = NULL; + gpg_error_t err; + void *buffer = NULL; + size_t buflen; +@@ -311,6 +332,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) + info ("Running test %d: iteration=%d\n", testno, iter); + + gcry_mpi_ec_new (&ctx, NULL, "X448"); ++ if (in_fips_mode) ++ { ++ if (ctx) ++ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ return; ++ } + Q = gcry_mpi_point_new (0); + + if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 56) +@@ -583,6 +613,9 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; ++ + start_timer (); + check_x448 (); + stop_timer (); +-- +2.31.1 + + +From d3a603cd4a0ff2a8df35f5bb39efd64c52b2b2c5 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 10:11:42 +0200 +Subject: [PATCH 5/8] tests: Expect the 192b ECDSA tests to fail in fips mode + +* tests/dsa-rfc6979.c (check_dsa_rfc6979): Expect ECDSA 192b keys to + fail in FIPS mode. + (main): Detect FIPS mode. +-- +The 192b ECDSA curve is not FIPS approved so it does not work. This adds +a flag to the list of the keys to mark if it is expected to work in FIPS +mode. + +Signed-off-by: Jakub Jelen +--- + tests/dsa-rfc6979.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/tests/dsa-rfc6979.c b/tests/dsa-rfc6979.c +index 7d3d2080..0f124575 100644 +--- a/tests/dsa-rfc6979.c ++++ b/tests/dsa-rfc6979.c +@@ -33,6 +33,7 @@ + #define PGM "dsa-rfc6979" + #include "t-common.h" + ++static int in_fips_mode = 0; + + static void + show_sexp (const char *prefix, gcry_sexp_t a) +@@ -111,6 +112,7 @@ check_dsa_rfc6979 (void) + static struct { + const char *name; + const char *key; ++ int fips; + } keys[] = { + { + "DSA, 1024 bits", +@@ -130,7 +132,7 @@ check_dsa_rfc6979 (void) + " 92195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D" + " 4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E6" + " 82F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B#)" +- " ))" ++ " ))", 1 + }, + { + "DSA, 2048 bits", +@@ -162,7 +164,7 @@ check_dsa_rfc6979 (void) + " 687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D1" + " 23AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA" + " 74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)" +- " ))" ++ " ))", 1 + }, + { + "ECDSA, 192 bits (prime field)", +@@ -172,7 +174,7 @@ check_dsa_rfc6979 (void) + " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" + " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" + " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" +- " ))" ++ " ))", 0 + }, + { + "ECDSA, 224 bits (prime field)", +@@ -183,7 +185,7 @@ check_dsa_rfc6979 (void) + " 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C" + " EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)" + " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)" +- " ))" ++ " ))", 1 + }, + { + "ECDSA, 256 bits (prime field)", +@@ -194,7 +196,7 @@ check_dsa_rfc6979 (void) + " 60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6" + " 7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)" + " (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)" +- " ))" ++ " ))", 1 + }, + { + "ECDSA, 384 bits (prime field)", +@@ -208,7 +210,7 @@ check_dsa_rfc6979 (void) + " 288B231C3AE0D4FE7344FD2533264720#)" + " (d #6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8" + " 96D5724E4C70A825F872C9EA60D2EDF5#)" +- " ))" ++ " ))", 1 + }, + { + "ECDSA, 521 bits (prime field)", +@@ -225,7 +227,7 @@ check_dsa_rfc6979 (void) + " (d #FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75" + " CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B8" + " 3538#)" +- " ))" ++ " ))", 1 + }, + { NULL } + }; +@@ -937,6 +939,12 @@ check_dsa_rfc6979 (void) + die ("building data sexp failed: %s\n", gpg_strerror (err)); + + err = gcry_pk_sign (&sig, data, seckey); ++ if (in_fips_mode && !keys[i].fips) ++ { ++ if (!err) ++ fail ("signing should not work in FIPS mode: %s\n", gpg_strerror (err)); ++ continue; ++ } + if (err) + fail ("signing failed: %s\n", gpg_strerror (err)); + +@@ -972,6 +980,8 @@ main (int argc, char **argv) + die ("version mismatch; pgm=%s, library=%s\n", + GCRYPT_VERSION,gcry_check_version (NULL)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; + if (debug) + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); + /* No valuable keys are create, so we can speed up our RNG. */ +-- +2.31.1 + + +From d4a52861e7d0d1871f4c1d32bc0815f0824eb9ab Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 10:32:33 +0200 +Subject: [PATCH 6/8] tests: Skip secmem overflow test in FIPS mode + +* tests/t-secmem.c (main): Skip overflow tests in FIPS mode because they + are fatal and there is no way to override the outofcore handler. +-- + +Signed-off-by: Jakub Jelen +--- + tests/t-secmem.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/tests/t-secmem.c b/tests/t-secmem.c +index 2b769134..692c0f1a 100644 +--- a/tests/t-secmem.c ++++ b/tests/t-secmem.c +@@ -37,6 +37,7 @@ + #define MINIMUM_POOL_SIZE 16384 + static size_t pool_size; + static size_t chunk_size; ++static int in_fips_mode = 0; + + static void + test_secmem (void) +@@ -182,8 +183,11 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0)); ++ /* This is ignored in FIPS Mode */ + gcry_set_outofcore_handler (outofcore_handler, NULL); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; + + /* Libgcrypt prints a warning when the first overflow is allocated; + * we do not want to see that. */ +@@ -192,7 +196,8 @@ main (int argc, char **argv) + + + test_secmem (); +- test_secmem_overflow (); ++ if (!in_fips_mode) ++ test_secmem_overflow (); + /* FIXME: We need to improve the tests, for example by registering + * our own log handler and comparing the output of + * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */ +-- +2.31.1 + + +From fc6de9c7b48ab45deb8ea84d1c768e4f056edb08 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 10:52:00 +0200 +Subject: [PATCH 7/8] tests: Transient DSA keys work in FIPS mode + +* tests/pubkey.c (check_run): Enable tests with DSA transient keys which + work in FIPS. +-- + +Signed-off-by: Jakub Jelen +--- + tests/pubkey.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/tests/pubkey.c b/tests/pubkey.c +index 754952ee..cd51e0a2 100644 +--- a/tests/pubkey.c ++++ b/tests/pubkey.c +@@ -680,15 +680,12 @@ check_run (void) + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + +- if (!gcry_fips_mode_active ()) +- { +- if (verbose) +- fprintf (stderr, "Generating transient DSA key.\n"); +- get_dsa_key_new (&pkey, &skey, 1); +- /* Fixme: Add a check function for DSA keys. */ +- gcry_sexp_release (pkey); +- gcry_sexp_release (skey); +- } ++ if (verbose) ++ fprintf (stderr, "Generating transient DSA key.\n"); ++ get_dsa_key_new (&pkey, &skey, 1); ++ /* Fixme: Add a check function for DSA keys. */ ++ gcry_sexp_release (pkey); ++ gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key (FIPS 186).\n"); +-- +2.31.1 + + +From e68b538008063938b9b054f18e56e9f27bb3a720 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 10:53:13 +0200 +Subject: [PATCH 8/8] tests: Generating DSA from domain should fail in FIPS + mode + +* tests/pubkey.c (get_dsa_key_with_domain_new): Expect failure in FIPS + mode + (check_x931_derived_key): Simplify testing for FIPS mode. + (main): Check for fips mode. +-- + +Signed-off-by: Jakub Jelen +--- + tests/pubkey.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/tests/pubkey.c b/tests/pubkey.c +index cd51e0a2..7209f44e 100644 +--- a/tests/pubkey.c ++++ b/tests/pubkey.c +@@ -29,6 +29,7 @@ + #define PGM "pubkey" + #include "t-common.h" + ++static int in_fips_mode; + + /* Sample RSA keys, taken from basic.c. */ + +@@ -518,6 +519,14 @@ get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); ++ if (in_fips_mode) ++ { ++ if (!rc) ++ die ("generating DSA key should fail in FIPS mode: %s\n", gcry_strerror (rc)); ++ *pkey = NULL; ++ *skey = NULL; ++ return; ++ } + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + +@@ -899,7 +908,7 @@ check_x931_derived_key (int what) + err = _gcry_pk_util_get_nbits(key_spec, &nbits); + if (err) + die ("nbits not found\n"); +- if (gcry_fips_mode_active() && nbits < 2048) ++ if (in_fips_mode && nbits < 2048) + { + info("RSA key test with %d bits skipped in fips mode\n", nbits); + goto leave; +@@ -1186,6 +1195,9 @@ main (int argc, char **argv) + /* No valuable keys are create, so we can speed up our RNG. */ + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; ++ + for (i=0; i < 2; i++) + check_run (); + +@@ -1193,7 +1205,7 @@ main (int argc, char **argv) + check_x931_derived_key (i); + + check_ecc_sample_key (); +- if (!gcry_fips_mode_active ()) ++ if (!in_fips_mode) + check_ed25519ecdsa_sample_key (); + + return !!error_count; +-- +2.31.1 + +commit 61c87070abc4baeb9d847db015e6a3031f349483 +Author: NIIBE Yutaka +Date: Wed Jul 7 15:52:06 2021 +0900 + + tests: Skip unavailable ciphers in FIPS mode. + + * tests/basic.c (_check_poly1305_cipher): + (check_ocb_cipher_largebuf_split): Skip unavailable ciphers when + IN_FIPS_MODE. + (check_ocb_cipher_checksum, check_gost28147_cipher_basic): Likewise. + + -- + + GnuPG-bug-id: 5520 + Signed-off-by: NIIBE Yutaka + +diff --git a/tests/basic.c b/tests/basic.c +index 0a1e8293..43ef122e 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -5026,6 +5026,14 @@ _check_poly1305_cipher (unsigned int step) + + for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) + { ++ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ tv[i].algo); ++ continue; ++ } ++ + if (verbose) + fprintf (stderr, " checking POLY1305 mode for %s [%i]\n", + gcry_cipher_algo_name (tv[i].algo), +@@ -6643,6 +6651,14 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, + memcpy(inbuf + i, hash, 16); + } + ++ if (gcry_cipher_test_algo (algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ algo); ++ goto out_free; ++ } ++ + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) + err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); +@@ -6841,6 +6857,14 @@ check_ocb_cipher_checksum (int algo, int keylen) + blk[byteidx] |= 1 << bitpos; + } + ++ if (gcry_cipher_test_algo (algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ algo); ++ goto out_free; ++ } ++ + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) + err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); +@@ -7651,6 +7675,15 @@ check_gost28147_cipher_basic (enum gcry_cipher_algos algo) + + if (verbose) + fprintf (stderr, " Starting GOST28147 cipher checks.\n"); ++ ++ if (gcry_cipher_test_algo (algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ algo); ++ return; ++ } ++ + keylen = gcry_cipher_get_algo_keylen(algo); + if (!keylen) + { +commit b98ca3f798abd17696f52163665204c4e83d9092 +Author: Jussi Kivilinna +Date: Wed Jul 7 18:21:27 2021 +0300 + + tests/basic: use SHA256 instead of RMD160 for SHAKE extract testing + + * tests/basic.c (check_one_md): Use GCRY_MD_SHA256 as 'crcalgo' for + SHAKE128/SHAKE256 testing. + -- + + RMD160 was used to calculate output checksum from two SHAKE extract + streams, which are run with different extract buffer size but for + same total length and with same input. Patch switches to use SHA256 + for checksumming for FIPS support. + + GnuPG-bug-id: 5520 + Signed-off-by: Jussi Kivilinna + +diff --git a/tests/basic.c b/tests/basic.c +index bc34bb99..eb6d1514 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -10395,7 +10395,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen, + + if (*data == '!' && !data[1]) + { +- int crcalgo = GCRY_MD_RMD160; ++ int crcalgo = GCRY_MD_SHA256; + gcry_md_hd_t crc1, crc2; + size_t startlen; + size_t piecelen; +commit ccb076e8aabb9c49e7026258b3a36a8422f6bbe4 +Author: NIIBE Yutaka +Date: Wed Jul 7 16:29:48 2021 +0900 + + tests: Fix tests/basic.c for FIPS mode. + + * tests/basic.c (main): Use bare gcry_control for + GCRYCTL_FORCE_FIPS_MODE. + + -- + + GnuPG-bug-id: 5520 + Signed-off-by: NIIBE Yutaka + +diff --git a/tests/basic.c b/tests/basic.c +index 43ef122e..bc34bb99 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -14610,7 +14610,7 @@ main (int argc, char **argv) + gcry_md_hd_t md; + + /* First trigger a self-test. */ +- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); ++ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("not in operational state after self-test\n"); + +@@ -14639,7 +14639,7 @@ main (int argc, char **argv) + { + /* Now run a self-test and to get back into + operational state. */ +- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); ++ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("did not reach operational after error " + "and self-test\n"); diff --git a/libgcrypt.spec b/libgcrypt.spec index 5b0e0aa..5b355fa 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -27,15 +27,13 @@ Patch2: libgcrypt-1.8.5-use-fipscheck.patch # modify FIPS RSA and DSA keygen to comply with requirements Patch5: libgcrypt-1.8.4-fips-keygen.patch # fix the tests to work correctly in the FIPS mode -Patch6: libgcrypt-1.8.4-tests-fipsmode.patch +Patch6: libgcrypt-1.9.3-fips-tests.patch # update the CAVS tests Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness Patch11: libgcrypt-1.8.4-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch -# fix tests to work with approved ECC -Patch14: libgcrypt-1.7.3-ecc-test-fix.patch # Run the FIPS mode initialization in the shared library constructor Patch18: libgcrypt-1.8.3-fips-ctor.patch # Do not try to open /dev/urandom if getrandom() works @@ -92,7 +90,6 @@ applications using libgcrypt. %patch7 -p1 -b .cavs %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt -%patch14 -p1 -b .eccfix %patch18 -p1 -b .fips-ctor %patch24 -p1 -b .getrandom %patch26 -p1 -b .fips-enttest From ef01d2c6d0905a778d45dfa31eb3b11a47adbf5a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 23 Aug 2021 14:03:10 +0200 Subject: [PATCH 167/214] libgcrypt-1.9.4-1 --- .gitignore | 1 + curves.c | 133 ++- ecc-curves.c | 60 +- hobble-libgcrypt | 1 - libgcrypt-1.9.3-CVE-2021-33560.patch | 100 --- libgcrypt.spec | 13 +- sources | 2 +- t-mpi-point.c | 1213 -------------------------- 8 files changed, 178 insertions(+), 1345 deletions(-) delete mode 100644 libgcrypt-1.9.3-CVE-2021-33560.patch delete mode 100644 t-mpi-point.c diff --git a/.gitignore b/.gitignore index 69b0cfb..870812f 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.9.1-hobbled.tar.xz /libgcrypt-1.9.2-hobbled.tar.xz /libgcrypt-1.9.3-hobbled.tar.xz +/libgcrypt-1.9.4-hobbled.tar.xz diff --git a/curves.c b/curves.c index 5441b53..1b190d1 100644 --- a/curves.c +++ b/curves.c @@ -33,7 +33,7 @@ #include "t-common.h" /* Number of curves defined in ../cipger/ecc-curves.c */ -#define N_CURVES 19 +#define N_CURVES 20 /* A real world sample public key. */ static char const sample_key_1[] = @@ -99,6 +99,119 @@ check_matching (void) static void check_get_params (void) { + static struct { + int algo; + const char *name; + int error_expected; + } tv[] = + { + { GCRY_PK_ECC, "Ed25519" }, + { GCRY_PK_ECC, "1.3.6.1.4.1.11591.15.1" }, + { GCRY_PK_ECC, "1.3.101.112" }, + + { GCRY_PK_ECC, "Curve25519" }, + { GCRY_PK_ECC, "1.3.6.1.4.1.3029.1.5.1" }, + { GCRY_PK_ECC, "1.3.101.110" }, + { GCRY_PK_ECC, "X25519" }, + + { GCRY_PK_ECC, "Ed448" }, + { GCRY_PK_ECC, "X448" }, + { GCRY_PK_ECC, "1.3.101.113" }, + { GCRY_PK_ECC, "1.3.101.111" }, + + { GCRY_PK_ECC, "NIST P-192" }, + { GCRY_PK_ECC, "1.2.840.10045.3.1.1" }, + { GCRY_PK_ECC, "prime192v1" }, + { GCRY_PK_ECC, "secp192r1" }, + { GCRY_PK_ECC, "nistp192" }, + + { GCRY_PK_ECC, "NIST P-224" }, + { GCRY_PK_ECC, "secp224r1" }, + { GCRY_PK_ECC, "1.3.132.0.33" }, + { GCRY_PK_ECC, "nistp224" }, + + { GCRY_PK_ECC, "NIST P-256" }, + { GCRY_PK_ECC, "1.2.840.10045.3.1.7" }, + { GCRY_PK_ECC, "prime256v1" }, + { GCRY_PK_ECC, "secp256r1" }, + { GCRY_PK_ECC, "nistp256" }, + + { GCRY_PK_ECC, "NIST P-384" }, + { GCRY_PK_ECC, "secp384r1" }, + { GCRY_PK_ECC, "1.3.132.0.34" }, + { GCRY_PK_ECC, "nistp384" }, + + { GCRY_PK_ECC, "NIST P-521" }, + { GCRY_PK_ECC, "secp521r1" }, + { GCRY_PK_ECC, "1.3.132.0.35" }, + { GCRY_PK_ECC, "nistp521" }, + + { GCRY_PK_ECC, "GOST2001-test" }, + { GCRY_PK_ECC, "1.2.643.2.2.35.0" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "1.2.643.2.2.35.1" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, + { GCRY_PK_ECC, "1.2.643.2.2.35.2" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "1.2.643.2.2.35.3" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-XchA" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-XchB" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "1.2.643.2.2.36.0" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "1.2.643.2.2.36.1" }, + + /* Noet that GOST2012-256-tc26-A" is only in the curve alias + * list but has no parameter entry. */ + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.2" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "GOST2012-256-tc26-B" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.3" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, + { GCRY_PK_ECC, "GOST2012-256-tc26-C" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.4" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "GOST2012-256-tc26-D" }, + + { GCRY_PK_ECC, "GOST2012-512-test" }, + { GCRY_PK_ECC, "GOST2012-test" }, + { GCRY_PK_ECC, "GOST2012-512-test" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.0" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-A" }, + { GCRY_PK_ECC, "GOST2012-tc26-A" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-B" }, + { GCRY_PK_ECC, "GOST2012-tc26-B" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-A" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.1" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-B" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.2" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-C" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.3" }, + + { GCRY_PK_ECC, "secp256k1" }, + { GCRY_PK_ECC, "1.3.132.0.10" }, + + { GCRY_PK_ECC, "sm2p256v1" }, + { GCRY_PK_ECC, "1.2.156.10197.1.301" }, + + /* Check also the ECC algo mapping. */ + { GCRY_PK_ECDSA, "Ed25519" }, + { GCRY_PK_EDDSA, "Ed25519" }, + { GCRY_PK_ECDH, "Ed25519" }, + { GCRY_PK_ECDSA, "Curve25519" }, + { GCRY_PK_EDDSA, "Curve25519" }, + { GCRY_PK_ECDH, "Curve25519" }, + { GCRY_PK_ECC, "NoSuchCurve", 1 }, + { GCRY_PK_RSA, "rsa", 1 }, + { GCRY_PK_ELG, "elg", 1 }, + { GCRY_PK_DSA, "dsa", 1 } + }; + int idx; gcry_sexp_t param; const char *name; @@ -114,6 +227,24 @@ check_get_params (void) sample_key_1_curve, name); gcry_sexp_release (param); + + /* Some simple tests */ + for (idx=0; idx < DIM (tv); idx++) + { + param = gcry_pk_get_param (tv[idx].algo, tv[idx].name); + if (!param) + { + if (!tv[idx].error_expected) + fail ("get_param: test %d (%s) failed\n", idx, tv[idx].name); + } + else + { + if (tv[idx].error_expected) + fail ("get_param: test %d (%s) failed (error expected)\n", + idx, tv[idx].name); + } + gcry_sexp_release (param); + } } diff --git a/ecc-curves.c b/ecc-curves.c index a974bcf..5236b19 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -55,6 +55,11 @@ static const struct { "Ed448", "1.3.101.113" }, /* rfc8410 */ { "X448", "1.3.101.111" }, /* rfc8410 */ + { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */ + { "NIST P-192", "prime192v1" }, /* X9.62 name. */ + { "NIST P-192", "secp192r1" }, /* SECP name. */ + { "NIST P-192", "nistp192" }, /* rfc5656. */ + { "NIST P-224", "secp224r1" }, { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */ { "NIST P-224", "nistp224" }, /* rfc5656. */ @@ -194,6 +199,35 @@ static const ecc_domain_parms_t domain_parms[] = "8DF3F6EDB8027E2346430D211312C4B150677AF76FD7223D457B5B1A", 4, }, +#if 0 /* No real specs yet found. */ + { + /* x^2 + y^2 = 1 + 3617x^2y^2 mod 2^414 - 17 */ + "Curve3617", + "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF", + MPI_EC_EDWARDS, 0, + "0x01", + "0x0e21", + "0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB3CC92414CF" + "706022B36F1C0338AD63CF181B0E71A5E106AF79", + "0x1A334905141443300218C0631C326E5FCD46369F44C03EC7F57FF35498A4AB4D" + "6D6BA111301A73FAA8537C64C4FD3812F3CBC595", + "0x22", + 8 + }, +#endif /*0*/ + { + "NIST P-192", 192, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xfffffffffffffffffffffffffffffffeffffffffffffffff", + "0xfffffffffffffffffffffffffffffffefffffffffffffffc", + "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", + "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", + + "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", + "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", + 1 + }, { "NIST P-224", 224, 1, MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, @@ -1243,45 +1277,27 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, gcry_sexp_t _gcry_ecc_get_param_sexp (const char *name) { - unsigned int nbits; elliptic_curve_t E; - mpi_ec_t ctx; - gcry_mpi_t g_x, g_y; gcry_mpi_t pkey[5]; gcry_sexp_t result; - int i; memset (&E, 0, sizeof E); - if (_gcry_ecc_fill_in_curve (0, name, &E, &nbits)) + if (_gcry_ecc_fill_in_curve (0, name, &E, NULL)) return NULL; - g_x = mpi_new (0); - g_y = mpi_new (0); - ctx = _gcry_mpi_ec_p_internal_new (E.model, - E.dialect, - 0, - E.p, E.a, E.b); - if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx)) - log_fatal ("ecc get param: Failed to get affine coordinates\n"); - _gcry_mpi_ec_free (ctx); - _gcry_mpi_point_free_parts (&E.G); - pkey[0] = E.p; pkey[1] = E.a; pkey[2] = E.b; - pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p); + pkey[3] = _gcry_ecc_ec2os (E.G.x, E.G.y, E.p); pkey[4] = E.n; - mpi_free (g_x); - mpi_free (g_y); - if (sexp_build (&result, NULL, "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)))", pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], E.h)) result = NULL; - for (i=0; i < DIM (pkey); i++) - _gcry_mpi_release (pkey[i]); + _gcry_ecc_curve_free (&E); + _gcry_mpi_release (pkey[3]); return result; } diff --git a/hobble-libgcrypt b/hobble-libgcrypt index 3c76f73..1aa88dc 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -8,5 +8,4 @@ set -e -x rm -f cipher/ecc-curves.c rm -f tests/curves.c -rm -f tests/t-mpi-point.c rm -f tests/keygrip.c diff --git a/libgcrypt-1.9.3-CVE-2021-33560.patch b/libgcrypt-1.9.3-CVE-2021-33560.patch deleted file mode 100644 index 2161840..0000000 --- a/libgcrypt-1.9.3-CVE-2021-33560.patch +++ /dev/null @@ -1,100 +0,0 @@ -commit 3462280f2e23e16adf3ed5176e0f2413d8861320 -Author: NIIBE Yutaka -Date: Fri May 21 11:15:07 2021 +0900 - - cipher: Fix ElGamal encryption for other implementations. - - * cipher/elgamal.c (gen_k): Remove support of smaller K. - (do_encrypt): Never use smaller K. - (sign): Folllow the change of gen_k. - - -- - - Cherry-pick master commit of: - 632d80ef30e13de6926d503aa697f92b5dbfbc5e - - This change basically reverts encryption changes in two commits: - - 74386120dad6b3da62db37f7044267c8ef34689b - 78531373a342aeb847950f404343a05e36022065 - - Use of smaller K for ephemeral key in ElGamal encryption is only good, - when we can guarantee that recipient's key is generated by our - implementation (or compatible). - - For detail, please see: - - Luca De Feo, Bertram Poettering, Alessandro Sorniotti, - "On the (in)security of ElGamal in OpenPGP"; - in the proceedings of CCS'2021. - - CVE-id: CVE-2021-33560 - GnuPG-bug-id: 5328 - Suggested-by: Luca De Feo, Bertram Poettering, Alessandro Sorniotti - Signed-off-by: NIIBE Yutaka - -diff --git a/cipher/elgamal.c b/cipher/elgamal.c -index 9835122f..eead4502 100644 ---- a/cipher/elgamal.c -+++ b/cipher/elgamal.c -@@ -66,7 +66,7 @@ static const char *elg_names[] = - - - static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie); --static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k); -+static gcry_mpi_t gen_k (gcry_mpi_t p); - static gcry_err_code_t generate (ELG_secret_key *sk, unsigned nbits, - gcry_mpi_t **factors); - static int check_secret_key (ELG_secret_key *sk); -@@ -189,11 +189,10 @@ test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie ) - - /**************** - * Generate a random secret exponent k from prime p, so that k is -- * relatively prime to p-1. With SMALL_K set, k will be selected for -- * better encryption performance - this must never be used signing! -+ * relatively prime to p-1. - */ - static gcry_mpi_t --gen_k( gcry_mpi_t p, int small_k ) -+gen_k( gcry_mpi_t p ) - { - gcry_mpi_t k = mpi_alloc_secure( 0 ); - gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) ); -@@ -202,18 +201,7 @@ gen_k( gcry_mpi_t p, int small_k ) - unsigned int nbits, nbytes; - char *rndbuf = NULL; - -- if (small_k) -- { -- /* Using a k much lesser than p is sufficient for encryption and -- * it greatly improves the encryption performance. We use -- * Wiener's table and add a large safety margin. */ -- nbits = wiener_map( orig_nbits ) * 3 / 2; -- if( nbits >= orig_nbits ) -- BUG(); -- } -- else -- nbits = orig_nbits; -- -+ nbits = orig_nbits; - - nbytes = (nbits+7)/8; - if( DBG_CIPHER ) -@@ -492,7 +480,7 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey ) - * error code. - */ - -- k = gen_k( pkey->p, 1 ); -+ k = gen_k( pkey->p ); - mpi_powm (a, pkey->g, k, pkey->p); - - /* b = (y^k * input) mod p -@@ -608,7 +596,7 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey ) - * - */ - mpi_sub_ui(p_1, p_1, 1); -- k = gen_k( skey->p, 0 /* no small K ! */ ); -+ k = gen_k( skey->p ); - mpi_powm( a, skey->g, k, skey->p ); - mpi_mul(t, skey->x, a ); - mpi_subm(t, input, t, p_1 ); diff --git a/libgcrypt.spec b/libgcrypt.spec index 5b355fa..a90a8ba 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.9.3 -Release: 4%{?dist} +Version: 1.9.4 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -18,7 +18,6 @@ Source3: hobble-libgcrypt # Approved ECC support Source4: ecc-curves.c Source5: curves.c -Source6: t-mpi-point.c Source7: random.conf Source8: keygrip.c # make FIPS hmac compatible with fipscheck - non upstreamable @@ -46,8 +45,6 @@ Patch27: libgcrypt-1.8.3-md-fips-enforce.patch Patch28: libgcrypt-1.8.5-intel-cet.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch -# Fix for CVE-2021-33560 -Patch31: libgcrypt-1.9.3-CVE-2021-33560.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -96,10 +93,9 @@ applications using libgcrypt. %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module -%patch31 -p1 -b .CVE-2021-33560 cp %{SOURCE4} cipher/ -cp %{SOURCE5} %{SOURCE6} %{SOURCE8} tests/ +cp %{SOURCE5} %{SOURCE8} tests/ %build # This package has a configure test which uses ASMs, but does not link the @@ -206,6 +202,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Mon Aug 23 2021 Jakub Jelen - 1.9.4-1 +- New upstream release (#1996467) + * Thu Jul 22 2021 Fedora Release Engineering - 1.9.3-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild diff --git a/sources b/sources index 84854e4..8d0f1cb 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.3-hobbled.tar.xz) = 5c6f3ee57ec496af6d82000979a79d220a5b9be7a3a9d064d727ff7e54cf107e5b398d9ec8d822594a7fe53bc0d4324e96a5b41d55a77f103109620b88c61f1a +SHA512 (libgcrypt-1.9.4-hobbled.tar.xz) = 80b1b2159ec3c7795450037d76d81b737f2734f1cff72c8aa6ac8c1a5654ece4fce0aabfbed0cce99d123747831db135df0d040f67081052cb2363bf52f5d4e6 diff --git a/t-mpi-point.c b/t-mpi-point.c deleted file mode 100644 index 9a6190e..0000000 --- a/t-mpi-point.c +++ /dev/null @@ -1,1213 +0,0 @@ -/* t-mpi-point.c - Tests for mpi point functions - * Copyright (C) 2013 g10 Code GmbH - * - * This file is part of Libgcrypt. - * - * Libgcrypt 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. - * - * Libgcrypt 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 program; if not, see . - */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#include -#include -#include - -#define PGM "t-mpi-point" -#include "t-common.h" - -static struct -{ - const char *desc; /* Description of the curve. */ - const char *p; /* Order of the prime field. */ - const char *a, *b; /* The coefficients. */ - const char *n; /* The order of the base point. */ - const char *g_x, *g_y; /* Base point. */ - const char *h; /* Cofactor. */ -} test_curve[] = - { - { - "NIST P-224", - "0xffffffffffffffffffffffffffffffff000000000000000000000001", - "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", - "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", - "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , - - "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", - "0x01" - }, - { - "NIST P-256", - "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", - "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", - "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - - "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", - "0x01" - }, - { - "NIST P-384", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000ffffffff", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000fffffffc", - "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" - "c656398d8a2ed19d2a85c8edd3ec2aef", - "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" - "581a0db248b0a77aecec196accc52973", - - "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" - "5502f25dbf55296c3a545e3872760ab7", - "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f", - "0x01" - }, - { - "NIST P-521", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", - "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" - "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", - "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - - "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" - "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", - "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", - "0x01" - }, - { - "Ed25519", - "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC", - "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3", - "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", - "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658", - "0x08" - }, - { NULL, NULL, NULL, NULL, NULL, NULL } - }; - -/* A sample public key for NIST P-256. */ -static const char sample_p256_q[] = - "04" - "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E" - "E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; -static const char sample_p256_q_x[] = - "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E"; -static const char sample_p256_q_y[] = - "00E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; - - -/* A sample public key for Ed25519. */ -static const char sample_ed25519_q[] = - "04" - "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce" - "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7"; -static const char sample_ed25519_q_x[] = - "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce"; -static const char sample_ed25519_q_y[] = - "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7"; -static const char sample_ed25519_q_eddsa[] = - "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; -static const char sample_ed25519_d[] = - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"; - - -static void -print_mpi_2 (const char *text, const char *text2, gcry_mpi_t a) -{ - gcry_error_t err; - char *buf; - void *bufaddr = &buf; - - err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); - if (err) - fprintf (stderr, "%s%s: [error printing number: %s]\n", - text, text2? text2:"", gpg_strerror (err)); - else - { - fprintf (stderr, "%s%s: %s\n", text, text2? text2:"", buf); - gcry_free (buf); - } -} - - -static void -print_mpi (const char *text, gcry_mpi_t a) -{ - print_mpi_2 (text, NULL, a); -} - - -static void -print_point (const char *text, gcry_mpi_point_t a) -{ - gcry_mpi_t x, y, z; - - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - gcry_mpi_point_get (x, y, z, a); - print_mpi_2 (text, ".x", x); - print_mpi_2 (text, ".y", y); - print_mpi_2 (text, ".z", z); - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); -} - - -static void -print_sexp (const char *prefix, gcry_sexp_t a) -{ - char *buf; - size_t size; - - if (prefix) - fputs (prefix, stderr); - size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); - buf = gcry_xmalloc (size); - - gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); - fprintf (stderr, "%.*s", (int)size, buf); - gcry_free (buf); -} - - -static gcry_mpi_t -hex2mpi (const char *string) -{ - gpg_error_t err; - gcry_mpi_t val; - - err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); - if (err) - die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err)); - return val; -} - - -/* Convert STRING consisting of hex characters into its binary - representation and return it as an allocated buffer. The valid - length of the buffer is returned at R_LENGTH. The string is - delimited by end of string. The function returns NULL on - error. */ -static void * -hex2buffer (const char *string, size_t *r_length) -{ - const char *s; - unsigned char *buffer; - size_t length; - - buffer = xmalloc (strlen(string)/2+1); - length = 0; - for (s=string; *s; s +=2 ) - { - if (!hexdigitp (s) || !hexdigitp (s+1)) - return NULL; /* Invalid hex digits. */ - ((unsigned char*)buffer)[length++] = xtoi_2 (s); - } - *r_length = length; - return buffer; -} - - -static gcry_mpi_t -hex2mpiopa (const char *string) -{ - char *buffer; - size_t buflen; - gcry_mpi_t val; - - buffer = hex2buffer (string, &buflen); - if (!buffer) - die ("hex2mpiopa '%s' failed: parser error\n", string); - val = gcry_mpi_set_opaque (NULL, buffer, buflen*8); - if (!buffer) - die ("hex2mpiopa '%s' failed: set_opaque error\n", string); - return val; -} - - -/* Compare A to B, where B is given as a hex string. */ -static int -cmp_mpihex (gcry_mpi_t a, const char *b) -{ - gcry_mpi_t bval; - int res; - - if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) - bval = hex2mpiopa (b); - else - bval = hex2mpi (b); - res = gcry_mpi_cmp (a, bval); - gcry_mpi_release (bval); - return res; -} - - -/* Wrapper to emulate the libgcrypt internal EC context allocation - function. */ -static gpg_error_t -ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a) -{ - gpg_error_t err; - gcry_sexp_t sexp; - - if (p && a) - err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m)(a %m))", p, a); - else if (p) - err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m))", p); - else if (a) - err = gcry_sexp_build (&sexp, NULL, "(ecdsa (a %m))", a); - else - err = gcry_sexp_build (&sexp, NULL, "(ecdsa)"); - if (err) - return err; - err = gcry_mpi_ec_new (r_ctx, sexp, NULL); - gcry_sexp_release (sexp); - return err; -} - - - -static void -set_get_point (void) -{ - gcry_mpi_point_t point, point2; - gcry_mpi_t x, y, z; - - wherestr = "set_get_point"; - info ("checking point setting functions\n"); - - point = gcry_mpi_point_new (0); - x = gcry_mpi_set_ui (NULL, 17); - y = gcry_mpi_set_ui (NULL, 42); - z = gcry_mpi_set_ui (NULL, 11371); - gcry_mpi_point_get (x, y, z, point); - if (gcry_mpi_cmp_ui (x, 0) - || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) - fail ("new point not initialized to (0,0,0)\n"); - gcry_mpi_point_snatch_get (x, y, z, point); - point = NULL; - if (gcry_mpi_cmp_ui (x, 0) - || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) - fail ("snatch_get failed\n"); - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); - - point = gcry_mpi_point_new (0); - x = gcry_mpi_set_ui (NULL, 17); - y = gcry_mpi_set_ui (NULL, 42); - z = gcry_mpi_set_ui (NULL, 11371); - gcry_mpi_point_set (point, x, y, z); - gcry_mpi_set_ui (x, 23); - gcry_mpi_set_ui (y, 24); - gcry_mpi_set_ui (z, 25); - gcry_mpi_point_get (x, y, z, point); - if (gcry_mpi_cmp_ui (x, 17) - || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) - fail ("point_set/point_get failed\n"); - gcry_mpi_point_snatch_set (point, x, y, z); - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - gcry_mpi_point_get (x, y, z, point); - if (gcry_mpi_cmp_ui (x, 17) - || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) - fail ("point_snatch_set/point_get failed\n"); - - point2 = gcry_mpi_point_copy (point); - - gcry_mpi_point_get (x, y, z, point2); - if (gcry_mpi_cmp_ui (x, 17) - || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) - fail ("point_copy failed (1)\n"); - - gcry_mpi_point_release (point); - - gcry_mpi_point_get (x, y, z, point2); - if (gcry_mpi_cmp_ui (x, 17) - || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) - fail ("point_copy failed (2)\n"); - - gcry_mpi_point_release (point2); - - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); -} - - -static void -context_alloc (void) -{ - gpg_error_t err; - gcry_ctx_t ctx; - gcry_mpi_t p, a; - - wherestr = "context_alloc"; - info ("checking context functions\n"); - - p = gcry_mpi_set_ui (NULL, 1); - a = gcry_mpi_set_ui (NULL, 1); - err = ec_p_new (&ctx, p, a); - if (err) - die ("ec_p_new returned an error: %s\n", gpg_strerror (err)); - gcry_mpi_release (p); - gcry_mpi_release (a); - gcry_ctx_release (ctx); - - p = NULL; - a = gcry_mpi_set_ui (NULL, 0); - - err = ec_p_new (&ctx, p, a); - if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (1)\n"); - - gcry_mpi_release (a); - a = NULL; - err = ec_p_new (&ctx, p, a); - if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (2)\n"); - -} - - -static int -get_and_cmp_mpi (const char *name, const char *mpistring, const char *desc, - gcry_ctx_t ctx) -{ - gcry_mpi_t mpi; - - mpi = gcry_mpi_ec_get_mpi (name, ctx, 1); - if (!mpi) - { - fail ("error getting parameter '%s' of curve '%s'\n", name, desc); - return 1; - } - if (debug) - print_mpi (name, mpi); - if (cmp_mpihex (mpi, mpistring)) - { - fail ("parameter '%s' of curve '%s' does not match\n", name, desc); - gcry_mpi_release (mpi); - return 1; - } - gcry_mpi_release (mpi); - return 0; -} - - -static int -get_and_cmp_point (const char *name, - const char *mpi_x_string, const char *mpi_y_string, - const char *desc, gcry_ctx_t ctx) -{ - gcry_mpi_point_t point; - gcry_mpi_t x, y, z; - int result = 0; - - point = gcry_mpi_ec_get_point (name, ctx, 1); - if (!point) - { - fail ("error getting point parameter '%s' of curve '%s'\n", name, desc); - return 1; - } - if (debug) - print_point (name, point); - - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - gcry_mpi_point_snatch_get (x, y, z, point); - if (cmp_mpihex (x, mpi_x_string)) - { - fail ("x coordinate of '%s' of curve '%s' does not match\n", name, desc); - result = 1; - } - if (cmp_mpihex (y, mpi_y_string)) - { - fail ("y coordinate of '%s' of curve '%s' does not match\n", name, desc); - result = 1; - } - if (cmp_mpihex (z, "01")) - { - fail ("z coordinate of '%s' of curve '%s' is not 1\n", name, desc); - result = 1; - } - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); - return result; -} - - -static void -context_param (void) -{ - gpg_error_t err; - int idx; - gcry_ctx_t ctx = NULL; - gcry_mpi_t q, d; - gcry_sexp_t keyparam; - - wherestr = "context_param"; - - info ("checking standard curves\n"); - for (idx=0; test_curve[idx].desc; idx++) - { - /* P-192 and Ed25519 are not supported in fips mode */ - if (gcry_fips_mode_active()) - { - if (!strcmp(test_curve[idx].desc, "NIST P-192") - || !strcmp(test_curve[idx].desc, "Ed25519")) - { - info ("skipping %s in fips mode\n", test_curve[idx].desc ); - continue; - } - } - - gcry_ctx_release (ctx); - err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc); - if (err) - { - fail ("can't create context for curve '%s': %s\n", - test_curve[idx].desc, gpg_strerror (err)); - continue; - } - if (get_and_cmp_mpi ("p", test_curve[idx].p, test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_mpi ("a", test_curve[idx].a, test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_mpi ("b", test_curve[idx].b, test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_mpi ("g.x",test_curve[idx].g_x, test_curve[idx].desc,ctx)) - continue; - if (get_and_cmp_mpi ("g.y",test_curve[idx].g_y, test_curve[idx].desc,ctx)) - continue; - if (get_and_cmp_mpi ("n", test_curve[idx].n, test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y, - test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx)) - continue; - - } - - info ("checking sample public key (nistp256)\n"); - q = hex2mpi (sample_p256_q); - err = gcry_sexp_build (&keyparam, NULL, - "(public-key(ecc(curve %s)(q %m)))", - "NIST P-256", q); - if (err) - die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (q); - - /* We can't call gcry_pk_testkey because it is only implemented for - private keys. */ - /* err = gcry_pk_testkey (keyparam); */ - /* if (err) */ - /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ - /* gpg_strerror (err)); */ - - gcry_ctx_release (ctx); - err = gcry_mpi_ec_new (&ctx, keyparam, NULL); - if (err) - fail ("gcry_mpi_ec_new failed for sample public key (nistp256): %s\n", - gpg_strerror (err)); - else - { - gcry_sexp_t sexp; - - get_and_cmp_mpi ("q", sample_p256_q, "nistp256", ctx); - get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "nistp256", - ctx); - - /* Delete Q. */ - err = gcry_mpi_ec_set_mpi ("q", NULL, ctx); - if (err) - fail ("clearing Q for nistp256 failed: %s\n", gpg_strerror (err)); - if (gcry_mpi_ec_get_mpi ("q", ctx, 0)) - fail ("clearing Q for nistp256 did not work\n"); - - /* Set Q again. */ - q = hex2mpi (sample_p256_q); - err = gcry_mpi_ec_set_mpi ("q", q, ctx); - if (err) - fail ("setting Q for nistp256 failed: %s\n", gpg_strerror (err)); - get_and_cmp_mpi ("q", sample_p256_q, "nistp256(2)", ctx); - gcry_mpi_release (q); - - /* Get as s-expression. */ - err = gcry_pubkey_get_sexp (&sexp, 0, ctx); - if (err) - fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); - else if (debug) - print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); - gcry_sexp_release (sexp); - - err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); - if (err) - fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", - gpg_strerror (err)); - else if (debug) - print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); - gcry_sexp_release (sexp); - - err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); - if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) - fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", - gpg_strerror (err)); - gcry_sexp_release (sexp); - } - - /* Skipping Ed25519 if in FIPS mode (it isn't supported) */ - if (gcry_fips_mode_active()) - goto cleanup; - - info ("checking sample public key (Ed25519)\n"); - q = hex2mpi (sample_ed25519_q); - gcry_sexp_release (keyparam); - err = gcry_sexp_build (&keyparam, NULL, - "(public-key(ecc(curve %s)(flags eddsa)(q %m)))", - "Ed25519", q); - if (err) - die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (q); - - /* We can't call gcry_pk_testkey because it is only implemented for - private keys. */ - /* err = gcry_pk_testkey (keyparam); */ - /* if (err) */ - /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ - /* gpg_strerror (err)); */ - - gcry_ctx_release (ctx); - err = gcry_mpi_ec_new (&ctx, keyparam, NULL); - if (err) - fail ("gcry_mpi_ec_new failed for sample public key: %s\n", - gpg_strerror (err)); - else - { - gcry_sexp_t sexp; - - get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519", ctx); - get_and_cmp_point ("q", sample_ed25519_q_x, sample_ed25519_q_y, - "Ed25519", ctx); - get_and_cmp_mpi ("q@eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx); - - /* Set d to see whether Q is correctly re-computed. */ - d = hex2mpi (sample_ed25519_d); - err = gcry_mpi_ec_set_mpi ("d", d, ctx); - if (err) - fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (d); - get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx); - - /* Delete Q by setting d and then clearing d. The clearing is - required so that we can check whether Q has been cleared and - because further tests only expect a public key. */ - d = hex2mpi (sample_ed25519_d); - err = gcry_mpi_ec_set_mpi ("d", d, ctx); - if (err) - fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (d); - err = gcry_mpi_ec_set_mpi ("d", NULL, ctx); - if (err) - fail ("setting d for Ed25519 failed(2): %s\n", gpg_strerror (err)); - if (gcry_mpi_ec_get_mpi ("q", ctx, 0)) - fail ("setting d for Ed25519 did not reset Q\n"); - - /* Set Q again. We need to use an opaque MPI here because - sample_ed25519_q is in uncompressed format which can only be - auto-detected if passed opaque. */ - q = hex2mpiopa (sample_ed25519_q); - err = gcry_mpi_ec_set_mpi ("q", q, ctx); - if (err) - fail ("setting Q for Ed25519 failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (q); - get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(2)", ctx); - - /* Get as s-expression. */ - err = gcry_pubkey_get_sexp (&sexp, 0, ctx); - if (err) - fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); - else if (debug) - print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); - gcry_sexp_release (sexp); - - err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); - if (err) - fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", - gpg_strerror (err)); - else if (debug) - print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); - gcry_sexp_release (sexp); - - err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); - if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) - fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", - gpg_strerror (err)); - gcry_sexp_release (sexp); - - } - - cleanup: - gcry_ctx_release (ctx); - gcry_sexp_release (keyparam); -} - - - - -/* Create a new point from (X,Y,Z) given as hex strings. */ -gcry_mpi_point_t -make_point (const char *x, const char *y, const char *z) -{ - gcry_mpi_point_t point; - - point = gcry_mpi_point_new (0); - gcry_mpi_point_snatch_set (point, hex2mpi (x), hex2mpi (y), hex2mpi (z)); - - return point; -} - - -/* This tests checks that the low-level EC API yields the same result - as using the high level API. The values have been taken from a - test run using the high level API. */ -static void -basic_ec_math (void) -{ - gpg_error_t err; - gcry_ctx_t ctx; - gcry_mpi_t P, A; - gcry_mpi_point_t G, Q; - gcry_mpi_t d; - gcry_mpi_t x, y, z; - - wherestr = "basic_ec_math"; - info ("checking basic math functions for EC\n"); - - P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); - A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); - G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", - "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", - "1"); - d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D"); - Q = gcry_mpi_point_new (0); - - err = ec_p_new (&ctx, P, A); - if (err) - die ("ec_p_new failed: %s\n", gpg_strerror (err)); - - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - - { - /* A quick check that multiply by zero works. */ - gcry_mpi_t tmp; - - tmp = gcry_mpi_new (0); - gcry_mpi_ec_mul (Q, tmp, G, ctx); - gcry_mpi_release (tmp); - gcry_mpi_point_get (x, y, z, Q); - if (gcry_mpi_cmp_ui (z, 0)) - fail ("multiply a point by zero failed\n"); - } - - gcry_mpi_ec_mul (Q, d, G, ctx); - - if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) - fail ("failed to get affine coordinates\n"); - if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE") - || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966")) - fail ("computed affine coordinates of public key do not match\n"); - if (debug) - { - print_mpi ("q.x", x); - print_mpi ("q.y", y); - } - - gcry_mpi_release (z); - gcry_mpi_release (y); - gcry_mpi_release (x); - gcry_mpi_point_release (Q); - gcry_mpi_release (d); - gcry_mpi_point_release (G); - gcry_mpi_release (A); - gcry_mpi_release (P); - gcry_ctx_release (ctx); -} - - -/* This is the same as basic_ec_math but uses more advanced - features. */ -static void -basic_ec_math_simplified (void) -{ -} - - -/* Check the math used with Twisted Edwards curves. */ -static void -twistededwards_math (void) -{ - gpg_error_t err; - gcry_ctx_t ctx; - gcry_mpi_point_t G, Q; - gcry_mpi_t k; - gcry_mpi_t w, a, x, y, z, p, n, b, I; - - wherestr = "twistededwards_math"; - info ("checking basic Twisted Edwards math\n"); - - err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519"); - if (err) - die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err)); - - k = hex2mpi - ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004" - "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6"); - G = gcry_mpi_ec_get_point ("g", ctx, 1); - if (!G) - die ("gcry_mpi_ec_get_point(G) failed\n"); - Q = gcry_mpi_point_new (0); - - - w = gcry_mpi_new (0); - a = gcry_mpi_new (0); - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - I = gcry_mpi_new (0); - p = gcry_mpi_ec_get_mpi ("p", ctx, 1); - n = gcry_mpi_ec_get_mpi ("n", ctx, 1); - b = gcry_mpi_ec_get_mpi ("b", ctx, 1); - - /* Check: 2^{p-1} mod p == 1 */ - gcry_mpi_sub_ui (a, p, 1); - gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p); - if (gcry_mpi_cmp_ui (w, 1)) - fail ("failed assertion: 2^{p-1} mod p == 1\n"); - - /* Check: p % 4 == 1 */ - gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR); - if (gcry_mpi_cmp_ui (w, 1)) - fail ("failed assertion: p %% 4 == 1\n"); - - /* Check: 2^{n-1} mod n == 1 */ - gcry_mpi_sub_ui (a, n, 1); - gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n); - if (gcry_mpi_cmp_ui (w, 1)) - fail ("failed assertion: 2^{n-1} mod n == 1\n"); - - /* Check: b^{(p-1)/2} mod p == p-1 */ - gcry_mpi_sub_ui (a, p, 1); - gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1); - gcry_mpi_powm (w, b, x, p); - gcry_mpi_abs (w); - if (gcry_mpi_cmp (w, a)) - fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n"); - - /* I := 2^{(p-1)/4} mod p */ - gcry_mpi_sub_ui (a, p, 1); - gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1); - gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p); - - /* Check: I^2 mod p == p-1 */ - gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p); - if (gcry_mpi_cmp (w, a)) - fail ("failed assertion: I^2 mod p == p-1\n"); - - /* Check: G is on the curve */ - if (!gcry_mpi_ec_curve_point (G, ctx)) - fail ("failed assertion: G is on the curve\n"); - - /* Check: nG == (0,1) */ - gcry_mpi_ec_mul (Q, n, G, ctx); - if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) - fail ("failed to get affine coordinates\n"); - if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1)) - fail ("failed assertion: nG == (0,1)\n"); - - /* Now two arbitrary point operations taken from the ed25519.py - sample data. */ - gcry_mpi_release (a); - a = hex2mpi - ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496" - "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3"); - gcry_mpi_ec_mul (Q, a, G, ctx); - if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) - fail ("failed to get affine coordinates\n"); - if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be" - "00014fecc2165ca5cee9eee19fe4d2c1")) - || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2" - "4025645f0b820e72b8cad4f0a909a092"))) - { - fail ("sample point multiply failed:\n"); - print_mpi ("r", a); - print_mpi ("Rx", x); - print_mpi ("Ry", y); - } - - gcry_mpi_release (a); - a = hex2mpi - ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004" - "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6"); - gcry_mpi_ec_mul (Q, a, G, ctx); - if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) - fail ("failed to get affine coordinates\n"); - if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371" - "82324bd01ce6f3cf81ab44e62959c82a")) - || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784" - "8a826e80cce2869072ac60c3004356e5"))) - { - fail ("sample point multiply failed:\n"); - print_mpi ("r", a); - print_mpi ("Rx", x); - print_mpi ("Ry", y); - } - - - gcry_mpi_release (I); - gcry_mpi_release (b); - gcry_mpi_release (n); - gcry_mpi_release (p); - gcry_mpi_release (w); - gcry_mpi_release (a); - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); - gcry_mpi_point_release (Q); - gcry_mpi_point_release (G); - gcry_mpi_release (k); - gcry_ctx_release (ctx); -} - - -/* Check the point on curve function. */ -static void -point_on_curve (void) -{ - static struct { - const char *curve; - int oncurve; /* Point below is on the curve. */ - const char *qx; - const char *qy; - } t[] = { - { - "NIST P-256", 0, - "015B4F6775D68D4D2E2192C6B8027FC5A3D49957E453CB251155AA3FF5D3EC9974", - "4BC4C87B57A25E1056831208AB5B8F091142F891E9FF19F1E090B030DF1087B3" - }, { - "NIST P-256", 0, - "D22C316E7EBE7B293BD66808E000806F0754398A5D72A4F9BBC21C26EAC0A651", - "3C8DB80CC3CDE5E530D040536E6A58AAB41C33FA70B30896943513FF3690132D" - }, { - "NIST P-256", 0, - "0130F7E7BC52854CA493A0DE87DC4AB3B4343758F2B634F15B10D70DBC0A5A5291", - "86F9CA73C25CE86D54CB21C181AECBB52A5971334FF5040F76CAE9845ED46023" - }, { - "NIST P-256", 1, - "14957B602C7849F28858C7407696F014BC091D6D68C449560B7A38147D6E6A9B", - "A8E09EFEECFE00C797A0848F38B61992D30C61FAB13021E88C8BD3545B3A6C63" - }, { - "NIST P-256", 0, - "923DE4957241DD97780841C76294DB0D4F5DC04C3045081174764D2D32AD2D53", - "01B4B1A2027C02F0F520A3B01E4CE3C668BF481346A74499C5D1044A53E210B600" - }, { - "NIST P-256", 1, - "9021DFAB8B4DAEAADA634AAA26D6E5FFDF8C0476FF5CA31606C870A1B933FB36", - "9AFC65EEB24E46C7B75712EF29A981CB09FAC56E2B81D3ED024748CCAB1CB77E" - }, { - "NIST P-256", 0, - "011529F0B26DE5E0EB2DA4BFB6C149C802CB52EE479DD666553286928A4005E990", - "0EBC63DB2104884456DC0AA81A3F4E99D93B7AE2CD4B1489655EA9BE6289CF9E" - }, { - "NIST P-256", 1, - "216EC5DE8CA989199D31F0DFCD381DCC9270A0785365EC3E34CA347C070A87BE", - "87A88897BA763509ECC1DBE28D9D37F6F4E70E3B99B1CD3C0B934D4190968A6D" - }, { - "NIST P-256", 1, - "7ABAA44ACBC6016FDB52A6F45F6178E65CBFC35F9920D99149CA9999612CE945", - "88F7684BDCDA31EAFB6CAD859F8AB29B5D921D7DB2B34DF7E40CE36235F45B63" - }, { - "NIST P-256", 0, - "E765B4272D211DD0064189B55421FB76BB3A7756364A6CB1627FAED848157A84", - "C13171CFFB243E06B203F0996BBDD16F52292AD11F2DA81106E9C2FD87F4FA0F" - }, { - "NIST P-256", 0, - "EE4999DFC3A1871EE7A592BE26A09BEC9D9B561613EE9EFB6ED42F17985C9CDC", - "8399E967338A7A618336AF70DA67D9CAC1C19267809652F5C5183C8B129E0902" - }, { - "NIST P-256", 0, - "F755D0CF2642A2C7FBACCC8E9E442B8B047A99C6E052B2FA5AB0544B36B4D51C", - "AA080F17657B6565D9A4D94BD260B54D92FEE8DC4A78C4FC9C19209933AF39B0" - } , { - "NIST P-384", 0, - "CBFC7DBEBF15BEAD682549757F9BBA0E3F67669DF13FCE0EBE8024B725B38B00" - "83EC46A8F2FF3203C5C7F8C7E722A5EF", - "0548FE281BEAB18FD1AB86F59B0CA524479A4A81373C83B78AFFD801FAC75922" - "96470753DCF46173C9AA4A8A4C2FBE51" - }, { - "NIST P-384", 0, - "1DC8E054A883DB81EAEDE6C487B26816C927B8196780525A6CA8F675D2557752" - "02CE06CCBE705EA8A38AA2894D4BEEE6", - "010191050E867AFAA96A199FE9C591CF8B853D81486786DA889124881FB39D2F" - "8E0875F4C4BB1E3D0F8535C7A52306FB82" - }, { - "NIST P-384", 1, - "2539FC368CE1D5E464B6C0FBB12D557B712327DB086975255AD7D17F7E7E4F23" - "D719ED4116E2CC907AEB92CF22331A60", - "8843FDBA742CB64323E49CEBE8DD74908CFC9C3AA0015662DFBB7219E92CF32E" - "9FC63F61EF19DE9B3CEA98D163ABF254" - }, { - "NIST P-384", 0, - "0B786DACF400D43575394349EDD9F9CD145FC7EF737A3C5F69B253BE7639DB24" - "EC2F0CA62FF1F90B6515DE356EC2A404", - "225D6B2939CC7F7133F43353946A682C68DAC6BB75EE9CF6BD9A1609FA915692" - "72F4D3A87E88529754E109BB9B61B03B" - }, { - "NIST P-384", 0, - "76C660C9F58CF2051F9F8B06049694AB6FE418009DE6F0A0833BC690CEC06CC2" - "9A440AD51C94CF5BC28817C8C6E2D302", - "012974E5D9E55304ED294AB6C7A3C65B663E67ABC5E6F6C0F6498B519F2F6CA1" - "8306976291F3ADC0B5ABA42DED376EA9A5" - }, { - "NIST P-384", 0, - "23D758B1EDB8E12E9E707C53C131A19D9464B20EE05C99766F5ABDF9F906AD03" - "B958BF28B022E54E320672C4BAD4EEC0", - "01E9E72870C88F4C82A5AB3CC8A3398E8F006BF3EC05FFBB1EFF8AEE88020FEA" - "9E558E9F58ED1D324C9DCBCB4E8F2A5970" - }, { - "NIST P-384", 0, - "D062B96D5A10F715ACF361F99262ABF0F7693A8BB60ECB1DF459CF95750E4293" - "18BCB9FC60499D009F949298F3F9F47B", - "9089C6328E4B39A73D7EE6FAE1A77E48CE354B83BBCE432082C32C8FD6784B86" - "CFE9C552E2E720F5DA5806503D3784CD" - }, { - "NIST P-384", 0, - "2A951D4D6EB35C43D94866280D37365B82441BC84D62CBFF3365CAB1FD0A3E20" - "823CA8F84D2BBF4EA687885437DE7839", - "01CC7D762AFE613F7B5568BC516568A421159C40599E8D52DE10E8F9488931E1" - "69F3656C322DE45C4A70DC6DB9A661E599" - }, { - "NIST P-384", 1, - "A4BAEE6CDAF3AEB69032B3FBA811707C54F5753670DA5173D891547E8CBAEEF3" - "89B92C9A55573A596123415FBFA26991", - "3241EA716583C11C71BB30AF6C5E3A6637956F17ADBBE641BAB52E8539F9FC7B" - "F3B04F46DBFFE08151E0F0950CC70081" - }, { - "NIST P-384", 0, - "5C0E18B0DE3261BCBCFC7B702C2D75CF481336BFBADF420BADC616235C1966AB" - "4C0F876575DDEC1BDB3F3F04061C9AE4", - "E90C78550D1C922F1D8161D8C9C0576E29BD09CA665376FA887D13FA8DF48352" - "D7BBEEFB803F6CC8FC7895E47F348D33" - }, { - "NIST P-384", 1, - "2015864CD50F0A1A50E6401F44191665C19E4AD4B4903EA9EB464E95D1070E36" - "F1D8325E45734D5A0FDD103F4DF6F83E", - "5FB3E9A5C59DD5C5262A8176CB7032A00AE33AED08485884A3E5D68D9EEB990B" - "F26E8D87EC175577E782AD51A6A12C02" - }, { - "NIST P-384", 1, - "56EBF5310EEF5A5D8D001F570A18625383ECD4882B3FC738A69874E7C9D8F89C" - "187BECA23369DFD6C15CC0DA0629958F", - "C1230B349FB662CB762563DB8F9FCB32D5CCA16120681C474D67D279CCA6F6DB" - "73DE6AA96140B5C457B7486E06D318CE" - }, { - "NIST P-521", 0, - "01E4D82EE5CD6DA37080252295EFA273BBBA6952012D0120EAF131E73F1E5024" - "36E3324624471040030E1C345D65490ECEE9B64E03B15B6C7EB69A39C618BAFEED70", - "03EE3A3C88A6933B7B16016BE4CC4E3BF5EA0625CB3DB2604CDCBBD02CABBC90" - "8904D9DB42998F6C5101D4D4318ACFC9643C9CD641F636D1810ED86F1840EA74F3C0" - }, { - "NIST P-521", 0, - "01F3DFCB5433387B6B2E3F74177F4F3D7300F05E1AD49DE112630E27B1C8A437" - "1E742CB020E0039B5477FC897D17332034F9660B3066764EFF5FB440EB8856E782E3", - "02D337616C9D202DC5E290C486F5855CBD6A8470AE62CA96245834CF49257D8D" - "96D4041B15007650DEE668C00DDBF749054256C571F60980AC74D0DBCA7FB96C2F48" - }, { - "NIST P-521", 1, - "822A846606DC9E96452CAC373567A8B57D9ACA15B177F75DD7EF10C635F52CE4" - "EF6ABEEDB90D3F48F50A0C9015A95C955A25C45DE8413DE3BF899B6B1E62CF7CB8", - "0102771B5F3EC8C36838CEC04DCBC28AD1E38C37DAB0EA89B5EE92D21F7A35CE" - "ABC8B155EDC70154D6DFA2E77EC1D8C4A3406A6BD0ECF8F1EE2AC33A02464CB70C97" - }, { - "NIST P-521", 0, - "F733D48467912D1FFE46CF442F27FDD218D190E7B8A829D822DA3B6BAF9B987E" - "5B4BCCE34499248F59EEAF74F63ED15FF73F243C6FC3FD5E5842F6A3BA34C2022D", - "0281AAAD1B7EEBABEB6EC67932CB7E95717AFA3B4CF7A2DB151CD537C419C3A5" - "156ED9160758190B47696CDC15E81BBAD12975283907A571604DB23F702AEA4B38FF" - }, { - "NIST P-521", 0, - "03B1B274175AAEB5907152E5114CCAEADA28A7ADD4A2B1831C3D8302E8596489" - "E2C98B9B8D0CAE98C03BB11E28CE66D4736449758AF58BAFE40EF5A5FA22C9A43117", - "94C5951F81D544E959EDFC5DC1D5F42FE427871D4FB91A43A0B4A6BEA6B35B9E" - "BC5FB444C70BE4FD47B4ED16704F8C86EF019FC47C7FF2271F8B0DDEA9E2D3BCDD" - }, { - "NIST P-521", 1, - "F2248C318055DE37CD706D4FCAF7E7D96737A4A7B6B8067A66DCD58B6B8DFC55" - "90ECE67F6AA67F9C51B57E7B023075F2F42909BF47361CB6881C10F55FB7215B56", - "0162F735CE6A2ADA54CAF96A12D6888C02DE0A74638CF34CE39DABBACA4D651B" - "7E6ED1A65B551B36BAE7BE474BB6E6905ED0E33C7BA2021885027C7C6E40C5613004" - }, { - "NIST P-521", 0, - "9F08E97FEADCF0A391CA1EA4D97B5FE62D3B164593E12027EB967BD6E1FA841A" - "9831158DF164BCAD0BF3ADA96127745E25F349BDDD52EEA1654892B35960C9C023", - "AE2A25F5440F258AFACA6925C4C9F7AEAD3CB67153C4FACB31AC33F58B43A78C" - "B14F682FF726CEE2A6B6F6B481AEEB29A9B3150F02D1CFB764672BA8294C477291" - }, { - "NIST P-521", 0, - "01047B52014748C904980716953206A93F0D01B34CA94A997407FA93FE304F86" - "17BB6E402B2BB8B434C2671ECE953ABE7BADB75713CD9DF950943A33A9A19ACCDABE", - "7433533F098037DEA616337986887D01C5CC8DEC3DC1FDB9CDF7287EF27CC125" - "54FCF3A5E212DF9DAD9F8A3A7173B23FC6E15930704F3AEE1B074BDDB0ED6823E4" - }, { - "NIST P-521", 0, - "01C2A9EBF51592FE6589F618EAADA1697D9B2EC7CE5D48C9E80FC597642B23F1" - "F0EBE953449762BD3F094F57791D9850AFE98BBDA9872BE399B7BDD617860076BB03", - "0B822E27692F63DB8E12C59BB3CCA172B9BBF613CAE5F9D1474186E45E8B26FF" - "962084E1C6BE74821EDBB60941A3B75516F603719563433383812BFEA89EC14B89" - }, { - "NIST P-521", 0, - "99390F342C3F0D46E80C5B65C61E8AA8ACA0B6D4E1352404586364A05D8398E9" - "2BC71A644E8663F0A9B87D0B3ACAEE32F2AB9B321317AD23059D045EBAB91C5D93", - "82FCF93AE4467EB57766F2B150E736636727E7282500CD482DA70D153D195F2B" - "DF9B96D689A0DC1BB9137B41557A33F202F1B71840544CBEFF03072E77E4BB6F0B" - }, { - "NIST P-521", 1, - "018E48E80594FF5496D8CC7DF8A19D6AA18805A4EF4490038AED6A1E9AA18056" - "D0244A97DCF6D132C6804E3F4F369922119544B4C057D783C848FB798B48730A382C", - "01AF510B4F5E1C40BC9C110216D35E7C6D7A2BEE52914FC98258676288449901" - "F27A07EE91DF2D5D79259712906C3E18A990CBF35BCAC41A952820CE2BA8D0220080" - }, { - "NIST P-521", 1, - "ADCEF3539B4BC831DC0AFD173137A4426152058AFBAE06A17FCB89F4DB6E48B5" - "335CB88F8E4DB475A1E390E5656072F06605BFB84CBF9795B7992ECA04A8E10CA1", - "01BCB985AFD6404B9EDA49B6190AAA346BF7D5909CA440C0F7E505C62FAC8635" - "31D3EB7B2AC4DD4F4404E4B12E9D6D3C596179587F3724B1EFFF684CFDB4B21826B9" - } - }; - gpg_error_t err; - int tidx; - const char *lastcurve = NULL; - gcry_ctx_t ctx = NULL; - gcry_mpi_t qx = NULL; - gcry_mpi_t qy = NULL; - gcry_mpi_point_t Q; - int oncurve; - - wherestr = "point_on_curve"; - for (tidx=0; tidx < DIM (t); tidx++) - { - if (!t[tidx].curve) - { - if (!lastcurve || !ctx) - die ("invalid test vectors at idx %d\n", tidx); - } - else if (!ctx || !lastcurve || strcmp (t[tidx].curve, lastcurve)) - { - lastcurve = t[tidx].curve; - gcry_ctx_release (ctx); - err = gcry_mpi_ec_new (&ctx, NULL, lastcurve); - if (err) - die ("error creating context for curve %s at idx %d: %s\n", - lastcurve, tidx, gpg_strerror (err)); - - info ("checking points on curve %s\n", lastcurve); - } - - gcry_mpi_release (qx); - gcry_mpi_release (qy); - qx = hex2mpi (t[tidx].qx); - qy = hex2mpi (t[tidx].qy); - - Q = gcry_mpi_point_set (NULL, qx, qy, GCRYMPI_CONST_ONE); - if (!Q) - die ("gcry_mpi_point_set(Q) failed at idx %d\n", tidx); - - oncurve = gcry_mpi_ec_curve_point (Q, ctx); - - if (t[tidx].oncurve && !oncurve) - { - fail ("point expected on curve but not identified as such (i=%d):\n", - tidx); - print_point (" Q", Q); - } - else if (!t[tidx].oncurve && oncurve) - { - fail ("point not expected on curve but identified as such (i=%d):\n", - tidx); - print_point (" Q", Q); - } - gcry_mpi_point_release (Q); - } - - gcry_mpi_release (qx); - gcry_mpi_release (qy); - gcry_ctx_release (ctx); -} - - -int -main (int argc, char **argv) -{ - - if (argc > 1 && !strcmp (argv[1], "--verbose")) - verbose = 1; - else if (argc > 1 && !strcmp (argv[1], "--debug")) - verbose = debug = 1; - - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - - xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - - set_get_point (); - context_alloc (); - context_param (); - basic_ec_math (); - point_on_curve (); - - /* The tests are for P-192 and ed25519 which are not supported in - FIPS mode. */ - if (!gcry_fips_mode_active()) - { - basic_ec_math_simplified (); - twistededwards_math (); - } - - info ("All tests completed. Errors: %d\n", error_count); - return error_count ? 1 : 0; -} From 02e6d9b5f1047a4901bd459e25a1dbf59653f6b0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 Oct 2021 11:46:31 +0200 Subject: [PATCH 168/214] Remove a no longer needed patch --- libgcrypt-1.8.3-fips-enttest.patch | 113 ----------------------------- libgcrypt.spec | 3 - 2 files changed, 116 deletions(-) delete mode 100644 libgcrypt-1.8.3-fips-enttest.patch diff --git a/libgcrypt-1.8.3-fips-enttest.patch b/libgcrypt-1.8.3-fips-enttest.patch deleted file mode 100644 index 34e54bf..0000000 --- a/libgcrypt-1.8.3-fips-enttest.patch +++ /dev/null @@ -1,113 +0,0 @@ -diff -up libgcrypt-1.8.3/random/random-drbg.c.fips-enttest libgcrypt-1.8.3/random/random-drbg.c ---- libgcrypt-1.8.3/random/random-drbg.c.fips-enttest 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/random/random-drbg.c 2019-06-24 10:04:23.219547141 +0200 -@@ -317,6 +317,7 @@ struct drbg_state_s - gcry_cipher_hd_t ctr_handle; /* CTR mode cipher handle */ - int seeded:1; /* DRBG fully seeded? */ - int pr:1; /* Prediction resistance enabled? */ -+ int ent_primed:1; /* Previous entropy data primed? */ - /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the - * process which did the initialization so that we can detect a fork. - * The volatile modifier is required so that the compiler does not -@@ -324,6 +325,7 @@ struct drbg_state_s - pid_t seed_init_pid; - const struct drbg_state_ops_s *d_ops; - const struct drbg_core_s *core; -+ unsigned char ent_hash[64]; /* Hash of previous entropy data */ - struct drbg_test_data_s *test_data; - }; - -@@ -610,11 +612,13 @@ drbg_get_entropy (drbg_state_t drbg, uns - size_t len) - { - int rc = 0; -+ unsigned char newhash[64]; - - /* Perform testing as defined in 11.3.2 */ - if (drbg->test_data && drbg->test_data->fail_seed_source) - return -1; - -+redo: - read_cb_buffer = buffer; - read_cb_size = len; - read_cb_len = 0; -@@ -634,6 +638,27 @@ drbg_get_entropy (drbg_state_t drbg, uns - #else - rc = -1; - #endif -+ -+ /* to avoid storing the actual entropy obtained for indefinite -+ time, we just store the SHA-512 hash of the entropy gathered -+ */ -+ _gcry_md_hash_buffer (GCRY_MD_SHA512, newhash, buffer, len); -+ -+ if (!drbg->ent_primed) -+ { -+ memcpy (drbg->ent_hash, newhash, sizeof (drbg->ent_hash)); -+ drbg->ent_primed = 1; -+ goto redo; -+ } -+ -+ if (memcmp (newhash, drbg->ent_hash, sizeof (drbg->ent_hash)) == 0) -+ { -+ fips_signal_error ("Entropy source failed the continuous test"); -+ return -1; /* continuous entropy test failed */ -+ } -+ -+ memcpy (drbg->ent_hash, newhash, sizeof (drbg->ent_hash)); -+ - return rc; - } - -@@ -1341,26 +1366,38 @@ drbg_seed (drbg_state_t drbg, drbg_strin - } - else - { -+ int nonce = 0; - /* Gather entropy equal to the security strength of the DRBG. - * With a derivation function, a nonce is required in addition - * to the entropy. A nonce must be at least 1/2 of the security - * strength of the DRBG in size. Thus, entropy * nonce is 3/2 - * of the strength. The consideration of a nonce is only -- * applicable during initial seeding. */ -+ * applicable during initial seeding. -+ * To avoid pulling different length of data from entropy -+ * source, we use 2 * strength for initial seeding. */ - entropylen = drbg_sec_strength (drbg->core->flags); - if (!entropylen) - return GPG_ERR_GENERAL; - if (0 == reseed) -- /* make sure we round up strength/2 in -- * case it is not divisible by 2 */ -- entropylen = ((entropylen + 1) / 2) * 3; -+ { -+ nonce = 1; -+ } - dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen)); -- entropy = xcalloc_secure (1, entropylen); -+ entropy = xcalloc_secure (nonce + 1, entropylen); - if (!entropy) - return GPG_ERR_ENOMEM; - ret = drbg_get_entropy (drbg, entropy, entropylen); - if (ret) - goto out; -+ if (nonce) -+ { -+ ret = drbg_get_entropy (drbg, entropy + entropylen, entropylen); -+ if (ret) -+ goto out; -+ /* make sure we round up strength/2 in -+ * case it is not divisible by 2 */ -+ entropylen = 2 * entropylen; -+ } - drbg_string_fill (&data1, entropy, entropylen); - } - -@@ -1597,6 +1634,7 @@ drbg_instantiate (drbg_state_t drbg, - drbg->core = &drbg_cores[coreref]; - drbg->pr = pr; - drbg->seeded = 0; -+ drbg->ent_primed = 0; - if (drbg->core->flags & DRBG_HMAC) - drbg->d_ops = &drbg_hmac_ops; - else if (drbg->core->flags & DRBG_HASH_MASK) diff --git a/libgcrypt.spec b/libgcrypt.spec index a90a8ba..f09a85d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -37,8 +37,6 @@ Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch Patch18: libgcrypt-1.8.3-fips-ctor.patch # Do not try to open /dev/urandom if getrandom() works Patch24: libgcrypt-1.8.5-getrandom.patch -# Continuous FIPS entropy test -Patch26: libgcrypt-1.8.3-fips-enttest.patch # Disable non-approved FIPS hashes in the enforced FIPS mode Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # Missing Intel CET support in the library (#1954049) @@ -89,7 +87,6 @@ applications using libgcrypt. %patch13 -p1 -b .gccopt %patch18 -p1 -b .fips-ctor %patch24 -p1 -b .getrandom -%patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module From 4b1e516cd711a3875698b58056f5351570da199b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 Oct 2021 11:52:10 +0200 Subject: [PATCH 169/214] Removed unused CAVS patch --- libgcrypt-1.7.3-fips-cavs.patch | 1311 ------------------------------- libgcrypt.spec | 3 - 2 files changed, 1314 deletions(-) delete mode 100644 libgcrypt-1.7.3-fips-cavs.patch diff --git a/libgcrypt-1.7.3-fips-cavs.patch b/libgcrypt-1.7.3-fips-cavs.patch deleted file mode 100644 index 42d028e..0000000 --- a/libgcrypt-1.7.3-fips-cavs.patch +++ /dev/null @@ -1,1311 +0,0 @@ -diff -up libgcrypt-1.7.3/tests/cavs_driver.pl.cavs libgcrypt-1.7.3/tests/cavs_driver.pl ---- libgcrypt-1.7.3/tests/cavs_driver.pl.cavs 2013-03-15 20:25:38.000000000 +0100 -+++ libgcrypt-1.7.3/tests/cavs_driver.pl 2016-11-22 17:29:06.067553077 +0100 -@@ -1,9 +1,11 @@ - #!/usr/bin/env perl - # --# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ -+# $Id: cavs_driver.pl 2124 2010-12-20 07:56:30Z smueller $ - # - # CAVS test driver (based on the OpenSSL driver) - # Written by: Stephan Müller -+# Werner Koch (libgcrypt interface) -+# Tomas Mraz (addition of DSA2) - # Copyright (c) atsec information security corporation - # - # Permission is hereby granted, free of charge, to any person obtaining a copy -@@ -85,13 +87,16 @@ - # T[CBC|CFB??|ECB|OFB]varkey - # T[CBC|CFB??|ECB|OFB]invperm - # T[CBC|CFB??|ECB|OFB]vartext -+# WARNING: TDES in CFB and OFB mode problems see below - # - # ANSI X9.31 RNG - # ANSI931_AES128MCT - # ANSI931_AES128VST - # --# DSA -+# DSA2 - # PQGGen -+# PQGVer -+# KeyPair - # SigGen - # SigVer - # -@@ -101,6 +106,36 @@ - # RC4PltBD - # RC4REGT - # -+# -+# TDES MCT for CFB and OFB: -+# ------------------------- -+# The inner loop cannot be handled by this script. If you want to have tests -+# for these cipher types, implement your own inner loop and add it to -+# crypto_mct. -+# -+# the value $next_source in crypto_mct is NOT set by the standard implementation -+# of this script. It would need to be set as follows for these two (code take -+# from fipsdrv.c from libgcrypt - the value input at the end will contain the -+# the value for $next_source: -+# -+# ... inner loop ... -+# ... -+# get_current_iv (hd, last_iv, blocklen); -+# ... encrypt / decrypt (input is the data to be en/decrypted and output is the -+# result of operation) ... -+# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) -+# memcpy (input, last_iv, blocklen); -+# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) -+# memcpy (input, last_iv, blocklen); -+# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) -+# { -+# /* Reconstruct the output vector. */ -+# int i; -+# for (i=0; i < blocklen; i++) -+# input[i] ^= output[i]; -+# } -+# ... inner loop ends ... -+# ==> now, the value of input is to be put into $next_source - - use strict; - use warnings; -@@ -226,6 +261,8 @@ my $hmac; - # Generate the P, Q, G, Seed, counter, h (value used to generate g) values - # for DSA - # $1: modulus size -+# $2: q size -+# $3: seed (might be empty string) - # return: string with the calculated values in hex format, where each value - # is separated from the previous with a \n in the following order: - # P\n -@@ -236,6 +273,19 @@ my $hmac; - # h - my $dsa_pqggen; - -+# Generate the G value from P and Q -+# for DSA -+# $1: modulus size -+# $2: q size -+# $3: P in hex form -+# $4: Q in hex form -+# return: string with the calculated values in hex format, where each value -+# is separated from the previous with a \n in the following order: -+# P\n -+# Q\n -+# G\n -+my $dsa_ggen; -+ - # - # Generate an DSA public key from the provided parameters: - # $1: Name of file to create -@@ -255,16 +305,30 @@ my $dsa_verify; - - # generate a new DSA key with the following properties: - # PEM format --# $1 keyfile name --# return: file created, hash with keys of P, Q, G in hex format -+# $1: modulus size -+# $2: q size -+# $3 keyfile name -+# return: file created with key, string with values of P, Q, G in hex format - my $gen_dsakey; - -+# generate a new DSA private key XY parameters in domain: -+# PEM format -+# $1: P in hex form -+# $2: Q in hex form -+# $3: G in hex form -+# return: string with values of X, Y in hex format -+my $gen_dsakey_domain; -+ - # Sign a message with DSA - # $1: data to be signed in hex form - # $2: Key file in PEM format with the private key - # return: hash of digest information in hex format with Y, R, S as keys - my $dsa_sign; - -+my $rsa_keygen; -+ -+my $rsa_keygen_kat; -+ - ################################################################ - ##### OpenSSL interface functions - ################################################################ -@@ -404,6 +468,35 @@ sub libgcrypt_rsa_derive($$$$$$$$) { - } - - -+sub libgcrypt_rsa_keygen($) { -+ my $n = shift; -+ my $sexp; -+ -+ $n = sprintf ("%u", $n); -+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")))\n"; -+ -+ return pipe_through_program($sexp, "fipsdrv rsa-keygen"); -+} -+ -+ -+sub libgcrypt_rsa_keygen_kat($$$$) { -+ my $n = shift; -+ my $e = shift; -+ my $p = shift; -+ my $q = shift; -+ my $sexp; -+ -+ $n = sprintf ("%u", $n); -+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" -+ . "(test-parms" -+ . "(e #$e#)" -+ . "(p #$p#)" -+ . "(q #$q#))))\n"; -+ -+ return pipe_through_program($sexp, "fipsdrv rsa-keygen-kat"); -+} -+ -+ - sub libgcrypt_rsa_sign($$$) { - my $data = shift; - my $hashalgo = shift; -@@ -500,17 +593,32 @@ sub libgcrypt_hmac($$$$) { - return pipe_through_program($msg, $program); - } - --sub libgcrypt_dsa_pqggen($) { -+sub libgcrypt_dsa_pqggen($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $seed = shift; -+ -+ my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; -+ return pipe_through_program($seed, $program); -+} -+ -+sub libgcrypt_dsa_ggen($$$$) { - my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $domain = "(domain (p #$p#)(q #$q#))"; - -- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; - return pipe_through_program("", $program); - } - --sub libgcrypt_gen_dsakey($) { -+sub libgcrypt_gen_dsakey($$$) { -+ my $mod = shift; -+ my $qsize = shift; - my $file = shift; - -- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; - my $tmp; - my %ret; - -@@ -519,10 +627,21 @@ sub libgcrypt_gen_dsakey($) { - $tmp = pipe_through_program("", $program); - die "dsa key gen failed: file $file not created" if (! -f $file); - -- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); -+ @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); - return %ret; - } - -+sub libgcrypt_gen_dsakey_domain($$$) { -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; -+ -+ my $program = "fipsdrv --key '$domain' dsa-gen-key"; -+ -+ return pipe_through_program("", $program); -+} -+ - sub libgcrypt_dsa_genpubkey($$$$$) { - my $filename = shift; - my $p = shift; -@@ -1139,7 +1258,7 @@ sub hmac_kat($$$$) { - $out .= "Tlen = $tlen\n"; - $out .= "Key = $key\n"; - $out .= "Msg = $msg\n"; -- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; -+ $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; - - return $out; - } -@@ -1205,7 +1324,7 @@ sub crypto_mct($$$$$$$$) { - } - my ($CO, $CI); - my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); -- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); -+ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); - my $pid = open2($CO, $CI, $cipher_imp); - - my $calc_data = $iv; # CT[j] -@@ -1213,8 +1332,8 @@ sub crypto_mct($$$$$$$$) { - my $old_old_calc_data; # CT[j-2] - my $next_source; - -- # TDES inner loop implements logic within driver -- if ($cipher =~ /des/) { -+ # TDES inner loop implements logic within driver of libgcrypt -+ if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { - # Need to provide a dummy IV in case of ECB mode. - my $iv_arg = (defined($iv) && $iv ne "") - ? bin2hex($iv) -@@ -1238,6 +1357,10 @@ sub crypto_mct($$$$$$$$) { - $line = <$CO>; - } else { - for (my $j = 0; $j < $iloop; ++$j) { -+ if ($cipher =~ /des-ede3-ofb/ || -+ (!$enc && $cipher =~ /des-ede3-cfb/)) { -+ die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; -+ } - $old_old_calc_data = $old_calc_data; - $old_calc_data = $calc_data; - -@@ -1429,7 +1552,7 @@ sub rsa_sigver($$$$$) { - # $7 xq2 - # $8 Xq - # return: string formatted as expected by CAVS --sub rsa_keygen($$$$$$$$) { -+sub rsa_keygen_x931($$$$$$$$) { - my $modulus = shift; - my $e = shift; - my $xp1 = shift; -@@ -1503,21 +1626,23 @@ sub rngx931($$$$) { - return $out; - } - --# DSA PQGGen test -+# DSA PQGen test - # $1 modulus size --# $2 number of rounds to perform the test -+# $2 q size -+# $3 number of rounds to perform the test - # return: string formatted as expected by CAVS --sub dsa_pqggen_driver($$) { -+sub dsa_pqgen_driver($$$) { - my $mod = shift; -+ my $qsize = shift; - my $rounds = shift; - - my $out = ""; - for(my $i=0; $i<$rounds; $i++) { -- my $ret = &$dsa_pqggen($mod); -+ my $ret = &$dsa_pqggen($mod, $qsize, ""); - my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); -- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" -- if (!defined($P) || !defined($Q) || !defined($G) || -- !defined($Seed) || !defined($c) || !defined($H)); -+ die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || -+ !defined($Seed) || !defined($c)); - - # now change the counter to decimal as CAVS wants decimal - # counter value although all other is HEX -@@ -1525,15 +1650,166 @@ sub dsa_pqggen_driver($$) { - - $out .= "P = $P\n"; - $out .= "Q = $Q\n"; -- $out .= "G = $G\n"; -- $out .= "Seed = $Seed\n"; -- $out .= "c = $c\n"; -- $out .= "H = $H\n\n"; -+ $out .= "domain_parameter_seed = $Seed\n"; -+ $out .= "counter = $c\n\n"; - } - - return $out; - } - -+# DSA GGen test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# return: string formatted as expected by CAVS -+sub dsa_ggen_driver($$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_ggen($mod, $qsize, $p, $q); -+ my ($P, $Q, $G) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G for dsa_ggen" -+ if (!defined($P) || !defined($Q) || !defined($G)); -+ -+ $out .= "G = $G\n\n"; -+ -+ return $out; -+} -+ -+sub hexcomp($$) { -+ my $a = lc shift; -+ my $b = lc shift; -+ -+ if (length $a < length $b) { -+ my $c = $a; -+ $a = $b; -+ $b = $a; -+ } -+ -+ while (length $b < length $a) { -+ $b = "00$b"; -+ } -+ -+ return $a eq $b; -+} -+ -+# DSA PQVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 seed in hex form -+# $6 c decimal counter -+# return: string formatted as expected by CAVS -+sub dsa_pqver_driver($$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $seed = shift; -+ my $c = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2)); -+ -+ $c2 = hex($c2); -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($seed, $seed2) && $c == $c2) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ return $out; -+} -+ -+# DSA PQGVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 g in hex form -+# $6 seed in hex form -+# $7 c decimal counter -+# $8 h in hex form -+# return: string formatted as expected by CAVS -+sub dsa_pqgver_driver($$$$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $seed = shift; -+ my $c = shift; -+ my $h = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2) || !defined($h2)); -+ -+ -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ $out .= "H = $h\n"; -+ -+ $c2 = hex($c2); -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && -+ $c == $c2 && hex($h) == hex($h2)) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ -+ return $out; -+} -+ -+# DSA Keypair test -+# $1 modulus size -+# $2 q size -+# $3 number of rounds to perform the test -+# return: string formatted as expected by CAVS -+sub dsa_keypair_driver($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $rounds = shift; -+ -+ my $out = ""; -+ my $tmpkeyfile = "dsa_siggen.tmp.$$"; -+ my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); -+ $out .= "P = " . $pqg{'P'} . "\n"; -+ $out .= "Q = " . $pqg{'Q'} . "\n"; -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ unlink($tmpkeyfile); -+ -+ for(my $i=0; $i<$rounds; $i++) { -+ my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); -+ my ($X, $Y) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" -+ if (!defined($X) || !defined($Y)); -+ -+ $out .= "X = $X\n"; -+ $out .= "Y = $Y\n\n"; -+ } -+ -+ return $out; -+} - - # DSA SigGen test - # $1: Message to be signed in hex form -@@ -1598,6 +1874,53 @@ sub dsa_sigver($$$$$$$$) { - return $out; - } - -+# RSA Keygen RPP test -+# $1 modulus size -+# $2 number of rounds to perform the test -+# return: string formatted as expected by CAVS -+sub rsa_keygen_driver($$) { -+ my $mod = shift; -+ my $rounds = shift; -+ -+ my $out = ""; -+ -+ for(my $i=0; $i<$rounds; $i++) { -+ my $ret = &$rsa_keygen($mod); -+ my ($e, $p, $q, $n, $d) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of e, p, q, n, d for rsa_keygen" -+ if (!defined($e) || !defined($p) || !defined($q) || !defined($n) || !defined($d)); -+ -+ $out .= "e = $e\n"; -+ $out .= "p = $p\n"; -+ $out .= "q = $q\n"; -+ $out .= "n = $n\n"; -+ $out .= "d = $d\n\n"; -+ } -+ -+ return $out; -+} -+ -+# RSA RPP Keygen KAT test -+# $1 modulus size -+# $2 p in hex form -+# $3 q in hex form -+# return: string formatted as expected by CAVS -+sub rsa_keygen_kat_driver($$$) { -+ my $mod = shift; -+ my $p = shift; -+ my $q = shift; -+ -+ my $out = ""; -+ my $ret = &$rsa_keygen_kat($mod, $p, $q); -+ my ($Result) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of Result for rsa_keygen_kat" -+ if (!defined($Result)); -+ -+ $out .= "Result = $Result\n\n"; -+ return $out; -+} -+ -+ - ############################################################## - # Parser of input file and generator of result file - # -@@ -1658,12 +1981,18 @@ sub parse($$) { - my $klen = ""; - my $tlen = ""; - my $modulus = ""; -+ my $qsize = ""; - my $capital_n = 0; -+ my $num = 0; - my $capital_p = ""; - my $capital_q = ""; - my $capital_g = ""; - my $capital_y = ""; - my $capital_r = ""; -+ my $capital_h = ""; -+ my $c = ""; -+ my $prandom = ""; -+ my $qrandom = ""; - my $xp1 = ""; - my $xp2 = ""; - my $Xp = ""; -@@ -1700,7 +2029,7 @@ sub parse($$) { - - ##### Extract cipher - # XXX there may be more - to be added -- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { -+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyGen - Random Probably Prime|KeyPair|PQGVer)/) { - if ($tmpline =~ /CBC/) { $mode="cbc"; } - elsif ($tmpline =~ /ECB/) { $mode="ecb"; } - elsif ($tmpline =~ /OFB/) { $mode="ofb"; } -@@ -1749,7 +2078,23 @@ sub parse($$) { - - if ($tt == 0) { - ##### Identify the test type -- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { -+ if ($tmpline =~ /KeyGen - Random Probably Prime Known Answer Test/) { -+ $tt = 19; -+ die "Interface function rsa_keygen_kat for RSA key generation KAT not defined for tested library" -+ if (!defined($rsa_keygen_kat)); -+ } elsif ($tmpline =~ /KeyGen - Random Probably Prime Test/) { -+ $tt = 18; -+ die "Interface function rsa_keygen for RSA key generation not defined for tested library" -+ if (!defined($rsa_keygen)); -+ } elsif ($tmpline =~ /PQGVer/) { -+ $tt = 16; -+ die "Interface function for DSA PQGVer testing not defined for tested library" -+ if (!defined($dsa_pqggen)); -+ } elsif ($tmpline =~ /KeyPair/) { -+ $tt = 14; -+ die "Interface function dsa_keygen for DSA key generation not defined for tested library" -+ if (!defined($gen_dsakey_domain)); -+ } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { - $tt = 13; - die "Interface function rsa_derive for RSA key generation not defined for tested library" - if (!defined($rsa_derive)); -@@ -1760,11 +2105,11 @@ sub parse($$) { - } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { - $tt = 11; - die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" -- if (!defined($dsa_sign) || !defined($gen_rsakey)); -+ if (!defined($dsa_sign) || !defined($gen_dsakey)); - } elsif ($tmpline =~ /PQGGen/) { - $tt = 10; - die "Interface function for DSA PQGGen testing not defined for tested library" -- if (!defined($dsa_pqggen)); -+ if (!defined($dsa_pqggen) || !defined($dsa_ggen)); - } elsif ($tmpline =~ /Hash sizes tested/) { - $tt = 9; - die "Interface function hmac for HMAC testing not defined for tested library" -@@ -1792,7 +2137,7 @@ sub parse($$) { - } elsif ($tmpline =~ /Monte|MCT|Carlo/) { - $tt = 2; - die "Interface function state_cipher for Stateful Cipher operation defined for tested library" -- if (!defined($state_cipher) || !defined($state_cipher_des)); -+ if (!defined($state_cipher) && !defined($state_cipher_des)); - } elsif ($cipher =~ /^sha/) { - $tt = 3; - die "Interface function hash for Hashing not defined for tested library" -@@ -1875,18 +2220,44 @@ sub parse($$) { - die "Msg/Seed seen twice - input file crap" if ($pt ne ""); - $pt=$2; - } -- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request -+ $out .= $line . "\n"; # print it -+ if ($tt == 10) { -+ # now generate G from PQ -+ $tt = 15; -+ } -+ } -+ elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request -+ $out .= $line . "\n"; # print it -+ if ($tt == 16) { -+ # now verify PQG -+ $tt = 17; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests - $modulus = $1; -+ $qsize = $2; - $out .= $line . "\n\n"; # print it -+ # clear eventual PQG -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; - # generate the private key with given bit length now - # as we have the required key length in bit - if ($tt == 11) { - $dsa_keyfile = "dsa_siggen.tmp.$$"; -- my %pqg = &$gen_dsakey($dsa_keyfile); -+ my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); - $out .= "P = " . $pqg{'P'} . "\n"; - $out .= "Q = " . $pqg{'Q'} . "\n"; -- $out .= "G = " . $pqg{'G'} . "\n"; -- } elsif ( $tt == 5 ) { -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ $modulus = $1; -+ $out .= $line . "\n\n"; # print it -+ # generate the private key with given bit length now -+ # as we have the required key length in bit -+ if ( $tt == 5 ) { - # XXX maybe a secure temp file name is better here - # but since it is not run on a security sensitive - # system, I hope that this is fine -@@ -1907,6 +2278,9 @@ sub parse($$) { - } - elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests - $e=$1; -+ if ($tt == 19) { -+ $out .= $line . "\n"; # print it -+ } - } - elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests - die "S seen twice - input file crap" if ($signature ne ""); -@@ -1932,11 +2306,16 @@ sub parse($$) { - if ($tlen ne ""); - $tlen=$1; - } -- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen -+ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair - die "N seen twice - check input file" - if ($capital_n); - $capital_n = $1; - } -+ elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen -+ die "Num seen twice - check input file" -+ if ($num); -+ $num = $1; -+ } - elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer - die "P seen twice - check input file" - if ($capital_p); -@@ -1965,6 +2344,16 @@ sub parse($$) { - if ($capital_r); - $capital_r = $1; - } -+ elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer -+ die "H seen twice - check input file" -+ if ($capital_h); -+ $capital_h = $1; -+ } -+ elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer -+ die "c seen twice - check input file" -+ if ($c); -+ $c = $1; -+ } - elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen - die "xp1 seen twice - check input file" - if ($xp1); -@@ -1995,6 +2384,22 @@ sub parse($$) { - if ($Xq); - $Xq = $1; - } -+ elsif ($line =~ /^prandom\s*=\s*(.*)/) { #RSA key gen KAT -+ die "prandom seen twice - check input file" -+ if ($prandom); -+ $prandom = $1; -+ $out .= $line . "\n"; # print it -+ } -+ elsif ($line =~ /^qrandom\s*=\s*(.*)/) { #RSA key gen KAT -+ die "qrandom seen twice - check input file" -+ if ($qrandom); -+ $qrandom = $1; -+ $out .= $line . "\n"; # print it -+ } -+ elsif ($tt == 19 && $line =~ /^ / && $qrandom eq "") { #RSA key gen KAT -+ $qrandom = "00"; -+ $out .= $line . "\n"; # print it -+ } - else { - $out .= $line . "\n"; - } -@@ -2074,11 +2479,10 @@ sub parse($$) { - } - } - elsif ($tt == 10) { -- if ($modulus ne "" && $capital_n > 0) { -- $out .= dsa_pqggen_driver($modulus, $capital_n); -- #$mod is not resetted -- $capital_n = 0; -- } -+ if ($modulus ne "" && $qsize ne "" && $num > 0) { -+ $out .= dsa_pqgen_driver($modulus, $qsize, $num); -+ $num = 0; -+ } - } - elsif ($tt == 11) { - if ($pt ne "" && $dsa_keyfile ne "") { -@@ -2124,7 +2528,7 @@ sub parse($$) { - $xq1 ne "" && - $xq2 ne "" && - $Xq ne "") { -- $out .= rsa_keygen($modulus, -+ $out .= rsa_keygen_x931($modulus, - $e, - $xp1, - $xp2, -@@ -2141,6 +2545,96 @@ sub parse($$) { - $Xq = ""; - } - } -+ elsif ($tt == 14) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_n > 0) { -+ $out .= dsa_keypair_driver($modulus, -+ $qsize, -+ $capital_n); -+ $capital_n = 0; -+ } -+ } -+ elsif ($tt == 15) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "") { -+ $out .= dsa_ggen_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q); -+ $capital_p = ""; -+ $capital_q = ""; -+ $num--; -+ } -+ } -+ elsif ($tt == 16) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $pt ne "" && -+ $c ne "") { -+ $out .= dsa_pqver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $pt, -+ $c); -+ $capital_p = ""; -+ $capital_q = ""; -+ $pt = ""; -+ $c = ""; -+ } -+ } -+ elsif ($tt == 17) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $capital_g ne "" && -+ $pt ne "" && -+ $c ne "" && -+ $capital_h ne "") { -+ $out .= dsa_pqgver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $capital_g, -+ $pt, -+ $c, -+ $capital_h); -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; -+ $pt = ""; -+ $c = ""; -+ $capital_h = ""; -+ } -+ } -+ elsif ($tt == 18) { -+ if ($modulus ne "" && -+ $capital_n > 0) { -+ $out .= rsa_keygen_driver($modulus, -+ $capital_n); -+ $capital_n = 0; -+ } -+ } -+ elsif ($tt == 19) { -+ if ($modulus ne "" && -+ $e ne "" && -+ $prandom ne "" && -+ $qrandom ne "") { -+ $out .= rsa_keygen_kat_driver($modulus, -+ $e, -+ $prandom, -+ $qrandom); -+ $prandom = ""; -+ $qrandom = ""; -+ $e = ""; -+ } -+ } - elsif ($tt > 0) { - die "Test case $tt not defined"; - } -@@ -2199,10 +2693,14 @@ sub main() { - $state_rng = \&libgcrypt_state_rng; - $hmac = \&libgcrypt_hmac; - $dsa_pqggen = \&libgcrypt_dsa_pqggen; -+ $dsa_ggen = \&libgcrypt_dsa_ggen; - $gen_dsakey = \&libgcrypt_gen_dsakey; -+ $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; - $dsa_sign = \&libgcrypt_dsa_sign; - $dsa_verify = \&libgcrypt_dsa_verify; - $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; -+ $rsa_keygen = \&libgcrypt_rsa_keygen; -+ $rsa_keygen_kat = \&libgcrypt_rsa_keygen_kat; - } else { - die "Invalid interface option given"; - } -diff -up libgcrypt-1.7.3/tests/cavs_tests.sh.cavs libgcrypt-1.7.3/tests/cavs_tests.sh ---- libgcrypt-1.7.3/tests/cavs_tests.sh.cavs 2013-03-15 20:25:38.000000000 +0100 -+++ libgcrypt-1.7.3/tests/cavs_tests.sh 2016-11-22 17:29:06.067553077 +0100 -@@ -55,7 +55,7 @@ function run_one_test () { - [ -d "$respdir" ] || mkdir "$respdir" - [ -f "$rspfile" ] && rm "$rspfile" - -- if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then -+ if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then - dflag="-D" - fi - -diff -up libgcrypt-1.7.3/tests/fipsdrv.c.cavs libgcrypt-1.7.3/tests/fipsdrv.c ---- libgcrypt-1.7.3/tests/fipsdrv.c.cavs 2016-07-14 11:19:17.000000000 +0200 -+++ libgcrypt-1.7.3/tests/fipsdrv.c 2016-11-22 17:33:15.468330859 +0100 -@@ -892,6 +892,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) - die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); - - p = buf; -+ while (*p) -+ *p++ = tolower(*p); -+ p = buf; - if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) - p += 2; - -@@ -1765,14 +1768,14 @@ run_rsa_verify (const void *data, size_t - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen (int keysize) -+dsa_gen (int keysize, int qsize) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; - - err = gcry_sexp_build (&keyspec, NULL, -- "(genkey (dsa (nbits %d)(use-fips186-2)))", -- keysize); -+ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", -+ keysize, qsize); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1790,7 +1793,7 @@ dsa_gen (int keysize) - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) -+dsa_gen_with_seed (int keysize, int qsize, const void *seed, size_t seedlen) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; -@@ -1799,10 +1802,11 @@ dsa_gen_with_seed (int keysize, const vo - "(genkey" - " (dsa" - " (nbits %d)" -- " (use-fips186-2)" -+ " (qbits %d)" -+ " (use-fips186)" - " (derive-parms" - " (seed %b))))", -- keysize, (int)seedlen, seed); -+ keysize, qsize, (int)seedlen, seed); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1810,6 +1814,37 @@ dsa_gen_with_seed (int keysize, const vo - err = gcry_pk_genkey (&key, keyspec); - if (err) - die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); -+ -+ gcry_sexp_release (keyspec); -+ -+ return key; -+} -+ -+/* Generate a DSA key with specified domain parameters and return the complete -+ S-expression. */ -+static gcry_sexp_t -+dsa_gen_key (const char *domain) -+{ -+ gpg_error_t err; -+ gcry_sexp_t keyspec, key, domspec; -+ -+ err = gcry_sexp_new (&domspec, domain, strlen(domain), 0); -+ if (err) -+ die ("gcry_sexp_build failed for domain spec: %s\n", -+ gpg_strerror (err)); -+ -+ err = gcry_sexp_build (&keyspec, NULL, -+ "(genkey" -+ " (dsa" -+ " (use-fips186)" -+ " %S))", -+ domspec); -+ if (err) -+ die ("gcry_sexp_build failed for DSA key generation: %s\n", -+ gpg_strerror (err)); -+ err = gcry_pk_genkey (&key, keyspec); -+ if (err) -+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (keyspec); - -@@ -1849,7 +1884,7 @@ ecdsa_gen_key (const char *curve) - with one parameter per line in hex format using this order: p, q, - g, seed, counter, h. */ - static void --print_dsa_domain_parameters (gcry_sexp_t key) -+print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) - { - gcry_sexp_t l1, l2; - gcry_mpi_t mpi; -@@ -1885,6 +1920,9 @@ print_dsa_domain_parameters (gcry_sexp_t - } - gcry_sexp_release (l1); - -+ if (!print_misc) -+ return; -+ - /* Extract the seed values. */ - l1 = gcry_sexp_find_token (key, "misc-key-info", 0); - if (!l1) -@@ -1976,38 +2014,106 @@ print_ecdsa_dq (gcry_sexp_t key) - } - - --/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+/* Print just the XY private key parameters. KEY -+ is the complete key as returned by dsa_gen. We print to stdout -+ with one parameter per line in hex format using this order: x, y. */ -+static void -+print_dsa_xy (gcry_sexp_t key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t mpi; -+ int idx; -+ -+ l1 = gcry_sexp_find_token (key, "private-key", 0); -+ if (!l1) -+ die ("private key not found in genkey result\n"); -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("returned private key not formed as expected\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ /* Extract the parameters from the S-expression and print them to stdout. */ -+ for (idx=0; "xy"[idx]; idx++) -+ { -+ l2 = gcry_sexp_find_token (l1, "xy"+idx, 1); -+ if (!l2) -+ die ("no %c parameter in returned public key\n", "xy"[idx]); -+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); -+ if (!mpi) -+ die ("no value for %c parameter in returned private key\n","xy"[idx]); -+ gcry_sexp_release (l2); -+ if (standalone_mode) -+ printf ("%c = ", "XY"[idx]); -+ print_mpi_line (mpi, 1); -+ gcry_mpi_release (mpi); -+ } -+ -+ gcry_sexp_release (l1); -+} -+ -+ -+/* Generate DSA pq domain parameters for a modulus size of KEYSIZE. The - result is printed to stdout with one parameter per line in hex -- format and in this order: p, q, g, seed, counter, h. If SEED is -+ format and in this order: p, q, seed, counter. If SEED is - not NULL this seed value will be used for the generation. */ - static void --run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) -+run_dsa_pqg_gen (int keysize, int qsize, const void *seed, size_t seedlen) - { - gcry_sexp_t key; - - if (seed) -- key = dsa_gen_with_seed (keysize, seed, seedlen); -+ key = dsa_gen_with_seed (keysize, qsize, seed, seedlen); - else -- key = dsa_gen (keysize); -- print_dsa_domain_parameters (key); -+ key = dsa_gen (keysize, qsize); -+ print_dsa_domain_parameters (key, 1); -+ gcry_sexp_release (key); -+} -+ -+ -+/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+ result is printed to stdout with one parameter per line in hex -+ format and in this order: p, q, g, seed, counter, h. If SEED is -+ not NULL this seed value will be used for the generation. */ -+static void -+run_dsa_g_gen (int keysize, int qsize, const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_domain_parameters (key, 0); -+ gcry_sexp_release (key); -+} -+ -+/* Generate a DSA key with specified domain parameters -+ and print the XY values. */ -+static void -+run_dsa_gen_key (const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_xy (key); -+ - gcry_sexp_release (key); - } - - - /* Generate a DSA key of size of KEYSIZE and write the private key to - FILENAME. Also write the parameters to stdout in the same way as -- run_dsa_pqg_gen. */ -+ run_dsa_g_gen. */ - static void --run_dsa_gen (int keysize, const char *filename) -+run_dsa_gen (int keysize, int qsize, const char *filename) - { - gcry_sexp_t key, private_key; - FILE *fp; - -- key = dsa_gen (keysize); -+ key = dsa_gen (keysize, qsize); - private_key = gcry_sexp_find_token (key, "private-key", 0); - if (!private_key) - die ("private key not found in genkey result\n"); -- print_dsa_domain_parameters (key); -+ print_dsa_domain_parameters (key, 1); - - fp = fopen (filename, "wb"); - if (!fp) -@@ -2020,6 +2126,53 @@ run_dsa_gen (int keysize, const char *fi - } - - -+static int -+dsa_hash_from_key(gcry_sexp_t s_key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t q; -+ unsigned int qbits; -+ -+ l1 = gcry_sexp_find_token (s_key, "public-key", 0); -+ if (!l1) -+ { -+ l1 = gcry_sexp_find_token (s_key, "private-key", 0); -+ if (!l1) -+ die ("neither private nor public key found in the loaded key\n"); -+ } -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("public key not formed as expected - no dsa\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ l2 = gcry_sexp_find_token (l1, "q", 0); -+ if (!l2) -+ die ("public key not formed as expected - no q\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); -+ if (!q) -+ die ("public key not formed as expected - no mpi in q\n"); -+ qbits = gcry_mpi_get_nbits(q); -+ gcry_sexp_release(l1); -+ gcry_mpi_release(q); -+ switch(qbits) -+ { -+ case 160: -+ return GCRY_MD_SHA1; -+ case 224: -+ return GCRY_MD_SHA224; -+ case 256: -+ return GCRY_MD_SHA256; -+ default: -+ die("bad number bits (%d) of q in key\n", qbits); -+ } -+ return GCRY_MD_NONE; -+} -+ - - /* Sign DATA of length DATALEN using the key taken from the S-expression - encoded KEYFILE. */ -@@ -2029,11 +2182,16 @@ run_dsa_sign (const void *data, size_t d - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; -+ -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ gcry_md_hash_buffer (algo, hash, data, datalen); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -2044,8 +2202,6 @@ run_dsa_sign (const void *data, size_t d - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); -- - err = gcry_pk_sign (&s_sig, s_data, s_key); - if (err) - { -@@ -2121,13 +2277,18 @@ run_dsa_verify (const void *data, size_t - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); -+ -+ gcry_md_hash_buffer (algo, hash, data, datalen); - /* Note that we can't simply use %b with HASH to build the - S-expression, because that might yield a negative value. */ -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -2138,7 +2299,6 @@ run_dsa_verify (const void *data, size_t - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); - s_sig = read_sexp_from_file (sigfile); - - err = gcry_pk_verify (s_sig, s_data, s_key); -@@ -2304,7 +2464,7 @@ usage (int show_help) - "MODE:\n" - " encrypt, decrypt, digest, random, hmac-sha,\n" - " rsa-{derive,gen,sign,verify},\n" -- " dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" -+ " dsa-{pq-gen,g-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" - "OPTIONS:\n" - " --verbose Print additional information\n" - " --binary Input and output is in binary form\n" -@@ -2315,6 +2475,7 @@ usage (int show_help) - " --algo NAME Use algorithm NAME\n" - " --curve NAME Select ECC curve spec NAME\n" - " --keysize N Use a keysize of N bits\n" -+ " --qize N Use a DSA q parameter size of N bits\n" - " --signature NAME Take signature from file NAME\n" - " --chunk N Read in chunks of N bytes (implies --binary)\n" - " --pkcs1 Use PKCS#1 encoding\n" -@@ -2344,6 +2505,7 @@ main (int argc, char **argv) - const char *dt_string = NULL; - const char *algo_string = NULL; - const char *keysize_string = NULL; -+ const char *qsize_string = NULL; - const char *signature_string = NULL; - FILE *input; - void *data; -@@ -2437,6 +2599,14 @@ main (int argc, char **argv) - keysize_string = *argv; - argc--; argv++; - } -+ else if (!strcmp (*argv, "--qsize")) -+ { -+ argc--; argv++; -+ if (!argc) -+ usage (0); -+ qsize_string = *argv; -+ argc--; argv++; -+ } - else if (!strcmp (*argv, "--signature")) - { - argc--; argv++; -@@ -2792,23 +2962,49 @@ main (int argc, char **argv) - } - else if (!strcmp (mode_string, "dsa-pqg-gen")) - { -- int keysize; -+ int keysize, qsize; -+ -+ keysize = keysize_string? atoi (keysize_string) : 0; -+ if (keysize < 1024 || keysize > 3072) -+ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ run_dsa_pqg_gen (keysize, qsize, datalen? data:NULL, datalen); -+ } -+ else if (!strcmp (mode_string, "dsa-g-gen")) -+ { -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ if (!key_string) -+ die ("option --key containing pq domain parameters is required in this mode\n"); -+ run_dsa_g_gen (keysize, qsize, key_string); -+ } -+ else if (!strcmp (mode_string, "dsa-gen-key")) -+ { -+ if (!key_string) -+ die ("option --key containing pqg domain parameters is required in this mode\n"); -+ run_dsa_gen_key (key_string); - } - else if (!strcmp (mode_string, "dsa-gen")) - { -- int keysize; -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); - if (!key_string) - die ("option --key is required in this mode\n"); -- run_dsa_gen (keysize, key_string); -+ run_dsa_gen (keysize, qsize, key_string); - } - else if (!strcmp (mode_string, "dsa-sign")) - { diff --git a/libgcrypt.spec b/libgcrypt.spec index f09a85d..3dd4420 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -27,8 +27,6 @@ Patch2: libgcrypt-1.8.5-use-fipscheck.patch Patch5: libgcrypt-1.8.4-fips-keygen.patch # fix the tests to work correctly in the FIPS mode Patch6: libgcrypt-1.9.3-fips-tests.patch -# update the CAVS tests -Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness Patch11: libgcrypt-1.8.4-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) @@ -82,7 +80,6 @@ applications using libgcrypt. %patch2 -p1 -b .use-fipscheck %patch5 -p1 -b .fips-keygen %patch6 -p1 -b .tests-fipsmode -%patch7 -p1 -b .cavs %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt %patch18 -p1 -b .fips-ctor From aff6b907cfe5498f9ca030f8db8621b59c76c9e8 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jan 2022 16:16:00 +0000 Subject: [PATCH 170/214] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3dd4420..9880c7f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.4 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -196,6 +196,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Jan 20 2022 Fedora Release Engineering - 1.9.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Mon Aug 23 2021 Jakub Jelen - 1.9.4-1 - New upstream release (#1996467) From 364af5a45153c9e9e07d7dbc0829a22aabef9320 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 2 Feb 2022 10:57:27 +0100 Subject: [PATCH 171/214] libgcrypt-1.10.0-1 --- .gitignore | 2 + curves.c | 271 ---- ecc-curves.c | 1483 ------------------ hobble-libgcrypt | 11 - keygrip.c | 341 ---- libgcrypt-1.10.0-disable-brainpool.patch | 239 +++ libgcrypt-1.6.1-mpicoder-gccopt.patch | 104 -- libgcrypt-1.8.3-fips-ctor.patch | 73 - libgcrypt-1.8.3-md-fips-enforce.patch | 37 - libgcrypt-1.8.4-fips-keygen.patch | 64 - libgcrypt-1.8.4-use-poll.patch | 77 - libgcrypt-1.8.5-fips-module.patch | 139 -- libgcrypt-1.8.5-getrandom.patch | 277 ---- libgcrypt-1.8.5-intel-cet.patch | 34 - libgcrypt-1.8.5-use-fipscheck.patch | 77 - libgcrypt-1.9.3-fips-tests.patch | 1804 ---------------------- libgcrypt.spec | 97 +- random.conf | 4 - sources | 3 +- 19 files changed, 277 insertions(+), 4860 deletions(-) delete mode 100644 curves.c delete mode 100644 ecc-curves.c delete mode 100755 hobble-libgcrypt delete mode 100644 keygrip.c create mode 100644 libgcrypt-1.10.0-disable-brainpool.patch delete mode 100644 libgcrypt-1.6.1-mpicoder-gccopt.patch delete mode 100644 libgcrypt-1.8.3-fips-ctor.patch delete mode 100644 libgcrypt-1.8.3-md-fips-enforce.patch delete mode 100644 libgcrypt-1.8.4-fips-keygen.patch delete mode 100644 libgcrypt-1.8.4-use-poll.patch delete mode 100644 libgcrypt-1.8.5-fips-module.patch delete mode 100644 libgcrypt-1.8.5-getrandom.patch delete mode 100644 libgcrypt-1.8.5-intel-cet.patch delete mode 100644 libgcrypt-1.8.5-use-fipscheck.patch delete mode 100644 libgcrypt-1.9.3-fips-tests.patch delete mode 100644 random.conf diff --git a/.gitignore b/.gitignore index 870812f..1bb23eb 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.9.2-hobbled.tar.xz /libgcrypt-1.9.3-hobbled.tar.xz /libgcrypt-1.9.4-hobbled.tar.xz +/libgcrypt-1.10.0.tar.bz2 +/libgcrypt-1.10.0.tar.bz2.sig diff --git a/curves.c b/curves.c deleted file mode 100644 index 1b190d1..0000000 --- a/curves.c +++ /dev/null @@ -1,271 +0,0 @@ -/* curves.c - ECC curves regression tests - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * This file is part of Libgcrypt. - * - * Libgcrypt 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. - * - * Libgcrypt 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 program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -#include "../src/gcrypt-int.h" - - -#define PGM "curves" -#include "t-common.h" - -/* Number of curves defined in ../cipger/ecc-curves.c */ -#define N_CURVES 20 - -/* A real world sample public key. */ -static char const sample_key_1[] = -"(public-key\n" -" (ecdsa\n" -" (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)\n" -" (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)\n" -" (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)\n" -" (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n" -" (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n" -" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n" -" (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE" - "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n" -" ))"; -static char const sample_key_1_curve[] = "NIST P-256"; -static unsigned int sample_key_1_nbits = 256; - -static void -list_curves (void) -{ - int idx; - const char *name; - unsigned int nbits; - - for (idx=0; (name = gcry_pk_get_curve (NULL, idx, &nbits)); idx++) - { - if (verbose) - printf ("%s - %u bits\n", name, nbits); - } - if (idx != N_CURVES) - fail ("expected %d curves but got %d\n", N_CURVES, idx); - if (gcry_pk_get_curve (NULL, -1, NULL)) - fail ("curve iteration failed\n"); -} - - -static void -check_matching (void) -{ - gpg_error_t err; - gcry_sexp_t key; - const char *name; - unsigned int nbits; - - err = gcry_sexp_new (&key, sample_key_1, 0, 1); - if (err) - die ("parsing s-expression string failed: %s\n", gpg_strerror (err)); - name = gcry_pk_get_curve (key, 0, &nbits); - if (!name) - fail ("curve name not found for sample_key_1\n"); - else if (strcmp (name, sample_key_1_curve)) - fail ("expected curve name %s but got %s for sample_key_1\n", - sample_key_1_curve, name); - else if (nbits != sample_key_1_nbits) - fail ("expected curve size %u but got %u for sample_key_1\n", - sample_key_1_nbits, nbits); - - gcry_sexp_release (key); -} - - -static void -check_get_params (void) -{ - static struct { - int algo; - const char *name; - int error_expected; - } tv[] = - { - { GCRY_PK_ECC, "Ed25519" }, - { GCRY_PK_ECC, "1.3.6.1.4.1.11591.15.1" }, - { GCRY_PK_ECC, "1.3.101.112" }, - - { GCRY_PK_ECC, "Curve25519" }, - { GCRY_PK_ECC, "1.3.6.1.4.1.3029.1.5.1" }, - { GCRY_PK_ECC, "1.3.101.110" }, - { GCRY_PK_ECC, "X25519" }, - - { GCRY_PK_ECC, "Ed448" }, - { GCRY_PK_ECC, "X448" }, - { GCRY_PK_ECC, "1.3.101.113" }, - { GCRY_PK_ECC, "1.3.101.111" }, - - { GCRY_PK_ECC, "NIST P-192" }, - { GCRY_PK_ECC, "1.2.840.10045.3.1.1" }, - { GCRY_PK_ECC, "prime192v1" }, - { GCRY_PK_ECC, "secp192r1" }, - { GCRY_PK_ECC, "nistp192" }, - - { GCRY_PK_ECC, "NIST P-224" }, - { GCRY_PK_ECC, "secp224r1" }, - { GCRY_PK_ECC, "1.3.132.0.33" }, - { GCRY_PK_ECC, "nistp224" }, - - { GCRY_PK_ECC, "NIST P-256" }, - { GCRY_PK_ECC, "1.2.840.10045.3.1.7" }, - { GCRY_PK_ECC, "prime256v1" }, - { GCRY_PK_ECC, "secp256r1" }, - { GCRY_PK_ECC, "nistp256" }, - - { GCRY_PK_ECC, "NIST P-384" }, - { GCRY_PK_ECC, "secp384r1" }, - { GCRY_PK_ECC, "1.3.132.0.34" }, - { GCRY_PK_ECC, "nistp384" }, - - { GCRY_PK_ECC, "NIST P-521" }, - { GCRY_PK_ECC, "secp521r1" }, - { GCRY_PK_ECC, "1.3.132.0.35" }, - { GCRY_PK_ECC, "nistp521" }, - - { GCRY_PK_ECC, "GOST2001-test" }, - { GCRY_PK_ECC, "1.2.643.2.2.35.0" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "1.2.643.2.2.35.1" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, - { GCRY_PK_ECC, "1.2.643.2.2.35.2" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "1.2.643.2.2.35.3" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-XchA" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-XchB" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "1.2.643.2.2.36.0" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "1.2.643.2.2.36.1" }, - - /* Noet that GOST2012-256-tc26-A" is only in the curve alias - * list but has no parameter entry. */ - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.2" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "GOST2012-256-tc26-B" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.3" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, - { GCRY_PK_ECC, "GOST2012-256-tc26-C" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.4" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "GOST2012-256-tc26-D" }, - - { GCRY_PK_ECC, "GOST2012-512-test" }, - { GCRY_PK_ECC, "GOST2012-test" }, - { GCRY_PK_ECC, "GOST2012-512-test" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.0" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-A" }, - { GCRY_PK_ECC, "GOST2012-tc26-A" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-B" }, - { GCRY_PK_ECC, "GOST2012-tc26-B" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-A" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.1" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-B" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.2" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-C" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.3" }, - - { GCRY_PK_ECC, "secp256k1" }, - { GCRY_PK_ECC, "1.3.132.0.10" }, - - { GCRY_PK_ECC, "sm2p256v1" }, - { GCRY_PK_ECC, "1.2.156.10197.1.301" }, - - /* Check also the ECC algo mapping. */ - { GCRY_PK_ECDSA, "Ed25519" }, - { GCRY_PK_EDDSA, "Ed25519" }, - { GCRY_PK_ECDH, "Ed25519" }, - { GCRY_PK_ECDSA, "Curve25519" }, - { GCRY_PK_EDDSA, "Curve25519" }, - { GCRY_PK_ECDH, "Curve25519" }, - { GCRY_PK_ECC, "NoSuchCurve", 1 }, - { GCRY_PK_RSA, "rsa", 1 }, - { GCRY_PK_ELG, "elg", 1 }, - { GCRY_PK_DSA, "dsa", 1 } - }; - int idx; - gcry_sexp_t param; - const char *name; - - param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_1_curve); - if (!param) - fail ("error gerring parameters for `%s'\n", sample_key_1_curve); - - name = gcry_pk_get_curve (param, 0, NULL); - if (!name) - fail ("get_param: curve name not found for sample_key_1\n"); - else if (strcmp (name, sample_key_1_curve)) - fail ("get_param: expected curve name %s but got %s for sample_key_1\n", - sample_key_1_curve, name); - - gcry_sexp_release (param); - - /* Some simple tests */ - for (idx=0; idx < DIM (tv); idx++) - { - param = gcry_pk_get_param (tv[idx].algo, tv[idx].name); - if (!param) - { - if (!tv[idx].error_expected) - fail ("get_param: test %d (%s) failed\n", idx, tv[idx].name); - } - else - { - if (tv[idx].error_expected) - fail ("get_param: test %d (%s) failed (error expected)\n", - idx, tv[idx].name); - } - gcry_sexp_release (param); - } -} - - -int -main (int argc, char **argv) -{ - if (argc > 1 && !strcmp (argv[1], "--verbose")) - verbose = 1; - else if (argc > 1 && !strcmp (argv[1], "--debug")) - verbose = debug = 1; - - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - - xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - list_curves (); - check_matching (); - check_get_params (); - - return error_count ? 1 : 0; -} diff --git a/ecc-curves.c b/ecc-curves.c deleted file mode 100644 index 5236b19..0000000 --- a/ecc-curves.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* ecc-curves.c - Elliptic Curve parameter mangement - * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. - * Copyright (C) 2013 g10 Code GmbH - * - * This file is part of Libgcrypt. - * - * Libgcrypt 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. - * - * Libgcrypt 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 program; if not, see . - */ - -#include -#include -#include -#include -#include - -#include "g10lib.h" -#include "mpi.h" -#include "mpi-internal.h" -#include "cipher.h" -#include "context.h" -#include "ec-context.h" -#include "pubkey-internal.h" -#include "ecc-common.h" - - -static gpg_err_code_t -point_from_keyparam (gcry_mpi_point_t *r_a, - gcry_sexp_t keyparam, const char *name, mpi_ec_t ec); - -/* This tables defines aliases for curve names. */ -static const struct -{ - const char *name; /* Our name. */ - const char *other; /* Other name. */ -} curve_aliases[] = - { - { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, /* OpenPGP */ - { "Ed25519", "1.3.101.112" }, /* rfc8410 */ - - { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, /* OpenPGP */ - { "Curve25519", "1.3.101.110" }, /* rfc8410 */ - { "Curve25519", "X25519" }, /* rfc8410 */ - - { "Ed448", "1.3.101.113" }, /* rfc8410 */ - { "X448", "1.3.101.111" }, /* rfc8410 */ - - { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */ - { "NIST P-192", "prime192v1" }, /* X9.62 name. */ - { "NIST P-192", "secp192r1" }, /* SECP name. */ - { "NIST P-192", "nistp192" }, /* rfc5656. */ - - { "NIST P-224", "secp224r1" }, - { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */ - { "NIST P-224", "nistp224" }, /* rfc5656. */ - - { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */ - { "NIST P-256", "prime256v1" }, - { "NIST P-256", "secp256r1" }, - { "NIST P-256", "nistp256" }, /* rfc5656. */ - - { "NIST P-384", "secp384r1" }, - { "NIST P-384", "1.3.132.0.34" }, - { "NIST P-384", "nistp384" }, /* rfc5656. */ - - { "NIST P-521", "secp521r1" }, - { "NIST P-521", "1.3.132.0.35" }, - { "NIST P-521", "nistp521" }, /* rfc5656. */ - - { "GOST2001-test", "1.2.643.2.2.35.0" }, - { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" }, - { "GOST2001-CryptoPro-B", "1.2.643.2.2.35.2" }, - { "GOST2001-CryptoPro-C", "1.2.643.2.2.35.3" }, - { "GOST2001-CryptoPro-A", "GOST2001-CryptoPro-XchA" }, - { "GOST2001-CryptoPro-C", "GOST2001-CryptoPro-XchB" }, - { "GOST2001-CryptoPro-A", "1.2.643.2.2.36.0" }, - { "GOST2001-CryptoPro-C", "1.2.643.2.2.36.1" }, - - { "GOST2012-256-tc26-A", "1.2.643.7.1.2.1.1.1" }, - { "GOST2001-CryptoPro-A", "1.2.643.7.1.2.1.1.2" }, - { "GOST2001-CryptoPro-A", "GOST2012-256-tc26-B" }, - { "GOST2001-CryptoPro-B", "1.2.643.7.1.2.1.1.3" }, - { "GOST2001-CryptoPro-B", "GOST2012-256-tc26-C" }, - { "GOST2001-CryptoPro-C", "1.2.643.7.1.2.1.1.4" }, - { "GOST2001-CryptoPro-C", "GOST2012-256-tc26-D" }, - - { "GOST2012-512-test", "GOST2012-test" }, - { "GOST2012-512-test", "1.2.643.7.1.2.1.2.0" }, - { "GOST2012-512-tc26-A", "GOST2012-tc26-A" }, - { "GOST2012-512-tc26-B", "GOST2012-tc26-B" }, - { "GOST2012-512-tc26-A", "1.2.643.7.1.2.1.2.1" }, - { "GOST2012-512-tc26-B", "1.2.643.7.1.2.1.2.2" }, - { "GOST2012-512-tc26-C", "1.2.643.7.1.2.1.2.3" }, - - { "secp256k1", "1.3.132.0.10" }, - - { "sm2p256v1", "1.2.156.10197.1.301" }, - - { NULL, NULL} - }; - - -typedef struct -{ - const char *desc; /* Description of the curve. */ - unsigned int nbits; /* Number of bits. */ - unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */ - - /* The model describing this curve. This is mainly used to select - the group equation. */ - enum gcry_mpi_ec_models model; - - /* The actual ECC dialect used. This is used for curve specific - optimizations and to select encodings etc. */ - enum ecc_dialects dialect; - - const char *p; /* The prime defining the field. */ - const char *a, *b; /* The coefficients. For Twisted Edwards - Curves b is used for d. For Montgomery - Curves (a,b) has ((A-2)/4,B^-1). */ - const char *n; /* The order of the base point. */ - const char *g_x, *g_y; /* Base point. */ - unsigned int h; /* Cofactor. */ -} ecc_domain_parms_t; - - -/* This static table defines all available curves. */ -static const ecc_domain_parms_t domain_parms[] = - { - { - /* (-x^2 + y^2 = 1 + dx^2y^2) */ - "Ed25519", 255, 0, - MPI_EC_EDWARDS, ECC_DIALECT_ED25519, - "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "-0x01", - "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", - "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", - "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658", - 8 - }, - { - /* (y^2 = x^3 + 486662*x^2 + x) */ - "Curve25519", 255, 0, - MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD, - "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "0x01DB41", - "0x01", - "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", - "0x0000000000000000000000000000000000000000000000000000000000000009", - "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9", - 8 - /* Note: As per RFC-7748 errata eid4730 the g_y value should be - * "0x5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14" - * but that breaks the keygrip. The new value is recovered in - * the function _gcry_ecc_fill_in_curve. See bug #4712. - */ - }, - { - /* (x^2 + y^2 = 1 + dx^2y^2) */ - "Ed448", 448, 0, - MPI_EC_EDWARDS, ECC_DIALECT_SAFECURVE, - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "0x01", - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756", - "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3", - "0x4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324" - "A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E", - "0x693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E" - "05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14", - 4, - }, - { - /* (y^2 = x^3 + 156326*x^2 + x) */ - "X448", 448, 0, - MPI_EC_MONTGOMERY, ECC_DIALECT_SAFECURVE, - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "0x98A9", - "0x01", - "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3", - "0x00000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000000000000005", - "0x7D235D1295F5B1F66C98AB6E58326FCECBAE5D34F55545D060F75DC2" - "8DF3F6EDB8027E2346430D211312C4B150677AF76FD7223D457B5B1A", - 4, - }, -#if 0 /* No real specs yet found. */ - { - /* x^2 + y^2 = 1 + 3617x^2y^2 mod 2^414 - 17 */ - "Curve3617", - "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF", - MPI_EC_EDWARDS, 0, - "0x01", - "0x0e21", - "0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB3CC92414CF" - "706022B36F1C0338AD63CF181B0E71A5E106AF79", - "0x1A334905141443300218C0631C326E5FCD46369F44C03EC7F57FF35498A4AB4D" - "6D6BA111301A73FAA8537C64C4FD3812F3CBC595", - "0x22", - 8 - }, -#endif /*0*/ - { - "NIST P-192", 192, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffeffffffffffffffff", - "0xfffffffffffffffffffffffffffffffefffffffffffffffc", - "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", - "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", - - "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", - "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", - 1 - }, - { - "NIST P-224", 224, 1, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xffffffffffffffffffffffffffffffff000000000000000000000001", - "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", - "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", - "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , - - "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", - 1 - }, - { - "NIST P-256", 256, 1, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", - "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", - "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - - "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", - 1 - }, - { - "NIST P-384", 384, 1, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000ffffffff", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000fffffffc", - "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" - "c656398d8a2ed19d2a85c8edd3ec2aef", - "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" - "581a0db248b0a77aecec196accc52973", - - "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" - "5502f25dbf55296c3a545e3872760ab7", - "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f", - 1 - }, - { - "NIST P-521", 521, 1, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", - "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" - "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - - "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" - "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", - "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" - "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", - 1 - }, - - { - "GOST2001-test", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x8000000000000000000000000000000000000000000000000000000000000431", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x5fbff498aa938ce739b8e022fbafef40563f6e6a3472fc2a514c0ce9dae23b7e", - "0x8000000000000000000000000000000150fe8a1892976154c59cfc193accf5b3", - - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8", - 1 - }, - { - "GOST2001-CryptoPro-A", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd94", - "0x00000000000000000000000000000000000000000000000000000000000000a6", - "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14", - 1 - }, - { - "GOST2001-CryptoPro-B", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x8000000000000000000000000000000000000000000000000000000000000c99", - "0x8000000000000000000000000000000000000000000000000000000000000c96", - "0x3e1af419a269a5f866a7d3c25c3df80ae979259373ff2b182f49d4ce7e1bbc8b", - "0x800000000000000000000000000000015f700cfff1a624e5e497161bcc8a198f", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc", - 1 - }, - { - "GOST2001-CryptoPro-C", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d759b", - "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d7598", - "0x000000000000000000000000000000000000000000000000000000000000805a", - "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67", - 1 - }, - { - "GOST2012-256-A", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97", - "0xc2173f1513981673af4892c23035a27ce25e2013bf95aa33b22c656f277e7335", - "0x295f9bae7428ed9ccc20e7c359a9d41a22fccd9108e17bf7ba9337a6f8ae9513", - "0x400000000000000000000000000000000fd8cddfc87b6635c115af556c360c67", - "0x91e38443a5e82c0d880923425712b2bb658b9196932e02c78b2582fe742daa28", - "0x32879423ab1a0375895786c4bb46e9565fde0b5344766740af268adb32322e5c", - 4 - }, - { - "GOST2012-512-test", 511, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" - "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x1cff0806a31116da29d8cfa54e57eb748bc5f377e49400fdd788b649eca1ac4" - "361834013b2ad7322480a89ca58e0cf74bc9e540c2add6897fad0a3084f302adc", - "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" - "a82f2d7ecb1dbac719905c5eecc423f1d86e25edbe23c595d644aaf187e6e6df", - - "0x24d19cc64572ee30f396bf6ebbfd7a6c5213b3b3d7057cc825f91093a68cd762" - "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a", - "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2" - "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e", - 1 - }, - { - "GOST2012-512-tc26-A", 512, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7", - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc4", - "0xe8c2505dedfc86ddc1bd0b2b6667f1da34b82574761cb0e879bd081cfd0b6265" - "ee3cb090f30d27614cb4574010da90dd862ef9d4ebee4761503190785a71c760", - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "27e69532f48d89116ff22b8d4e0560609b4b38abfad2b85dcacdb1411f10b275", - "0x0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000003", - "0x7503cfe87a836ae3a61b8816e25450e6ce5e1c93acf1abc1778064fdcbefa921" - "df1626be4fd036e93d75e6a50e3a41e98028fe5fc235f5b889a589cb5215f2a4", - 1 - }, - { - "GOST2012-512-tc26-B", 512, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x8000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000006f", - "0x8000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000006c", - "0x687d1b459dc841457e3e06cf6f5e2517b97c7d614af138bcbf85dc806c4b289f" - "3e965d2db1416d217f8b276fad1ab69c50f78bee1fa3106efb8ccbc7c5140116", - "0x8000000000000000000000000000000000000000000000000000000000000001" - "49a1ec142565a545acfdb77bd9d40cfa8b996712101bea0ec6346c54374f25bd", - "0x0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000002", - "0x1a8f7eda389b094c2c071e3647a8940f3c123b697578c213be6dd9e6c8ec7335" - "dcb228fd1edf4a39152cbcaaf8c0398828041055f94ceeec7e21340780fe41bd", - 1 - }, - { - "GOST2012-512-tc26-C", 512, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7", - "0xdc9203e514a721875485a529d2c722fb187bc8980eb866644de41c68e1430645" - "46e861c0e2c9edd92ade71f46fcf50ff2ad97f951fda9f2a2eb6546f39689bd3", - "0xb4c4ee28cebc6c2c8ac12952cf37f16ac7efb6a9f69f4b57ffda2e4f0de5ade0" - "38cbc2fff719d2c18de0284b8bfef3b52b8cc7a5f5bf0a3c8d2319a5312557e1", - "0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "c98cdba46506ab004c33a9ff5147502cc8eda9e7a769a12694623cef47f023ed", - "0xe2e31edfc23de7bdebe241ce593ef5de2295b7a9cbaef021d385f7074cea043a" - "a27272a7ae602bf2a7b9033db9ed3610c6fb85487eae97aac5bc7928c1950148", - "0xf5ce40d95b5eb899abbccff5911cb8577939804d6527378b8c108c3d2090ff9be" - "18e2d33e3021ed2ef32d85822423b6304f726aa854bae07d0396e9a9addc40f", - 4 - }, - - { - "secp256k1", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", - "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", - 1 - }, - - { - "sm2p256v1", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffeffffffffffffffffffffffffffffffff00000000ffffffffffffffff", - "0xfffffffeffffffffffffffffffffffffffffffff00000000fffffffffffffffc", - "0x28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93", - "0xfffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123", - "0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7", - "0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0", - 1 - }, - - { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } - }; - - - - -/* Return a copy of POINT. */ -static gcry_mpi_point_t -point_copy (gcry_mpi_point_t point) -{ - gcry_mpi_point_t newpoint; - - if (point) - { - newpoint = mpi_point_new (0); - point_set (newpoint, point); - } - else - newpoint = NULL; - return newpoint; -} - - -/* Helper to scan a hex string. */ -static gcry_mpi_t -scanval (const char *string) -{ - gpg_err_code_t rc; - gcry_mpi_t val; - - rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); - if (rc) - log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc)); - return val; -} - - -/* Return the index of the domain_parms table for a curve with NAME. - Return -1 if not found. */ -static int -find_domain_parms_idx (const char *name) -{ - int idx, aliasno; - - /* First check our native curves. */ - for (idx = 0; domain_parms[idx].desc; idx++) - if (!strcmp (name, domain_parms[idx].desc)) - return idx; - - /* If not found consult the alias table. */ - if (!domain_parms[idx].desc) - { - for (aliasno = 0; curve_aliases[aliasno].name; aliasno++) - if (!strcmp (name, curve_aliases[aliasno].other)) - break; - if (curve_aliases[aliasno].name) - { - for (idx = 0; domain_parms[idx].desc; idx++) - if (!strcmp (curve_aliases[aliasno].name, domain_parms[idx].desc)) - return idx; - } - } - - return -1; -} - - -/* Generate the crypto system setup. This function takes the NAME of - a curve or the desired number of bits and stores at R_CURVE the - parameters of the named curve or those of a suitable curve. If - R_NBITS is not NULL, the chosen number of bits is stored there. - NULL may be given for R_CURVE, if the value is not required and for - example only a quick test for availability is desired. Note that - the curve fields should be initialized to zero because fields which - are not NULL are skipped. */ -gpg_err_code_t -_gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, - elliptic_curve_t *curve, unsigned int *r_nbits) -{ - int idx; - const char *resname = NULL; /* Set to a found curve name. */ - - if (name) - idx = find_domain_parms_idx (name); - else - { - for (idx = 0; domain_parms[idx].desc; idx++) - if (nbits == domain_parms[idx].nbits - && domain_parms[idx].model == MPI_EC_WEIERSTRASS) - break; - if (!domain_parms[idx].desc) - idx = -1; - } - if (idx < 0) - return GPG_ERR_UNKNOWN_CURVE; - - resname = domain_parms[idx].desc; - - /* In fips mode we only support NIST curves. Note that it is - possible to bypass this check by specifying the curve parameters - directly. */ - if (fips_mode () && !domain_parms[idx].fips ) - return GPG_ERR_NOT_SUPPORTED; - - switch (domain_parms[idx].model) - { - case MPI_EC_WEIERSTRASS: - case MPI_EC_EDWARDS: - case MPI_EC_MONTGOMERY: - break; - default: - return GPG_ERR_BUG; - } - - - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - - if (curve) - { - curve->model = domain_parms[idx].model; - curve->dialect = domain_parms[idx].dialect; - if (!curve->p) - curve->p = scanval (domain_parms[idx].p); - if (!curve->a) - { - curve->a = scanval (domain_parms[idx].a); - if (curve->a->sign) - { - mpi_resize (curve->a, curve->p->nlimbs); - _gcry_mpih_sub_n (curve->a->d, curve->p->d, - curve->a->d, curve->p->nlimbs); - curve->a->nlimbs = curve->p->nlimbs; - curve->a->sign = 0; - } - } - if (!curve->b) - { - curve->b = scanval (domain_parms[idx].b); - if (curve->b->sign) - { - mpi_resize (curve->b, curve->p->nlimbs); - _gcry_mpih_sub_n (curve->b->d, curve->p->d, - curve->b->d, curve->p->nlimbs); - curve->b->nlimbs = curve->p->nlimbs; - curve->b->sign = 0; - } - } - if (!curve->n) - curve->n = scanval (domain_parms[idx].n); - if (!curve->G.x) - curve->G.x = scanval (domain_parms[idx].g_x); - if (!curve->G.y) - curve->G.y = scanval (domain_parms[idx].g_y); - curve->h = domain_parms[idx].h; - - /* - * In the constants of domain_parms, we defined Curve25519 - * domain parameters as the ones in RFC-7748 before the errata - * (eid4730). To keep the computation having exact same values, - * we recover the new value of g_y, here. - */ - if (!strcmp (resname, "Curve25519")) - mpi_sub (curve->G.y, curve->p, curve->G.y); - - if (!curve->G.z) - curve->G.z = mpi_alloc_set_ui (1); - if (!curve->name) - curve->name = resname; - } - - return 0; -} - - -/* Give the name of the curve NAME, store the curve parameters into P, - A, B, G, and N if they point to NULL value. Note that G is - returned in standard uncompressed format. Also update MODEL and - DIALECT if they are not NULL. */ -gpg_err_code_t -_gcry_ecc_update_curve_param (const char *name, - enum gcry_mpi_ec_models *model, - enum ecc_dialects *dialect, - gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, - gcry_mpi_t *g, gcry_mpi_t *n) -{ - int idx; - - idx = find_domain_parms_idx (name); - if (idx < 0) - return GPG_ERR_UNKNOWN_CURVE; - - if (g) - { - char *buf; - size_t len; - - len = 4; - len += strlen (domain_parms[idx].g_x+2); - len += strlen (domain_parms[idx].g_y+2); - len++; - buf = xtrymalloc (len); - if (!buf) - return gpg_err_code_from_syserror (); - strcpy (stpcpy (stpcpy (buf, "0x04"), domain_parms[idx].g_x+2), - domain_parms[idx].g_y+2); - _gcry_mpi_release (*g); - *g = scanval (buf); - xfree (buf); - } - if (model) - *model = domain_parms[idx].model; - if (dialect) - *dialect = domain_parms[idx].dialect; - if (p) - { - _gcry_mpi_release (*p); - *p = scanval (domain_parms[idx].p); - } - if (a) - { - _gcry_mpi_release (*a); - *a = scanval (domain_parms[idx].a); - } - if (b) - { - _gcry_mpi_release (*b); - *b = scanval (domain_parms[idx].b); - } - if (n) - { - _gcry_mpi_release (*n); - *n = scanval (domain_parms[idx].n); - } - return 0; -} - - -/* Return the name matching the parameters in PKEY. This works only - with curves described by the Weierstrass equation. */ -const char * -_gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) -{ - gpg_err_code_t rc; - const char *result = NULL; - elliptic_curve_t E; - gcry_mpi_point_t G = NULL; - gcry_mpi_t tmp = NULL; - int idx; - - memset (&E, 0, sizeof E); - - if (r_nbits) - *r_nbits = 0; - - if (!keyparms) - { - idx = iterator; - if (idx >= 0 && idx < DIM (domain_parms)) - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - } - return result; - } - - - /* - * Extract the curve parameters.. - */ - rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "pabn", - &E.p, &E.a, &E.b, &E.n, NULL)); - if (rc == GPG_ERR_NO_OBJ) - { - /* This might be the second use case of checking whether a - specific curve given by name is supported. */ - gcry_sexp_t l1; - char *name; - - l1 = sexp_find_token (keyparms, "curve", 5); - if (!l1) - goto leave; /* No curve name parameter. */ - - name = sexp_nth_string (l1, 1); - sexp_release (l1); - if (!name) - goto leave; /* Name missing or out of core. */ - - idx = find_domain_parms_idx (name); - xfree (name); - if (idx >= 0) /* Curve found. */ - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - } - return result; - } - - if (rc) - goto leave; - - rc = point_from_keyparam (&G, keyparms, "g", NULL); - if (rc) - goto leave; - - _gcry_mpi_point_init (&E.G); - _gcry_mpi_point_set (&E.G, G->x, G->y, G->z); - - for (idx = 0; domain_parms[idx].desc; idx++) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].p); - if (mpi_cmp (tmp, E.p)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].a); - if (tmp->sign) - { - if (!mpi_cmpabs (tmp, E.a)) - /* For backward compatibility to <= libgcrypt 1.8, we - allow this match to support existing keys in SEXP. */ - ; - else - { - mpi_resize (tmp, E.p->nlimbs); - _gcry_mpih_sub_n (tmp->d, E.p->d, - tmp->d, E.p->nlimbs); - tmp->nlimbs = E.p->nlimbs; - tmp->sign = 0; - if (mpi_cmp (tmp, E.a)) - continue; - } - } - else if (mpi_cmp (tmp, E.a)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].b); - if (tmp->sign) - { - if (!mpi_cmpabs (tmp, E.b)) - /* Same for backward compatibility, see above. */ - ; - else - { - mpi_resize (tmp, E.p->nlimbs); - _gcry_mpih_sub_n (tmp->d, E.p->d, - tmp->d, E.p->nlimbs); - tmp->nlimbs = E.p->nlimbs; - tmp->sign = 0; - if (mpi_cmp (tmp, E.b)) - continue; - } - } - else if (mpi_cmp (tmp, E.b)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].n); - if (mpi_cmp (tmp, E.n)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (mpi_cmp (tmp, E.G.x)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (mpi_cmp (tmp, E.G.y)) - continue; - - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - break; - } - - leave: - _gcry_mpi_point_release (G); - _gcry_mpi_release (tmp); - _gcry_mpi_release (E.p); - _gcry_mpi_release (E.a); - _gcry_mpi_release (E.b); - _gcry_mpi_point_free_parts (&E.G); - _gcry_mpi_release (E.n); - return result; -} - - -/* Helper to extract an MPI from key parameters. */ -static gpg_err_code_t -mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name, - int opaque) -{ - gcry_err_code_t ec = 0; - gcry_sexp_t l1; - - l1 = sexp_find_token (keyparam, name, 0); - if (l1) - { - *r_a = sexp_nth_mpi (l1, 1, opaque? GCRYMPI_FMT_OPAQUE : GCRYMPI_FMT_USG); - sexp_release (l1); - if (!*r_a) - ec = GPG_ERR_INV_OBJ; - } - return ec; -} - -/* Helper to extract a point from key parameters. If no parameter - with NAME is found, the functions tries to find a non-encoded point - by appending ".x", ".y" and ".z" to NAME. ".z" is in this case - optional and defaults to 1. EC is the context which at this point - may not be fully initialized. */ -static gpg_err_code_t -point_from_keyparam (gcry_mpi_point_t *r_a, - gcry_sexp_t keyparam, const char *name, mpi_ec_t ec) -{ - gcry_err_code_t rc; - gcry_sexp_t l1; - gcry_mpi_point_t point; - - l1 = sexp_find_token (keyparam, name, 0); - if (l1) - { - gcry_mpi_t a; - - a = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE); - sexp_release (l1); - if (!a) - return GPG_ERR_INV_OBJ; - - point = mpi_point_new (0); - rc = _gcry_mpi_ec_decode_point (point, a, ec); - mpi_free (a); - if (rc) - { - mpi_point_release (point); - return rc; - } - } - else - { - char *tmpname; - gcry_mpi_t x = NULL; - gcry_mpi_t y = NULL; - gcry_mpi_t z = NULL; - - tmpname = xtrymalloc (strlen (name) + 2 + 1); - if (!tmpname) - return gpg_err_code_from_syserror (); - strcpy (stpcpy (tmpname, name), ".x"); - rc = mpi_from_keyparam (&x, keyparam, tmpname, 0); - if (rc) - { - xfree (tmpname); - return rc; - } - strcpy (stpcpy (tmpname, name), ".y"); - rc = mpi_from_keyparam (&y, keyparam, tmpname, 0); - if (rc) - { - mpi_free (x); - xfree (tmpname); - return rc; - } - strcpy (stpcpy (tmpname, name), ".z"); - rc = mpi_from_keyparam (&z, keyparam, tmpname, 0); - if (rc) - { - mpi_free (y); - mpi_free (x); - xfree (tmpname); - return rc; - } - if (!z) - z = mpi_set_ui (NULL, 1); - if (x && y) - point = mpi_point_snatch_set (NULL, x, y, z); - else - { - mpi_free (x); - mpi_free (y); - mpi_free (z); - point = NULL; - } - xfree (tmpname); - } - - if (point) - *r_a = point; - return 0; -} - - - -static gpg_err_code_t -mpi_ec_get_elliptic_curve (elliptic_curve_t *E, int *r_flags, - gcry_sexp_t keyparam, const char *curvename) -{ - gpg_err_code_t errc; - unsigned int nbits; - gcry_sexp_t l1; - - errc = _gcry_pk_util_get_nbits (keyparam, &nbits); - if (errc) - return errc; - - E->model = MPI_EC_WEIERSTRASS; - E->dialect = ECC_DIALECT_STANDARD; - E->h = 1; - - if (keyparam) - { - /* Parse an optional flags list. */ - l1 = sexp_find_token (keyparam, "flags", 0); - if (l1) - { - int flags = 0; - - errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL); - sexp_release (l1); - l1 = NULL; - if (errc) - goto leave; - - *r_flags |= flags; - } - - /* Parse the deprecated optional transient-key flag. */ - l1 = sexp_find_token (keyparam, "transient-key", 0); - if (l1) - { - *r_flags |= PUBKEY_FLAG_TRANSIENT_KEY; - sexp_release (l1); - } - - /* Check whether a curve name was given. */ - l1 = sexp_find_token (keyparam, "curve", 5); - - /* If we don't have a curve name or if override parameters have - explicitly been requested, parse them. */ - if (!l1 || (*r_flags & PUBKEY_FLAG_PARAM)) - { - gcry_mpi_point_t G = NULL; - gcry_mpi_t cofactor = NULL; - - errc = mpi_from_keyparam (&E->p, keyparam, "p", 0); - if (errc) - goto leave; - errc = mpi_from_keyparam (&E->a, keyparam, "a", 0); - if (errc) - goto leave; - errc = mpi_from_keyparam (&E->b, keyparam, "b", 0); - if (errc) - goto leave; - errc = point_from_keyparam (&G, keyparam, "g", NULL); - if (errc) - goto leave; - if (G) - { - _gcry_mpi_point_init (&E->G); - mpi_point_set (&E->G, G->x, G->y, G->z); - mpi_point_set (G, NULL, NULL, NULL); - mpi_point_release (G); - } - errc = mpi_from_keyparam (&E->n, keyparam, "n", 0); - if (errc) - goto leave; - errc = mpi_from_keyparam (&cofactor, keyparam, "h", 0); - if (errc) - goto leave; - if (cofactor) - { - mpi_get_ui (&E->h, cofactor); - mpi_free (cofactor); - } - } - } - else - l1 = NULL; /* No curvename. */ - - /* Check whether a curve parameter is available and use that to fill - in missing values. If no curve parameter is available try an - optional provided curvename. If only the curvename has been - given use that one. */ - if (l1 || curvename || nbits) - { - char *name; - - if (l1) - { - name = sexp_nth_string (l1, 1); - sexp_release (l1); - if (!name) - { - errc = GPG_ERR_INV_OBJ; /* Name missing or out of core. */ - goto leave; - } - } - else - name = NULL; - - errc = _gcry_ecc_fill_in_curve (nbits, name? name : curvename, E, NULL); - xfree (name); - if (errc) - goto leave; - } - - leave: - return errc; -} - -static gpg_err_code_t -mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags, - elliptic_curve_t *E, gcry_sexp_t keyparam) -{ - gpg_err_code_t errc = 0; - - ec->G = mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z); - E->G.x = NULL; - E->G.y = NULL; - E->G.z = NULL; - ec->n = E->n; - E->n = NULL; - ec->h = E->h; - ec->name = E->name; - - /* Now that we know the curve name we can look for the public key - Q. point_from_keyparam needs to know the curve parameters so - that it is able to use the correct decompression. Parsing - the private key D could have been done earlier but it is less - surprising if we do it here as well. */ - if (keyparam) - { - int is_opaque_bytes = ((ec->dialect == ECC_DIALECT_ED25519 - && (flags & PUBKEY_FLAG_EDDSA)) - || (ec->dialect == ECC_DIALECT_SAFECURVE)); - - errc = point_from_keyparam (&ec->Q, keyparam, "q", ec); - if (errc) - return errc; - errc = mpi_from_keyparam (&ec->d, keyparam, "d", is_opaque_bytes); - - /* Size of opaque bytes should match size of P. */ - if (!errc && ec->d && is_opaque_bytes) - { - unsigned int n = mpi_get_nbits (ec->d); - unsigned int len; - - len = (ec->nbits+7)/8; - /* EdDSA requires additional bit for sign. */ - if ((ec->nbits%8) == 0 && ec->model == MPI_EC_EDWARDS) - len++; - - if ((n+7)/8 != len) - { - if (ec->dialect == ECC_DIALECT_ED25519) - { - /* - * GnuPG (<= 2.2) or OpenPGP implementations with no - * SOS support may remove zeros at the beginning. - * Recover those zeros. - */ - /* - * Also, GnuPG (<= 2.2) may add additional zero at - * the beginning, when private key is moved from - * OpenPGP to gpg-agent. Remove such a zero-prefix. - */ - const unsigned char *buf; - unsigned char *value; - - buf = mpi_get_opaque (ec->d, &n); - if (!buf) - return GPG_ERR_INV_OBJ; - - value = xtrymalloc_secure (len); - if (!value) - return gpg_err_code_from_syserror (); - - if ((n+7)/8 < len) - /* Recover zeros. */ - { - memset (value, 0, len - (n+7)/8); - memcpy (value + len - (n+7)/8, buf, (n+7)/8); - } - else if ((n+7)/8 == len + 1) - /* Remove a zero. */ - memcpy (value, buf+1, len); - else - { - xfree (value); - return GPG_ERR_INV_OBJ; - } - - mpi_set_opaque (ec->d, value, len*8); - } - else - { - if (DBG_CIPHER) - log_debug ("scalar size (%d) != prime size (%d)", - (n+7)/8, len); - - errc = GPG_ERR_INV_OBJ; - } - } - } - } - - return errc; -} - -gpg_err_code_t -_gcry_mpi_ec_internal_new (mpi_ec_t *r_ec, int *r_flags, const char *name_op, - gcry_sexp_t keyparam, const char *curvename) -{ - gpg_err_code_t errc; - elliptic_curve_t E; - mpi_ec_t ec; - - *r_ec = NULL; - - memset (&E, 0, sizeof E); - errc = mpi_ec_get_elliptic_curve (&E, r_flags, keyparam, curvename); - if (errc) - goto leave; - - ec = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, *r_flags, - E.p, E.a, E.b); - if (!ec) - goto leave; - - errc = mpi_ec_setup_elliptic_curve (ec, *r_flags, &E, keyparam); - if (errc) - { - _gcry_mpi_ec_free (ec); - goto leave; - } - else - *r_ec = ec; - - if (!errc && DBG_CIPHER) - { - gcry_mpi_t mpi_q = NULL; - gcry_sexp_t l1; - char msg[80]; - - l1 = sexp_find_token (keyparam, "q", 0); - if (l1) - { - mpi_q = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE); - sexp_release (l1); - } - - log_debug ("%s info: %s/%s%s\n", name_op, - _gcry_ecc_model2str (ec->model), - _gcry_ecc_dialect2str (ec->dialect), - (*r_flags & PUBKEY_FLAG_EDDSA)? "+EdDSA" : ""); - if (ec->name) - log_debug ("%s name: %s\n", name_op, ec->name); - snprintf (msg, sizeof msg, "%s p", name_op); - log_printmpi (msg, ec->p); - snprintf (msg, sizeof msg, "%s a", name_op); - log_printmpi (msg, ec->a); - snprintf (msg, sizeof msg, "%s b", name_op); - log_printmpi (msg, ec->b); - snprintf (msg, sizeof msg, "%s g", name_op); - log_printpnt (msg, ec->G, NULL); - snprintf (msg, sizeof msg, "%s n", name_op); - log_printmpi (msg, ec->n); - log_debug ("%s h:+%02x\n", name_op, ec->h); - if (mpi_q) - { - snprintf (msg, sizeof msg, "%s q", name_op); - log_printmpi (msg, mpi_q); - mpi_free (mpi_q); - } - if (!fips_mode () && ec->d) - { - snprintf (msg, sizeof msg, "%s d", name_op); - log_printmpi (msg, ec->d); - } - } - - leave: - _gcry_ecc_curve_free (&E); - return errc; -} - -/* This function creates a new context for elliptic curve operations. - Either KEYPARAM or CURVENAME must be given. If both are given and - KEYPARAM has no curve parameter, CURVENAME is used to add missing - parameters. On success 0 is returned and the new context stored at - R_CTX. On error NULL is stored at R_CTX and an error code is - returned. The context needs to be released using - gcry_ctx_release. */ -gpg_err_code_t -_gcry_mpi_ec_new (gcry_ctx_t *r_ctx, - gcry_sexp_t keyparam, const char *curvename) -{ - gpg_err_code_t errc; - elliptic_curve_t E; - gcry_ctx_t ctx = NULL; - int flags = 0; - mpi_ec_t ec; - - *r_ctx = NULL; - - memset (&E, 0, sizeof E); - errc = mpi_ec_get_elliptic_curve (&E, &flags, keyparam, curvename); - if (errc) - goto leave; - - errc = _gcry_mpi_ec_p_new (&ctx, E.model, E.dialect, flags, E.p, E.a, E.b); - if (errc) - goto leave; - - ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); - errc = mpi_ec_setup_elliptic_curve (ec, flags, &E, keyparam); - if (errc) - goto leave; - - *r_ctx = ctx; - ctx = NULL; - - leave: - _gcry_ecc_curve_free (&E); - _gcry_ctx_release (ctx); - return errc; -} - - -/* Return the parameters of the curve NAME as an S-expression. */ -gcry_sexp_t -_gcry_ecc_get_param_sexp (const char *name) -{ - elliptic_curve_t E; - gcry_mpi_t pkey[5]; - gcry_sexp_t result; - - memset (&E, 0, sizeof E); - if (_gcry_ecc_fill_in_curve (0, name, &E, NULL)) - return NULL; - - pkey[0] = E.p; - pkey[1] = E.a; - pkey[2] = E.b; - pkey[3] = _gcry_ecc_ec2os (E.G.x, E.G.y, E.p); - pkey[4] = E.n; - - if (sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], E.h)) - result = NULL; - - _gcry_ecc_curve_free (&E); - _gcry_mpi_release (pkey[3]); - - return result; -} - - -/* Return an MPI (or opaque MPI) described by NAME and the context EC. - If COPY is true a copy is returned, if not a const MPI may be - returned. In any case mpi_free must be used. */ -gcry_mpi_t -_gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) -{ - if (!*name) - return NULL; - - if (!strcmp (name, "p") && ec->p) - return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p); - if (!strcmp (name, "a") && ec->a) - return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a); - if (!strcmp (name, "b") && ec->b) - return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); - if (!strcmp (name, "n") && ec->n) - return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); - if (!strcmp (name, "h")) - { - gcry_mpi_t h = _gcry_mpi_get_const (ec->h); - - return !copy? h : mpi_set (NULL, h); - } - if (!strcmp (name, "d") && ec->d) - return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); - - /* Return a requested point coordinate. */ - if (!strcmp (name, "g.x") && ec->G && ec->G->x) - return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x); - if (!strcmp (name, "g.y") && ec->G && ec->G->y) - return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y); - if (!strcmp (name, "q.x") && ec->Q && ec->Q->x) - return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x); - if (!strcmp (name, "q.y") && ec->Q && ec->Q->y) - return mpi_is_const (ec->Q->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y); - - /* If the base point has been requested, return it in standard - encoding. */ - if (!strcmp (name, "g") && ec->G) - return _gcry_mpi_ec_ec2os (ec->G, ec); - - /* If the public key has been requested, return it by default in - standard uncompressed encoding or if requested in other - encodings. */ - if (*name == 'q' && (!name[1] || name[1] == '@')) - { - /* If only the private key is given, compute the public key. */ - if (!ec->Q) - ec->Q = _gcry_ecc_compute_public (NULL, ec); - - if (!ec->Q) - return NULL; - - if (name[1] != '@') - return _gcry_mpi_ec_ec2os (ec->Q, ec); - - if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_EDWARDS) - { - unsigned char *encpk; - unsigned int encpklen; - - if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0, - &encpk, &encpklen)) - return mpi_set_opaque (NULL, encpk, encpklen*8); - } - } - - return NULL; -} - - -/* Return a point described by NAME and the context EC. */ -gcry_mpi_point_t -_gcry_ecc_get_point (const char *name, mpi_ec_t ec) -{ - if (!strcmp (name, "g") && ec->G) - return point_copy (ec->G); - if (!strcmp (name, "q")) - { - /* If only the private key is given, compute the public key. */ - if (!ec->Q) - ec->Q = _gcry_ecc_compute_public (NULL, ec); - - if (ec->Q) - return point_copy (ec->Q); - } - - return NULL; -} - - -/* Store the MPI NEWVALUE into the context EC under NAME. */ -gpg_err_code_t -_gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) -{ - gpg_err_code_t rc = 0; - - if (!*name) - ; - else if (!strcmp (name, "p")) - { - mpi_free (ec->p); - ec->p = mpi_copy (newvalue); - _gcry_mpi_ec_get_reset (ec); - } - else if (!strcmp (name, "a")) - { - mpi_free (ec->a); - ec->a = mpi_copy (newvalue); - _gcry_mpi_ec_get_reset (ec); - } - else if (!strcmp (name, "b")) - { - mpi_free (ec->b); - ec->b = mpi_copy (newvalue); - } - else if (!strcmp (name, "n")) - { - mpi_free (ec->n); - ec->n = mpi_copy (newvalue); - } - else if (!strcmp (name, "h")) - { - mpi_get_ui (&ec->h, newvalue); - } - else if (*name == 'q' && (!name[1] || name[1] == '@')) - { - if (newvalue) - { - if (!ec->Q) - ec->Q = mpi_point_new (0); - rc = _gcry_mpi_ec_decode_point (ec->Q, newvalue, ec); - } - if (rc || !newvalue) - { - _gcry_mpi_point_release (ec->Q); - ec->Q = NULL; - } - /* Note: We assume that Q matches d and thus do not reset d. */ - } - else if (!strcmp (name, "d")) - { - mpi_free (ec->d); - ec->d = mpi_copy (newvalue); - if (ec->d) - { - /* We need to reset the public key because it may not - anymore match. */ - _gcry_mpi_point_release (ec->Q); - ec->Q = NULL; - } - } - else - rc = GPG_ERR_UNKNOWN_NAME; - - return rc; -} - - -/* Store the point NEWVALUE into the context EC under NAME. */ -gpg_err_code_t -_gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec) -{ - if (!strcmp (name, "g")) - { - _gcry_mpi_point_release (ec->G); - ec->G = point_copy (newvalue); - } - else if (!strcmp (name, "q")) - { - _gcry_mpi_point_release (ec->Q); - ec->Q = point_copy (newvalue); - } - else - return GPG_ERR_UNKNOWN_NAME; - - return 0; -} diff --git a/hobble-libgcrypt b/hobble-libgcrypt deleted file mode 100755 index 1aa88dc..0000000 --- a/hobble-libgcrypt +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# Quit out if anything fails. -set -e -x - -# Clean out patent-or-otherwise-encumbered code. -# EC: ????????? ??/??/2015 - -rm -f cipher/ecc-curves.c -rm -f tests/curves.c -rm -f tests/keygrip.c diff --git a/keygrip.c b/keygrip.c deleted file mode 100644 index 56fbba8..0000000 --- a/keygrip.c +++ /dev/null @@ -1,341 +0,0 @@ -/* keygrip.c - verifies that keygrips are calculated as expected - * Copyright (C) 2005 Free Software Foundation, Inc. - * - * This file is part of Libgcrypt. - * - * Libgcrypt 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. - * - * Libgcrypt 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 program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#define PGM "keygrip" -#include "t-common.h" - -static int repetitions; - - - -static void -print_hex (const char *text, const void *buf, size_t n) -{ - const unsigned char *p = buf; - - fputs (text, stdout); - for (; n; n--, p++) - printf ("%02X", *p); - putchar ('\n'); -} - - - - -static struct -{ - int algo; - const char *key; - const unsigned char grip[20]; -} key_grips[] = - { - { - GCRY_PK_RSA, - "(private-key" - " (rsa" - " (n #00B6B509596A9ECABC939212F891E656A626BA07DA8521A9CAD4C08E640C04052FBB87F424EF1A0275A48A9299AC9DB69ABE3D0124E6C756B1F7DFB9B842D6251AEA6EE85390495CADA73D671537FCE5850A932F32BAB60AB1AC1F852C1F83C625E7A7D70CDA9EF16D5C8E47739D77DF59261ABE8454807FF441E143FBD37F8545#)" - " (e #010001#)" - " (d #077AD3DE284245F4806A1B82B79E616FBDE821C82D691A65665E57B5FAD3F34E67F401E7BD2E28699E89D9C496CF821945AE83AC7A1231176A196BA6027E77D85789055D50404A7A2A95B1512F91F190BBAEF730ED550D227D512F89C0CDB31AC06FA9A19503DDF6B66D0B42B9691BFD6140EC1720FFC48AE00C34796DC899E5#)" - " (p #00D586C78E5F1B4BF2E7CD7A04CA091911706F19788B93E44EE20AAF462E8363E98A72253ED845CCBF2481BB351E8557C85BCFFF0DABDBFF8E26A79A0938096F27#)" - " (q #00DB0CDF60F26F2A296C88D6BF9F8E5BE45C0DDD713C96CC73EBCB48B061740943F21D2A93D6E42A7211E7F02A95DCED6C390A67AD21ECF739AE8A0CA46FF2EBB3#)" - " (u #33149195F16912DB20A48D020DBC3B9E3881B39D722BF79378F6340F43148A6E9FC5F53E2853B7387BA4443BA53A52FCA8173DE6E85B42F9783D4A7817D0680B#)))", - "\x32\xCF\xFA\x85\xB1\x79\x1F\xBB\x26\x14\xE9\x1A\xFD\xF3\xAF\xE3\x32\x08\x2E\x25" - }, - { - GCRY_PK_DSA, - " (public-key" - " (dsa" - " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" - " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" - " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" - " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)))", - "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" - - }, - { - GCRY_PK_DSA, - "(private-key" - " (dsa" - " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" - " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" - " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" - " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)" - " (x #0087F9E91BFBCC1163DE71ED86D557708E32F8ADDE#)))", - "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" - }, - { - GCRY_PK_ECDSA, - "(public-key" - " (ecdsa(flags param)" - " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" - " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)" - " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" - " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" - " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" - " (h #000000000000000000000000000000000000000000000000000000000000000001#)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { - GCRY_PK_ECDSA, - "(public-key" - " (ecdsa(flags param)" - " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" - " (curve \"NIST P-256\")" - " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" - " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" - " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" - " (h #000000000000000000000000000000000000000000000000000000000000000001#)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { - GCRY_PK_ECDSA, - "(public-key" - " (ecdsa" - " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" - " (curve \"NIST P-256\")" - " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" - " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" - " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" - " (h #000000000000000000000000000000000000000000000000000000000000000001#)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { - GCRY_PK_ECDSA, - "(public-key" - " (ecdsa" - " (curve secp256r1)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve secp256r1)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { /* Ed25519 standard */ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Ed25519)" - " (q #04" - " 1CC662926E7EFF4982B7FB8B928E61CD74CCDD85277CC57196C3AD20B611085F" - " 47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)" - " ))", - "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8" - "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1" - }, - { /* Ed25519+EdDSA */ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Ed25519)(flags eddsa)" - " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" - "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" - }, - { /* Ed25519+EdDSA (with compression prefix) */ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Ed25519)(flags eddsa)" - " (q #40" - " 773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" - "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" - }, - { /* Ed25519+EdDSA (same but uncompressed)*/ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Ed25519)(flags eddsa)" - " (q #04" - " 629ad237d1ed04dcd4abe1711dd699a1cf51b1584c4de7a4ef8b8a640180b26f" - " 5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" - "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" - }, - { /* Cv25519 */ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Curve25519)(flags djb-tweak)" - " (q #40" - " 918C1733127F6BF2646FAE3D081A18AE77111C903B906310B077505EFFF12740#)" - " ))", - "\x0F\x89\xA5\x65\xD3\xEA\x18\x7C\xE8\x39" - "\x33\x23\x98\xF5\xD4\x80\x67\x7D\xF4\x9C" - }, - { /* Random key */ - GCRY_PK_RSA, - "(shadowed-private-key" - " (rsa" - " (n #00B493C79928398DA9D99AC0E949FE6EB62F683CB974FFFBFBC01066F5C9A89B" - " D3DC48EAD7C65F36EA943C2B2C865C26C4884FF9EDFDA8C99C855B737D77EEF6" - " B85DBC0CCEC0E900C1F89A6893A2A93E8B31028469B6927CEB2F08687E547C68" - " 6B0A2F7E50A194FF7AB7637E03DE0912EF7F6E5F1EC37625BD1620CCC2E7A564" - " 31E168CDAFBD1D9E61AE47A69A6FA03EF22F844528A710B2392F262B95A3078C" - " F321DC8325F92A5691EF69F34FD0DE0B22C79D29DC87723FCADE463829E8E5F7" - " D196D73D6C9C180F6A6A0DDBF7B9D8F7FA293C36163B12199EF6A1A95CAE4051" - " E3069C522CC6C4A7110F663A5DAD20F66C13A1674D050088208FAE4F33B3AB51" - " 03#)" - " (e #00010001#)" - " (shadowed t1-v1" - " (#D2760001240102000005000123350000# OPENPGP.1)" - ")))", - "\xE5\x6E\xE6\xEE\x5A\x2F\xDC\x3E\x98\x9D" - "\xFE\x49\xDA\xF5\x67\x43\xE3\x27\x28\x33" - } - }; - - -static void -check (void) -{ - unsigned char buf[20]; - unsigned char *ret; - gcry_error_t err; - gcry_sexp_t sexp; - unsigned int i; - int repn; - - for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++) - { - if (gcry_pk_test_algo (key_grips[i].algo)) - { - if (verbose) - fprintf (stderr, "algo %d not available; test skipped\n", - key_grips[i].algo); - continue; - } - err = gcry_sexp_sscan (&sexp, NULL, key_grips[i].key, - strlen (key_grips[i].key)); - if (err) - die ("scanning data %d failed: %s\n", i, gpg_strerror (err)); - - if (debug) - info ("check(%d): s-exp='%s'\n", i, key_grips[i].key); - - for (repn=0; repn < repetitions; repn++) - { - ret = gcry_pk_get_keygrip (sexp, buf); - if (!ret) - die ("gcry_pk_get_keygrip failed for %d\n", i); - - if ( memcmp (key_grips[i].grip, buf, sizeof (buf)) ) - { - print_hex ("keygrip: ", buf, sizeof buf); - die ("keygrip for %d does not match\n", i); - } - else if (debug && !repn) - print_hex ("keygrip: ", buf, sizeof buf); - } - - gcry_sexp_release (sexp); - } -} - - - -static void -progress_handler (void *cb_data, const char *what, int printchar, - int current, int total) -{ - (void)cb_data; - (void)what; - (void)current; - (void)total; - - putchar (printchar); -} - -int -main (int argc, char **argv) -{ - int last_argc = -1; - - if (argc) - { argc--; argv++; } - - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--verbose")) - { - verbose = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--debug")) - { - verbose = 1; - debug = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--repetitions")) - { - argc--; argv++; - if (argc) - { - repetitions = atoi(*argv); - argc--; argv++; - } - } - } - - if (repetitions < 1) - repetitions = 1; - - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - - gcry_set_progress_handler (progress_handler, NULL); - - xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - - check (); - - return 0; -} diff --git a/libgcrypt-1.10.0-disable-brainpool.patch b/libgcrypt-1.10.0-disable-brainpool.patch new file mode 100644 index 0000000..f0c5a72 --- /dev/null +++ b/libgcrypt-1.10.0-disable-brainpool.patch @@ -0,0 +1,239 @@ +From d651e25be0bc0c11f4d3d7c72be8cfbbe82b3874 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 10 Sep 2021 18:39:00 +0200 +Subject: [PATCH] Allow building libgcrypt without Brainpool curves + +* README: Document possibility to build without brainpool curves +* cipher/ecc-curves.c: Conditionalize brainpool curves definitions +* configure.ac: Implement possibility to build without brainpool curves +* tests/curves.c: Skip brainpool curves if they are not built-in +* tests/keygrip.c: Skip brainpool curves if they are not built-in + +-- + +Signed-off-by: Jakub Jelen +--- + README | 3 +++ + cipher/ecc-curves.c | 4 ++++ + configure.ac | 13 +++++++++++++ + tests/curves.c | 46 ++++++++++++++++++++++++++++++--------------- + tests/keygrip.c | 2 ++ + 5 files changed, 53 insertions(+), 15 deletions(-) + +diff --git a/README b/README +index 436b6cd4..1044109c 100644 +--- a/README ++++ b/README +@@ -127,6 +127,9 @@ + the list used with the current build the program + tests/version may be used. + ++ --disable-brainpool ++ Do not build in support for Brainpool curves. ++ + --disable-endian-check + Don't let configure test for the endianness but + try to use the OS provided macros at compile +diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c +index 7c86e12c..8fd95a9c 100644 +--- a/cipher/ecc-curves.c ++++ b/cipher/ecc-curves.c +@@ -77,6 +77,7 @@ static const struct + { "NIST P-521", "1.3.132.0.35" }, + { "NIST P-521", "nistp521" }, /* rfc5656. */ + ++#ifdef ENABLE_BRAINPOOL + { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" }, + { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" }, + { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" }, +@@ -84,6 +85,7 @@ static const struct + { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" }, + { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"}, + { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"}, ++#endif /* ENABLE_BRAINPOOL */ + + { "GOST2001-test", "1.2.643.2.2.35.0" }, + { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" }, +@@ -297,6 +299,7 @@ static const ecc_domain_parms_t domain_parms[] = + 1 + }, + ++#ifdef ENABLE_BRAINPOOL + { "brainpoolP160r1", 160, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f", +@@ -391,6 +394,7 @@ static const ecc_domain_parms_t domain_parms[] = + "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892", + 1 + }, ++#endif /* ENABLE_BRAINPOOL */ + { + "GOST2001-test", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, +diff --git a/configure.ac b/configure.ac +index 6efbf139..f4ac1887 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -614,6 +614,14 @@ AC_ARG_WITH(fips-module-version, + AC_DEFINE_UNQUOTED(FIPS_MODULE_VERSION, "$fips_module_version", + [Define FIPS module version for certification]) + ++# Implementation of the --disable-brainpool switch. ++AC_MSG_CHECKING([whether we want to disable the use of brainpool curves]) ++AC_ARG_ENABLE(brainpool, ++ AS_HELP_STRING([--disable-brainpool], ++ [Disable the brainpool curves]), ++ use_brainpool="$enableval",use_brainpool=yes) ++AC_MSG_RESULT($use_brainpool) ++ + # Implementation of the --disable-jent-support switch. + AC_MSG_CHECKING([whether jitter entropy support is requested]) + AC_ARG_ENABLE(jent-support, +@@ -2466,6 +2474,10 @@ if test x"$ppccryptosupport" = xyes ; then + AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1, + [Enable support for POWER 8 (PowerISA 2.07) crypto extension.]) + fi ++if test x"$use_brainpool" = xyes ; then ++ AC_DEFINE(ENABLE_BRAINPOOL, 1, ++ [Enable support for the brainpool curves.]) ++fi + if test x"$jentsupport" = xyes ; then + AC_DEFINE(ENABLE_JENT_SUPPORT, 1, + [Enable support for the jitter entropy collector.]) +@@ -3296,6 +3308,7 @@ GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) + GCRY_MSG_WRAP([Enabled kdf algorithms: ],[$enabled_kdfs]) + GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers]) + GCRY_MSG_SHOW([Random number generator: ],[$random]) ++GCRY_MSG_SHOW([Enabled Brainpool curves: ],[$use_brainpool]) + GCRY_MSG_SHOW([Try using jitter entropy: ],[$jentsupport]) + GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities]) + GCRY_MSG_SHOW([FIPS module version: ],[$fips_module_version]) +diff --git a/tests/curves.c b/tests/curves.c +index 3c738171..8eb79565 100644 +--- a/tests/curves.c ++++ b/tests/curves.c +@@ -33,7 +33,11 @@ + #include "t-common.h" + + /* Number of curves defined in ../cipher/ecc-curves.c */ +-#define N_CURVES 27 ++#ifdef ENABLE_BRAINPOOL ++# define N_CURVES 27 ++#else ++# define N_CURVES 20 ++#endif + + /* A real world sample public key. */ + static char const sample_key_1[] = +@@ -52,6 +56,7 @@ static char const sample_key_1[] = + static char const sample_key_1_curve[] = "NIST P-256"; + static unsigned int sample_key_1_nbits = 256; + ++#ifdef ENABLE_BRAINPOOL + /* A made up sample public key. */ + static char const sample_key_2[] = + "(public-key\n" +@@ -68,6 +73,7 @@ static char const sample_key_2[] = + " ))"; + static char const sample_key_2_curve[] = "brainpoolP160r1"; + static unsigned int sample_key_2_nbits = 160; ++#endif /* ENABLE_BRAINPOOL */ + + static int in_fips_mode; + +@@ -113,6 +119,7 @@ check_matching (void) + + gcry_sexp_release (key); + ++#ifdef ENABLE_BRAINPOOL + if (!in_fips_mode) + { + err = gcry_sexp_new (&key, sample_key_2, 0, 1); +@@ -130,6 +137,7 @@ check_matching (void) + + gcry_sexp_release (key); + } ++#endif /* ENABLE_BRAINPOOL */ + } + + #define TEST_ERROR_EXPECTED (1 << 0) +@@ -185,20 +193,26 @@ check_get_params (void) + { GCRY_PK_ECC, "1.3.132.0.35" }, + { GCRY_PK_ECC, "nistp521" }, + +- { GCRY_PK_ECC, "brainpoolP160r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP192r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP224r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP256r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP320r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP384r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP512r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13", TEST_NOFIPS }, ++#ifdef ENABLE_BRAINPOOL ++# define BRAINPOOL_FLAGS TEST_NOFIPS ++#else ++# define BRAINPOOL_FLAGS TEST_ERROR_EXPECTED ++#endif /* ENABLE_BRAINPOOL */ ++ { GCRY_PK_ECC, "brainpoolP160r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP192r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP224r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP256r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP320r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP384r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP512r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13", BRAINPOOL_FLAGS }, ++#undef BRAINPOOL_ERROR_EXPECTED + + { GCRY_PK_ECC, "GOST2001-test", TEST_NOFIPS }, + { GCRY_PK_ECC, "1.2.643.2.2.35.0", TEST_NOFIPS }, +@@ -282,6 +296,7 @@ check_get_params (void) + + gcry_sexp_release (param); + ++#ifdef ENABLE_BRAINPOOL + if (!in_fips_mode) + { + param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_2_curve); +@@ -297,6 +312,7 @@ check_get_params (void) + + gcry_sexp_release (param); + } ++#endif /* ENABLE_BRAINPOOL */ + + /* Some simple tests */ + for (idx=0; idx < DIM (tv); idx++) +diff --git a/tests/keygrip.c b/tests/keygrip.c +index 49bd71bc..fc4c17be 100644 +--- a/tests/keygrip.c ++++ b/tests/keygrip.c +@@ -149,6 +149,7 @@ static struct + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, ++#ifdef ENABLE_BRAINPOOL + { + GCRY_PK_ECC, + "(public-key" +@@ -197,6 +198,7 @@ static struct + "\xD6\xE1\xBF\x43\xAC\x9B\x9A\x12\xE7\x3F", + 1 + }, ++#endif /*ENABLE_BRAINPOOL */ + { /* Ed25519 standard */ + GCRY_PK_ECC, + "(public-key" +-- +2.34.1 + diff --git a/libgcrypt-1.6.1-mpicoder-gccopt.patch b/libgcrypt-1.6.1-mpicoder-gccopt.patch deleted file mode 100644 index 12555d3..0000000 --- a/libgcrypt-1.6.1-mpicoder-gccopt.patch +++ /dev/null @@ -1,104 +0,0 @@ -diff -up libgcrypt-1.6.1/mpi/mpicoder.c.gccopt libgcrypt-1.6.1/mpi/mpicoder.c ---- libgcrypt-1.6.1/mpi/mpicoder.c.gccopt 2014-02-28 15:37:53.983139821 +0100 -+++ libgcrypt-1.6.1/mpi/mpicoder.c 2014-02-28 15:47:35.312576387 +0100 -@@ -627,16 +627,16 @@ _gcry_mpi_print (enum gcry_mpi_format fo - extra = 1; - } - -- if (buffer && n > len) -- { -- /* The provided buffer is too short. */ -- xfree (tmp); -- return GPG_ERR_TOO_SHORT; -- } - if (buffer) - { - unsigned char *s = buffer; - -+ if (n > len) -+ { -+ /* The provided buffer is too short. */ -+ xfree (tmp); -+ return GPG_ERR_TOO_SHORT; -+ } - if (extra == 1) - *s++ = 0; - else if (extra) -@@ -654,13 +654,12 @@ _gcry_mpi_print (enum gcry_mpi_format fo - /* Note: We ignore the sign for this format. */ - /* FIXME: for performance reasons we should put this into - mpi_aprint because we can then use the buffer directly. */ -- -- if (buffer && n > len) -- return GPG_ERR_TOO_SHORT; - if (buffer) - { - unsigned char *tmp; - -+ if (n > len) -+ return GPG_ERR_TOO_SHORT; - tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL); - if (!tmp) - return gpg_err_code_from_syserror (); -@@ -678,14 +677,14 @@ _gcry_mpi_print (enum gcry_mpi_format fo - if (negative) - return GPG_ERR_INV_ARG; - -- if (buffer && n+2 > len) -- return GPG_ERR_TOO_SHORT; -- - if (buffer) - { - unsigned char *tmp; - unsigned char *s = buffer; - -+ if (n+2 > len) -+ return GPG_ERR_TOO_SHORT; -+ - s[0] = nbits >> 8; - s[1] = nbits; - -@@ -724,16 +723,16 @@ _gcry_mpi_print (enum gcry_mpi_format fo - extra=1; - } - -- if (buffer && n+4 > len) -- { -- xfree(tmp); -- return GPG_ERR_TOO_SHORT; -- } -- - if (buffer) - { - unsigned char *s = buffer; - -+ if (n+4 > len) -+ { -+ xfree(tmp); -+ return GPG_ERR_TOO_SHORT; -+ } -+ - *s++ = n >> 24; - *s++ = n >> 16; - *s++ = n >> 8; -@@ -761,15 +760,15 @@ _gcry_mpi_print (enum gcry_mpi_format fo - if (!n || (*tmp & 0x80)) - extra = 2; - -- if (buffer && 2*n + extra + negative + 1 > len) -- { -- xfree(tmp); -- return GPG_ERR_TOO_SHORT; -- } - if (buffer) - { - unsigned char *s = buffer; - -+ if (2*n + extra + negative + 1 > len) -+ { -+ xfree(tmp); -+ return GPG_ERR_TOO_SHORT; -+ } - if (negative) - *s++ = '-'; - if (extra) diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch deleted file mode 100644 index a5d3467..0000000 --- a/libgcrypt-1.8.3-fips-ctor.patch +++ /dev/null @@ -1,73 +0,0 @@ -diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c ---- libgcrypt-1.8.3/src/global.c.fips-ctor 2017-11-23 19:25:58.000000000 +0100 -+++ libgcrypt-1.8.3/src/global.c 2020-04-17 16:29:59.258218015 +0200 -@@ -141,6 +141,34 @@ global_init (void) - } - - -+#ifndef FIPS_MODULE_PATH -+#define FIPS_MODULE_PATH "/etc/system-fips" -+#endif -+ -+void __attribute__ ((constructor)) _gcry_global_constructor (void) -+{ -+ int rv; -+ -+ rv = access (FIPS_MODULE_PATH, F_OK); -+ if (rv < 0 && errno != ENOENT) -+ rv = 0; -+ -+ if (!rv) -+ { -+ int no_secmem_save; -+ -+ /* it should be always 0 at this point but let's keep on the safe side */ -+ no_secmem_save = no_secure_memory; -+ no_secure_memory = 1; -+ /* force selftests */ -+ global_init(); -+ _gcry_fips_run_selftests (0); -+ if (!fips_mode()) -+ _gcry_random_close_fds (); -+ no_secure_memory = no_secmem_save; -+ } -+} -+ - /* This function is called by the macro fips_is_operational and makes - sure that the minimal initialization has been done. This is far - from a perfect solution and hides problems with an improper -@@ -671,8 +699,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - - case GCRYCTL_FIPS_MODE_P: - if (fips_mode () -- && !_gcry_is_fips_mode_inactive () -- && !no_secure_memory) -+ && !_gcry_is_fips_mode_inactive ()) - rc = GPG_ERR_GENERAL; /* Used as TRUE value */ - break; - -@@ -749,9 +776,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - break; - - case GCRYCTL_SET_ENFORCED_FIPS_FLAG: -- if (!_gcry_global_any_init_done) -+ if (fips_mode ()) - { -- /* Not yet initialized at all. Set the enforced fips mode flag */ -+ /* We are in FIPS mode, we can set the enforced fips mode flag. */ - _gcry_set_preferred_rng_type (0); - _gcry_set_enforced_fips_mode (); - } -diff --git a/tests/t-secmem.c b/tests/t-secmem.c -index 2b769134..1d33bbfd 100644 ---- a/tests/t-secmem.c -+++ b/tests/t-secmem.c -@@ -54,7 +54,7 @@ test_secmem (void) - - /* Allocating another 2k should fail for the default 16k pool. */ - b = gcry_malloc_secure (chunk_size*4); -- if (b) -+ if (b && !gcry_fips_mode_active ()) - fail ("allocation did not fail as expected\n"); - - for (i=0; i < DIM(a); i++) diff --git a/libgcrypt-1.8.3-md-fips-enforce.patch b/libgcrypt-1.8.3-md-fips-enforce.patch deleted file mode 100644 index 3b730a1..0000000 --- a/libgcrypt-1.8.3-md-fips-enforce.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -up libgcrypt-1.8.3/cipher/md.c.fips-enforce libgcrypt-1.8.3/cipher/md.c ---- libgcrypt-1.8.3/cipher/md.c.fips-enforce 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/cipher/md.c 2020-04-17 15:07:31.364945130 +0200 -@@ -409,13 +409,10 @@ md_enable (gcry_md_hd_t hd, int algorith - } - - -- if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) -+ if (!err && !spec->flags.fips && fips_mode ()) - { -- _gcry_inactivate_fips_mode ("MD5 used"); - if (_gcry_enforced_fips_mode () ) - { -- /* We should never get to here because we do not register -- MD5 in enforced fips mode. But better throw an error. */ - err = GPG_ERR_DIGEST_ALGO; - } - } -diff --git a/tests/t-kdf.c b/tests/t-kdf.c -index 7a48e98a..48309b9a 100644 ---- a/tests/t-kdf.c -+++ b/tests/t-kdf.c -@@ -1104,6 +1104,13 @@ check_pbkdf2 (void) - GCRY_KDF_PBKDF2, tv[tvidx].hashalgo, - tv[tvidx].salt, tv[tvidx].saltlen, - tv[tvidx].c, tv[tvidx].dklen, outbuf); -+ if (gcry_fips_mode_active() && tvidx > 6) -+ { -+ if (!err) -+ fail ("pbkdf2 test %d unexpectedly passed in FIPS mode: %s\n", -+ tvidx, gpg_strerror (err)); -+ continue; -+ } - if (err) - fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); - else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) - diff --git a/libgcrypt-1.8.4-fips-keygen.patch b/libgcrypt-1.8.4-fips-keygen.patch deleted file mode 100644 index a3e241f..0000000 --- a/libgcrypt-1.8.4-fips-keygen.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff -up libgcrypt-1.8.4/cipher/dsa.c.fips-keygen libgcrypt-1.8.4/cipher/dsa.c ---- libgcrypt-1.8.4/cipher/dsa.c.fips-keygen 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/cipher/dsa.c 2019-02-12 14:29:25.629513989 +0100 -@@ -457,13 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -- else -+ else if (!domain->p || !domain->q) - ec = _gcry_generate_fips186_3_prime (nbits, qbits, - initial_seed.seed, - initial_seed.seedlen, - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen, NULL); -+ else -+ { -+ /* Domain parameters p and q are given; use them. */ -+ prime_p = mpi_copy (domain->p); -+ prime_q = mpi_copy (domain->q); -+ gcry_assert (mpi_get_nbits (prime_p) == nbits); -+ gcry_assert (mpi_get_nbits (prime_q) == qbits); -+ ec = 0; -+ } - sexp_release (initial_seed.sexp); - if (ec) - goto leave; -@@ -855,13 +866,12 @@ dsa_generate (const gcry_sexp_t genparms - sexp_release (l1); - sexp_release (domainsexp); - -- /* Check that all domain parameters are available. */ -- if (!domain.p || !domain.q || !domain.g) -+ /* Check that p and q domain parameters are available. */ -+ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) - { - _gcry_mpi_release (domain.p); - _gcry_mpi_release (domain.q); - _gcry_mpi_release (domain.g); -- sexp_release (deriveparms); - return GPG_ERR_MISSING_VALUE; - } - -diff -up libgcrypt-1.8.4/cipher/rsa.c.fips-keygen libgcrypt-1.8.4/cipher/rsa.c ---- libgcrypt-1.8.4/cipher/rsa.c.fips-keygen 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/cipher/rsa.c 2019-02-12 14:29:25.630513971 +0100 -@@ -389,7 +389,7 @@ generate_fips (RSA_secret_key *sk, unsig - - if (nbits < 1024 || (nbits & 0x1FF)) - return GPG_ERR_INV_VALUE; -- if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072) -+ if (fips_mode() && nbits < 2048) - return GPG_ERR_INV_VALUE; - - /* The random quality depends on the transient_key flag. */ -@@ -696,7 +696,7 @@ generate_x931 (RSA_secret_key *sk, unsig - - *swapped = 0; - -- if (e_value == 1) /* Alias for a secure value. */ -+ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ - e_value = 65537; - - /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ diff --git a/libgcrypt-1.8.4-use-poll.patch b/libgcrypt-1.8.4-use-poll.patch deleted file mode 100644 index 8032992..0000000 --- a/libgcrypt-1.8.4-use-poll.patch +++ /dev/null @@ -1,77 +0,0 @@ -diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndlinux.c ---- libgcrypt-1.8.4/random/rndlinux.c.use-poll 2018-10-26 13:50:20.000000000 +0200 -+++ libgcrypt-1.8.4/random/rndlinux.c 2018-11-20 15:51:56.760669058 +0100 -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #if defined(__APPLE__) && defined(__MACH__) - #include - #ifdef __MAC_10_11 -@@ -241,9 +242,8 @@ _gcry_rndlinux_gather_random (void (*add - return with something we will actually use 100ms. */ - while (length) - { -- fd_set rfds; -- struct timeval tv; - int rc; -+ struct pollfd pfd; - - /* If we have a modern operating system, we first try to use the new - * getentropy function. That call guarantees that the kernel's -@@ -300,36 +300,25 @@ _gcry_rndlinux_gather_random (void (*add - any_need_entropy = 1; - } - -- /* If the system has no limit on the number of file descriptors -- and we encounter an fd which is larger than the fd_set size, -- we don't use the select at all. The select code is only used -- to emit progress messages. A better solution would be to -- fall back to poll() if available. */ --#ifdef FD_SETSIZE -- if (fd < FD_SETSIZE) --#endif -+ pfd.fd = fd; -+ pfd.events = POLLIN; -+ -+ _gcry_pre_syscall (); -+ rc = poll(&pfd, 1, delay); -+ _gcry_post_syscall (); -+ if (!rc) - { -- FD_ZERO(&rfds); -- FD_SET(fd, &rfds); -- tv.tv_sec = delay; -- tv.tv_usec = delay? 0 : 100000; -- _gcry_pre_syscall (); -- rc = select (fd+1, &rfds, NULL, NULL, &tv); -- _gcry_post_syscall (); -- if (!rc) -- { -- any_need_entropy = 1; -- delay = 3; /* Use 3 seconds henceforth. */ -- continue; -- } -- else if( rc == -1 ) -- { -- log_error ("select() error: %s\n", strerror(errno)); -- if (!delay) -- delay = 1; /* Use 1 second if we encounter an error before -- we have ever blocked. */ -- continue; -- } -+ any_need_entropy = 1; -+ delay = 3000; /* Use 3 seconds henceforth. */ -+ continue; -+ } -+ else if( rc == -1 ) -+ { -+ log_error ("poll() error: %s\n", strerror(errno)); -+ if (!delay) -+ delay = 1000; /* Use 1 second if we encounter an error before -+ we have ever blocked. */ -+ continue; - } - - do diff --git a/libgcrypt-1.8.5-fips-module.patch b/libgcrypt-1.8.5-fips-module.patch deleted file mode 100644 index 8ffe465..0000000 --- a/libgcrypt-1.8.5-fips-module.patch +++ /dev/null @@ -1,139 +0,0 @@ -diff -up libgcrypt-1.8.5/src/fips.c.fips-module libgcrypt-1.8.5/src/fips.c ---- libgcrypt-1.8.5/src/fips.c.fips-module 2020-04-20 19:07:45.924919645 +0200 -+++ libgcrypt-1.8.5/src/fips.c 2020-04-20 19:10:33.690722470 +0200 -@@ -35,10 +35,6 @@ - #include "hmac256.h" - - --/* The name of the file used to force libgcrypt into fips mode. */ --#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" -- -- - /* The states of the finite state machine used in fips mode. */ - enum module_states - { -@@ -122,54 +118,6 @@ _gcry_initialize_fips_mode (int force) - goto leave; - } - -- /* For testing the system it is useful to override the system -- provided detection of the FIPS mode and force FIPS mode using a -- file. The filename is hardwired so that there won't be any -- confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is -- actually used. The file itself may be empty. */ -- if ( !access (FIPS_FORCE_FILE, F_OK) ) -- { -- gcry_assert (!_gcry_no_fips_mode_required); -- goto leave; -- } -- -- /* Checking based on /proc file properties. */ -- { -- static const char procfname[] = "/proc/sys/crypto/fips_enabled"; -- FILE *fp; -- int saved_errno; -- -- fp = fopen (procfname, "r"); -- if (fp) -- { -- char line[256]; -- -- if (fgets (line, sizeof line, fp) && atoi (line)) -- { -- /* System is in fips mode. */ -- fclose (fp); -- gcry_assert (!_gcry_no_fips_mode_required); -- goto leave; -- } -- fclose (fp); -- } -- else if ((saved_errno = errno) != ENOENT -- && saved_errno != EACCES -- && !access ("/proc/version", F_OK) ) -- { -- /* Problem reading the fips file despite that we have the proc -- file system. We better stop right away. */ -- log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", -- procfname, strerror (saved_errno)); --#ifdef HAVE_SYSLOG -- syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -- "reading `%s' failed: %s - abort", -- procfname, strerror (saved_errno)); --#endif /*HAVE_SYSLOG*/ -- abort (); -- } -- } -- - /* Fips not not requested, set flag. */ - _gcry_no_fips_mode_required = 1; - -diff -up libgcrypt-1.8.5/src/g10lib.h.fips-module libgcrypt-1.8.5/src/g10lib.h ---- libgcrypt-1.8.5/src/g10lib.h.fips-module 2020-04-20 19:07:45.918919759 +0200 -+++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 19:11:05.003125740 +0200 -@@ -422,6 +422,9 @@ gpg_err_code_t _gcry_sexp_vextract_param - - /*-- fips.c --*/ - -+/* The name of the file used to force libgcrypt into fips mode. */ -+#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" -+ - extern int _gcry_no_fips_mode_required; - - void _gcry_initialize_fips_mode (int force); -diff -up libgcrypt-1.8.5/src/global.c.fips-module libgcrypt-1.8.5/src/global.c ---- libgcrypt-1.8.5/src/global.c.fips-module 2020-04-20 19:07:45.919919741 +0200 -+++ libgcrypt-1.8.5/src/global.c 2020-04-20 19:07:45.950919149 +0200 -@@ -160,6 +160,53 @@ void __attribute__ ((constructor)) _gcry - rv = access (FIPS_MODULE_PATH, F_OK); - if (rv < 0 && errno != ENOENT) - rv = 0; -+ -+ /* For testing the system it is useful to override the system -+ provided detection of the FIPS mode and force FIPS mode using a -+ file. The filename is hardwired so that there won't be any -+ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is -+ actually used. The file itself may be empty. */ -+ if ( !access (FIPS_FORCE_FILE, F_OK) ) -+ { -+ rv = 0; -+ force_fips_mode = 1; -+ } -+ -+ /* Checking based on /proc file properties. */ -+ { -+ static const char procfname[] = "/proc/sys/crypto/fips_enabled"; -+ FILE *fp; -+ int saved_errno; -+ -+ fp = fopen (procfname, "r"); -+ if (fp) -+ { -+ char line[256]; -+ -+ if (fgets (line, sizeof line, fp) && atoi (line)) -+ { -+ /* System is in fips mode. */ -+ rv = 0; -+ force_fips_mode = 1; -+ } -+ fclose (fp); -+ } -+ else if ((saved_errno = errno) != ENOENT -+ && saved_errno != EACCES -+ && !access ("/proc/version", F_OK) ) -+ { -+ /* Problem reading the fips file despite that we have the proc -+ file system. We better stop right away. */ -+ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", -+ procfname, strerror (saved_errno)); -+#ifdef HAVE_SYSLOG -+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -+ "reading `%s' failed: %s - abort", -+ procfname, strerror (saved_errno)); -+#endif /*HAVE_SYSLOG*/ -+ abort (); -+ } -+ } - - if (!rv) - { diff --git a/libgcrypt-1.8.5-getrandom.patch b/libgcrypt-1.8.5-getrandom.patch deleted file mode 100644 index 1779dc1..0000000 --- a/libgcrypt-1.8.5-getrandom.patch +++ /dev/null @@ -1,277 +0,0 @@ -diff -up libgcrypt-1.8.5/random/rand-internal.h.getrandom libgcrypt-1.8.5/random/rand-internal.h ---- libgcrypt-1.8.5/random/rand-internal.h.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/rand-internal.h 2020-04-20 14:55:34.875949624 +0200 -@@ -47,6 +47,7 @@ void _gcry_random_progress (const char * - - /*-- random-csprng.c --*/ - void _gcry_rngcsprng_initialize (int full); -+void _gcry_rngcsprng_deinit (void); - void _gcry_rngcsprng_close_fds (void); - void _gcry_rngcsprng_dump_stats (void); - void _gcry_rngcsprng_secure_alloc (void); -@@ -68,6 +69,7 @@ void _gcry_rngcsprng_fast_poll (void); - - /*-- random-drbg.c --*/ - void _gcry_rngdrbg_inititialize (int full); -+void _gcry_rngdrbg_deinit (void); - void _gcry_rngdrbg_close_fds (void); - void _gcry_rngdrbg_dump_stats (void); - int _gcry_rngdrbg_is_faked (void); -diff -up libgcrypt-1.8.5/random/random.c.getrandom libgcrypt-1.8.5/random/random.c ---- libgcrypt-1.8.5/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/random.c 2020-04-20 14:55:34.876949605 +0200 -@@ -110,8 +110,8 @@ _gcry_random_read_conf (void) - unsigned int result = 0; - - fp = fopen (fname, "r"); -- if (!fp) -- return result; -+ if (!fp) /* We make only_urandom the default. */ -+ return RANDOM_CONF_ONLY_URANDOM; - - for (;;) - { -@@ -228,6 +228,22 @@ _gcry_random_initialize (int full) - } - - -+/* Deinitialize this random subsystem. */ -+void -+_gcry_random_deinit (void) -+{ -+ if (fips_mode ()) -+ _gcry_rngdrbg_deinit (); -+ else if (rng_types.standard) -+ _gcry_rngcsprng_deinit (); -+ else if (rng_types.fips) -+ _gcry_rngdrbg_deinit (); -+ else -+ _gcry_rngcsprng_deinit (); -+ /* not needed for system */ -+} -+ -+ - /* If possible close file descriptors used by the RNG. */ - void - _gcry_random_close_fds (void) -diff -up libgcrypt-1.8.5/random/random-csprng.c.getrandom libgcrypt-1.8.5/random/random-csprng.c ---- libgcrypt-1.8.5/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/random-csprng.c 2020-04-20 15:04:27.182877975 +0200 -@@ -55,6 +55,10 @@ - #ifdef __MINGW32__ - #include - #endif -+#if defined(__linux__) && defined(HAVE_SYSCALL) -+# include -+# include -+#endif - #include "g10lib.h" - #include "random.h" - #include "rand-internal.h" -@@ -343,6 +347,21 @@ _gcry_rngcsprng_initialize (int full) - } - - -+void -+_gcry_rngcsprng_deinit (void) -+{ -+ lock_pool(); -+ pool_writepos = 0; -+ pool_readpos = 0; -+ pool_filled = 0; -+ pool_filled_counter = 0; -+ did_initial_extra_seeding = 0; -+ pool_balance = 0; -+ just_mixed = 0; -+ unlock_pool(); -+} -+ -+ - /* Try to close the FDs of the random gather module. This is - currently only implemented for rndlinux. */ - void -@@ -1116,6 +1135,22 @@ getfnc_gather_random (void))(void (*)(co - enum random_origins, size_t, int); - - #if USE_RNDLINUX -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ long ret; -+ char buffer[1]; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret != -1 || errno != ENOSYS) -+ { -+ fnc = _gcry_rndlinux_gather_random; -+ return fnc; -+ } -+ else -+ /* The syscall is not supported - fallback to /dev/urandom. */ -+#endif - if ( !access (NAME_OF_DEV_RANDOM, R_OK) - && !access (NAME_OF_DEV_URANDOM, R_OK)) - { -diff -up libgcrypt-1.8.5/random/random-drbg.c.getrandom libgcrypt-1.8.5/random/random-drbg.c ---- libgcrypt-1.8.5/random/random-drbg.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/random-drbg.c 2020-04-20 15:02:37.782947902 +0200 -@@ -1811,6 +1811,22 @@ _gcry_rngdrbg_inititialize (int full) - } - - /* -+ * Deinitialize the DRBG invoked by the libgcrypt API -+ * It will be automatically re-initialized on next call -+ */ -+void -+_gcry_rngdrbg_deinit (void) -+{ -+ drbg_lock (); -+ if (drbg_state) -+ { -+ drbg_uninstantiate (drbg_state); -+ drbg_state = NULL; -+ } -+ drbg_unlock (); -+} -+ -+/* - * Backend handler function for GCRYCTL_DRBG_REINIT - * - * Select a different DRBG type and initialize it. -diff -up libgcrypt-1.8.5/random/random.h.getrandom libgcrypt-1.8.5/random/random.h ---- libgcrypt-1.8.5/random/random.h.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/random.h 2020-04-20 14:55:34.877949586 +0200 -@@ -29,6 +29,7 @@ void _gcry_register_random_progress (voi - - void _gcry_set_preferred_rng_type (int type); - void _gcry_random_initialize (int full); -+void _gcry_random_deinit (void); - void _gcry_random_close_fds (void); - int _gcry_get_rng_type (int ignore_fips_mode); - void _gcry_random_dump_stats(void); -diff -up libgcrypt-1.8.5/random/rndlinux.c.getrandom libgcrypt-1.8.5/random/rndlinux.c ---- libgcrypt-1.8.5/random/rndlinux.c.getrandom 2020-04-20 15:01:50.159848963 +0200 -+++ libgcrypt-1.8.5/random/rndlinux.c 2020-04-20 16:14:21.901610921 +0200 -@@ -35,6 +35,7 @@ - #if defined(__linux__) || !defined(HAVE_GETENTROPY) - #ifdef HAVE_SYSCALL - # include -+# include - # ifdef __NR_getrandom - # define getentropy(buf,buflen) syscall (__NR_getrandom, buf, buflen, 0) - # endif -@@ -147,12 +148,12 @@ _gcry_rndlinux_gather_random (void (*add - if (!add) - { - /* Special mode to close the descriptors. */ -- if (fd_random != -1) -+ if (fd_random >= 0) - { - close (fd_random); - fd_random = -1; - } -- if (fd_urandom != -1) -+ if (fd_urandom >= 0) - { - close (fd_urandom); - fd_urandom = -1; -@@ -166,12 +167,12 @@ _gcry_rndlinux_gather_random (void (*add - apid = getpid (); - if (my_pid != apid) - { -- if (fd_random != -1) -+ if (fd_random >= 0) - { - close (fd_random); - fd_random = -1; - } -- if (fd_urandom != -1) -+ if (fd_urandom >= 0) - { - close (fd_urandom); - fd_urandom = -1; -@@ -216,7 +217,23 @@ _gcry_rndlinux_gather_random (void (*add - that we always require the device to be existent but want a more - graceful behaviour if the rarely needed close operation has been - used and the device needs to be re-opened later. */ -- if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom) -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ if (fd_urandom != -2 && !_gcry_in_constructor ()) -+ { -+ long ret; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret > -1 || errno == EAGAIN || errno == EINTR) -+ { -+ fd_urandom = -2; -+ fd_random = -2; -+ } -+ } -+#endif -+ if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom && !_gcry_in_constructor ()) - { - if (fd_random == -1) - { -@@ -270,9 +288,7 @@ _gcry_rndlinux_gather_random (void (*add - _gcry_post_syscall (); - } - while (ret == -1 && errno == EINTR); -- if (ret == -1 && errno == ENOSYS) -- ; /* getentropy is not supported - fallback to pulling from fd. */ -- else -+ if (1) - { /* getentropy is supported. Some sanity checks. */ - if (ret == -1) - log_fatal ("unexpected error from getentropy: %s\n", -diff -up libgcrypt-1.8.5/src/g10lib.h.getrandom libgcrypt-1.8.5/src/g10lib.h ---- libgcrypt-1.8.5/src/g10lib.h.getrandom 2020-04-20 15:08:16.528538580 +0200 -+++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 15:08:28.641309399 +0200 -@@ -464,6 +464,6 @@ gpg_err_code_t _gcry_fips_run_selftests - void _gcry_fips_noreturn (void); - #define fips_noreturn() (_gcry_fips_noreturn ()) - -- -+int _gcry_in_constructor (void); - - #endif /* G10LIB_H */ -diff -up libgcrypt-1.8.5/src/global.c.getrandom libgcrypt-1.8.5/src/global.c ---- libgcrypt-1.8.5/src/global.c.getrandom 2020-04-20 15:06:21.891707597 +0200 -+++ libgcrypt-1.8.5/src/global.c 2020-04-20 15:07:29.018437509 +0200 -@@ -145,10 +145,18 @@ global_init (void) - #define FIPS_MODULE_PATH "/etc/system-fips" - #endif - -+static int in_constructor = 0; -+ -+int _gcry_in_constructor(void) -+{ -+ return in_constructor; -+} -+ - void __attribute__ ((constructor)) _gcry_global_constructor (void) - { - int rv; - -+ in_constructor = 1; - rv = access (FIPS_MODULE_PATH, F_OK); - if (rv < 0 && errno != ENOENT) - rv = 0; -@@ -163,10 +171,12 @@ void __attribute__ ((constructor)) _gcry - /* force selftests */ - global_init(); - _gcry_fips_run_selftests (0); -- if (!fips_mode()) -- _gcry_random_close_fds (); -+ _gcry_random_close_fds (); -+ _gcry_random_deinit (); - no_secure_memory = no_secmem_save; - } -+ -+ in_constructor = 0; - } - - /* This function is called by the macro fips_is_operational and makes diff --git a/libgcrypt-1.8.5-intel-cet.patch b/libgcrypt-1.8.5-intel-cet.patch deleted file mode 100644 index a19d2f1..0000000 --- a/libgcrypt-1.8.5-intel-cet.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b04c0a86b19856071c29d2a6285f3240c606ee7a Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Tue, 27 Apr 2021 09:08:41 -0700 -Subject: [PATCH] Always include in cipher assembly codes - -* cipher/poly1305-s390x.S: Always include . - -When Intel CET is enabled, we need to include in assembly codes -to mark Intel CET support even if it is empty. We should always include - in cipher assembly codes so that they will be marked for -Intel CET support when compiling for x86-64 and i686. - -Signed-off-by: H.J. Lu ---- - cipher/poly1305-s390x.S | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cipher/poly1305-s390x.S b/cipher/poly1305-s390x.S -index 844245f6..28bed560 100644 ---- a/cipher/poly1305-s390x.S -+++ b/cipher/poly1305-s390x.S -@@ -18,8 +18,8 @@ - * License along with this program; if not, see . - */ - --#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9 - #include -+#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9 - #if defined(HAVE_GCC_INLINE_ASM_S390X) - - #include "asm-poly1305-s390x.h" --- -GitLab - diff --git a/libgcrypt-1.8.5-use-fipscheck.patch b/libgcrypt-1.8.5-use-fipscheck.patch deleted file mode 100644 index 46145d8..0000000 --- a/libgcrypt-1.8.5-use-fipscheck.patch +++ /dev/null @@ -1,77 +0,0 @@ -diff -up libgcrypt-1.8.5/src/fips.c.use-fipscheck libgcrypt-1.8.5/src/fips.c ---- libgcrypt-1.8.5/src/fips.c.use-fipscheck 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/src/fips.c 2020-04-23 10:18:36.235764741 +0200 -@@ -581,23 +581,50 @@ run_random_selftests (void) - return !!err; - } - -+#ifdef ENABLE_HMAC_BINARY_CHECK -+static int -+get_library_path(const char *libname, const char *symbolname, char *path, size_t pathlen) -+{ -+ Dl_info info; -+ void *dl, *sym; -+ int rv = -1; -+ -+ dl = dlopen(libname, RTLD_LAZY); -+ if (dl == NULL) { -+ return -1; -+ } -+ -+ sym = dlsym(dl, symbolname); -+ -+ if (sym != NULL && dladdr(sym, &info)) { -+ strncpy(path, info.dli_fname, pathlen-1); -+ path[pathlen-1] = '\0'; -+ rv = 0; -+ } -+ -+ dlclose(dl); -+ -+ return rv; -+} -+#endif -+ - /* Run an integrity check on the binary. Returns 0 on success. */ - static int - check_binary_integrity (void) - { - #ifdef ENABLE_HMAC_BINARY_CHECK - gpg_error_t err; -- Dl_info info; -+ char libpath[4096]; - unsigned char digest[32]; - int dlen; - char *fname = NULL; -- const char key[] = "What am I, a doctor or a moonshuttle conductor?"; -- -- if (!dladdr ("gcry_check_version", &info)) -+ const char key[] = "orboDeJITITejsirpADONivirpUkvarP"; -+ -+ if (get_library_path ("libgcrypt.so.20", "gcry_check_version", libpath, sizeof(libpath))) - err = gpg_error_from_syserror (); - else - { -- dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname, -+ dlen = _gcry_hmac256_file (digest, sizeof digest, libpath, - key, strlen (key)); - if (dlen < 0) - err = gpg_error_from_syserror (); -@@ -605,7 +632,7 @@ check_binary_integrity (void) - err = gpg_error (GPG_ERR_INTERNAL); - else - { -- fname = xtrymalloc (strlen (info.dli_fname) + 1 + 5 + 1 ); -+ fname = xtrymalloc (strlen (libpath) + 1 + 5 + 1 ); - if (!fname) - err = gpg_error_from_syserror (); - else -@@ -614,7 +641,7 @@ check_binary_integrity (void) - char *p; - - /* Prefix the basename with a dot. */ -- strcpy (fname, info.dli_fname); -+ strcpy (fname, libpath); - p = strrchr (fname, '/'); - if (p) - p++; diff --git a/libgcrypt-1.9.3-fips-tests.patch b/libgcrypt-1.9.3-fips-tests.patch deleted file mode 100644 index 1ddc64f..0000000 --- a/libgcrypt-1.9.3-fips-tests.patch +++ /dev/null @@ -1,1804 +0,0 @@ -commit 57cf83834bc00a7431378aabda692bf700e4876c -Author: Jussi Kivilinna -Date: Sat Apr 17 17:06:40 2021 +0300 - - tests/bench-slope: add ECC benchmarking - - * tests/bench-slope.c (bench_print_result_nsec_per_iteration): New. - (bench_print_header_nsec_per_iteration): New. - (kdf_bench_one, kdf_bench): Use new print helper functions. - [USE_ECC]: New ECC benchmarks. - (ecc_bench): New. - (print_help): Add 'ecc' option. - (main): Add ECC benchmarks. - -- - - Signed-off-by: Jussi Kivilinna - -diff --git a/tests/bench-slope.c b/tests/bench-slope.c -index c8647b6b..9b4a139a 100644 ---- a/tests/bench-slope.c -+++ b/tests/bench-slope.c -@@ -783,6 +783,54 @@ bench_print_result (double nsecs_per_byte) - bench_print_result_std (nsecs_per_byte); - } - -+static void -+bench_print_result_nsec_per_iteration (double nsecs_per_iteration) -+{ -+ double cycles_per_iteration; -+ char nsecpiter_buf[16]; -+ char cpiter_buf[16]; -+ char mhz_buf[16]; -+ -+ strcpy(cpiter_buf, csv_mode ? "" : "-"); -+ strcpy(mhz_buf, csv_mode ? "" : "-"); -+ -+ double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); -+ -+ /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ -+ if (bench_ghz > 0.0) -+ { -+ cycles_per_iteration = nsecs_per_iteration * bench_ghz; -+ double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); -+ double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); -+ } -+ -+ if (csv_mode) -+ { -+ if (auto_ghz) -+ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", -+ current_section_name, -+ current_algo_name ? current_algo_name : "", -+ current_mode_name ? current_mode_name : "", -+ nsecpiter_buf, -+ cpiter_buf, -+ mhz_buf); -+ else -+ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", -+ current_section_name, -+ current_algo_name ? current_algo_name : "", -+ current_mode_name ? current_mode_name : "", -+ nsecpiter_buf, -+ cpiter_buf); -+ } -+ else -+ { -+ if (auto_ghz) -+ printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); -+ else -+ printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); -+ } -+} -+ - static void - bench_print_section (const char *section_name, const char *print_name) - { -@@ -819,6 +867,28 @@ bench_print_header (int algo_width, const char *algo_name) - } - } - -+static void -+bench_print_header_nsec_per_iteration (int algo_width, const char *algo_name) -+{ -+ if (csv_mode) -+ { -+ gcry_free (current_algo_name); -+ current_algo_name = gcry_xstrdup (algo_name); -+ } -+ else -+ { -+ if (algo_width < 0) -+ printf (" %-*s | ", -algo_width, algo_name); -+ else -+ printf (" %-*s | ", algo_width, algo_name); -+ -+ if (auto_ghz) -+ printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); -+ else -+ printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); -+ } -+} -+ - static void - bench_print_algo (int algo_width, const char *algo_name) - { -@@ -1991,11 +2061,7 @@ kdf_bench_one (int algo, int subalgo) - struct bench_kdf_mode mode = { &kdf_ops }; - struct bench_obj obj = { 0 }; - double nsecs_per_iteration; -- double cycles_per_iteration; - char algo_name[32]; -- char nsecpiter_buf[16]; -- char cpiter_buf[16]; -- char mhz_buf[16]; - - mode.algo = algo; - mode.subalgo = subalgo; -@@ -2030,45 +2096,7 @@ kdf_bench_one (int algo, int subalgo) - obj.priv = &mode; - - nsecs_per_iteration = do_slope_benchmark (&obj); -- -- strcpy(cpiter_buf, csv_mode ? "" : "-"); -- strcpy(mhz_buf, csv_mode ? "" : "-"); -- -- double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); -- -- /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ -- if (bench_ghz > 0.0) -- { -- cycles_per_iteration = nsecs_per_iteration * bench_ghz; -- double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); -- double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); -- } -- -- if (csv_mode) -- { -- if (auto_ghz) -- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", -- current_section_name, -- current_algo_name ? current_algo_name : "", -- current_mode_name ? current_mode_name : "", -- nsecpiter_buf, -- cpiter_buf, -- mhz_buf); -- else -- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", -- current_section_name, -- current_algo_name ? current_algo_name : "", -- current_mode_name ? current_mode_name : "", -- nsecpiter_buf, -- cpiter_buf); -- } -- else -- { -- if (auto_ghz) -- printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); -- else -- printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); -- } -+ bench_print_result_nsec_per_iteration (nsecs_per_iteration); - } - - void -@@ -2079,14 +2107,7 @@ kdf_bench (char **argv, int argc) - - bench_print_section ("kdf", "KDF"); - -- if (!csv_mode) -- { -- printf (" %-*s | ", 24, ""); -- if (auto_ghz) -- printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); -- else -- printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); -- } -+ bench_print_header_nsec_per_iteration (24, ""); - - if (argv && argc) - { -@@ -2116,13 +2137,571 @@ kdf_bench (char **argv, int argc) - } - - -+/************************************************************ ECC benchmarks. */ -+ -+#if USE_ECC -+enum bench_ecc_algo -+{ -+ ECC_ALGO_ED25519 = 0, -+ ECC_ALGO_ED448, -+ ECC_ALGO_NIST_P192, -+ ECC_ALGO_NIST_P224, -+ ECC_ALGO_NIST_P256, -+ ECC_ALGO_NIST_P384, -+ ECC_ALGO_NIST_P521, -+ ECC_ALGO_SECP256K1, -+ __MAX_ECC_ALGO -+}; -+ -+enum bench_ecc_operation -+{ -+ ECC_OPER_MULT = 0, -+ ECC_OPER_KEYGEN, -+ ECC_OPER_SIGN, -+ ECC_OPER_VERIFY, -+ __MAX_ECC_OPER -+}; -+ -+struct bench_ecc_oper -+{ -+ enum bench_ecc_operation oper; -+ const char *name; -+ struct bench_ops *ops; -+ -+ enum bench_ecc_algo algo; -+}; -+ -+struct bench_ecc_mult_hd -+{ -+ gcry_ctx_t ec; -+ gcry_mpi_t k, x, y; -+ gcry_mpi_point_t G, Q; -+}; -+ -+struct bench_ecc_hd -+{ -+ gcry_sexp_t key_spec; -+ gcry_sexp_t data; -+ gcry_sexp_t pub_key; -+ gcry_sexp_t sec_key; -+ gcry_sexp_t sig; -+}; -+ -+ -+static const char * -+ecc_algo_name (int algo) -+{ -+ switch (algo) -+ { -+ case ECC_ALGO_ED25519: -+ return "Ed25519"; -+ case ECC_ALGO_ED448: -+ return "Ed448"; -+ case ECC_ALGO_NIST_P192: -+ return "NIST-P192"; -+ case ECC_ALGO_NIST_P224: -+ return "NIST-P224"; -+ case ECC_ALGO_NIST_P256: -+ return "NIST-P256"; -+ case ECC_ALGO_NIST_P384: -+ return "NIST-P384"; -+ case ECC_ALGO_NIST_P521: -+ return "NIST-P521"; -+ case ECC_ALGO_SECP256K1: -+ return "secp256k1"; -+ default: -+ return NULL; -+ } -+} -+ -+static const char * -+ecc_algo_curve (int algo) -+{ -+ switch (algo) -+ { -+ case ECC_ALGO_ED25519: -+ return "Ed25519"; -+ case ECC_ALGO_ED448: -+ return "Ed448"; -+ case ECC_ALGO_NIST_P192: -+ return "NIST P-192"; -+ case ECC_ALGO_NIST_P224: -+ return "NIST P-224"; -+ case ECC_ALGO_NIST_P256: -+ return "NIST P-256"; -+ case ECC_ALGO_NIST_P384: -+ return "NIST P-384"; -+ case ECC_ALGO_NIST_P521: -+ return "NIST P-521"; -+ case ECC_ALGO_SECP256K1: -+ return "secp256k1"; -+ default: -+ return NULL; -+ } -+} -+ -+static int -+ecc_nbits (int algo) -+{ -+ switch (algo) -+ { -+ case ECC_ALGO_ED25519: -+ return 255; -+ case ECC_ALGO_ED448: -+ return 448; -+ case ECC_ALGO_NIST_P192: -+ return 192; -+ case ECC_ALGO_NIST_P224: -+ return 224; -+ case ECC_ALGO_NIST_P256: -+ return 256; -+ case ECC_ALGO_NIST_P384: -+ return 384; -+ case ECC_ALGO_NIST_P521: -+ return 521; -+ case ECC_ALGO_SECP256K1: -+ return 256; -+ default: -+ return 0; -+ } -+} -+ -+static int -+ecc_map_name (const char *name) -+{ -+ int i; -+ -+ for (i = 0; i < __MAX_ECC_ALGO; i++) -+ { -+ if (strcmp(ecc_algo_name(i), name) == 0) -+ { -+ return i; -+ } -+ } -+ -+ return -1; -+} -+ -+ -+static int -+bench_ecc_mult_init (struct bench_obj *obj) -+{ -+ struct bench_ecc_oper *oper = obj->priv; -+ struct bench_ecc_mult_hd *hd; -+ int p_size = ecc_nbits (oper->algo); -+ gpg_error_t err; -+ gcry_mpi_t p; -+ -+ obj->min_bufsize = 1; -+ obj->max_bufsize = 4; -+ obj->step_size = 1; -+ obj->num_measure_repetitions = -+ num_measurement_repetitions / obj->max_bufsize; -+ -+ while (obj->num_measure_repetitions == 0) -+ { -+ if (obj->max_bufsize == 2) -+ { -+ obj->num_measure_repetitions = 2; -+ } -+ else -+ { -+ obj->max_bufsize--; -+ obj->num_measure_repetitions = -+ num_measurement_repetitions / obj->max_bufsize; -+ } -+ } -+ -+ hd = calloc (1, sizeof(*hd)); -+ if (!hd) -+ return -1; -+ -+ err = gcry_mpi_ec_new (&hd->ec, NULL, ecc_algo_curve(oper->algo)); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_mpi_ec_new failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ hd->G = gcry_mpi_ec_get_point ("g", hd->ec, 1); -+ hd->Q = gcry_mpi_point_new (0); -+ hd->x = gcry_mpi_new (0); -+ hd->y = gcry_mpi_new (0); -+ hd->k = gcry_mpi_new (p_size); -+ gcry_mpi_randomize (hd->k, p_size, GCRY_WEAK_RANDOM); -+ p = gcry_mpi_ec_get_mpi ("p", hd->ec, 1); -+ gcry_mpi_mod (hd->k, hd->k, p); -+ gcry_mpi_release (p); -+ -+ obj->hd = hd; -+ return 0; -+} -+ -+static void -+bench_ecc_mult_free (struct bench_obj *obj) -+{ -+ struct bench_ecc_mult_hd *hd = obj->hd; -+ -+ gcry_mpi_release (hd->k); -+ gcry_mpi_release (hd->y); -+ gcry_mpi_release (hd->x); -+ gcry_mpi_point_release (hd->Q); -+ gcry_mpi_point_release (hd->G); -+ gcry_ctx_release (hd->ec); -+ free (hd); -+ obj->hd = NULL; -+} -+ -+static void -+bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) -+{ -+ struct bench_ecc_mult_hd *hd = obj->hd; -+ size_t i; -+ -+ (void)buf; -+ -+ for (i = 0; i < num_iter; i++) -+ { -+ gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec); -+ if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec)) -+ { -+ fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n"); -+ exit (1); -+ } -+ } -+} -+ -+ -+static int -+bench_ecc_init (struct bench_obj *obj) -+{ -+ struct bench_ecc_oper *oper = obj->priv; -+ struct bench_ecc_hd *hd; -+ int p_size = ecc_nbits (oper->algo); -+ gpg_error_t err; -+ gcry_mpi_t x; -+ -+ obj->min_bufsize = 1; -+ obj->max_bufsize = 4; -+ obj->step_size = 1; -+ obj->num_measure_repetitions = -+ num_measurement_repetitions / obj->max_bufsize; -+ -+ while (obj->num_measure_repetitions == 0) -+ { -+ if (obj->max_bufsize == 2) -+ { -+ obj->num_measure_repetitions = 2; -+ } -+ else -+ { -+ obj->max_bufsize--; -+ obj->num_measure_repetitions = -+ num_measurement_repetitions / obj->max_bufsize; -+ } -+ } -+ -+ hd = calloc (1, sizeof(*hd)); -+ if (!hd) -+ return -1; -+ -+ x = gcry_mpi_new (p_size); -+ gcry_mpi_randomize (x, p_size, GCRY_WEAK_RANDOM); -+ -+ switch (oper->algo) -+ { -+ default: -+ return -1; -+ -+ case ECC_ALGO_ED25519: -+ err = gcry_sexp_build (&hd->key_spec, NULL, -+ "(genkey (ecdsa (curve \"Ed25519\")" -+ "(flags eddsa)))"); -+ if (err) -+ break; -+ err = gcry_sexp_build (&hd->data, NULL, -+ "(data (flags eddsa)(hash-algo sha512)" -+ " (value %m))", x); -+ break; -+ -+ case ECC_ALGO_ED448: -+ err = gcry_sexp_build (&hd->key_spec, NULL, -+ "(genkey (ecdsa (curve \"Ed448\")" -+ "(flags eddsa)))"); -+ if (err) -+ break; -+ err = gcry_sexp_build (&hd->data, NULL, -+ "(data (flags eddsa)(hash-algo shake256)" -+ " (value %m))", x); -+ break; -+ -+ case ECC_ALGO_NIST_P192: -+ case ECC_ALGO_NIST_P224: -+ case ECC_ALGO_NIST_P256: -+ case ECC_ALGO_NIST_P384: -+ case ECC_ALGO_NIST_P521: -+ err = gcry_sexp_build (&hd->key_spec, NULL, -+ "(genkey (ECDSA (nbits %d)))", p_size); -+ if (err) -+ break; -+ err = gcry_sexp_build (&hd->data, NULL, -+ "(data (flags raw) (value %m))", x); -+ break; -+ } -+ -+ gcry_mpi_release (x); -+ -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_sexp_build failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ -+ obj->hd = hd; -+ return 0; -+} -+ -+static void -+bench_ecc_free (struct bench_obj *obj) -+{ -+ struct bench_ecc_hd *hd = obj->hd; -+ -+ gcry_sexp_release (hd->sig); -+ gcry_sexp_release (hd->pub_key); -+ gcry_sexp_release (hd->sec_key); -+ gcry_sexp_release (hd->data); -+ gcry_sexp_release (hd->key_spec); -+ free (hd); -+ obj->hd = NULL; -+} -+ -+static void -+bench_ecc_keygen (struct bench_ecc_hd *hd) -+{ -+ gcry_sexp_t key_pair; -+ gpg_error_t err; -+ -+ err = gcry_pk_genkey (&key_pair, hd->key_spec); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_pk_genkey failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ -+ hd->pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); -+ if (!hd->pub_key) -+ { -+ fprintf (stderr, PGM ": public part missing in key\n"); -+ exit (1); -+ } -+ hd->sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); -+ if (!hd->sec_key) -+ { -+ fprintf (stderr, PGM ": private part missing in key\n"); -+ exit (1); -+ } -+ -+ gcry_sexp_release (key_pair); -+} -+ -+static void -+bench_ecc_keygen_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) -+{ -+ struct bench_ecc_hd *hd = obj->hd; -+ size_t i; -+ -+ (void)buf; -+ -+ for (i = 0; i < num_iter; i++) -+ { -+ bench_ecc_keygen (hd); -+ gcry_sexp_release (hd->pub_key); -+ gcry_sexp_release (hd->sec_key); -+ } -+ -+ hd->pub_key = NULL; -+ hd->sec_key = NULL; -+} -+ -+static void -+bench_ecc_sign_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) -+{ -+ struct bench_ecc_hd *hd = obj->hd; -+ gpg_error_t err; -+ size_t i; -+ -+ (void)buf; -+ -+ bench_ecc_keygen (hd); -+ -+ for (i = 0; i < num_iter; i++) -+ { -+ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ gcry_sexp_release (hd->sig); -+ } -+ -+ gcry_sexp_release (hd->pub_key); -+ gcry_sexp_release (hd->sec_key); -+ hd->sig = NULL; -+ hd->pub_key = NULL; -+ hd->sec_key = NULL; -+} -+ -+static void -+bench_ecc_verify_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) -+{ -+ struct bench_ecc_hd *hd = obj->hd; -+ gpg_error_t err; -+ int i; -+ -+ (void)buf; -+ -+ bench_ecc_keygen (hd); -+ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ -+ for (i = 0; i < num_iter; i++) -+ { -+ err = gcry_pk_verify (hd->sig, hd->data, hd->pub_key); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_pk_verify failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ } -+ -+ gcry_sexp_release (hd->sig); -+ gcry_sexp_release (hd->pub_key); -+ gcry_sexp_release (hd->sec_key); -+ hd->sig = NULL; -+ hd->pub_key = NULL; -+ hd->sec_key = NULL; -+} -+ -+ -+static struct bench_ops ecc_mult_ops = { -+ &bench_ecc_mult_init, -+ &bench_ecc_mult_free, -+ &bench_ecc_mult_do_bench -+}; -+ -+static struct bench_ops ecc_keygen_ops = { -+ &bench_ecc_init, -+ &bench_ecc_free, -+ &bench_ecc_keygen_do_bench -+}; -+ -+static struct bench_ops ecc_sign_ops = { -+ &bench_ecc_init, -+ &bench_ecc_free, -+ &bench_ecc_sign_do_bench -+}; -+ -+static struct bench_ops ecc_verify_ops = { -+ &bench_ecc_init, -+ &bench_ecc_free, -+ &bench_ecc_verify_do_bench -+}; -+ -+ -+static struct bench_ecc_oper ecc_operations[] = { -+ { ECC_OPER_MULT, "mult", &ecc_mult_ops }, -+ { ECC_OPER_KEYGEN, "keygen", &ecc_keygen_ops }, -+ { ECC_OPER_SIGN, "sign", &ecc_sign_ops }, -+ { ECC_OPER_VERIFY, "verify", &ecc_verify_ops }, -+ { 0, NULL, NULL } -+}; -+ -+ -+static void -+cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper) -+{ -+ struct bench_ecc_oper oper = *poper; -+ struct bench_obj obj = { 0 }; -+ double result; -+ -+ if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT) -+ return; -+ -+ oper.algo = algo; -+ -+ bench_print_mode (14, oper.name); -+ -+ obj.ops = oper.ops; -+ obj.priv = &oper; -+ -+ result = do_slope_benchmark (&obj); -+ bench_print_result_nsec_per_iteration (result); -+} -+ -+ -+static void -+_ecc_bench (int algo) -+{ -+ const char *algo_name; -+ int i; -+ -+ algo_name = ecc_algo_name (algo); -+ -+ bench_print_header_nsec_per_iteration (14, algo_name); -+ -+ for (i = 0; ecc_operations[i].name; i++) -+ cipher_ecc_one (algo, &ecc_operations[i]); -+ -+ bench_print_footer (14); -+} -+#endif -+ -+ -+void -+ecc_bench (char **argv, int argc) -+{ -+#if USE_ECC -+ int i, algo; -+ -+ bench_print_section ("ecc", "ECC"); -+ -+ if (argv && argc) -+ { -+ for (i = 0; i < argc; i++) -+ { -+ algo = ecc_map_name (argv[i]); -+ if (algo >= 0) -+ _ecc_bench (algo); -+ } -+ } -+ else -+ { -+ for (i = 0; i < __MAX_ECC_ALGO; i++) -+ _ecc_bench (i); -+ } -+#else -+ (void)argv; -+ (void)argc; -+#endif -+} -+ - /************************************************************** Main program. */ - - void - print_help (void) - { - static const char *help_lines[] = { -- "usage: bench-slope [options] [hash|mac|cipher|kdf [algonames]]", -+ "usage: bench-slope [options] [hash|mac|cipher|kdf|ecc [algonames]]", - "", - " options:", - " --cpu-mhz Set CPU speed for calculating cycles", -@@ -2304,6 +2883,7 @@ main (int argc, char **argv) - mac_bench (NULL, 0); - cipher_bench (NULL, 0); - kdf_bench (NULL, 0); -+ ecc_bench (NULL, 0); - } - else if (!strcmp (*argv, "hash")) - { -@@ -2337,6 +2917,14 @@ main (int argc, char **argv) - warm_up_cpu (); - kdf_bench ((argc == 0) ? NULL : argv, argc); - } -+ else if (!strcmp (*argv, "ecc")) -+ { -+ argc--; -+ argv++; -+ -+ warm_up_cpu (); -+ ecc_bench ((argc == 0) ? NULL : argv, argc); -+ } - else - { - fprintf (stderr, PGM ": unknown argument: %s\n", *argv); - -commit 9911069388e762d2a85bc2a11ca6cfcc4c895e4f -Author: Jussi Kivilinna -Date: Wed Jun 16 20:27:01 2021 +0300 - - bench-slope: add X25519 and X448 scalar multiplication - - * tests/bench-slope.c (ECC_ALGO_X25519, ECC_ALGO_X448): New. - (ecc_algo_name, ecc_algo_curve, ecc_nbits): Add X25519 and X448. - (bench_ecc_mult_do_bench): Pass Y as NULL to ec_get_affine with - X25519 and X448. - (cipher_ecc_one): Run only multiplication bench for X25519 and X448. - -- - - Signed-off-by: Jussi Kivilinna - -diff --git a/tests/bench-slope.c b/tests/bench-slope.c -index 9b4a139a..35272094 100644 ---- a/tests/bench-slope.c -+++ b/tests/bench-slope.c -@@ -2144,6 +2144,8 @@ enum bench_ecc_algo - { - ECC_ALGO_ED25519 = 0, - ECC_ALGO_ED448, -+ ECC_ALGO_X25519, -+ ECC_ALGO_X448, - ECC_ALGO_NIST_P192, - ECC_ALGO_NIST_P224, - ECC_ALGO_NIST_P256, -@@ -2197,6 +2199,10 @@ ecc_algo_name (int algo) - return "Ed25519"; - case ECC_ALGO_ED448: - return "Ed448"; -+ case ECC_ALGO_X25519: -+ return "X25519"; -+ case ECC_ALGO_X448: -+ return "X448"; - case ECC_ALGO_NIST_P192: - return "NIST-P192"; - case ECC_ALGO_NIST_P224: -@@ -2223,6 +2229,10 @@ ecc_algo_curve (int algo) - return "Ed25519"; - case ECC_ALGO_ED448: - return "Ed448"; -+ case ECC_ALGO_X25519: -+ return "Curve25519"; -+ case ECC_ALGO_X448: -+ return "X448"; - case ECC_ALGO_NIST_P192: - return "NIST P-192"; - case ECC_ALGO_NIST_P224: -@@ -2249,6 +2259,10 @@ ecc_nbits (int algo) - return 255; - case ECC_ALGO_ED448: - return 448; -+ case ECC_ALGO_X25519: -+ return 255; -+ case ECC_ALGO_X448: -+ return 448; - case ECC_ALGO_NIST_P192: - return 192; - case ECC_ALGO_NIST_P224: -@@ -2355,15 +2369,26 @@ bench_ecc_mult_free (struct bench_obj *obj) - static void - bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) - { -+ struct bench_ecc_oper *oper = obj->priv; - struct bench_ecc_mult_hd *hd = obj->hd; -+ gcry_mpi_t y; - size_t i; - - (void)buf; - -+ if (oper->algo == ECC_ALGO_X25519 || oper->algo == ECC_ALGO_X448) -+ { -+ y = NULL; -+ } -+ else -+ { -+ y = hd->y; -+ } -+ - for (i = 0; i < num_iter; i++) - { - gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec); -- if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec)) -+ if (gcry_mpi_ec_get_affine (hd->x, y, hd->Q, hd->ec)) - { - fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n"); - exit (1); -@@ -2634,7 +2659,8 @@ cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper) - struct bench_obj obj = { 0 }; - double result; - -- if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT) -+ if ((algo == ECC_ALGO_X25519 || algo == ECC_ALGO_X448 || -+ algo == ECC_ALGO_SECP256K1) && oper.oper != ECC_OPER_MULT) - return; - - oper.algo = algo; - - -From bd49a4fa915b8a078c341b35f5a51fcb2a004c35 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Mon, 12 Jul 2021 21:35:18 +0200 -Subject: [PATCH 1/8] mac: Disable AES GMAC in FIPS mode - -* cipher/mac-gmac.c (_gcry_mac_type_spec_gmac_aes): Remove FIPS flag --- -The GMAC does not work in FIPS mode until libgcrypt will have internal -IV generator. - -Signed-off-by: Jakub Jelen ---- - cipher/mac-gmac.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cipher/mac-gmac.c b/cipher/mac-gmac.c -index e04c6d1e..1d59d085 100644 ---- a/cipher/mac-gmac.c -+++ b/cipher/mac-gmac.c -@@ -157,7 +157,7 @@ static gcry_mac_spec_ops_t gmac_ops = { - - #if USE_AES - gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = { -- GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES", -+ GCRY_MAC_GMAC_AES, {0, 0}, "GMAC_AES", - &gmac_ops - }; - #endif --- -2.31.1 - - -From fd0e1c3e7f6062579869d345875d6ef823706e56 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Mon, 12 Jul 2021 21:36:34 +0200 -Subject: [PATCH 2/8] tests: Do not expect GCM work in FIPS - -* tests/basic.c (check_one_cipher_core): Expect GCM ciphers to fail in - FIPS mode - (check_cipher_modes): Skip GCM ciphers tests as they fail quite late - in gcry_cipher_gettag(). --- - -Signed-off-by: Jakub Jelen ---- - tests/basic.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/tests/basic.c b/tests/basic.c -index 0572c46e..d7b7f496 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -9510,6 +9510,13 @@ check_one_cipher_core (int algo, int mode, int flags, - - clutter_vector_registers(); - err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain); -+ if (in_fips_mode && mode == GCRY_CIPHER_MODE_GCM) -+ { -+ if (!err) -+ fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt is expected to " -+ "fail in FIPS mode: %s\n", pass, algo, mode, gpg_strerror (err)); -+ goto err_out_free; -+ } - if (err) - { - fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", -@@ -10257,7 +10264,12 @@ check_cipher_modes(void) - check_cfb_cipher (); - check_ofb_cipher (); - check_ccm_cipher (); -- check_gcm_cipher (); -+ if (!in_fips_mode) -+ { -+ /* This will have to go through modifications as the GCM fails in fips -+ * as late as in gcry_cipher_gettag, but we want to allow it in the end */ -+ check_gcm_cipher (); -+ } - check_poly1305_cipher (); - check_ocb_cipher (); - check_xts_cipher (); --- -2.31.1 - - -From ccbb1694693080822858e2065cf88ab43ec03fbc Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 09:18:52 +0200 -Subject: [PATCH 3/8] tests: Skip unsupported mechanisms in FIPS mode - -* tests/bench-slope.c (cipher_bench_one): Skip GCM mode in FIPS mode - (ecc_algo_fips_allowed): New function - (_ecc_bench): Skip algorithms disabled in FIPS mode - (main): Check for FIPS mode -* tests/benchmark.c (cipher_bench): Skip GCM in FIPS mode --- -In FIPS mode, not all the curves are allowed. This is already checked in -other parts of the code base, but not in the benchmark test. - -Signed-off-by: Jakub Jelen ---- - tests/bench-slope.c | 33 +++++++++++++++++++++++++++++++-- - tests/benchmark.c | 4 ++++ - 2 files changed, 35 insertions(+), 2 deletions(-) - -diff --git a/tests/bench-slope.c b/tests/bench-slope.c -index 35272094..5bdb391e 100644 ---- a/tests/bench-slope.c -+++ b/tests/bench-slope.c -@@ -70,6 +70,7 @@ static double bench_ghz; - /* Current accuracy of auto-detected CPU Ghz. */ - static double bench_ghz_diff; - -+static int in_fips_mode = 0; - - /*************************************** Default parameters for measurements. */ - -@@ -1642,8 +1643,8 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode) - if (mode.mode == GCRY_CIPHER_MODE_CCM && blklen != GCRY_CCM_BLOCK_LEN) - return; - -- /* GCM has restrictions for block-size */ -- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) -+ /* GCM has restrictions for block-size; not allowed in FIPS mode */ -+ if (mode.mode == GCRY_CIPHER_MODE_GCM && (in_fips_mode || blklen != GCRY_GCM_BLOCK_LEN)) - return; - - /* XTS has restrictions for block-size */ -@@ -2190,6 +2191,27 @@ struct bench_ecc_hd - }; - - -+static int -+ecc_algo_fips_allowed (int algo) -+{ -+ switch (algo) -+ { -+ case ECC_ALGO_NIST_P224: -+ case ECC_ALGO_NIST_P256: -+ case ECC_ALGO_NIST_P384: -+ case ECC_ALGO_NIST_P521: -+ return 1; -+ case ECC_ALGO_SECP256K1: -+ case ECC_ALGO_ED25519: -+ case ECC_ALGO_ED448: -+ case ECC_ALGO_X25519: -+ case ECC_ALGO_X448: -+ case ECC_ALGO_NIST_P192: -+ default: -+ return 0; -+ } -+} -+ - static const char * - ecc_algo_name (int algo) - { -@@ -2681,6 +2703,10 @@ _ecc_bench (int algo) - const char *algo_name; - int i; - -+ /* Skip not allowed mechanisms */ -+ if (!ecc_algo_fips_allowed(algo)) -+ return; -+ - algo_name = ecc_algo_name (algo); - - bench_print_header_nsec_per_iteration (14, algo_name); -@@ -2899,6 +2925,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - if (in_regression_test) - fputs ("Note: " PGM " running in quick regression test mode.\n", stdout); - -diff --git a/tests/benchmark.c b/tests/benchmark.c -index 605b50c6..24141371 100644 ---- a/tests/benchmark.c -+++ b/tests/benchmark.c -@@ -943,6 +943,10 @@ cipher_bench ( const char *algoname ) - && algo != GCRY_CIPHER_CHACHA20) - continue; - -+ /* GCM is not available in FIPS mode */ -+ if (in_fips_mode && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM) -+ continue; -+ - if (modes[modeidx].req_blocksize > 0 - && blklen != modes[modeidx].req_blocksize) - { --- -2.31.1 - - -From 744baa85722da10d7374c6eca6b08b8197819ab6 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 09:20:18 +0200 -Subject: [PATCH 4/8] tests: Expect curves 25519/448 to fail in FIPS mode - -* tests/t-cv25519.c (test_cv_hl): Expect the operation to fail in FIPS - mode. - (test_cv_x25519, test_it): Ditto. - (main) Detect FIPS mode. -* tests/t-ed25519.c (one_test): Expect the operation to fail in FIPS - mode. - (main) Detect FIPS mode. -* tests/t-ed448.c (one_test): Expect the operation to fail in FIPS - mode. - (main) Detect FIPS mode. -* tests/t-x448.c (test_cv_hl): Expect the operation to fail in FIPS - mode. - (test_cv_x448, test_cv): Ditto. - (main) Detect FIPS mode. --- -The ed25519, ed448, cv25519 and cv448 curves are not available in FIPS -mode. Some of the tests already skipped these, but it is always better -to make sure thy are failing, rather than just skipping these. - -Signed-off-by: Jakub Jelen ---- - tests/t-cv25519.c | 37 +++++++++++++++++++++++++++++++++++-- - tests/t-ed25519.c | 18 ++++++++++++++---- - tests/t-ed448.c | 18 ++++++++++++++---- - tests/t-x448.c | 41 +++++++++++++++++++++++++++++++++++++---- - 4 files changed, 100 insertions(+), 14 deletions(-) - -diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c -index 0de50a02..b4126f4c 100644 ---- a/tests/t-cv25519.c -+++ b/tests/t-cv25519.c -@@ -33,6 +33,7 @@ - #include "t-common.h" - #define N_TESTS 18 - -+static int in_fips_mode = 0; - - static void - print_mpi (const char *text, gcry_mpi_t a) -@@ -188,7 +189,17 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, - xfree (buffer); - buffer = NULL; - -- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) -+ err = gcry_pk_encrypt (&s_result, s_data, s_pk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_encrypt failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -281,7 +292,17 @@ test_cv_x25519 (int testno, const char *k_str, const char *u_str, - goto leave; - } - -- if ((err = gcry_ecc_mul_point (algo, result, scalar, point))) -+ err = gcry_ecc_mul_point (algo, result, scalar, point); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_ecc_mul_point failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -335,6 +356,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) - info ("Running test %d: iteration=%d\n", testno, iter); - - gcry_mpi_ec_new (&ctx, NULL, "Curve25519"); -+ if (in_fips_mode) -+ { -+ if (ctx) -+ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ return; -+ } - Q = gcry_mpi_point_new (0); - - if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32) -@@ -640,6 +670,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - start_timer (); - check_cv25519 (); - stop_timer (); -diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c -index a5271c25..567bc797 100644 ---- a/tests/t-ed25519.c -+++ b/tests/t-ed25519.c -@@ -36,6 +36,7 @@ - static int sign_with_pk; - static int no_verify; - static int custom_data_file; -+static int in_fips_mode = 0; - - - static void -@@ -271,7 +272,17 @@ one_test (int testno, const char *sk, const char *pk, - goto leave; - } - -- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) -+ err = gcry_pk_sign (&s_sig, s_msg, s_sk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); - if (debug) - show_sexp ("sig=", s_sig); -@@ -481,9 +492,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -- /* Ed25519 isn't supported in fips mode */ -- if (gcry_fips_mode_active()) -- return 77; -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - - start_timer (); - check_ed25519 (fname); -diff --git a/tests/t-ed448.c b/tests/t-ed448.c -index 1f445ffc..f38cd10c 100644 ---- a/tests/t-ed448.c -+++ b/tests/t-ed448.c -@@ -36,6 +36,7 @@ - static int sign_with_pk; - static int no_verify; - static int custom_data_file; -+static int in_fips_mode = 0; - - - static void -@@ -302,7 +303,17 @@ one_test (int testno, int ph, const char *sk, const char *pk, - } - } - -- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) -+ err = gcry_pk_sign (&s_sig, s_msg, s_sk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); - if (debug) - show_sexp ("sig=", s_sig); -@@ -521,9 +532,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -- /* Ed448 isn't supported in fips mode */ -- if (gcry_fips_mode_active()) -- return 77; -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - - start_timer (); - check_ed448 (fname); -diff --git a/tests/t-x448.c b/tests/t-x448.c -index 5c3cbeb9..cc4b10fc 100644 ---- a/tests/t-x448.c -+++ b/tests/t-x448.c -@@ -34,6 +34,7 @@ - #include "t-common.h" - #define N_TESTS 9 - -+static int in_fips_mode = 0; - - static void - print_mpi (const char *text, gcry_mpi_t a) -@@ -179,8 +180,18 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, - xfree (buffer); - buffer = NULL; - -- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) -- fail ("gcry_pk_encrypt failed for test %d: %s", testno, -+ err = gcry_pk_encrypt (&s_result, s_data, s_pk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) -+ fail ("gcry_pk_encrypt goto leavefailed for test %d: %s", testno, - gpg_strerror (err)); - - s_tmp = gcry_sexp_find_token (s_result, "s", 0); -@@ -257,7 +268,17 @@ test_cv_x448 (int testno, const char *k_str, const char *u_str, - goto leave; - } - -- if ((err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point))) -+ err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point); -+ if (in_fips_mode) -+ { -+ if (err != GPG_ERR_NOT_SUPPORTED) -+ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d: %s", -+ testno, gpg_strerror (err)); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_ecc_mul_point failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -296,7 +317,7 @@ test_cv (int testno, const char *k_str, const char *u_str, - static void - test_it (int testno, const char *k_str, int iter, const char *result_str) - { -- gcry_ctx_t ctx; -+ gcry_ctx_t ctx = NULL; - gpg_error_t err; - void *buffer = NULL; - size_t buflen; -@@ -311,6 +332,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) - info ("Running test %d: iteration=%d\n", testno, iter); - - gcry_mpi_ec_new (&ctx, NULL, "X448"); -+ if (in_fips_mode) -+ { -+ if (ctx) -+ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ return; -+ } - Q = gcry_mpi_point_new (0); - - if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 56) -@@ -583,6 +613,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - start_timer (); - check_x448 (); - stop_timer (); --- -2.31.1 - - -From d3a603cd4a0ff2a8df35f5bb39efd64c52b2b2c5 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 10:11:42 +0200 -Subject: [PATCH 5/8] tests: Expect the 192b ECDSA tests to fail in fips mode - -* tests/dsa-rfc6979.c (check_dsa_rfc6979): Expect ECDSA 192b keys to - fail in FIPS mode. - (main): Detect FIPS mode. --- -The 192b ECDSA curve is not FIPS approved so it does not work. This adds -a flag to the list of the keys to mark if it is expected to work in FIPS -mode. - -Signed-off-by: Jakub Jelen ---- - tests/dsa-rfc6979.c | 24 +++++++++++++++++------- - 1 file changed, 17 insertions(+), 7 deletions(-) - -diff --git a/tests/dsa-rfc6979.c b/tests/dsa-rfc6979.c -index 7d3d2080..0f124575 100644 ---- a/tests/dsa-rfc6979.c -+++ b/tests/dsa-rfc6979.c -@@ -33,6 +33,7 @@ - #define PGM "dsa-rfc6979" - #include "t-common.h" - -+static int in_fips_mode = 0; - - static void - show_sexp (const char *prefix, gcry_sexp_t a) -@@ -111,6 +112,7 @@ check_dsa_rfc6979 (void) - static struct { - const char *name; - const char *key; -+ int fips; - } keys[] = { - { - "DSA, 1024 bits", -@@ -130,7 +132,7 @@ check_dsa_rfc6979 (void) - " 92195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D" - " 4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E6" - " 82F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B#)" -- " ))" -+ " ))", 1 - }, - { - "DSA, 2048 bits", -@@ -162,7 +164,7 @@ check_dsa_rfc6979 (void) - " 687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D1" - " 23AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA" - " 74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)" -- " ))" -+ " ))", 1 - }, - { - "ECDSA, 192 bits (prime field)", -@@ -172,7 +174,7 @@ check_dsa_rfc6979 (void) - " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" - " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" - " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" -- " ))" -+ " ))", 0 - }, - { - "ECDSA, 224 bits (prime field)", -@@ -183,7 +185,7 @@ check_dsa_rfc6979 (void) - " 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C" - " EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)" - " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)" -- " ))" -+ " ))", 1 - }, - { - "ECDSA, 256 bits (prime field)", -@@ -194,7 +196,7 @@ check_dsa_rfc6979 (void) - " 60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6" - " 7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)" - " (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)" -- " ))" -+ " ))", 1 - }, - { - "ECDSA, 384 bits (prime field)", -@@ -208,7 +210,7 @@ check_dsa_rfc6979 (void) - " 288B231C3AE0D4FE7344FD2533264720#)" - " (d #6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8" - " 96D5724E4C70A825F872C9EA60D2EDF5#)" -- " ))" -+ " ))", 1 - }, - { - "ECDSA, 521 bits (prime field)", -@@ -225,7 +227,7 @@ check_dsa_rfc6979 (void) - " (d #FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75" - " CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B8" - " 3538#)" -- " ))" -+ " ))", 1 - }, - { NULL } - }; -@@ -937,6 +939,12 @@ check_dsa_rfc6979 (void) - die ("building data sexp failed: %s\n", gpg_strerror (err)); - - err = gcry_pk_sign (&sig, data, seckey); -+ if (in_fips_mode && !keys[i].fips) -+ { -+ if (!err) -+ fail ("signing should not work in FIPS mode: %s\n", gpg_strerror (err)); -+ continue; -+ } - if (err) - fail ("signing failed: %s\n", gpg_strerror (err)); - -@@ -972,6 +980,8 @@ main (int argc, char **argv) - die ("version mismatch; pgm=%s, library=%s\n", - GCRYPT_VERSION,gcry_check_version (NULL)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - /* No valuable keys are create, so we can speed up our RNG. */ --- -2.31.1 - - -From d4a52861e7d0d1871f4c1d32bc0815f0824eb9ab Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 10:32:33 +0200 -Subject: [PATCH 6/8] tests: Skip secmem overflow test in FIPS mode - -* tests/t-secmem.c (main): Skip overflow tests in FIPS mode because they - are fatal and there is no way to override the outofcore handler. --- - -Signed-off-by: Jakub Jelen ---- - tests/t-secmem.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/tests/t-secmem.c b/tests/t-secmem.c -index 2b769134..692c0f1a 100644 ---- a/tests/t-secmem.c -+++ b/tests/t-secmem.c -@@ -37,6 +37,7 @@ - #define MINIMUM_POOL_SIZE 16384 - static size_t pool_size; - static size_t chunk_size; -+static int in_fips_mode = 0; - - static void - test_secmem (void) -@@ -182,8 +183,11 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0)); -+ /* This is ignored in FIPS Mode */ - gcry_set_outofcore_handler (outofcore_handler, NULL); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - - /* Libgcrypt prints a warning when the first overflow is allocated; - * we do not want to see that. */ -@@ -192,7 +196,8 @@ main (int argc, char **argv) - - - test_secmem (); -- test_secmem_overflow (); -+ if (!in_fips_mode) -+ test_secmem_overflow (); - /* FIXME: We need to improve the tests, for example by registering - * our own log handler and comparing the output of - * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */ --- -2.31.1 - - -From fc6de9c7b48ab45deb8ea84d1c768e4f056edb08 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 10:52:00 +0200 -Subject: [PATCH 7/8] tests: Transient DSA keys work in FIPS mode - -* tests/pubkey.c (check_run): Enable tests with DSA transient keys which - work in FIPS. --- - -Signed-off-by: Jakub Jelen ---- - tests/pubkey.c | 15 ++++++--------- - 1 file changed, 6 insertions(+), 9 deletions(-) - -diff --git a/tests/pubkey.c b/tests/pubkey.c -index 754952ee..cd51e0a2 100644 ---- a/tests/pubkey.c -+++ b/tests/pubkey.c -@@ -680,15 +680,12 @@ check_run (void) - gcry_sexp_release (pkey); - gcry_sexp_release (skey); - -- if (!gcry_fips_mode_active ()) -- { -- if (verbose) -- fprintf (stderr, "Generating transient DSA key.\n"); -- get_dsa_key_new (&pkey, &skey, 1); -- /* Fixme: Add a check function for DSA keys. */ -- gcry_sexp_release (pkey); -- gcry_sexp_release (skey); -- } -+ if (verbose) -+ fprintf (stderr, "Generating transient DSA key.\n"); -+ get_dsa_key_new (&pkey, &skey, 1); -+ /* Fixme: Add a check function for DSA keys. */ -+ gcry_sexp_release (pkey); -+ gcry_sexp_release (skey); - - if (verbose) - fprintf (stderr, "Generating DSA key (FIPS 186).\n"); --- -2.31.1 - - -From e68b538008063938b9b054f18e56e9f27bb3a720 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 10:53:13 +0200 -Subject: [PATCH 8/8] tests: Generating DSA from domain should fail in FIPS - mode - -* tests/pubkey.c (get_dsa_key_with_domain_new): Expect failure in FIPS - mode - (check_x931_derived_key): Simplify testing for FIPS mode. - (main): Check for fips mode. --- - -Signed-off-by: Jakub Jelen ---- - tests/pubkey.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/tests/pubkey.c b/tests/pubkey.c -index cd51e0a2..7209f44e 100644 ---- a/tests/pubkey.c -+++ b/tests/pubkey.c -@@ -29,6 +29,7 @@ - #define PGM "pubkey" - #include "t-common.h" - -+static int in_fips_mode; - - /* Sample RSA keys, taken from basic.c. */ - -@@ -518,6 +519,14 @@ get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); - rc = gcry_pk_genkey (&key, key_spec); - gcry_sexp_release (key_spec); -+ if (in_fips_mode) -+ { -+ if (!rc) -+ die ("generating DSA key should fail in FIPS mode: %s\n", gcry_strerror (rc)); -+ *pkey = NULL; -+ *skey = NULL; -+ return; -+ } - if (rc) - die ("error generating DSA key: %s\n", gcry_strerror (rc)); - -@@ -899,7 +908,7 @@ check_x931_derived_key (int what) - err = _gcry_pk_util_get_nbits(key_spec, &nbits); - if (err) - die ("nbits not found\n"); -- if (gcry_fips_mode_active() && nbits < 2048) -+ if (in_fips_mode && nbits < 2048) - { - info("RSA key test with %d bits skipped in fips mode\n", nbits); - goto leave; -@@ -1186,6 +1195,9 @@ main (int argc, char **argv) - /* No valuable keys are create, so we can speed up our RNG. */ - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - for (i=0; i < 2; i++) - check_run (); - -@@ -1193,7 +1205,7 @@ main (int argc, char **argv) - check_x931_derived_key (i); - - check_ecc_sample_key (); -- if (!gcry_fips_mode_active ()) -+ if (!in_fips_mode) - check_ed25519ecdsa_sample_key (); - - return !!error_count; --- -2.31.1 - -commit 61c87070abc4baeb9d847db015e6a3031f349483 -Author: NIIBE Yutaka -Date: Wed Jul 7 15:52:06 2021 +0900 - - tests: Skip unavailable ciphers in FIPS mode. - - * tests/basic.c (_check_poly1305_cipher): - (check_ocb_cipher_largebuf_split): Skip unavailable ciphers when - IN_FIPS_MODE. - (check_ocb_cipher_checksum, check_gost28147_cipher_basic): Likewise. - - -- - - GnuPG-bug-id: 5520 - Signed-off-by: NIIBE Yutaka - -diff --git a/tests/basic.c b/tests/basic.c -index 0a1e8293..43ef122e 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -5026,6 +5026,14 @@ _check_poly1305_cipher (unsigned int step) - - for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) - { -+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ tv[i].algo); -+ continue; -+ } -+ - if (verbose) - fprintf (stderr, " checking POLY1305 mode for %s [%i]\n", - gcry_cipher_algo_name (tv[i].algo), -@@ -6643,6 +6651,14 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, - memcpy(inbuf + i, hash, 16); - } - -+ if (gcry_cipher_test_algo (algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ algo); -+ goto out_free; -+ } -+ - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); -@@ -6841,6 +6857,14 @@ check_ocb_cipher_checksum (int algo, int keylen) - blk[byteidx] |= 1 << bitpos; - } - -+ if (gcry_cipher_test_algo (algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ algo); -+ goto out_free; -+ } -+ - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); -@@ -7651,6 +7675,15 @@ check_gost28147_cipher_basic (enum gcry_cipher_algos algo) - - if (verbose) - fprintf (stderr, " Starting GOST28147 cipher checks.\n"); -+ -+ if (gcry_cipher_test_algo (algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ algo); -+ return; -+ } -+ - keylen = gcry_cipher_get_algo_keylen(algo); - if (!keylen) - { -commit b98ca3f798abd17696f52163665204c4e83d9092 -Author: Jussi Kivilinna -Date: Wed Jul 7 18:21:27 2021 +0300 - - tests/basic: use SHA256 instead of RMD160 for SHAKE extract testing - - * tests/basic.c (check_one_md): Use GCRY_MD_SHA256 as 'crcalgo' for - SHAKE128/SHAKE256 testing. - -- - - RMD160 was used to calculate output checksum from two SHAKE extract - streams, which are run with different extract buffer size but for - same total length and with same input. Patch switches to use SHA256 - for checksumming for FIPS support. - - GnuPG-bug-id: 5520 - Signed-off-by: Jussi Kivilinna - -diff --git a/tests/basic.c b/tests/basic.c -index bc34bb99..eb6d1514 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -10395,7 +10395,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen, - - if (*data == '!' && !data[1]) - { -- int crcalgo = GCRY_MD_RMD160; -+ int crcalgo = GCRY_MD_SHA256; - gcry_md_hd_t crc1, crc2; - size_t startlen; - size_t piecelen; -commit ccb076e8aabb9c49e7026258b3a36a8422f6bbe4 -Author: NIIBE Yutaka -Date: Wed Jul 7 16:29:48 2021 +0900 - - tests: Fix tests/basic.c for FIPS mode. - - * tests/basic.c (main): Use bare gcry_control for - GCRYCTL_FORCE_FIPS_MODE. - - -- - - GnuPG-bug-id: 5520 - Signed-off-by: NIIBE Yutaka - -diff --git a/tests/basic.c b/tests/basic.c -index 43ef122e..bc34bb99 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -14610,7 +14610,7 @@ main (int argc, char **argv) - gcry_md_hd_t md; - - /* First trigger a self-test. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); -+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("not in operational state after self-test\n"); - -@@ -14639,7 +14639,7 @@ main (int argc, char **argv) - { - /* Now run a self-test and to get back into - operational state. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); -+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("did not reach operational after error " - "and self-test\n"); diff --git a/libgcrypt.spec b/libgcrypt.spec index 9880c7f..d657930 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,46 +1,11 @@ Name: libgcrypt -Version: 1.9.4 -Release: 2%{?dist} +Version: 1.10.0 +Release: 1%{?dist} URL: https://www.gnupg.org/ -Source0: libgcrypt-%{version}-hobbled.tar.xz -# The original libgcrypt sources now contain potentially patented ECC -# cipher support. We have to remove it in the tarball we ship with -# the hobble-libgcrypt script. -# (We replace it with RH approved ECC in Source4-5) -# rm -rf libgcrypt-x.y.z # make sure there are no leftover files -# tar -xf libgcrypt-x.y.z.tar.bz2 -# pushd libgcrypt-x.y.z && ../hobble-libgcrypt && popd -# tar -cvJf libgcrypt-x.y.z-hobbled.tar.xz libgcrypt-x.y.z -#Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2 -#Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2.sig +Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 +Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com -Source3: hobble-libgcrypt -# Approved ECC support -Source4: ecc-curves.c -Source5: curves.c -Source7: random.conf -Source8: keygrip.c -# make FIPS hmac compatible with fipscheck - non upstreamable -# update on soname bump -Patch2: libgcrypt-1.8.5-use-fipscheck.patch -# modify FIPS RSA and DSA keygen to comply with requirements -Patch5: libgcrypt-1.8.4-fips-keygen.patch -# fix the tests to work correctly in the FIPS mode -Patch6: libgcrypt-1.9.3-fips-tests.patch -# use poll instead of select when gathering randomness -Patch11: libgcrypt-1.8.4-use-poll.patch -# slight optimalization of mpicoder.c to silence Valgrind (#968288) -Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch -# Run the FIPS mode initialization in the shared library constructor -Patch18: libgcrypt-1.8.3-fips-ctor.patch -# Do not try to open /dev/urandom if getrandom() works -Patch24: libgcrypt-1.8.5-getrandom.patch -# Disable non-approved FIPS hashes in the enforced FIPS mode -Patch27: libgcrypt-1.8.3-md-fips-enforce.patch -# Missing Intel CET support in the library (#1954049) -Patch28: libgcrypt-1.8.5-intel-cet.patch -# FIPS module is redefined a little bit (implicit by kernel FIPS mode) -Patch30: libgcrypt-1.8.5-fips-module.patch +Patch1: libgcrypt-1.10.0-disable-brainpool.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -76,20 +41,7 @@ applications using libgcrypt. %prep %setup -q -%{SOURCE3} -%patch2 -p1 -b .use-fipscheck -%patch5 -p1 -b .fips-keygen -%patch6 -p1 -b .tests-fipsmode -%patch11 -p1 -b .use-poll -%patch13 -p1 -b .gccopt -%patch18 -p1 -b .fips-ctor -%patch24 -p1 -b .getrandom -%patch27 -p1 -b .fips-enforce -%patch28 -p1 -b .intel-cet -%patch30 -p1 -b .fips-module - -cp %{SOURCE4} cipher/ -cp %{SOURCE5} %{SOURCE8} tests/ +%patch1 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -101,29 +53,48 @@ cp %{SOURCE5} %{SOURCE8} tests/ # F34, so we use it here explicitly %define _lto_cflags -flto=auto -ffat-lto-objects +grep "Red Hat" /etc/system-release && \ +export FIPS_SWITCH="--with-fips-module-version=RHEL%{?rhel}-%{name}-%{version}-$(date +%Y%m%d)" +grep "Fedora" /etc/system-release && \ +export FIPS_SWITCH="--with-fips-module-version=Fedora%{?fedora}-%{name}-%{version}-$(date +%Y%m%d)" +grep "CentOS" /etc/system-release && \ +export FIPS_SWITCH="--with-fips-module-version=CentOS%{?centos}-%{name}-%{version}-$(date +%Y%m%d)" + +# should be all algorithms except SM3 and SM4 +export DIGESTS='crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2' +export CIPHERS='arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20' + autoreconf -f %configure --disable-static \ %ifarch sparc64 --disable-asm \ %endif --enable-noexecstack \ - --enable-hmac-binary-check \ - --enable-pubkey-ciphers='dsa elgamal rsa ecc' \ - --disable-O-flag-munging + --enable-hmac-binary-check=%{hmackey} \ + --disable-brainpool \ + --enable-digests="$DIGESTS" \ + --enable-ciphers="$CIPHERS" \ + $FIPS_SWITCH sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool %make_build %check -src/hmac256 %{hmackey} src/.libs/%{gcrysoname} | cut -f1 -d ' ' >src/.libs/.%{gcrysoname}.hmac - make check +# try in faked FIPS mode too +LIBGCRYPT_FORCE_FIPS_MODE=1 make check # Add generation of HMAC checksums of the final stripped binaries +%define libpath $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname}.?.? %define __spec_install_post \ %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ %{__os_install_post} \ - src/hmac256 %{hmackey} $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname} | cut -f1 -d ' ' >$RPM_BUILD_ROOT%{gcrylibdir}/.%{gcrysoname}.hmac \ + dd if=/dev/zero of=%{libpath}.hmac bs=32 count=1 \ + objcopy --update-section .rodata1=%{libpath}.hmac %{libpath} %{libpath}.empty \ + src/hmac256 --binary %{hmackey} %{libpath}.empty > %{libpath}.hmac \ + objcopy --update-section .rodata1=%{libpath}.hmac %{libpath}.empty %{libpath}.new \ + mv -f %{libpath}.new %{libpath} \ + rm -f %{libpath}.hmac %{libpath}.empty %{nil} %install @@ -168,16 +139,13 @@ popd # Create /etc/gcrypt (hardwired, not dependent on the configure invocation) so # that _someone_ owns it. mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt -install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %ldconfig_scriptlets %files %dir /etc/gcrypt -%config(noreplace) /etc/gcrypt/random.conf %{gcrylibdir}/libgcrypt.so.*.* %{gcrylibdir}/%{gcrysoname} -%{gcrylibdir}/.%{gcrysoname}.hmac %license COPYING.LIB %doc AUTHORS NEWS THANKS @@ -196,6 +164,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Feb 02 2022 Jakub Jelen - 1.10.0-1 +- New upstream release (#2049322) + * Thu Jan 20 2022 Fedora Release Engineering - 1.9.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild diff --git a/random.conf b/random.conf deleted file mode 100644 index 6041bcd..0000000 --- a/random.conf +++ /dev/null @@ -1,4 +0,0 @@ -# use only /dev/urandom - see https://www.2uo.de/myths-about-urandom/ -only-urandom -# Keep jitter entropy generator enabled (should do no harm) -#disable-jent diff --git a/sources b/sources index 8d0f1cb..745f52b 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ -SHA512 (libgcrypt-1.9.4-hobbled.tar.xz) = 80b1b2159ec3c7795450037d76d81b737f2734f1cff72c8aa6ac8c1a5654ece4fce0aabfbed0cce99d123747831db135df0d040f67081052cb2363bf52f5d4e6 +SHA512 (libgcrypt-1.10.0.tar.bz2) = 785c2e14272308956bb6adcea9567c4097edf103122e18cd3907fb42a110a48a5d59c0057f05a438acd7f221c70c7f7ff87e176bd6d7ed99d16e847f9d7be087 +SHA512 (libgcrypt-1.10.0.tar.bz2.sig) = 75201612225b206faaae284297e92d1b25dcaf0665bcf1f4c5cc9a3a750a803063d0f7bd0af556dbe419f1276c953ce047554fd18a144a90085a42a7ec885168 From 559b903aa2608fd74b66a1e9bc994b725d0e0400 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 2 Feb 2022 13:13:00 +0100 Subject: [PATCH 172/214] Update test to work again --- tests/smoke-test/Makefile | 10 +++- tests/smoke-test/runtest.sh | 106 +++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 16 deletions(-) diff --git a/tests/smoke-test/Makefile b/tests/smoke-test/Makefile index 0e0dda3..0682152 100644 --- a/tests/smoke-test/Makefile +++ b/tests/smoke-test/Makefile @@ -57,10 +57,14 @@ $(METADATA): Makefile @echo "Requires: libgcrypt" >> $(METADATA) @echo "Requires: nfs-utils" >> $(METADATA) @echo "Requires: rpm-build" >> $(METADATA) + @echo "Requires: autoconf automake libtool" >> $(METADATA) @echo "Requires: gawk" >> $(METADATA) - @echo "Requires: gcc-c++ fipscheck" >> $(METADATA) - @echo "Requires: libgpg-error-devel wget" >> $(METADATA) - @echo "Requires: pkgconfig texinfo libselinux-utils" >> $(METADATA) + @echo "Requires: gcc-c++" >> $(METADATA) + @echo "Requires: libgpg-error-devel" >> $(METADATA) + @echo "Requires: pkgconfig texinfo fipscheck libkcapi-fipscheck" >> $(METADATA) + @echo "Requires: crypto-policies-scripts" >> $(METADATA) + @echo "Requires: bc" >> $(METADATA) + @echo "RhtsRequires: library(distribution/fips)" >> $(METADATA) @echo "Releases: -RHEL3 -RHEL4" >> $(METADATA) @echo "Priority: Normal" >> $(METADATA) @echo "Architectures: i386 x86_64 s390x ia64" >> $(METADATA) diff --git a/tests/smoke-test/runtest.sh b/tests/smoke-test/runtest.sh index dd1803d..ddd0182 100755 --- a/tests/smoke-test/runtest.sh +++ b/tests/smoke-test/runtest.sh @@ -26,8 +26,6 @@ # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Include rhts environment -#. /usr/bin/rhts-environment.sh . /usr/share/beakerlib/beakerlib.sh PACKAGE="libgcrypt" @@ -35,36 +33,118 @@ PACKAGE="libgcrypt" rlJournalStart rlPhaseStartSetup + rlImport distribution/fips || rlFail "FIPS library needed for some phases" TmpDir=`mktemp -d` rlAssertRpm $PACKAGE - rlFileBackup --clean "/etc/gcrypt/fips_enabled" + rlRun "rlFileBackup --clean /etc/gcrypt/fips_enabled" + if [[ -r /etc/gcrypt/hwf.deny ]]; then + rlRun "rlFileBackup /etc/gcrypt/hwf.deny" + rlRun "rm -f /etc/gcrypt/hwf.deny" + fi rlRun "pushd $TmpDir" 0 - rlFetchSrcForInstalled $PACKAGE + rlRun "rlFetchSrcForInstalled $PACKAGE" rlRun "rpm -ihv `ls *.rpm`" 0 if grep '1' /proc/sys/crypto/fips_enabled; then rlRun "echo '1' > /etc/gcrypt/fips_enabled" 0 fi rlPhaseEnd - rlPhaseStartTest + rlPhaseStartTest "Package build" TOPDIR=`rpm --eval %_topdir` rlRun "pushd $TOPDIR" 0 rlRun "rm -rf BUILD/libgcrypt-*" 0-255 rlRun "rpmbuild -vv -bc SPECS/libgcrypt.spec" 0 rlRun "pushd BUILD/libgcrypt-*" 0 rlRun "fipshmac src/.libs/libgcrypt.so.??" 0 - rlRun "make check > $TmpDir/make_check.out" 0 - rlRun "popd" 0 - rlRun "popd" 0 - rlRun "grep \"All [0-9]\+ tests passed\" $TmpDir/make_check.out" 0 \ - "All tests passed" - rlRun "cat $TmpDir/make_check.out" 0 + rlRun "popd" + rlRun "popd" rlPhaseEnd + rlPhaseStartTest "Upstream testsuite" + rlRun "pushd $TOPDIR/BUILD/libgcrypt-*" 0 + exp_fails=() + if [[ $fipsMode = 'enabled' ]]; then + if rlIsFedora 33; then + exp_fails+=("basic") + exp_fails+=("basic-disable-all-hwf") + exp_fails+=("t-kdf") + exp_fails+=("t-secmem") + elif rlIsFedora 34; then + exp_fails+=("basic") + exp_fails+=("basic-disable-all-hwf") + exp_fails+=("t-kdf") + exp_fails+=("t-secmem") + exp_fails+=("t-x448") + elif rlIsFedora 35; then # Fedora-35 + exp_fails+=("curves") + fi + fi + rlRun "echo 'Expecting ${#exp_fails[@]} fails'" + exp_exitcode=0 + if [[ ${#exp_fails[@]} -gt 0 ]]; then exp_exitcode=2; fi + rlRun "make check &> $TmpDir/make_check.out" $exp_exitcode + rlRun "grep ^FAIL: $TmpDir/make_check.out" 0,1 "Print fails" + if [[ ${#exp_fails[@]} -gt 0 ]]; then + for f in "${exp_fails[@]}"; do + rlAssertGrep "^FAIL: $f\$" $TmpDir/make_check.out + done + [[ $(grep -c '^FAIL:' $TmpDir/make_check.out) -eq ${#exp_fails[@]} ]] || rlFail "Unexpected fails present" + else + rlRun "grep \"All [0-9]\+ tests passed\" $TmpDir/make_check.out" 0 \ + "All tests passed" + fi + rlRun "cat $TmpDir/make_check.out" + rlRun "popd" + rlPhaseEnd + + if ! (rlIsRHEL '<=8.4' || ([[ $fipsMode = "enabled" ]] && rlIsFedora '<37')); then + # (we are ~expecting to fix HW optimization problem around Fedora-37) + rlPhaseStartTest "Performance with HW optimizations disabled - bz1990059" + # we are gathering more samples, so that this test is robust in shared environments + N_SAMPLES=5 + N_MEDIAN=$(echo "$N_SAMPLES/2+1" |bc) + HWF_DENY_FILE="/etc/gcrypt/hwf.deny" + # Disabling via cmdline arguments would need either handpicking + # all the algorithms (variant with ":"), or making "all" work. + # "--disable-hwf all" does not work: https://dev.gnupg.org/T5636 + #dis_arg="--disable-hwf all" + dis_arg="" + + for x in "cipher:aes256:CBC enc" "hash:sha256:SHA256" "mac:hmac_sha256:HMAC_SHA256"; do + alg_type=$(echo $x |cut -d: -f1) + algorithm=$(echo $x |cut -d: -f2) + alg_line=$(echo $x |cut -d: -f3) + rlRun "rm -f $algorithm.ena $algorithm.dis" + rlLogInfo "Performance measurements started ..." + for i in `seq 1 $N_SAMPLES`; do + # run with HW optimizations ENAbled + rm -f $HWF_DENY_FILE + $TOPDIR/BUILD/libgcrypt-*/tests/bench-slope $alg_type $algorithm |grep "$alg_line" >>$algorithm.ena + + # run with HW optimizations DISabled + # this looks idiotic, but I wasn't able to make --disable-hwf work + echo "all" >$HWF_DENY_FILE + $TOPDIR/BUILD/libgcrypt-*/tests/bench-slope $dis_arg $alg_type $algorithm |grep "$alg_line" >>$algorithm.dis + done + rlLogInfo "Performance measurements finished" + rlRun "cat $algorithm.ena" + rlRun "cat $algorithm.dis" + dis=$(cat $algorithm.dis |cut -d'|' -f2 |awk '{ print $1 }' |sort -n |sed -n "$N_MEDIAN p") + ena=$(cat $algorithm.ena |cut -d'|' -f2 |awk '{ print $1 }' |sort -n |sed -n "$N_MEDIAN p") + rlRun "echo '$algorithm Time: disabled $dis enabled $ena'" + if (( $(echo "$dis > $ena" |bc -l) )); then + rlPass "HW optimizations work for $algorithm" + else + rlFail "HW optimizations DO NOT work for $algorithm" + fi + done + rlPhaseEnd + fi + rlPhaseStartCleanup - rlRun "popd" 0 + rlRun "popd" rlRun "rm -r $TmpDir" 0 - rlFileRestore + rlRun "rlFileRestore" rlPhaseEnd rlJournalPrintText From 0b1d9d2b6db97065449fd6f7fcf94703127ba813 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Mar 2022 11:18:05 +0200 Subject: [PATCH 173/214] libgcrypt-1.10.1-1 --- .gitignore | 2 + libgcrypt-1.10.0-disable-brainpool.patch | 91 +++++++++++++++++++++--- libgcrypt.spec | 9 ++- sources | 4 +- 4 files changed, 93 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 1bb23eb..5380134 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.9.4-hobbled.tar.xz /libgcrypt-1.10.0.tar.bz2 /libgcrypt-1.10.0.tar.bz2.sig +/libgcrypt-1.10.1.tar.bz2 +/libgcrypt-1.10.1.tar.bz2.sig diff --git a/libgcrypt-1.10.0-disable-brainpool.patch b/libgcrypt-1.10.0-disable-brainpool.patch index f0c5a72..f341efc 100644 --- a/libgcrypt-1.10.0-disable-brainpool.patch +++ b/libgcrypt-1.10.0-disable-brainpool.patch @@ -1,4 +1,4 @@ -From d651e25be0bc0c11f4d3d7c72be8cfbbe82b3874 Mon Sep 17 00:00:00 2001 +From f778433dd29fe07aa1791a0137f6f14febcce607 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 10 Sep 2021 18:39:00 +0200 Subject: [PATCH] Allow building libgcrypt without Brainpool curves @@ -8,6 +8,7 @@ Subject: [PATCH] Allow building libgcrypt without Brainpool curves * configure.ac: Implement possibility to build without brainpool curves * tests/curves.c: Skip brainpool curves if they are not built-in * tests/keygrip.c: Skip brainpool curves if they are not built-in +* tests/bench-slope.c: Skip brainpoll curves in they are not built-in -- @@ -16,15 +17,16 @@ Signed-off-by: Jakub Jelen README | 3 +++ cipher/ecc-curves.c | 4 ++++ configure.ac | 13 +++++++++++++ + tests/bench-slope.c | 12 ++++++++++++ tests/curves.c | 46 ++++++++++++++++++++++++++++++--------------- tests/keygrip.c | 2 ++ - 5 files changed, 53 insertions(+), 15 deletions(-) + 6 files changed, 65 insertions(+), 15 deletions(-) diff --git a/README b/README -index 436b6cd4..1044109c 100644 +index 4d7697dd..b290d01e 100644 --- a/README +++ b/README -@@ -127,6 +127,9 @@ +@@ -121,6 +121,9 @@ the list used with the current build the program tests/version may be used. @@ -71,10 +73,10 @@ index 7c86e12c..8fd95a9c 100644 "GOST2001-test", 256, 0, MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, diff --git a/configure.ac b/configure.ac -index 6efbf139..f4ac1887 100644 +index 0e67baf9..a63f7360 100644 --- a/configure.ac +++ b/configure.ac -@@ -614,6 +614,14 @@ AC_ARG_WITH(fips-module-version, +@@ -595,6 +595,14 @@ AC_ARG_WITH(fips-module-version, AC_DEFINE_UNQUOTED(FIPS_MODULE_VERSION, "$fips_module_version", [Define FIPS module version for certification]) @@ -89,7 +91,7 @@ index 6efbf139..f4ac1887 100644 # Implementation of the --disable-jent-support switch. AC_MSG_CHECKING([whether jitter entropy support is requested]) AC_ARG_ENABLE(jent-support, -@@ -2466,6 +2474,10 @@ if test x"$ppccryptosupport" = xyes ; then +@@ -2459,6 +2467,10 @@ if test x"$ppccryptosupport" = xyes ; then AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1, [Enable support for POWER 8 (PowerISA 2.07) crypto extension.]) fi @@ -100,7 +102,7 @@ index 6efbf139..f4ac1887 100644 if test x"$jentsupport" = xyes ; then AC_DEFINE(ENABLE_JENT_SUPPORT, 1, [Enable support for the jitter entropy collector.]) -@@ -3296,6 +3308,7 @@ GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) +@@ -3294,6 +3306,7 @@ GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) GCRY_MSG_WRAP([Enabled kdf algorithms: ],[$enabled_kdfs]) GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers]) GCRY_MSG_SHOW([Random number generator: ],[$random]) @@ -108,6 +110,79 @@ index 6efbf139..f4ac1887 100644 GCRY_MSG_SHOW([Try using jitter entropy: ],[$jentsupport]) GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities]) GCRY_MSG_SHOW([FIPS module version: ],[$fips_module_version]) +diff --git a/tests/bench-slope.c b/tests/bench-slope.c +index 5c49ac25..1b5941af 100644 +--- a/tests/bench-slope.c ++++ b/tests/bench-slope.c +@@ -2316,7 +2316,9 @@ enum bench_ecc_algo + ECC_ALGO_NIST_P384, + ECC_ALGO_NIST_P521, + ECC_ALGO_SECP256K1, ++#ifdef ENABLE_BRAINPOOL + ECC_ALGO_BRAINP256R1, ++#endif /* ENABLE_BRAINPOOL */ + __MAX_ECC_ALGO + }; + +@@ -2366,7 +2368,9 @@ ecc_algo_fips_allowed (int algo) + case ECC_ALGO_NIST_P521: + return 1; + case ECC_ALGO_SECP256K1: ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: ++#endif /* ENABLE_BRAINPOOL */ + case ECC_ALGO_ED25519: + case ECC_ALGO_ED448: + case ECC_ALGO_X25519: +@@ -2402,8 +2406,10 @@ ecc_algo_name (int algo) + return "NIST-P521"; + case ECC_ALGO_SECP256K1: + return "secp256k1"; ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: + return "brainpoolP256r1"; ++#endif /* ENABLE_BRAINPOOL */ + default: + return NULL; + } +@@ -2434,8 +2440,10 @@ ecc_algo_curve (int algo) + return "NIST P-521"; + case ECC_ALGO_SECP256K1: + return "secp256k1"; ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: + return "brainpoolP256r1"; ++#endif /* ENABLE_BRAINPOOL */ + default: + return NULL; + } +@@ -2466,8 +2474,10 @@ ecc_nbits (int algo) + return 521; + case ECC_ALGO_SECP256K1: + return 256; ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: + return 256; ++#endif /* ENABLE_BRAINPOOL */ + default: + return 0; + } +@@ -2665,6 +2675,7 @@ bench_ecc_init (struct bench_obj *obj) + err = gcry_sexp_build (&hd->data, NULL, + "(data (flags raw) (value %m))", x); + break; ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: + err = gcry_sexp_build (&hd->key_spec, NULL, + "(genkey (ECDSA (curve brainpoolP256r1)))"); +@@ -2673,6 +2684,7 @@ bench_ecc_init (struct bench_obj *obj) + err = gcry_sexp_build (&hd->data, NULL, + "(data (flags raw) (value %m))", x); + break; ++#endif /* ENABLE_BRAINPOOL */ + } + + gcry_mpi_release (x); diff --git a/tests/curves.c b/tests/curves.c index 3c738171..8eb79565 100644 --- a/tests/curves.c diff --git a/libgcrypt.spec b/libgcrypt.spec index d657930..f330028 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.10.0 +Version: 1.10.1 Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 @@ -90,9 +90,9 @@ LIBGCRYPT_FORCE_FIPS_MODE=1 make check %{__arch_install_post} \ %{__os_install_post} \ dd if=/dev/zero of=%{libpath}.hmac bs=32 count=1 \ - objcopy --update-section .rodata1=%{libpath}.hmac %{libpath} %{libpath}.empty \ + objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} %{libpath}.empty \ src/hmac256 --binary %{hmackey} %{libpath}.empty > %{libpath}.hmac \ - objcopy --update-section .rodata1=%{libpath}.hmac %{libpath}.empty %{libpath}.new \ + objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath}.empty %{libpath}.new \ mv -f %{libpath}.new %{libpath} \ rm -f %{libpath}.hmac %{libpath}.empty %{nil} @@ -164,6 +164,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Mar 29 2022 Jakub Jelen - 1.10.1-1 +- Final release (#2069263) + * Wed Feb 02 2022 Jakub Jelen - 1.10.0-1 - New upstream release (#2049322) diff --git a/sources b/sources index 745f52b..0021e06 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.10.0.tar.bz2) = 785c2e14272308956bb6adcea9567c4097edf103122e18cd3907fb42a110a48a5d59c0057f05a438acd7f221c70c7f7ff87e176bd6d7ed99d16e847f9d7be087 -SHA512 (libgcrypt-1.10.0.tar.bz2.sig) = 75201612225b206faaae284297e92d1b25dcaf0665bcf1f4c5cc9a3a750a803063d0f7bd0af556dbe419f1276c953ce047554fd18a144a90085a42a7ec885168 +SHA512 (libgcrypt-1.10.1.tar.bz2) = e5ca7966624fff16c3013795836a2c4377f0193dbb4ac5ad2b79654b1fa8992e17d83816569a402212dc8367a7980d4141f5d6ac282bae6b9f02186365b61f13 +SHA512 (libgcrypt-1.10.1.tar.bz2.sig) = b156ae05079776698bc95ba5a9e48e95de8f716aa1760ef4b2e7cb8518ccec660337fc7823f865bde870461800d472fd8e458d03a7095b6bb614f6dd96f796d8 From 7b71c161ddbc2b6bd4962b1fd79c9912e8240a1e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 1 Apr 2022 11:25:41 +0200 Subject: [PATCH 174/214] Sync the FIPS module name version with RHEL --- libgcrypt.spec | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index f330028..6b686a6 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,3 +1,19 @@ +# This is taken from gnutls.spec +%define srpmhash() %{lua: +local files = rpm.expand("%_specdir/libgcrypt.spec") +for i, p in ipairs(patches) do + files = files.." "..p +end +for i, p in ipairs(sources) do + files = files.." "..p +end +local sha256sum = assert(io.popen("cat "..files.."| sha256sum")) +local hash = sha256sum:read("*a") +sha256sum:close() +print(string.sub(hash, 0, 16)) +} + + Name: libgcrypt Version: 1.10.1 Release: 1%{?dist} @@ -53,17 +69,13 @@ applications using libgcrypt. # F34, so we use it here explicitly %define _lto_cflags -flto=auto -ffat-lto-objects -grep "Red Hat" /etc/system-release && \ -export FIPS_SWITCH="--with-fips-module-version=RHEL%{?rhel}-%{name}-%{version}-$(date +%Y%m%d)" -grep "Fedora" /etc/system-release && \ -export FIPS_SWITCH="--with-fips-module-version=Fedora%{?fedora}-%{name}-%{version}-$(date +%Y%m%d)" -grep "CentOS" /etc/system-release && \ -export FIPS_SWITCH="--with-fips-module-version=CentOS%{?centos}-%{name}-%{version}-$(date +%Y%m%d)" - # should be all algorithms except SM3 and SM4 export DIGESTS='crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2' export CIPHERS='arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20' +eval $(sed -n 's/^\(\(NAME\|VERSION_ID\)=.*\)/OS_\1/p' /etc/os-release) +export FIPS_MODULE_NAME="$OS_NAME ${OS_VERSION_ID%%.*} %name" + autoreconf -f %configure --disable-static \ %ifarch sparc64 @@ -74,7 +86,7 @@ autoreconf -f --disable-brainpool \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ - $FIPS_SWITCH + --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool %make_build From e7354685a27c2ed4481a4f632eea14fa47163662 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 8 Apr 2022 17:10:51 +0200 Subject: [PATCH 175/214] Adjust integrity check creation to match upstream (#2073018) --- libgcrypt.spec | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6b686a6..758808f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -101,12 +101,12 @@ LIBGCRYPT_FORCE_FIPS_MODE=1 make check %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ %{__os_install_post} \ - dd if=/dev/zero of=%{libpath}.hmac bs=32 count=1 \ - objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} %{libpath}.empty \ - src/hmac256 --binary %{hmackey} %{libpath}.empty > %{libpath}.hmac \ - objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath}.empty %{libpath}.new \ - mv -f %{libpath}.new %{libpath} \ - rm -f %{libpath}.hmac %{libpath}.empty + pushd src \ + sed -i -e 's|FILE=.*|FILE=\\\$1|' gen-note-integrity.sh \ + READELF=readelf AWK=awk ECHO_N="-n" bash gen-note-integrity.sh %{libpath} > %{libpath}.hmac \ + objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} new \ + mv -f new %{libpath} \ + rm -f %{libpath}.hmac \ %{nil} %install From 040bc4d9b98ea02e647982e915763b580253ced6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 8 Apr 2022 17:13:08 +0200 Subject: [PATCH 176/214] 1.10.1-2 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 758808f..b129fcf 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -16,7 +16,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -176,6 +176,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Fri Apr 08 2022 Jakub Jelen - 1.10.1-2 +- Adjust integrity check creation to match upstream (#2073018) + * Tue Mar 29 2022 Jakub Jelen - 1.10.1-1 - Final release (#2069263) From 9140219786a877c450d50a9d13e2de44f7bc0927 Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Sun, 29 May 2022 17:08:50 -0400 Subject: [PATCH 177/214] improve --disable-brainpool configure output The configure output from the --disable-brainpool option is confusing: checking whether we want to disable the use of brainpool curves... no Reword the message to make it clearer and match the nearby configure checks for other `--disable-*` options: checking whether brainpool curves support is requested... no --- libgcrypt-1.10.0-disable-brainpool.patch | 2 +- libgcrypt.spec | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libgcrypt-1.10.0-disable-brainpool.patch b/libgcrypt-1.10.0-disable-brainpool.patch index f341efc..8a9d980 100644 --- a/libgcrypt-1.10.0-disable-brainpool.patch +++ b/libgcrypt-1.10.0-disable-brainpool.patch @@ -81,7 +81,7 @@ index 0e67baf9..a63f7360 100644 [Define FIPS module version for certification]) +# Implementation of the --disable-brainpool switch. -+AC_MSG_CHECKING([whether we want to disable the use of brainpool curves]) ++AC_MSG_CHECKING([whether brainpool curves support is requested]) +AC_ARG_ENABLE(brainpool, + AS_HELP_STRING([--disable-brainpool], + [Disable the brainpool curves]), diff --git a/libgcrypt.spec b/libgcrypt.spec index b129fcf..f766487 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -16,7 +16,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -176,6 +176,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Sun May 29 2022 Todd Zullinger - 1.10.1-3 +- improve --disable-brainpool configure output + * Fri Apr 08 2022 Jakub Jelen - 1.10.1-2 - Adjust integrity check creation to match upstream (#2073018) From 6571417ff46056d7d6256bceb8e0066abe1fe961 Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Sun, 29 May 2022 15:41:22 -0400 Subject: [PATCH 178/214] use %bcond_with to disable brainpool curves The `%bcond_with` macro allows others to rebuild the package with the brainpool curves enabled by passing `--with brainpool` to `rpmbuild`. --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index f766487..5ed4f4c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -13,6 +13,8 @@ sha256sum:close() print(string.sub(hash, 0, 16)) } +# disable brainpool curves by default +%bcond_with brainpool Name: libgcrypt Version: 1.10.1 @@ -83,7 +85,7 @@ autoreconf -f %endif --enable-noexecstack \ --enable-hmac-binary-check=%{hmackey} \ - --disable-brainpool \ + %{!?with_brainpool:--disable-brainpool} \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" @@ -178,6 +180,7 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %changelog * Sun May 29 2022 Todd Zullinger - 1.10.1-3 - improve --disable-brainpool configure output +- use %%bcond_with to disable brainpool curves * Fri Apr 08 2022 Jakub Jelen - 1.10.1-2 - Adjust integrity check creation to match upstream (#2073018) From 491a0e733e7d8fe5f393c1846b247c214c8101e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Jun 2022 17:03:49 +0200 Subject: [PATCH 179/214] Fix annobin flags (#2016349) --- libgcrypt-1.10.1-annobin.patch | 22 ++++++++++++++++++++++ libgcrypt.spec | 4 ++++ 2 files changed, 26 insertions(+) create mode 100644 libgcrypt-1.10.1-annobin.patch diff --git a/libgcrypt-1.10.1-annobin.patch b/libgcrypt-1.10.1-annobin.patch new file mode 100644 index 0000000..c333c4e --- /dev/null +++ b/libgcrypt-1.10.1-annobin.patch @@ -0,0 +1,22 @@ +diff -rup libgcrypt.orig/src/Makefile.am libgcrypt-1.8.3/src/Makefile.am +--- libgcrypt.orig/src/Makefile.am 2021-10-18 16:36:20.914025497 +0100 ++++ libgcrypt-1.8.3/src/Makefile.am 2021-10-19 12:23:08.652960618 +0100 +@@ -108,6 +108,7 @@ endif !HAVE_W32_SYSTEM + + + libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \ ++ -Wc,-fplugin=annobin \ + $(libgcrypt_version_script_cmd) -version-info \ + @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@ + libgcrypt_la_DEPENDENCIES = \ +Only in libgcrypt-1.8.3/src: Makefile.am.annobin +diff -rup libgcrypt.orig/src/Makefile.in libgcrypt-1.8.3/src/Makefile.in +--- libgcrypt.orig/src/Makefile.in 2021-10-18 16:36:20.914025497 +0100 ++++ libgcrypt-1.8.3/src/Makefile.in 2021-10-19 12:23:37.791875325 +0100 +@@ -483,6 +483,7 @@ gcrypt_hwf_modules = @GCRYPT_HWF_MODULES + @HAVE_W32_SYSTEM_TRUE@gcrypt_deps = $(gcrypt_res) libgcrypt.def + @HAVE_W32_SYSTEM_FALSE@gcrypt_res_ldflag = + libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \ ++ -Wc,-fplugin=annobin \ + $(libgcrypt_version_script_cmd) -version-info \ + @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@ diff --git a/libgcrypt.spec b/libgcrypt.spec index 5ed4f4c..cd321d7 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -23,7 +23,10 @@ URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com +# brainpool curves are still not allowed to be shipped in Fedora Patch1: libgcrypt-1.10.0-disable-brainpool.patch +# Pass the annobin flags to the libgcrypt.so (#2016349) +Patch2: libgcrypt-1.10.1-annobin.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -60,6 +63,7 @@ applications using libgcrypt. %prep %setup -q %patch1 -p1 +%patch2 -p1 %build # This package has a configure test which uses ASMs, but does not link the From 2fe61ab47d8dbac25c3144e4790e9dd82daf2d17 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 21 Jul 2022 17:51:35 +0000 Subject: [PATCH 180/214] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index cd321d7..73d6e64 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -18,7 +18,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 3%{?dist} +Release: 4%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -182,6 +182,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 21 2022 Fedora Release Engineering - 1.10.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Sun May 29 2022 Todd Zullinger - 1.10.1-3 - improve --disable-brainpool configure output - use %%bcond_with to disable brainpool curves From 9e608ad3fa1de990e0e874131c817aae1a86c0ba Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Sun, 6 Nov 2022 19:05:40 -0500 Subject: [PATCH 181/214] enable brainpool curves by default Thanks to the Fedora Legal team, we are now able to include Brainpool ECC in Fedora. Matthew Miller notified the Fedora Legal list. References: https://bugzilla.redhat.com/1413618 https://lists.fedoraproject.org/archives/list/legal@lists.fedoraproject.org/message/752Z34MTHB6B4XRUW2TTAPEIUUK4O2LA/ --- libgcrypt-1.10.0-disable-brainpool.patch | 314 ----------------------- libgcrypt.spec | 14 +- 2 files changed, 5 insertions(+), 323 deletions(-) delete mode 100644 libgcrypt-1.10.0-disable-brainpool.patch diff --git a/libgcrypt-1.10.0-disable-brainpool.patch b/libgcrypt-1.10.0-disable-brainpool.patch deleted file mode 100644 index 8a9d980..0000000 --- a/libgcrypt-1.10.0-disable-brainpool.patch +++ /dev/null @@ -1,314 +0,0 @@ -From f778433dd29fe07aa1791a0137f6f14febcce607 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 10 Sep 2021 18:39:00 +0200 -Subject: [PATCH] Allow building libgcrypt without Brainpool curves - -* README: Document possibility to build without brainpool curves -* cipher/ecc-curves.c: Conditionalize brainpool curves definitions -* configure.ac: Implement possibility to build without brainpool curves -* tests/curves.c: Skip brainpool curves if they are not built-in -* tests/keygrip.c: Skip brainpool curves if they are not built-in -* tests/bench-slope.c: Skip brainpoll curves in they are not built-in - --- - -Signed-off-by: Jakub Jelen ---- - README | 3 +++ - cipher/ecc-curves.c | 4 ++++ - configure.ac | 13 +++++++++++++ - tests/bench-slope.c | 12 ++++++++++++ - tests/curves.c | 46 ++++++++++++++++++++++++++++++--------------- - tests/keygrip.c | 2 ++ - 6 files changed, 65 insertions(+), 15 deletions(-) - -diff --git a/README b/README -index 4d7697dd..b290d01e 100644 ---- a/README -+++ b/README -@@ -121,6 +121,9 @@ - the list used with the current build the program - tests/version may be used. - -+ --disable-brainpool -+ Do not build in support for Brainpool curves. -+ - --disable-endian-check - Don't let configure test for the endianness but - try to use the OS provided macros at compile -diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c -index 7c86e12c..8fd95a9c 100644 ---- a/cipher/ecc-curves.c -+++ b/cipher/ecc-curves.c -@@ -77,6 +77,7 @@ static const struct - { "NIST P-521", "1.3.132.0.35" }, - { "NIST P-521", "nistp521" }, /* rfc5656. */ - -+#ifdef ENABLE_BRAINPOOL - { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" }, - { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" }, - { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" }, -@@ -84,6 +85,7 @@ static const struct - { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" }, - { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"}, - { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"}, -+#endif /* ENABLE_BRAINPOOL */ - - { "GOST2001-test", "1.2.643.2.2.35.0" }, - { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" }, -@@ -297,6 +299,7 @@ static const ecc_domain_parms_t domain_parms[] = - 1 - }, - -+#ifdef ENABLE_BRAINPOOL - { "brainpoolP160r1", 160, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f", -@@ -391,6 +394,7 @@ static const ecc_domain_parms_t domain_parms[] = - "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892", - 1 - }, -+#endif /* ENABLE_BRAINPOOL */ - { - "GOST2001-test", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, -diff --git a/configure.ac b/configure.ac -index 0e67baf9..a63f7360 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -595,6 +595,14 @@ AC_ARG_WITH(fips-module-version, - AC_DEFINE_UNQUOTED(FIPS_MODULE_VERSION, "$fips_module_version", - [Define FIPS module version for certification]) - -+# Implementation of the --disable-brainpool switch. -+AC_MSG_CHECKING([whether brainpool curves support is requested]) -+AC_ARG_ENABLE(brainpool, -+ AS_HELP_STRING([--disable-brainpool], -+ [Disable the brainpool curves]), -+ use_brainpool="$enableval",use_brainpool=yes) -+AC_MSG_RESULT($use_brainpool) -+ - # Implementation of the --disable-jent-support switch. - AC_MSG_CHECKING([whether jitter entropy support is requested]) - AC_ARG_ENABLE(jent-support, -@@ -2459,6 +2467,10 @@ if test x"$ppccryptosupport" = xyes ; then - AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1, - [Enable support for POWER 8 (PowerISA 2.07) crypto extension.]) - fi -+if test x"$use_brainpool" = xyes ; then -+ AC_DEFINE(ENABLE_BRAINPOOL, 1, -+ [Enable support for the brainpool curves.]) -+fi - if test x"$jentsupport" = xyes ; then - AC_DEFINE(ENABLE_JENT_SUPPORT, 1, - [Enable support for the jitter entropy collector.]) -@@ -3294,6 +3306,7 @@ GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) - GCRY_MSG_WRAP([Enabled kdf algorithms: ],[$enabled_kdfs]) - GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers]) - GCRY_MSG_SHOW([Random number generator: ],[$random]) -+GCRY_MSG_SHOW([Enabled Brainpool curves: ],[$use_brainpool]) - GCRY_MSG_SHOW([Try using jitter entropy: ],[$jentsupport]) - GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities]) - GCRY_MSG_SHOW([FIPS module version: ],[$fips_module_version]) -diff --git a/tests/bench-slope.c b/tests/bench-slope.c -index 5c49ac25..1b5941af 100644 ---- a/tests/bench-slope.c -+++ b/tests/bench-slope.c -@@ -2316,7 +2316,9 @@ enum bench_ecc_algo - ECC_ALGO_NIST_P384, - ECC_ALGO_NIST_P521, - ECC_ALGO_SECP256K1, -+#ifdef ENABLE_BRAINPOOL - ECC_ALGO_BRAINP256R1, -+#endif /* ENABLE_BRAINPOOL */ - __MAX_ECC_ALGO - }; - -@@ -2366,7 +2368,9 @@ ecc_algo_fips_allowed (int algo) - case ECC_ALGO_NIST_P521: - return 1; - case ECC_ALGO_SECP256K1: -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: -+#endif /* ENABLE_BRAINPOOL */ - case ECC_ALGO_ED25519: - case ECC_ALGO_ED448: - case ECC_ALGO_X25519: -@@ -2402,8 +2406,10 @@ ecc_algo_name (int algo) - return "NIST-P521"; - case ECC_ALGO_SECP256K1: - return "secp256k1"; -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: - return "brainpoolP256r1"; -+#endif /* ENABLE_BRAINPOOL */ - default: - return NULL; - } -@@ -2434,8 +2440,10 @@ ecc_algo_curve (int algo) - return "NIST P-521"; - case ECC_ALGO_SECP256K1: - return "secp256k1"; -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: - return "brainpoolP256r1"; -+#endif /* ENABLE_BRAINPOOL */ - default: - return NULL; - } -@@ -2466,8 +2474,10 @@ ecc_nbits (int algo) - return 521; - case ECC_ALGO_SECP256K1: - return 256; -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: - return 256; -+#endif /* ENABLE_BRAINPOOL */ - default: - return 0; - } -@@ -2665,6 +2675,7 @@ bench_ecc_init (struct bench_obj *obj) - err = gcry_sexp_build (&hd->data, NULL, - "(data (flags raw) (value %m))", x); - break; -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: - err = gcry_sexp_build (&hd->key_spec, NULL, - "(genkey (ECDSA (curve brainpoolP256r1)))"); -@@ -2673,6 +2684,7 @@ bench_ecc_init (struct bench_obj *obj) - err = gcry_sexp_build (&hd->data, NULL, - "(data (flags raw) (value %m))", x); - break; -+#endif /* ENABLE_BRAINPOOL */ - } - - gcry_mpi_release (x); -diff --git a/tests/curves.c b/tests/curves.c -index 3c738171..8eb79565 100644 ---- a/tests/curves.c -+++ b/tests/curves.c -@@ -33,7 +33,11 @@ - #include "t-common.h" - - /* Number of curves defined in ../cipher/ecc-curves.c */ --#define N_CURVES 27 -+#ifdef ENABLE_BRAINPOOL -+# define N_CURVES 27 -+#else -+# define N_CURVES 20 -+#endif - - /* A real world sample public key. */ - static char const sample_key_1[] = -@@ -52,6 +56,7 @@ static char const sample_key_1[] = - static char const sample_key_1_curve[] = "NIST P-256"; - static unsigned int sample_key_1_nbits = 256; - -+#ifdef ENABLE_BRAINPOOL - /* A made up sample public key. */ - static char const sample_key_2[] = - "(public-key\n" -@@ -68,6 +73,7 @@ static char const sample_key_2[] = - " ))"; - static char const sample_key_2_curve[] = "brainpoolP160r1"; - static unsigned int sample_key_2_nbits = 160; -+#endif /* ENABLE_BRAINPOOL */ - - static int in_fips_mode; - -@@ -113,6 +119,7 @@ check_matching (void) - - gcry_sexp_release (key); - -+#ifdef ENABLE_BRAINPOOL - if (!in_fips_mode) - { - err = gcry_sexp_new (&key, sample_key_2, 0, 1); -@@ -130,6 +137,7 @@ check_matching (void) - - gcry_sexp_release (key); - } -+#endif /* ENABLE_BRAINPOOL */ - } - - #define TEST_ERROR_EXPECTED (1 << 0) -@@ -185,20 +193,26 @@ check_get_params (void) - { GCRY_PK_ECC, "1.3.132.0.35" }, - { GCRY_PK_ECC, "nistp521" }, - -- { GCRY_PK_ECC, "brainpoolP160r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP192r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP224r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP256r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP320r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP384r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP512r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13", TEST_NOFIPS }, -+#ifdef ENABLE_BRAINPOOL -+# define BRAINPOOL_FLAGS TEST_NOFIPS -+#else -+# define BRAINPOOL_FLAGS TEST_ERROR_EXPECTED -+#endif /* ENABLE_BRAINPOOL */ -+ { GCRY_PK_ECC, "brainpoolP160r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP192r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP224r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP256r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP320r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP384r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP512r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13", BRAINPOOL_FLAGS }, -+#undef BRAINPOOL_ERROR_EXPECTED - - { GCRY_PK_ECC, "GOST2001-test", TEST_NOFIPS }, - { GCRY_PK_ECC, "1.2.643.2.2.35.0", TEST_NOFIPS }, -@@ -282,6 +296,7 @@ check_get_params (void) - - gcry_sexp_release (param); - -+#ifdef ENABLE_BRAINPOOL - if (!in_fips_mode) - { - param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_2_curve); -@@ -297,6 +312,7 @@ check_get_params (void) - - gcry_sexp_release (param); - } -+#endif /* ENABLE_BRAINPOOL */ - - /* Some simple tests */ - for (idx=0; idx < DIM (tv); idx++) -diff --git a/tests/keygrip.c b/tests/keygrip.c -index 49bd71bc..fc4c17be 100644 ---- a/tests/keygrip.c -+++ b/tests/keygrip.c -@@ -149,6 +149,7 @@ static struct - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, -+#ifdef ENABLE_BRAINPOOL - { - GCRY_PK_ECC, - "(public-key" -@@ -197,6 +198,7 @@ static struct - "\xD6\xE1\xBF\x43\xAC\x9B\x9A\x12\xE7\x3F", - 1 - }, -+#endif /*ENABLE_BRAINPOOL */ - { /* Ed25519 standard */ - GCRY_PK_ECC, - "(public-key" --- -2.34.1 - diff --git a/libgcrypt.spec b/libgcrypt.spec index 73d6e64..f458aab 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -13,20 +13,15 @@ sha256sum:close() print(string.sub(hash, 0, 16)) } -# disable brainpool curves by default -%bcond_with brainpool - Name: libgcrypt Version: 1.10.1 -Release: 4%{?dist} +Release: 5%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com -# brainpool curves are still not allowed to be shipped in Fedora -Patch1: libgcrypt-1.10.0-disable-brainpool.patch # Pass the annobin flags to the libgcrypt.so (#2016349) -Patch2: libgcrypt-1.10.1-annobin.patch +Patch1: libgcrypt-1.10.1-annobin.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -63,7 +58,6 @@ applications using libgcrypt. %prep %setup -q %patch1 -p1 -%patch2 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -89,7 +83,6 @@ autoreconf -f %endif --enable-noexecstack \ --enable-hmac-binary-check=%{hmackey} \ - %{!?with_brainpool:--disable-brainpool} \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" @@ -182,6 +175,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Nov 08 2022 Todd Zullinger - 1.10.1-5 +- enable brainpool by default (#1413618) + * Thu Jul 21 2022 Fedora Release Engineering - 1.10.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From 96a092be6b72c9b160392320a380ebddc0dd0c4b Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Wed, 9 Nov 2022 17:53:31 -0500 Subject: [PATCH 182/214] fix sporadic failures generating RSA keys in FIPS mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test suite occasionally fails with "error generating RSA key: Number is not prime" in FIPS mode¹. Apply the upstream fix, cd30ed3c (cipher: Change the bounds for RSA key generation round., 2022-04-20). ¹ https://dev.gnupg.org/T5919 --- ...e-bounds-for-RSA-key-generation-roun.patch | 55 +++++++++++++++++++ libgcrypt.spec | 6 ++ 2 files changed, 61 insertions(+) create mode 100644 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch diff --git a/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch b/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch new file mode 100644 index 0000000..3ec87e6 --- /dev/null +++ b/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch @@ -0,0 +1,55 @@ +From cd30ed3c0d715aa0c58a32a29cfb1476163a5b94 Mon Sep 17 00:00:00 2001 +From: NIIBE Yutaka +Date: Wed, 20 Apr 2022 15:09:41 +0900 +Subject: [PATCH] cipher: Change the bounds for RSA key generation round. + +* cipher/rsa.c (generate_fips): Use 10 for p, 20 for q. + +-- + +Constants from FIPS 186-5-draft. + +GnuPG-bug-id: 5919 +Signed-off-by: NIIBE Yutaka +--- + cipher/rsa.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/cipher/rsa.c b/cipher/rsa.c +index 486a34f0..771413b3 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -476,7 +476,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, + + retry: + /* generate p and q */ +- for (i = 0; i < 5 * pbits; i++) ++ for (i = 0; i < 10 * pbits; i++) + { + ploop: + if (!testparms) +@@ -506,10 +506,10 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, + else if (testparms) + goto err; + } +- if (i >= 5 * pbits) ++ if (i >= 10 * pbits) + goto err; + +- for (i = 0; i < 5 * pbits; i++) ++ for (i = 0; i < 20 * pbits; i++) + { + qloop: + if (!testparms) +@@ -555,7 +555,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, + else if (testparms) + goto err; + } +- if (i >= 5 * pbits) ++ if (i >= 20 * pbits) + goto err; + + if (testparms) +-- +2.38.1 + diff --git a/libgcrypt.spec b/libgcrypt.spec index f458aab..89c1036 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -22,6 +22,10 @@ Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch +# https://dev.gnupg.org/T5919 +# tests occasionally fail with "error generating RSA key: Number is not prime" +# https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=cd30ed3c0 +Patch2: 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -58,6 +62,7 @@ applications using libgcrypt. %prep %setup -q %patch1 -p1 +%patch2 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -177,6 +182,7 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %changelog * Tue Nov 08 2022 Todd Zullinger - 1.10.1-5 - enable brainpool by default (#1413618) +- fix sporadic failures generating RSA keys in FIPS mode * Thu Jul 21 2022 Fedora Release Engineering - 1.10.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From 1a44ed4636073d3286676072091b274d04c5ff8e Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Sat, 3 Dec 2022 12:17:30 +0100 Subject: [PATCH 183/214] Port configure script to C99 Related to: --- libgcrypt-configure-c99.patch | 139 ++++++++++++++++++++++++++++++++++ libgcrypt.spec | 8 +- 2 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-configure-c99.patch diff --git a/libgcrypt-configure-c99.patch b/libgcrypt-configure-c99.patch new file mode 100644 index 0000000..321743a --- /dev/null +++ b/libgcrypt-configure-c99.patch @@ -0,0 +1,139 @@ +Add missing prototypes to test functions. Future compilers will not +support implicit function declarations by default, causing spurious +test failures. + +The patch has been submitted to the gcrypt-devel list, but has yet to +appear in the list archives. + +diff --git a/configure.ac b/configure.ac +index 6ea38f53b8548ee8..2baf25bc7d9481e6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1211,7 +1211,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARM assembly implementat + /* Test if '.type' and '.size' are supported. */ + ".size asmfunc,.-asmfunc;\n\t" + ".type asmfunc,%function;\n\t" +- );]], [ asmfunc(); ] )], ++ ); ++ void asmfunc(void);]], [ asmfunc(); ] )], + [gcry_cv_gcc_arm_platform_as_ok=yes]) + fi]) + if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then +@@ -1238,7 +1239,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARMv8/Aarch64 assembly i + "eor x0, x0, x30, ror #12;\n\t" + "add x0, x0, x30, asr #12;\n\t" + "eor v0.16b, v0.16b, v31.16b;\n\t" +- );]], [ asmfunc(); ] )], ++ ); ++ void asmfunc(void);]], [ asmfunc(); ] )], + [gcry_cv_gcc_aarch64_platform_as_ok=yes]) + fi]) + if test "$gcry_cv_gcc_aarch64_platform_as_ok" = "yes" ; then +@@ -1267,7 +1269,8 @@ AC_CACHE_CHECK([whether GCC assembler supports for CFI directives], + ".cfi_restore_state\n\t" + ".long 0\n\t" + ".cfi_endproc\n\t" +- );]])], ++ ); ++ void asmfunc(void)]])], + [gcry_cv_gcc_asm_cfi_directives=yes])]) + if test "$gcry_cv_gcc_asm_cfi_directives" = "yes" ; then + AC_DEFINE(HAVE_GCC_ASM_CFI_DIRECTIVES,1, +@@ -1666,7 +1669,8 @@ if test $amd64_as_feature_detection = yes; then + [gcry_cv_gcc_as_const_division_ok], + [gcry_cv_gcc_as_const_division_ok=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( +- [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]], ++ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t"); ++ void fn(void);]], + [fn();])], + [gcry_cv_gcc_as_const_division_ok=yes])]) + if test "$gcry_cv_gcc_as_const_division_ok" = "no" ; then +@@ -1679,7 +1683,8 @@ if test $amd64_as_feature_detection = yes; then + [gcry_cv_gcc_as_const_division_with_wadivide_ok], + [gcry_cv_gcc_as_const_division_with_wadivide_ok=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( +- [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]], ++ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t"); ++ void fn(void);]], + [fn();])], + [gcry_cv_gcc_as_const_division_with_wadivide_ok=yes])]) + if test "$gcry_cv_gcc_as_const_division_with_wadivide_ok" = "no" ; then +@@ -1715,7 +1720,8 @@ if test $amd64_as_feature_detection = yes; then + * and "-Wa,--divide" workaround failed, this causes assembly + * to be disable on this machine. */ + "xorl \$(123456789/12345678), %ebp;\n\t" +- );]], [ asmfunc(); ])], ++ ); ++ void asmfunc(void);]], [ asmfunc(); ])], + [gcry_cv_gcc_amd64_platform_as_ok=yes]) + fi]) + if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then +@@ -1734,7 +1740,8 @@ if test $amd64_as_feature_detection = yes; then + ".globl asmfunc\n\t" + "asmfunc:\n\t" + "xorq \$(1234), %rbp;\n\t" +- );]], [ asmfunc(); ])], ++ ); ++ void asmfunc(void);]], [ asmfunc(); ])], + [gcry_cv_gcc_win64_platform_as_ok=yes])]) + if test "$gcry_cv_gcc_win64_platform_as_ok" = "yes" ; then + AC_DEFINE(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS,1, +@@ -1767,7 +1774,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for Intel syntax assembly im + "sub eax, [esp + 4];\n\t" + "add dword ptr [esp + eax], 0b10101;\n\t" + ".att_syntax prefix\n\t" +- );]], [ actest(); ])], ++ ); ++ void actest(void);]], [ actest(); ])], + [gcry_cv_gcc_platform_as_ok_for_intel_syntax=yes]) + fi]) + if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then +@@ -1832,6 +1840,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports NEON instructions], + "vadd.u64 %q0, %q1;\n\t" + "vadd.s64 %d3, %d2, %d3;\n\t" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_neon=yes]) + fi]) +@@ -1879,6 +1888,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch32 Crypto Extension i + + "vmull.p64 q0, d0, d0;\n\t" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_aarch32_crypto=yes]) + fi]) +@@ -1907,6 +1917,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 NEON instructions] + "dup v0.8b, w0;\n\t" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_aarch64_neon=yes]) + fi]) +@@ -1955,6 +1966,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 Crypto Extension i + "pmull v0.1q, v0.1d, v31.1d;\n\t" + "pmull2 v0.1q, v0.2d, v31.2d;\n\t" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_aarch64_crypto=yes]) + fi]) +@@ -2050,6 +2062,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto + "vshasigmad %v0, %v1, 0, 15;\n" + "vpmsumd %v11, %v11, %v11;\n" + ); ++ void testfn(void); + ]], [ testfn(); ] )], + [gcry_cv_gcc_inline_asm_ppc_altivec=yes]) + fi]) +@@ -2075,6 +2088,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports PowerISA 3.00 instructions + "testfn:\n" + "stxvb16x %r1,%v12,%v30;\n" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_ppc_arch_3_00=yes]) + fi]) diff --git a/libgcrypt.spec b/libgcrypt.spec index 89c1036..7392318 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 5%{?dist} +Release: 6%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -27,6 +27,8 @@ Patch1: libgcrypt-1.10.1-annobin.patch # https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=cd30ed3c0 Patch2: 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch +Patch3: libgcrypt-configure-c99.patch + %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 %global hmackey orboDeJITITejsirpADONivirpUkvarP @@ -63,6 +65,7 @@ applications using libgcrypt. %setup -q %patch1 -p1 %patch2 -p1 +%patch3 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -180,6 +183,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Sat Dec 3 2022 Florian Weimer - 1.10.1-6 +- Port configure script to C99 + * Tue Nov 08 2022 Todd Zullinger - 1.10.1-5 - enable brainpool by default (#1413618) - fix sporadic failures generating RSA keys in FIPS mode From 31745f126fcd5bdaa8b28354d552e7f8c926d955 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 5 Dec 2022 13:47:38 +0100 Subject: [PATCH 184/214] libgcrypt-configure-c99.patch: Add upstream patch submission URL --- libgcrypt-configure-c99.patch | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libgcrypt-configure-c99.patch b/libgcrypt-configure-c99.patch index 321743a..8238ed4 100644 --- a/libgcrypt-configure-c99.patch +++ b/libgcrypt-configure-c99.patch @@ -2,8 +2,9 @@ Add missing prototypes to test functions. Future compilers will not support implicit function declarations by default, causing spurious test failures. -The patch has been submitted to the gcrypt-devel list, but has yet to -appear in the list archives. +Submitted upstream: + + diff --git a/configure.ac b/configure.ac index 6ea38f53b8548ee8..2baf25bc7d9481e6 100644 From 01380c605d1e634ff62231b57c8c7008558ccdde Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 16:23:04 +0000 Subject: [PATCH 185/214] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 7392318..3679c3b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 6%{?dist} +Release: 7%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -183,6 +183,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jan 19 2023 Fedora Release Engineering - 1.10.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Sat Dec 3 2022 Florian Weimer - 1.10.1-6 - Port configure script to C99 From a17db7fa5890b2266da7fb6347aa1367be7840bd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Apr 2023 14:20:12 +0200 Subject: [PATCH 186/214] Simplify HMAC checksum calculation and avoid using CWD --- libgcrypt.spec | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3679c3b..aae97fc 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -108,12 +108,12 @@ LIBGCRYPT_FORCE_FIPS_MODE=1 make check %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ %{__os_install_post} \ - pushd src \ + cd src \ sed -i -e 's|FILE=.*|FILE=\\\$1|' gen-note-integrity.sh \ READELF=readelf AWK=awk ECHO_N="-n" bash gen-note-integrity.sh %{libpath} > %{libpath}.hmac \ - objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} new \ - mv -f new %{libpath} \ - rm -f %{libpath}.hmac \ + objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} %{libpath}.new \ + mv -f %{libpath}.new %{libpath} \ + rm -f %{libpath}.hmac %{nil} %install From 021f499feb26e7b9cc90ee2c91eb48f723391b24 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Apr 2023 14:35:51 +0200 Subject: [PATCH 187/214] libgcrypt-1.10.2-1 * Remove already-applied patches * Avoid using deprecated %patchN --- .gitignore | 2 + ...e-bounds-for-RSA-key-generation-roun.patch | 55 ------- libgcrypt-configure-c99.patch | 140 ------------------ libgcrypt.spec | 17 +-- sources | 4 +- 5 files changed, 10 insertions(+), 208 deletions(-) delete mode 100644 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch delete mode 100644 libgcrypt-configure-c99.patch diff --git a/.gitignore b/.gitignore index 5380134..b60502b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.10.0.tar.bz2.sig /libgcrypt-1.10.1.tar.bz2 /libgcrypt-1.10.1.tar.bz2.sig +/libgcrypt-1.10.2.tar.bz2 +/libgcrypt-1.10.2.tar.bz2.sig diff --git a/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch b/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch deleted file mode 100644 index 3ec87e6..0000000 --- a/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch +++ /dev/null @@ -1,55 +0,0 @@ -From cd30ed3c0d715aa0c58a32a29cfb1476163a5b94 Mon Sep 17 00:00:00 2001 -From: NIIBE Yutaka -Date: Wed, 20 Apr 2022 15:09:41 +0900 -Subject: [PATCH] cipher: Change the bounds for RSA key generation round. - -* cipher/rsa.c (generate_fips): Use 10 for p, 20 for q. - --- - -Constants from FIPS 186-5-draft. - -GnuPG-bug-id: 5919 -Signed-off-by: NIIBE Yutaka ---- - cipher/rsa.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/cipher/rsa.c b/cipher/rsa.c -index 486a34f0..771413b3 100644 ---- a/cipher/rsa.c -+++ b/cipher/rsa.c -@@ -476,7 +476,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, - - retry: - /* generate p and q */ -- for (i = 0; i < 5 * pbits; i++) -+ for (i = 0; i < 10 * pbits; i++) - { - ploop: - if (!testparms) -@@ -506,10 +506,10 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, - else if (testparms) - goto err; - } -- if (i >= 5 * pbits) -+ if (i >= 10 * pbits) - goto err; - -- for (i = 0; i < 5 * pbits; i++) -+ for (i = 0; i < 20 * pbits; i++) - { - qloop: - if (!testparms) -@@ -555,7 +555,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, - else if (testparms) - goto err; - } -- if (i >= 5 * pbits) -+ if (i >= 20 * pbits) - goto err; - - if (testparms) --- -2.38.1 - diff --git a/libgcrypt-configure-c99.patch b/libgcrypt-configure-c99.patch deleted file mode 100644 index 8238ed4..0000000 --- a/libgcrypt-configure-c99.patch +++ /dev/null @@ -1,140 +0,0 @@ -Add missing prototypes to test functions. Future compilers will not -support implicit function declarations by default, causing spurious -test failures. - -Submitted upstream: - - - -diff --git a/configure.ac b/configure.ac -index 6ea38f53b8548ee8..2baf25bc7d9481e6 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1211,7 +1211,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARM assembly implementat - /* Test if '.type' and '.size' are supported. */ - ".size asmfunc,.-asmfunc;\n\t" - ".type asmfunc,%function;\n\t" -- );]], [ asmfunc(); ] )], -+ ); -+ void asmfunc(void);]], [ asmfunc(); ] )], - [gcry_cv_gcc_arm_platform_as_ok=yes]) - fi]) - if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then -@@ -1238,7 +1239,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARMv8/Aarch64 assembly i - "eor x0, x0, x30, ror #12;\n\t" - "add x0, x0, x30, asr #12;\n\t" - "eor v0.16b, v0.16b, v31.16b;\n\t" -- );]], [ asmfunc(); ] )], -+ ); -+ void asmfunc(void);]], [ asmfunc(); ] )], - [gcry_cv_gcc_aarch64_platform_as_ok=yes]) - fi]) - if test "$gcry_cv_gcc_aarch64_platform_as_ok" = "yes" ; then -@@ -1267,7 +1269,8 @@ AC_CACHE_CHECK([whether GCC assembler supports for CFI directives], - ".cfi_restore_state\n\t" - ".long 0\n\t" - ".cfi_endproc\n\t" -- );]])], -+ ); -+ void asmfunc(void)]])], - [gcry_cv_gcc_asm_cfi_directives=yes])]) - if test "$gcry_cv_gcc_asm_cfi_directives" = "yes" ; then - AC_DEFINE(HAVE_GCC_ASM_CFI_DIRECTIVES,1, -@@ -1666,7 +1669,8 @@ if test $amd64_as_feature_detection = yes; then - [gcry_cv_gcc_as_const_division_ok], - [gcry_cv_gcc_as_const_division_ok=no - AC_LINK_IFELSE([AC_LANG_PROGRAM( -- [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]], -+ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t"); -+ void fn(void);]], - [fn();])], - [gcry_cv_gcc_as_const_division_ok=yes])]) - if test "$gcry_cv_gcc_as_const_division_ok" = "no" ; then -@@ -1679,7 +1683,8 @@ if test $amd64_as_feature_detection = yes; then - [gcry_cv_gcc_as_const_division_with_wadivide_ok], - [gcry_cv_gcc_as_const_division_with_wadivide_ok=no - AC_LINK_IFELSE([AC_LANG_PROGRAM( -- [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]], -+ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t"); -+ void fn(void);]], - [fn();])], - [gcry_cv_gcc_as_const_division_with_wadivide_ok=yes])]) - if test "$gcry_cv_gcc_as_const_division_with_wadivide_ok" = "no" ; then -@@ -1715,7 +1720,8 @@ if test $amd64_as_feature_detection = yes; then - * and "-Wa,--divide" workaround failed, this causes assembly - * to be disable on this machine. */ - "xorl \$(123456789/12345678), %ebp;\n\t" -- );]], [ asmfunc(); ])], -+ ); -+ void asmfunc(void);]], [ asmfunc(); ])], - [gcry_cv_gcc_amd64_platform_as_ok=yes]) - fi]) - if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then -@@ -1734,7 +1740,8 @@ if test $amd64_as_feature_detection = yes; then - ".globl asmfunc\n\t" - "asmfunc:\n\t" - "xorq \$(1234), %rbp;\n\t" -- );]], [ asmfunc(); ])], -+ ); -+ void asmfunc(void);]], [ asmfunc(); ])], - [gcry_cv_gcc_win64_platform_as_ok=yes])]) - if test "$gcry_cv_gcc_win64_platform_as_ok" = "yes" ; then - AC_DEFINE(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS,1, -@@ -1767,7 +1774,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for Intel syntax assembly im - "sub eax, [esp + 4];\n\t" - "add dword ptr [esp + eax], 0b10101;\n\t" - ".att_syntax prefix\n\t" -- );]], [ actest(); ])], -+ ); -+ void actest(void);]], [ actest(); ])], - [gcry_cv_gcc_platform_as_ok_for_intel_syntax=yes]) - fi]) - if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then -@@ -1832,6 +1840,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports NEON instructions], - "vadd.u64 %q0, %q1;\n\t" - "vadd.s64 %d3, %d2, %d3;\n\t" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_neon=yes]) - fi]) -@@ -1879,6 +1888,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch32 Crypto Extension i - - "vmull.p64 q0, d0, d0;\n\t" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_aarch32_crypto=yes]) - fi]) -@@ -1907,6 +1917,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 NEON instructions] - "dup v0.8b, w0;\n\t" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_aarch64_neon=yes]) - fi]) -@@ -1955,6 +1966,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 Crypto Extension i - "pmull v0.1q, v0.1d, v31.1d;\n\t" - "pmull2 v0.1q, v0.2d, v31.2d;\n\t" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_aarch64_crypto=yes]) - fi]) -@@ -2050,6 +2062,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto - "vshasigmad %v0, %v1, 0, 15;\n" - "vpmsumd %v11, %v11, %v11;\n" - ); -+ void testfn(void); - ]], [ testfn(); ] )], - [gcry_cv_gcc_inline_asm_ppc_altivec=yes]) - fi]) -@@ -2075,6 +2088,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports PowerISA 3.00 instructions - "testfn:\n" - "stxvb16x %r1,%v12,%v30;\n" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_ppc_arch_3_00=yes]) - fi]) diff --git a/libgcrypt.spec b/libgcrypt.spec index aae97fc..899e3f9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,20 +14,14 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.10.1 -Release: 7%{?dist} +Version: 1.10.2 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch -# https://dev.gnupg.org/T5919 -# tests occasionally fail with "error generating RSA key: Number is not prime" -# https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=cd30ed3c0 -Patch2: 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch - -Patch3: libgcrypt-configure-c99.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -63,9 +57,7 @@ applications using libgcrypt. %prep %setup -q -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 +%patch 1 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -183,6 +175,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Apr 11 2023 Jakub Jelen - 1.10.2-1 +- New upstream release (#2185084) + * Thu Jan 19 2023 Fedora Release Engineering - 1.10.1-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild diff --git a/sources b/sources index 0021e06..d17dc31 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.10.1.tar.bz2) = e5ca7966624fff16c3013795836a2c4377f0193dbb4ac5ad2b79654b1fa8992e17d83816569a402212dc8367a7980d4141f5d6ac282bae6b9f02186365b61f13 -SHA512 (libgcrypt-1.10.1.tar.bz2.sig) = b156ae05079776698bc95ba5a9e48e95de8f716aa1760ef4b2e7cb8518ccec660337fc7823f865bde870461800d472fd8e458d03a7095b6bb614f6dd96f796d8 +SHA512 (libgcrypt-1.10.2.tar.bz2) = 3a850baddfe8ffe8b3e96dc54af3fbb9e1dab204db1f06b9b90b8fbbfb7fb7276260cd1e61ba4dde5a662a2385385007478834e62e95f785d2e3d32652adb29e +SHA512 (libgcrypt-1.10.2.tar.bz2.sig) = 9350444a0bcfa49217815a831f2286ccea470311673257bd809eb5dedbe97d2a5543b0bc7fb752312df69adeb7ac5f064e433f2545a8bf3e494027986cd8020c From 595da4e6ed75903702935ea05ca109dc89d31828 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Jun 2023 10:42:49 +0200 Subject: [PATCH 188/214] Disable jitter entropy generator to follow RHEL changes --- libgcrypt.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index 899e3f9..e2fdf1b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -83,6 +83,7 @@ autoreconf -f %endif --enable-noexecstack \ --enable-hmac-binary-check=%{hmackey} \ + --disable-jent-support \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" From f968cc8fb23b50db5cd8c6ee8df1520f6c8492e9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Jun 2023 11:14:17 +0200 Subject: [PATCH 189/214] Add SPDX license identifiers --- libgcrypt.spec | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index e2fdf1b..20c106b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -27,10 +27,7 @@ Patch1: libgcrypt-1.10.1-annobin.patch %global gcrysoname libgcrypt.so.20 %global hmackey orboDeJITITejsirpADONivirpUkvarP -# Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. -# Documentation and some utilities are GPLv2+ licensed. These files -# are in the devel subpackage. -License: LGPLv2+ +License: BSD-3-Clause AND (BSD-3-Clause OR GPL-2.0-only) AND GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later AND MIT-Modern-Variant Summary: A general-purpose cryptography library BuildRequires: gcc BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig @@ -41,7 +38,6 @@ BuildRequires: make %package devel Summary: Development files for the %{name} package -License: LGPLv2+ and GPLv2+ Requires: libgpg-error-devel Requires: %{name}%{?_isa} = %{version}-%{release} Requires: pkgconfig From bc207853a3e62b643b5568efe5d652c41a4165aa Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jul 2023 10:54:57 +0000 Subject: [PATCH 190/214] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 20c106b..2fc8354 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.2 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -172,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 20 2023 Fedora Release Engineering - 1.10.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Tue Apr 11 2023 Jakub Jelen - 1.10.2-1 - New upstream release (#2185084) From b03e7936f6484f7640eb06a9f1c42384f634290e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Nov 2023 18:38:23 +0100 Subject: [PATCH 191/214] update comment about algorithms --- libgcrypt.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 2fc8354..466e2b4 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -65,7 +65,7 @@ applications using libgcrypt. # F34, so we use it here explicitly %define _lto_cflags -flto=auto -ffat-lto-objects -# should be all algorithms except SM3 and SM4 +# should be all algorithms except SM3 and SM4, aria export DIGESTS='crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2' export CIPHERS='arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20' From f099f466e069df587753638f94f82c2c2c1e8dbc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Nov 2023 18:47:06 +0100 Subject: [PATCH 192/214] libgcrypt-1.10.3-1 --- .gitignore | 2 ++ libgcrypt.spec | 7 +++++-- sources | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index b60502b..3359399 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.10.1.tar.bz2.sig /libgcrypt-1.10.2.tar.bz2 /libgcrypt-1.10.2.tar.bz2.sig +/libgcrypt-1.10.3.tar.bz2 +/libgcrypt-1.10.3.tar.bz2.sig diff --git a/libgcrypt.spec b/libgcrypt.spec index 466e2b4..ca9eb5d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,8 +14,8 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.10.2 -Release: 2%{?dist} +Version: 1.10.3 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -172,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Nov 14 2023 Jakub Jelen - 1.10.3-1 +- New upstream release (#2249639) + * Thu Jul 20 2023 Fedora Release Engineering - 1.10.2-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild diff --git a/sources b/sources index d17dc31..09e5e42 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.10.2.tar.bz2) = 3a850baddfe8ffe8b3e96dc54af3fbb9e1dab204db1f06b9b90b8fbbfb7fb7276260cd1e61ba4dde5a662a2385385007478834e62e95f785d2e3d32652adb29e -SHA512 (libgcrypt-1.10.2.tar.bz2.sig) = 9350444a0bcfa49217815a831f2286ccea470311673257bd809eb5dedbe97d2a5543b0bc7fb752312df69adeb7ac5f064e433f2545a8bf3e494027986cd8020c +SHA512 (libgcrypt-1.10.3.tar.bz2) = 8a8d4c61a6622d8481ceb9edc88ec43f58da32e316f79f8d4775325a48f8936aaa9eb355923b39e2c267b784e9c390600daeb62e0c94f00e30bbadb0d8c0865d +SHA512 (libgcrypt-1.10.3.tar.bz2.sig) = 7b240b40992bbfd117ba6453377c3c8734aa70a43bc4e7d24b412b5f2446b85cd41e70950d2e973cc7e2da1f7669e267e276fd5f603e991b9a04919cb9bedab2 From 9caa9d782460e30d89a01f488166881d45dde212 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sun, 21 Jan 2024 04:08:26 +0000 Subject: [PATCH 193/214] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index ca9eb5d..237a21a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.3 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -172,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Sun Jan 21 2024 Fedora Release Engineering - 1.10.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Tue Nov 14 2023 Jakub Jelen - 1.10.3-1 - New upstream release (#2249639) From e851663be31ea6d9f01f5a15119df5bd9ab2a853 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 25 Jan 2024 02:13:24 +0000 Subject: [PATCH 194/214] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 237a21a..e42fa25 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.3 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -172,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jan 25 2024 Fedora Release Engineering - 1.10.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Sun Jan 21 2024 Fedora Release Engineering - 1.10.3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From fb3474ec1bced0045f855cef844aa31f746dd9b9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 26 Mar 2024 09:11:49 +0100 Subject: [PATCH 195/214] Replace deprecated fgrep (#2271503) --- libgcrypt-1.10.3-fgrep.patch | 24 ++++++++++++++++++++++++ libgcrypt.spec | 3 +++ 2 files changed, 27 insertions(+) create mode 100644 libgcrypt-1.10.3-fgrep.patch diff --git a/libgcrypt-1.10.3-fgrep.patch b/libgcrypt-1.10.3-fgrep.patch new file mode 100644 index 0000000..26bf036 --- /dev/null +++ b/libgcrypt-1.10.3-fgrep.patch @@ -0,0 +1,24 @@ +diff --git a/src/libgcrypt-config.in b/src/libgcrypt-config.in +--- a/src/libgcrypt-config.in ++++ b/src/libgcrypt-config.in +@@ -154,7 +154,7 @@ if test "$echo_cflags" = "yes"; then + + tmp="" + for i in $includes $cflags_final; do +- if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then ++ if echo "$tmp" | grep -F -v -- "$i" >/dev/null; then + tmp="$tmp $i" + fi + done +@@ -175,7 +175,7 @@ if test "$echo_libs" = "yes"; then + + tmp="" + for i in $libdirs $libs_final; do +- if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then ++ if echo "$tmp" | grep -F -v -- "$i" >/dev/null; then + tmp="$tmp $i" + fi + done +-- +2.44.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index e42fa25..b670241 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -22,6 +22,8 @@ Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch +# based on 128121e74b66793fabd24e478df6ea2ab568e24a but hardcoded the "grep -F" to avoid need to autoreconf +Patch2: libgcrypt-1.10.3-fgrep.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -54,6 +56,7 @@ applications using libgcrypt. %prep %setup -q %patch 1 -p1 +%patch 2 -p1 %build # This package has a configure test which uses ASMs, but does not link the From c4f54248a0551c4b538f895d4c3a56d9d1f5ef44 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 26 Mar 2024 09:12:42 +0100 Subject: [PATCH 196/214] 1.10.3-4 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index b670241..00904d7 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.3 -Release: 3%{?dist} +Release: 4%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -175,6 +175,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Mar 26 2024 Jakub Jelen - 1.10.3-4 +- Replace deprecated fgrep (#2271503) + * Thu Jan 25 2024 Fedora Release Engineering - 1.10.3-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From acfb1a25d81ce0763611401bc60ea7945a57018c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 19 Jun 2024 14:08:35 +0200 Subject: [PATCH 197/214] 1.11.0-1 --- .gitignore | 2 ++ libgcrypt-1.10.3-fgrep.patch | 24 ------------------------ libgcrypt.spec | 10 +++++----- sources | 4 ++-- 4 files changed, 9 insertions(+), 31 deletions(-) delete mode 100644 libgcrypt-1.10.3-fgrep.patch diff --git a/.gitignore b/.gitignore index 3359399..069ccb4 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.10.2.tar.bz2.sig /libgcrypt-1.10.3.tar.bz2 /libgcrypt-1.10.3.tar.bz2.sig +/libgcrypt-1.11.0.tar.bz2 +/libgcrypt-1.11.0.tar.bz2.sig diff --git a/libgcrypt-1.10.3-fgrep.patch b/libgcrypt-1.10.3-fgrep.patch deleted file mode 100644 index 26bf036..0000000 --- a/libgcrypt-1.10.3-fgrep.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/src/libgcrypt-config.in b/src/libgcrypt-config.in ---- a/src/libgcrypt-config.in -+++ b/src/libgcrypt-config.in -@@ -154,7 +154,7 @@ if test "$echo_cflags" = "yes"; then - - tmp="" - for i in $includes $cflags_final; do -- if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then -+ if echo "$tmp" | grep -F -v -- "$i" >/dev/null; then - tmp="$tmp $i" - fi - done -@@ -175,7 +175,7 @@ if test "$echo_libs" = "yes"; then - - tmp="" - for i in $libdirs $libs_final; do -- if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then -+ if echo "$tmp" | grep -F -v -- "$i" >/dev/null; then - tmp="$tmp $i" - fi - done --- -2.44.0 - diff --git a/libgcrypt.spec b/libgcrypt.spec index 00904d7..c240c9d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,16 +14,14 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.10.3 -Release: 4%{?dist} +Version: 1.11.0 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch -# based on 128121e74b66793fabd24e478df6ea2ab568e24a but hardcoded the "grep -F" to avoid need to autoreconf -Patch2: libgcrypt-1.10.3-fgrep.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -56,7 +54,6 @@ applications using libgcrypt. %prep %setup -q %patch 1 -p1 -%patch 2 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -175,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Wed Jun 19 2024 Jakub Jelen - 1.11.0-1 +- New upstream release (#2293064) + * Tue Mar 26 2024 Jakub Jelen - 1.10.3-4 - Replace deprecated fgrep (#2271503) diff --git a/sources b/sources index 09e5e42..4ef369d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.10.3.tar.bz2) = 8a8d4c61a6622d8481ceb9edc88ec43f58da32e316f79f8d4775325a48f8936aaa9eb355923b39e2c267b784e9c390600daeb62e0c94f00e30bbadb0d8c0865d -SHA512 (libgcrypt-1.10.3.tar.bz2.sig) = 7b240b40992bbfd117ba6453377c3c8734aa70a43bc4e7d24b412b5f2446b85cd41e70950d2e973cc7e2da1f7669e267e276fd5f603e991b9a04919cb9bedab2 +SHA512 (libgcrypt-1.11.0.tar.bz2) = 8e093e69e3c45d30838625ca008e995556f0d5b272de1c003d44ef94633bcc0d0ef5d95e8725eb531bfafb4490ac273488633e0c801200d4666194f86c3e270e +SHA512 (libgcrypt-1.11.0.tar.bz2.sig) = 8c5ceb50d70ccdedcc1ff4b31a65a07198567b85f582e3e67699cc3e5d012bebf7b1d4903652d11905a9cd845976ad7d3642474804777d0bdc46c6847d92fe38 From 186e09a1905735564fb294c64c24ab7883b218a4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Jun 2024 11:34:59 +0200 Subject: [PATCH 198/214] Unbreak s390x build --- ...e-SHA3-s390x-acceleration-for-CSHAKE.patch | 63 +++++++++++++++++++ libgcrypt.spec | 3 + 2 files changed, 66 insertions(+) create mode 100644 libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch diff --git a/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch b/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch new file mode 100644 index 0000000..0267ea0 --- /dev/null +++ b/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch @@ -0,0 +1,63 @@ +From 2486d9b5ae015c1786cb84466a751da4bc0d7122 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Thu, 20 Jun 2024 20:10:09 +0300 +Subject: [PATCH] Disable SHA3 s390x acceleration for CSHAKE + +* cipher/keccak.c (keccak_final_s390x): Add assert check for +expected SHAKE suffix. +(_gcry_cshake_customize, cshake_hash_buffers): Disable s390x +acceleration when selecting CSHAKE suffix. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/keccak.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/cipher/keccak.c b/cipher/keccak.c +index aaf83a62..44cc9f71 100644 +--- a/cipher/keccak.c ++++ b/cipher/keccak.c +@@ -745,6 +745,8 @@ keccak_final_s390x (void *context) + } + else + { ++ gcry_assert(ctx->suffix == SHAKE_DELIMITED_SUFFIX); ++ + klmd_shake_execute (ctx->kimd_func, &ctx->state, NULL, 0, ctx->buf, + ctx->count); + ctx->count = 0; +@@ -1497,9 +1499,14 @@ _gcry_cshake_customize (void *context, struct gcry_cshake_customization *p) + /* No customization */ + return 0; + ++ ctx->suffix = CSHAKE_DELIMITED_SUFFIX; ++#ifdef USE_S390X_CRYPTO ++ /* CSHAKE suffix is not supported by s390x/kimd. */ ++ ctx->kimd_func = 0; ++#endif ++ + len_written = cshake_input_n (ctx, p->n, p->n_len); + cshake_input_s (ctx, p->s, p->s_len, len_written); +- ctx->suffix = CSHAKE_DELIMITED_SUFFIX; + return 0; + } + +@@ -1536,9 +1543,14 @@ cshake_hash_buffers (const gcry_md_spec_t *spec, void *outbuf, size_t nbytes, + size_t s_len = iov[1].len; + size_t len; + ++ ctx.suffix = CSHAKE_DELIMITED_SUFFIX; ++#ifdef USE_S390X_CRYPTO ++ /* CSHAKE suffix is not supported by s390x/kimd. */ ++ ctx.kimd_func = 0; ++#endif ++ + len = cshake_input_n (&ctx, n, n_len); + cshake_input_s (&ctx, s, s_len, len); +- ctx.suffix = CSHAKE_DELIMITED_SUFFIX; + } + iovcnt -= 2; + iov += 2; +-- +2.43.0 diff --git a/libgcrypt.spec b/libgcrypt.spec index c240c9d..9931ad9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -22,6 +22,8 @@ Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch +# https://dev.gnupg.org/T7167 +Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -54,6 +56,7 @@ applications using libgcrypt. %prep %setup -q %patch 1 -p1 +%patch 2 -p1 %build # This package has a configure test which uses ASMs, but does not link the From 4949b993a1e7bfcf65cf8978da9011cc2d1b8771 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Jul 2024 17:57:05 +0200 Subject: [PATCH 199/214] Verify tarball signatures --- libgcrypt.spec | 4 +- signature_key.asc | 86 ++ wk@g10code.com | 2007 --------------------------------------------- 3 files changed, 89 insertions(+), 2008 deletions(-) create mode 100644 signature_key.asc delete mode 100644 wk@g10code.com diff --git a/libgcrypt.spec b/libgcrypt.spec index 9931ad9..17fd93c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -19,7 +19,7 @@ Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig -Source2: wk@g10code.com +Source2: https://gnupg.org/signature_key.asc # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch # https://dev.gnupg.org/T7167 @@ -37,6 +37,7 @@ BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig BuildRequires: texinfo BuildRequires: autoconf, automake, libtool BuildRequires: make +BuildRequires: gnupg2 %package devel Summary: Development files for the %{name} package @@ -54,6 +55,7 @@ in GNU Privacy Guard. This package contains files needed to develop applications using libgcrypt. %prep +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' %setup -q %patch 1 -p1 %patch 2 -p1 diff --git a/signature_key.asc b/signature_key.asc new file mode 100644 index 0000000..151e8fa --- /dev/null +++ b/signature_key.asc @@ -0,0 +1,86 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +eiInsGZ/+h5XYrpXTgA= +=4+Sn +-----END PGP PUBLIC KEY BLOCK----- diff --git a/wk@g10code.com b/wk@g10code.com deleted file mode 100644 index 5e193e3..0000000 --- a/wk@g10code.com +++ /dev/null @@ -1,2007 +0,0 @@ -Login: wk Name: Werner Koch -No project. -No plan. -Public key: - pub 1024D/5B0358A2 1999-03-15 [expires: 2011-07-11] - uid Werner Koch - uid Werner Koch - uid Werner Koch - uid Werner Koch - sub 1024D/010A57ED 2004-03-21 [expires: 2007-12-31] - sub 2048R/C3680A6E 2006-01-01 [expires: 2007-12-31] - - pub 1024R/1CE0C630 2006-01-01 [expires: 2008-12-31] - uid Werner Koch (dist sig) - - pub 1024R/37D92FFB 2003-11-17 [expires: 2009-12-31] - uid g10 Code (code signing key 1) - - pub 1024D/57548DCD 1998-07-07 [expired: 2005-12-31] - uid Werner Koch (gnupg sig) - - -5B0358A2 is my main key. -1CE0C630 is used to sign software distributions. -37D92FFB is used to sign certain source files. -57548DCD was used to sign GNU crypto software; - it has been superseded by 1CE0C630. - -Please note that I use a subkey for signing messages; some old OpenPGP -implementations may not be able to check such a signature. The primary -key is stored at a more or less secure place and only used on a spare -laptop which is not connected to any network. If you find a key -certified by this one, you can be sure that I personally met this -person and checked the name part of the user ID against an official -looking passport or another suitable photo id. My signature does not -say anything about the email address (I merely check that the address -looks plausible). - - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.7 (GNU/Linux) - -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 -Ooh6BBMRAgA6BQJEXmVkMxpodHRwOi8vd3d3LnNjLWRlbHBoaW4tZXNjaHdlaWxl -ci5kZS9wZ3AvaW5kZXguaHRtbAAKCRC0deIHurWCKcwdAJ4hvG79xMFKtYL0GGP8 -WuvvxnMnzQCfZUjHFhMNMGgrCPthD6oeNaw2FxCIRgQTEQIABgUCRFz9JwAKCRCK -o2Kv6XIyzVjaAJ9MSW3iP1fUZqr7xdbj/PLkHLzJeACfZNe6IgDrJk9E3a/8IKZi -E4iYtqWIRgQTEQIABgUCRFz9LwAKCRCn31hycNRMI+EXAKDRHf6ZRUGa6T7Uosgx -huo5I3sK6gCfRxthF9FN1SXK11O+tjRS1mwN0JaIYwQTEQIAGwUCNxrPkAUJDMl8 -gAMLCgMDFQMCAxYCAQIXgAASCRBd4kmWWwNYogdlR1BHAAEBXcIAnjv7ON5AiwzC -LBwm9h9ywufXJQuVAJ9RMq6lpPqnDly6UCKz+kGt0EplyIhmBBMRAgAeAwsKAwMV -AwIDFgIBAheAAhkBBQJAXdnoBQkTa4v/ABIHZUdQRwABAQkQXeJJllsDWKLs0gCg -y5RdOqhFvwUFYWj+dHb4LGt7xi0AoKduFxGMuM/loPShQnjvk/VVFesAiF4EExEC -AB4DCwoDAxUDAgMWAgECF4ACGQEFAkBd2egFCRNri/8ACgkQXeJJllsDCRDs0gCg -y5RdOqhFvwUFYWj+dHb4LGt7xi0AoKduFxGMuM/loPShQnjvk/VVFesAiQEVAwUQ -O0HCUNImKUTOasbBAQFLZwgAkgMC/ximskOjL/CxghgdkSWkDFdpEr3XYhzUdLes -WgN4AM28mGZZKA9la7dXXRrKYkxhX8mpL4C3Q9LnrafP+Zn1c8mTuNIxX86j7iZA -IksoZ4D2csN8NSMYT9pKK6jZP1IOckCFBBI0W/yMGUGulDitWj4TwIArf2xQkV73 -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -/////////////////////////////////////////////4hGBBMRAgAGBQJDRBuk -AAoJEOrUtZD2iZvAafoAoKReCbMFRrpwzb2tS7M6iHDbN9E+AJoDy8nLf8A4f/EV -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 -wZyP4MwTIOb4NIhGBBARAgAGBQJEKFdaAAoJEBH0xB6z+64zBhUAoJ6kWu5gDqHB -Z8Wan0YynEZi6tKyAJsHBacxx6UNYPENlVXlb0xl+kssa4h6BBMRAgA6BQJEXmVA -MxpodHRwOi8vd3d3LnNjLWRlbHBoaW4tZXNjaHdlaWxlci5kZS9wZ3AvaW5kZXgu -aHRtbAAKCRCUj9ag4Q9QLulZAJ992LLlu7wU5sJddqnffDzPoKh69QCgoX8QzBEi -SZjLKSrALwLCTYI/akSIegQTEQIAOgUCRF5lZDMaaHR0cDovL3d3dy5zYy1kZWxw -aGluLWVzY2h3ZWlsZXIuZGUvcGdwL2luZGV4Lmh0bWwACgkQtHXiB7q1gikU0QCf -ZM81Hr4p7ZPwxMZW+TVcRdaSIjoAoMq7mN4xSLtRsB/lGlFLhc1O4soLiEYEExEC -AAYFAkRc/SoACgkQiqNir+lyMs3HBACfb7fa3KzNGB9Oma3KDWeC42feCzAAoIfF -w3OXxtigxx8+AowiXGsZmqI+iEYEExECAAYFAkRc/TEACgkQp99YcnDUTCOrZQCg -gV7PoPMl1d+gvPTiuUAZm8UG/dYAn3PlOcTP4vxayC7OGSkoDA8Dut+KiEYEExEC -AAYFAkNEG6QACgkQ6tS1kPaJm8DI0ACfRfci8SHm+sQpjzKqr0zxfJT5yF0AnA37 -mn7nQyY28SJ2sddCo/f1JhvAiEYEEBECAAYFAkQFglgACgkQb11ZaBzVLeiG9wCf -aX6+h8bpMOraCn/sH1yQb6aI34EAoLzx4H6lGdyqnQTYiLXSrBTrto/niEYEEBEC -AAYFAkQGCjQACgkQmsnSLGNcY0vZ4wCgvBjcB5ABcNYRMEFSWsClxhaRAqUAmwUv -MA9NWdLk0pcUndbE3w70B5hUiEwEEhECAAwFAkQGKycFgwZSqcEACgkQ3+ZXkjKV -xc2qMwCfdew+RX+7ultYmO0Y8gRoLJzjBfgAn1UkZILe3+NKZBJTd1ZowJQiljHI -iEwEEhECAAwFAkQGK2cFgwZSqYEACgkQoOUVvzmICVQuFwCgqbjde48qPvUqLEip -he/zFq6pqgAAn1dXi6z+1s+bHavwCQK/q+3K5gdHiJwEEwECAAYFAkQNdesACgkQ -/dJ0ek5GOmrWRgQAoFF9IdTs5vX5OIDKIHW+d4aJfPg6w91SKkfpElDxNqZuk3rA -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 -nj+zW9f9Z2M0K2r+gldEC2Ew2yTl -=I1gH ------END PGP PUBLIC KEY BLOCK----- From b73849fad4e17c992e9e948dd9e6efe4cc46f757 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 18 Jul 2024 13:54:55 +0000 Subject: [PATCH 200/214] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 17fd93c..eebb9aa 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.0 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -177,6 +177,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 18 2024 Fedora Release Engineering - 1.11.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Wed Jun 19 2024 Jakub Jelen - 1.11.0-1 - New upstream release (#2293064) From 493faf840cc5bc3258bbcff7e4276951ed8082b0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 Jul 2024 13:38:35 +0200 Subject: [PATCH 201/214] Remove _lto_cflags override as it should be default --- libgcrypt.spec | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index eebb9aa..44f5232 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -61,15 +61,6 @@ applications using libgcrypt. %patch 2 -p1 %build -# This package has a configure test which uses ASMs, but does not link the -# resultant .o files. As such the ASM test is always successful, even on -# architectures were the ASM is not valid when compiling with LTO. -# -# -ffat-lto-objects is sufficient to address this issue. It is the default -# for F33, but is expected to only be enabled for packages that need it in -# F34, so we use it here explicitly -%define _lto_cflags -flto=auto -ffat-lto-objects - # should be all algorithms except SM3 and SM4, aria export DIGESTS='crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2' export CIPHERS='arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20' From 0b1eb3742d4d3bc7f9a37cb7a5d27e94d26fdf09 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 Jul 2024 13:40:29 +0200 Subject: [PATCH 202/214] disable -O flag mnging as the jent support is disabled anyway --- libgcrypt.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index 44f5232..b7d86b3 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -76,6 +76,7 @@ autoreconf -f --enable-noexecstack \ --enable-hmac-binary-check=%{hmackey} \ --disable-jent-support \ + --disable-O-flag-munging \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" From 98af486ed06636cfc6609db7766f83ed50267962 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 Jul 2024 14:00:08 +0200 Subject: [PATCH 203/214] 1.11.0-3 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index b7d86b3..0090ec5 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.0 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -169,6 +169,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 25 2024 Jakub Jelen - 1.11.0-3 +- Disable -O flag munging and remove needles modification of LTO flags. + * Thu Jul 18 2024 Fedora Release Engineering - 1.11.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From ebd8acdd2ef16401e716e7ec83cdb4e083f753aa Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 27 Jul 2024 12:31:49 +0200 Subject: [PATCH 204/214] Unbreak CF protection on the library --- libgcrypt-1.11.0-cf-protection.patch | 191 +++++++++++++++++++++++++++ libgcrypt.spec | 3 + 2 files changed, 194 insertions(+) create mode 100644 libgcrypt-1.11.0-cf-protection.patch diff --git a/libgcrypt-1.11.0-cf-protection.patch b/libgcrypt-1.11.0-cf-protection.patch new file mode 100644 index 0000000..e7ead95 --- /dev/null +++ b/libgcrypt-1.11.0-cf-protection.patch @@ -0,0 +1,191 @@ +From de3a04203b33c2248400392b535d2ab133bcd752 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Sat, 27 Jul 2024 08:16:56 +0300 +Subject: [PATCH] Do not build rijndael-vaes-avx2-i386 on x86-64 + +* configure.ac: Enable building i386 "rijndael-vaes" only +on i?86 host instead of x86 MPI arch ("i?86 + x86-64"). +-- + +Signed-off-by: Jussi Kivilinna +--- + configure.ac | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index d3dffb4b..1e182552 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3025,6 +3025,11 @@ if test "$found" = "1" ; then + AC_DEFINE(USE_AES, 1, [Defined if this module should be included]) + + case "${host}" in ++ i?86-*-*) ++ # Build with the VAES/AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-i386.lo" ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-avx2-i386.lo" ++ ;; + x86_64-*-*) + # Build with the assembly implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-amd64.lo" +@@ -3089,10 +3094,6 @@ if test "$found" = "1" ; then + + # Build with the Padlock implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-padlock.lo" +- +- # Build with the VAES/AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-i386.lo" +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-avx2-i386.lo" + ;; + esac + fi +-- +2.43.0 + + +From 9178af96038acd295d02a4c405c19435dce92ad8 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Fri, 26 Jul 2024 10:59:12 +0300 +Subject: [PATCH 1/2] Add CET support for x86-64 assembly + +* cipher/asm-common-amd64.h (ENDBRANCH): New. +(CFI_STARTPROC): Add ENDBRANCH. +[__CET__] (note.gnu.property): Add CET property section. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/asm-common-amd64.h | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h +index 3fa065e8..465ef62b 100644 +--- a/cipher/asm-common-amd64.h ++++ b/cipher/asm-common-amd64.h +@@ -76,9 +76,15 @@ + # endif + #endif + ++#ifdef __CET__ ++#define ENDBRANCH endbr64 ++#else ++#define ENDBRANCH /*_*/ ++#endif ++ + #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES + /* CFI directives to emit DWARF stack unwinding information. */ +-# define CFI_STARTPROC() .cfi_startproc ++# define CFI_STARTPROC() .cfi_startproc; ENDBRANCH + # define CFI_ENDPROC() .cfi_endproc + # define CFI_REMEMBER_STATE() .cfi_remember_state + # define CFI_RESTORE_STATE() .cfi_restore_state +@@ -146,7 +152,7 @@ + DW_SLEB128_28BIT(rsp_offs) + + #else +-# define CFI_STARTPROC() ++# define CFI_STARTPROC() ENDBRANCH + # define CFI_ENDPROC() + # define CFI_REMEMBER_STATE() + # define CFI_RESTORE_STATE() +@@ -214,4 +220,24 @@ + vpopcntb xmm16, xmm16; /* Supported only by newer AVX512 CPUs. */ \ + vpxord ymm16, ymm16, ymm16; + ++#ifdef __CET__ ++/* Generate CET property for all assembly files including this header. */ ++ELF(.section .note.gnu.property,"a") ++ELF(.align 8) ++ELF(.long 1f - 0f) ++ELF(.long 4f - 1f) ++ELF(.long 5) ++ELF(0:) ++ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ ++ELF(1:) ++ELF(.align 8) ++ELF(.long 0xc0000002) ++ELF(.long 3f - 2f) ++ELF(2:) ++ELF(.long 0x3) ++ELF(3:) ++ELF(.align 8) ++ELF(4:) ++#endif ++ + #endif /* GCRY_ASM_COMMON_AMD64_H */ +-- +2.43.0 + +From e7c81e64b1a81455ce72c54607ce6ab35c24f407 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Fri, 26 Jul 2024 11:09:37 +0300 +Subject: [PATCH 2/2] Add CET support for i386 assembly + +* cipher/asm-common-i386.h (ENDBRANCH): New. +(CFI_STARTPROC): Add ENDBRANCH. +[__CET__] (note.gnu.property): Add CET property section. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/asm-common-i386.h | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/cipher/asm-common-i386.h b/cipher/asm-common-i386.h +index d746ebc4..346a8ff2 100644 +--- a/cipher/asm-common-i386.h ++++ b/cipher/asm-common-i386.h +@@ -59,9 +59,15 @@ + movl name##@GOT(%reg), %reg; + #endif + ++#ifdef __CET__ ++#define ENDBRANCH endbr32 ++#else ++#define ENDBRANCH /*_*/ ++#endif ++ + #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES + /* CFI directives to emit DWARF stack unwinding information. */ +-# define CFI_STARTPROC() .cfi_startproc ++# define CFI_STARTPROC() .cfi_startproc; ENDBRANCH + # define CFI_ENDPROC() .cfi_endproc + # define CFI_REMEMBER_STATE() .cfi_remember_state + # define CFI_RESTORE_STATE() .cfi_restore_state +@@ -121,7 +127,7 @@ + DW_SLEB128_28BIT(esp_offs) + + #else +-# define CFI_STARTPROC() ++# define CFI_STARTPROC() ENDBRANCH + # define CFI_ENDPROC() + # define CFI_REMEMBER_STATE() + # define CFI_RESTORE_STATE() +@@ -158,4 +164,24 @@ + vpopcntb xmm7, xmm7; /* Supported only by newer AVX512 CPUs. */ \ + vpxord ymm7, ymm7, ymm7; + ++#ifdef __CET__ ++/* Generate CET property for all assembly files including this header. */ ++ELF(.section .note.gnu.property,"a") ++ELF(.align 4) ++ELF(.long 1f - 0f) ++ELF(.long 4f - 1f) ++ELF(.long 5) ++ELF(0:) ++ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ ++ELF(1:) ++ELF(.align 4) ++ELF(.long 0xc0000002) ++ELF(.long 3f - 2f) ++ELF(2:) ++ELF(.long 0x3) ++ELF(3:) ++ELF(.align 4) ++ELF(4:) ++#endif ++ + #endif /* GCRY_ASM_COMMON_AMD64_H */ +-- +2.43.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index 0090ec5..74d3528 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -24,6 +24,8 @@ Source2: https://gnupg.org/signature_key.asc Patch1: libgcrypt-1.10.1-annobin.patch # https://dev.gnupg.org/T7167 Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch +# https://dev.gnupg.org/T7220 +Patch3: libgcrypt-1.11.0-cf-protection.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -59,6 +61,7 @@ applications using libgcrypt. %setup -q %patch 1 -p1 %patch 2 -p1 +%patch 3 -p1 %build # should be all algorithms except SM3 and SM4, aria From efefee810753ddc19174e6532952fd156dedba83 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Aug 2024 09:03:18 +0200 Subject: [PATCH 205/214] Use upstream commits for CF protection --- libgcrypt-1.11.0-cf-protection.patch | 155 +++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 9 deletions(-) diff --git a/libgcrypt-1.11.0-cf-protection.patch b/libgcrypt-1.11.0-cf-protection.patch index e7ead95..ece660e 100644 --- a/libgcrypt-1.11.0-cf-protection.patch +++ b/libgcrypt-1.11.0-cf-protection.patch @@ -1,12 +1,55 @@ -From de3a04203b33c2248400392b535d2ab133bcd752 Mon Sep 17 00:00:00 2001 +From 7ee2e73495d051ca09dd57c90132a7a9cc53bc62 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Fri, 26 Jul 2024 11:00:30 +0300 +Subject: [PATCH] asm-common-amd64: add missing CFI directives for large memory + model code + +* cipher/asm-common-amd64.h [__code_model_large__] +(GET_EXTERN_POINTER): Add CFI_PUSH/CFI_POP directives. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/asm-common-amd64.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h +index 870fef9a..3fa065e8 100644 +--- a/cipher/asm-common-amd64.h ++++ b/cipher/asm-common-amd64.h +@@ -59,14 +59,18 @@ + # ifdef __code_model_large__ + # define GET_EXTERN_POINTER(name, reg) \ + pushq %r15; \ ++ CFI_PUSH(%r15); \ + pushq %r14; \ ++ CFI_PUSH(%r14); \ + 1: leaq 1b(%rip), reg; \ + movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \ + movabsq $name@GOT, %r15; \ + addq %r14, reg; \ + popq %r14; \ ++ CFI_POP(%r14); \ + movq (reg, %r15), reg; \ +- popq %r15; ++ popq %r15; \ ++ CFI_POP(%r15); + # else + # define GET_EXTERN_POINTER(name, reg) movq name@GOTPCREL(%rip), reg + # endif +-- +2.45.2 + +From dd42a4e03e066c49a6d83e0d3a07e4261d77121a Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 27 Jul 2024 08:16:56 +0300 -Subject: [PATCH] Do not build rijndael-vaes-avx2-i386 on x86-64 +Subject: [PATCH] Do not build i386 assembly on x86-64 * configure.ac: Enable building i386 "rijndael-vaes" only on i?86 host instead of x86 MPI arch ("i?86 + x86-64"). -- +GnuPG-bug-id: 7220 Signed-off-by: Jussi Kivilinna --- configure.ac | 9 +++++---- @@ -40,19 +83,112 @@ index d3dffb4b..1e182552 100644 esac fi -- -2.43.0 +2.45.2 +From 5797d75e3b916caf504bed73a8629c6c168be58d Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Sat, 27 Jul 2024 08:50:57 +0300 +Subject: [PATCH] Do not build amd64 assembly on i386 -From 9178af96038acd295d02a4c405c19435dce92ad8 Mon Sep 17 00:00:00 2001 +* configure.ac: Build "serpent-avx2-amd64" and +"camellia-*-amd64" only on x86-64. +-- + +GnuPG-bug-id: 7220 +Signed-off-by: Jussi Kivilinna +--- + configure.ac | 50 +++++++++++++++++++++++++++----------------------- + 1 file changed, 27 insertions(+), 23 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 1e182552..191aa38d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3133,14 +3133,14 @@ if test "$found" = "1" ; then + x86_64-*-*) + # Build with the SSE2 implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-sse2-amd64.lo" ++ ++ if test x"$avx2support" = xyes ; then ++ # Build with the AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" ++ fi + ;; + esac + +- if test x"$avx2support" = xyes ; then +- # Build with the AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" +- fi +- + if test x"$avx512support" = xyes ; then + # Build with the AVX512 implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx512-x86.lo" +@@ -3186,28 +3186,32 @@ if test "$found" = "1" ; then + ;; + esac + +- if test x"$avxsupport" = xyes ; then +- if test x"$aesnisupport" = xyes ; then +- # Build with the AES-NI/AVX implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx-amd64.lo" +- fi +- fi ++ case "${host}" in ++ x86_64-*-*) ++ if test x"$avxsupport" = xyes ; then ++ if test x"$aesnisupport" = xyes ; then ++ # Build with the AES-NI/AVX implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx-amd64.lo" ++ fi ++ fi + +- if test x"$avx2support" = xyes ; then +- if test x"$aesnisupport" = xyes ; then +- # Build with the AES-NI/AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx2-amd64.lo" ++ if test x"$avx2support" = xyes ; then ++ if test x"$aesnisupport" = xyes ; then ++ # Build with the AES-NI/AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx2-amd64.lo" + +- # Build with the VAES/AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-vaes-avx2-amd64.lo" ++ # Build with the VAES/AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-vaes-avx2-amd64.lo" + +- # Build with the GFNI/AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx2-amd64.lo" ++ # Build with the GFNI/AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx2-amd64.lo" + +- # Build with the GFNI/AVX512 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx512-amd64.lo" +- fi +- fi ++ # Build with the GFNI/AVX512 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx512-amd64.lo" ++ fi ++ fi ++ ;; ++ esac + fi + + LIST_MEMBER(idea, $enabled_ciphers) +-- +2.45.2 + +From d69e6a29b986cf1cb21e09d337a0de2564ef34f2 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Fri, 26 Jul 2024 10:59:12 +0300 -Subject: [PATCH 1/2] Add CET support for x86-64 assembly +Subject: [PATCH] Add CET support for x86-64 assembly * cipher/asm-common-amd64.h (ENDBRANCH): New. (CFI_STARTPROC): Add ENDBRANCH. [__CET__] (note.gnu.property): Add CET property section. -- +GnuPG-bug-id: 7220 Signed-off-by: Jussi Kivilinna --- cipher/asm-common-amd64.h | 30 ++++++++++++++++++++++++++++-- @@ -114,18 +250,19 @@ index 3fa065e8..465ef62b 100644 + #endif /* GCRY_ASM_COMMON_AMD64_H */ -- -2.43.0 +2.45.2 -From e7c81e64b1a81455ce72c54607ce6ab35c24f407 Mon Sep 17 00:00:00 2001 +From 64ec13d11b08fbe31cc6f83e9464e7e251d41019 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Fri, 26 Jul 2024 11:09:37 +0300 -Subject: [PATCH 2/2] Add CET support for i386 assembly +Subject: [PATCH] Add CET support for i386 assembly * cipher/asm-common-i386.h (ENDBRANCH): New. (CFI_STARTPROC): Add ENDBRANCH. [__CET__] (note.gnu.property): Add CET property section. -- +GnuPG-bug-id: 7220 Signed-off-by: Jussi Kivilinna --- cipher/asm-common-i386.h | 30 ++++++++++++++++++++++++++++-- @@ -187,5 +324,5 @@ index d746ebc4..346a8ff2 100644 + #endif /* GCRY_ASM_COMMON_AMD64_H */ -- -2.43.0 +2.45.2 From 6582e15a918a6279b1ffaa1f163d5e724e8f3d7f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Aug 2024 09:04:08 +0200 Subject: [PATCH 206/214] Fix PAC/BTI protection on Aarch64 --- libgcrypt-1.11.0-pac-bti-protection.patch | 229 ++++++++++++++++++++++ libgcrypt.spec | 2 + 2 files changed, 231 insertions(+) create mode 100644 libgcrypt-1.11.0-pac-bti-protection.patch diff --git a/libgcrypt-1.11.0-pac-bti-protection.patch b/libgcrypt-1.11.0-pac-bti-protection.patch new file mode 100644 index 0000000..3c713ab --- /dev/null +++ b/libgcrypt-1.11.0-pac-bti-protection.patch @@ -0,0 +1,229 @@ +From afdd68b162103820edb72ad170f8ee26f206b396 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Sun, 4 Aug 2024 18:51:34 +0300 +Subject: [PATCH] Add PAC/BTI support for AArch64 assembly + +* cipher/asm-common-aarch64.h (AARCH64_BTI_PROPERTY_FLAG) +(AARCH64_HINT_BTI_C, AARCH64_PAC_PROPERTY_FLAG) +(note.gnu.property): New. +(CFI_STARTPROC): Add AARCH64_HINT_BTI_C. +-- + +GnuPG-bug-id: 7220 +Signed-off-by: Jussi Kivilinna +--- + cipher/asm-common-aarch64.h | 50 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 48 insertions(+), 2 deletions(-) + +diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h +index 3a72d7c4..ff65ea6a 100644 +--- a/cipher/asm-common-aarch64.h ++++ b/cipher/asm-common-aarch64.h +@@ -45,9 +45,25 @@ + add reg, reg, #:lo12:name ; + #endif + ++#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 ++# define AARCH64_BTI_PROPERTY_FLAG (1 << 0) ++# define AARCH64_HINT_BTI_C \ ++ hint #34 ++#else ++# define AARCH64_BTI_PROPERTY_FLAG 0 /* No BTI */ ++# define AARCH64_HINT_BTI_C /*_*/ ++#endif ++ ++#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 3) != 0 ++/* PAC enabled, signed with either A or B key. */ ++# define AARCH64_PAC_PROPERTY_FLAG (1 << 1) ++#else ++# define AARCH64_PAC_PROPERTY_FLAG 0 /* No PAC */ ++#endif ++ + #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES + /* CFI directives to emit DWARF stack unwinding information. */ +-# define CFI_STARTPROC() .cfi_startproc ++# define CFI_STARTPROC() .cfi_startproc; AARCH64_HINT_BTI_C + # define CFI_ENDPROC() .cfi_endproc + # define CFI_REMEMBER_STATE() .cfi_remember_state + # define CFI_RESTORE_STATE() .cfi_restore_state +@@ -89,7 +105,7 @@ + DW_SLEB128_28BIT(rsp_offs) + + #else +-# define CFI_STARTPROC() ++# define CFI_STARTPROC() AARCH64_HINT_BTI_C + # define CFI_ENDPROC() + # define CFI_REMEMBER_STATE() + # define CFI_RESTORE_STATE() +@@ -129,4 +145,34 @@ + ldp d8, d9, [sp], #16; \ + CFI_ADJUST_CFA_OFFSET(-16); + ++#if (AARCH64_BTI_PROPERTY_FLAG | AARCH64_PAC_PROPERTY_FLAG) ++/* Generate PAC/BTI property for all assembly files including this header. ++ * ++ * libgcrypt support these extensions: ++ * - Armv8.3-A Pointer Authentication (PAC): ++ * As currently all AArch64 assembly functions are leaf functions and do ++ * not store/load link register LR, we just mark PAC as supported. ++ * ++ * - Armv8.5-A Branch Target Identification (BTI): ++ * All AArch64 assembly functions get branch target instruction through ++ * CFI_STARTPROC macro. ++ */ ++ELF(.section .note.gnu.property,"a") ++ELF(.balign 8) ++ELF(.long 1f - 0f) ++ELF(.long 4f - 1f) ++ELF(.long 5) ++ELF(0:) ++ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ ++ELF(1:) ++ELF(.balign 8) ++ELF(.long 0xc0000000) ++ELF(.long 3f - 2f) ++ELF(2:) ++ELF(.long (AARCH64_BTI_PROPERTY_FLAG | AARCH64_PAC_PROPERTY_FLAG)) ++ELF(3:) ++ELF(.balign 8) ++ELF(4:) ++#endif ++ + #endif /* GCRY_ASM_COMMON_AARCH64_H */ +-- +2.43.0 + +From 07706d69f238f6a3bfc3f74145686a02decbee9c Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Mon, 5 Aug 2024 20:18:05 +0300 +Subject: [PATCH] Do not build 32-bit ARM assembly on Aarch64 + +* configure.ac: Build "serpent-armv7-neon", "salsa20-armv7-neon", +"chacha20-armv7-neon", "sha512-armv7-neon" and "keccak-armv7-neon" +only on 32-bit ARM. +-- + +GnuPG-bug-id: 7220 +Signed-off-by: Jussi Kivilinna +--- + configure.ac | 54 ++++++++++++++++++++++++++++------------------------ + 1 file changed, 29 insertions(+), 25 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 191aa38d..2b6ddb7b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3139,17 +3139,18 @@ if test "$found" = "1" ; then + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" + fi + ;; ++ arm*-*-*) ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-armv7-neon.lo" ++ fi ++ ;; + esac + + if test x"$avx512support" = xyes ; then + # Build with the AVX512 implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx512-x86.lo" + fi +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(rfc2268, $enabled_ciphers) +@@ -3230,12 +3231,13 @@ if test "$found" = "1" ; then + # Build with the assembly implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-amd64.lo" + ;; ++ arm*-*-*) ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-armv7-neon.lo" ++ fi ++ ;; + esac +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(gost28147, $enabled_ciphers) +@@ -3256,6 +3258,12 @@ if test "$found" = "1" ; then + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-amd64-avx2.lo" + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-amd64-avx512.lo" + ;; ++ arm*-*-*) ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-armv7-neon.lo" ++ fi ++ ;; + aarch64-*-*) + # Build with the assembly implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-aarch64.lo" +@@ -3282,11 +3290,6 @@ if test "$found" = "1" ; then + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-s390x.lo" + ;; + esac +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(sm4, $enabled_ciphers) +@@ -3491,6 +3494,11 @@ if test "$found" = "1" ; then + arm*-*-*) + # Build with the assembly implementation + GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-arm.lo" ++ ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-armv7-neon.lo" ++ fi + ;; + aarch64-*-*) + # Build with the assembly implementation +@@ -3510,11 +3518,6 @@ if test "$found" = "1" ; then + # Build with the crypto extension implementation + GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-ppc.lo" + esac +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(sha3, $enabled_digests) +@@ -3527,12 +3530,13 @@ if test "$found" = "1" ; then + # Build with the assembly implementation + GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-amd64-avx512.lo" + ;; ++ arm*-*-*) ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-armv7-neon.lo" ++ fi ++ ;; + esac +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(tiger, $enabled_digests) +-- +2.43.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index 74d3528..e4ab400 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -26,6 +26,7 @@ Patch1: libgcrypt-1.10.1-annobin.patch Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch # https://dev.gnupg.org/T7220 Patch3: libgcrypt-1.11.0-cf-protection.patch +Patch4: libgcrypt-1.11.0-pac-bti-protection.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -62,6 +63,7 @@ applications using libgcrypt. %patch 1 -p1 %patch 2 -p1 %patch 3 -p1 +%patch 4 -p1 %build # should be all algorithms except SM3 and SM4, aria From 65c9f9c6a764fd46f2f1f12aa94b6c100358c89c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Aug 2024 09:04:41 +0200 Subject: [PATCH 207/214] Run annocheck as part of build to catch issues early --- libgcrypt.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index e4ab400..2c08d1c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -41,6 +41,7 @@ BuildRequires: texinfo BuildRequires: autoconf, automake, libtool BuildRequires: make BuildRequires: gnupg2 +BuildRequires: annobin-annocheck binutils %package devel Summary: Development files for the %{name} package @@ -93,6 +94,8 @@ make check # try in faked FIPS mode too LIBGCRYPT_FORCE_FIPS_MODE=1 make check +PROFILE=%{?dist} annocheck --ignore-unknown --verbose --profile=${PROFILE:1} $RPM_BUILD_ROOT%{gcrylibdir}/libgcrypt.so.20.5.0 + # Add generation of HMAC checksums of the final stripped binaries %define libpath $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname}.?.? %define __spec_install_post \ From 9c274d3bde2a67a4defaad5504803fb30ca8c8e4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Oct 2024 17:39:29 +0100 Subject: [PATCH 208/214] Fix CVE-2024-2236 --- libgcrypt-1.11.0-marvin.patch | 2123 +++++++++++++++++++++++++++++++++ libgcrypt.spec | 4 + 2 files changed, 2127 insertions(+) create mode 100644 libgcrypt-1.11.0-marvin.patch diff --git a/libgcrypt-1.11.0-marvin.patch b/libgcrypt-1.11.0-marvin.patch new file mode 100644 index 0000000..d2998f0 --- /dev/null +++ b/libgcrypt-1.11.0-marvin.patch @@ -0,0 +1,2123 @@ +From 984e245fd21ff6e0058403f620f760013a744a3a Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 7 Jun 2024 14:42:33 +0200 +Subject: [PATCH 1/7] rsa: Do not accept invalid PKCS#1.5 padding when + deciphering + +The current code can accept 0-length padding when deciphering +PKCS#1.5 ciphertext. This is against the specification and hopefully +nobody depends on this. + +-- +* cipher/rsa-common.c (_gcry_rsa_pkcs1_decode_for_enc): Fail for too + short padding. +* src/const-time.h (ct_lt_s): New. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa-common.c | 2 ++ + src/const-time.h | 6 ++++++ + 2 files changed, 8 insertions(+) + +diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c +index 1920eedd..e45cb30d 100644 +--- a/cipher/rsa-common.c ++++ b/cipher/rsa-common.c +@@ -247,6 +247,8 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + + failed |= not_found; + n0 += ct_is_zero (not_found); /* Skip the zero byte. */ ++ /* the valid padding is at least 8 bytes -- the plaintext needs to start at index 11 or later */ ++ failed |= ct_lt_s (n0, 11); + + /* To avoid an extra allocation we reuse the frame buffer. The only + caller of this function will anyway free the result soon. */ +diff --git a/src/const-time.h b/src/const-time.h +index 46eb187d..245967eb 100644 +--- a/src/const-time.h ++++ b/src/const-time.h +@@ -34,6 +34,12 @@ extern volatile unsigned int _gcry_ct_vone; + #endif + + ++static inline size_t ++ct_lt_s (size_t a, size_t b) ++{ ++ return ((a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(size_t) * 8 - 1)); ++} ++ + /* + * Return 0 if A is 0 and return 1 otherwise. + */ +-- +2.46.0 + + +From aca5bd25e819b2596754fdc6ecb1844462a5b4f0 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Wed, 10 Apr 2024 15:18:39 +0200 +Subject: [PATCH 2/7] rsa: Constant time blinding removal + +* cipher/rsa.c (secret_blinded): Use constant time mulm implementation +* configure.ac: New configure option --enable-marvin-workaround +* mpi/Makefile.am: Build constant time multiplication +* mpi/mpi-internal.h: Add constant time function prototypes +* mpi/mpi-mul-cs.c: New file with constant time multiplication and + modulo. +* mpi/mpi-mul.c (_gcry_mpi_mul_sec): New function. + (_gcry_mpi_mod_sec): New function. + (_gcry_mpi_mod_sec): New function. + (_gcry_mpi_reverse_sec): New function. + (_gcry_mpi_mulm_sec): New function. +* src/gcrypt-int.h: Add new functions. + +-- + +The current MPI code is not constant time, potentially leaking plaintext +when the attacker can observe enough decipher operations using RSA +PKCS#1.5. This is described as a Marvin Attack: + +https://eprint.iacr.org/2023/1442 + +Note, that this code is tested to be constant time only with the -O3 +optimization level. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa.c | 4 + + configure.ac | 16 +++ + mpi/Makefile.am | 4 + + mpi/mpi-internal.h | 6 ++ + mpi/mpi-mul-cs.c | 263 +++++++++++++++++++++++++++++++++++++++++++++ + mpi/mpi-mul.c | 169 +++++++++++++++++++++++++++++ + src/gcrypt-int.h | 6 ++ + 7 files changed, 468 insertions(+) + create mode 100644 mpi/mpi-mul-cs.c + +diff --git a/cipher/rsa.c b/cipher/rsa.c +index c7a809f4..2f735f9c 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -1197,7 +1197,11 @@ secret_blinded (gcry_mpi_t output, gcry_mpi_t input, + /* Undo blinding. Here we calculate: y = (x * r^-1) mod n, where x + * is the blinded decrypted data, ri is the modular multiplicative + * inverse of r and n is the RSA modulus. */ ++#ifdef WITH_MARVIN_WORKAROUND ++ mpi_mulm_sec (output, output, ri, sk->n); ++#else + mpi_mulm (output, output, ri, sk->n); ++#endif /* WITH_MARVIN_WORKAROUND */ + + _gcry_mpi_release (r); + _gcry_mpi_release (ri); +diff --git a/configure.ac b/configure.ac +index 4c45de22..3f63b88e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -603,6 +603,22 @@ AC_ARG_ENABLE(jent-support, + jentsupport=$enableval,jentsupport=yes) + AC_MSG_RESULT($jentsupport) + ++AC_MSG_CHECKING([whether a Marvin workaround is requested]) ++AC_ARG_ENABLE(marvin-workaround, ++ AS_HELP_STRING([--enable-marvin-workaround], ++ [Enable Marvin workaround for constant time PKCS1.5 depadding]), ++ [with_marvin_workaround="$enableval"], ++ [with_marvin_workaround=no]) ++AC_MSG_RESULT($with_marvin_workaround) ++if test "$with_marvin_workaround" = no ; then ++ WITH_MARVIN_WORKAROUND='' ++else ++ AC_DEFINE(WITH_MARVIN_WORKAROUND,1, ++ [Define to provide constant time PKCS1.5 depadding]) ++fi ++AM_CONDITIONAL(WITH_MARVIN_WORKAROUND, test "x$with_marvin_workaround" != xno) ++AC_SUBST(WITH_MARVIN_WORKAROUND) ++ + # Implementation of the --disable-padlock-support switch. + AC_MSG_CHECKING([whether padlock support is requested]) + AC_ARG_ENABLE(padlock-support, +diff --git a/mpi/Makefile.am b/mpi/Makefile.am +index 6fe63fce..85679e08 100644 +--- a/mpi/Makefile.am ++++ b/mpi/Makefile.am +@@ -181,3 +181,7 @@ EXTRA_libmpi_la_SOURCES = \ + asm-common-aarch64.h \ + asm-common-amd64.h \ + asm-common-i386.h ++ ++if WITH_MARVIN_WORKAROUND ++libmpi_la_SOURCES += mpi-mul-cs.c ++endif +diff --git a/mpi/mpi-internal.h b/mpi/mpi-internal.h +index 935bf3e1..39de5161 100644 +--- a/mpi/mpi-internal.h ++++ b/mpi/mpi-internal.h +@@ -239,6 +239,12 @@ void _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp, + mpi_ptr_t vp, mpi_size_t vsize, + struct karatsuba_ctx *ctx ); + ++#ifdef WITH_MARVIN_WORKAROUND ++/*-- mpih-mul-cs.c --*/ ++void mul_cs(mpi_limb_t *ret, mpi_limb_t *a, mpi_limb_t *b, size_t n, mpi_limb_t *tmp); ++void mod_cs(mpi_limb_t *ret, mpi_limb_t *a, size_t anum, mpi_limb_t *mod, size_t modnum, mpi_limb_t *tmp); ++size_t mod_limb_numb(size_t anum, size_t modnum); ++#endif /* WITH_MARVIN_WORKAROUND */ + + /*-- mpih-mul_1.c (or xxx/cpu/ *.S) --*/ + mpi_limb_t _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, +diff --git a/mpi/mpi-mul-cs.c b/mpi/mpi-mul-cs.c +new file mode 100644 +index 00000000..3f77ac94 +--- /dev/null ++++ b/mpi/mpi-mul-cs.c +@@ -0,0 +1,263 @@ ++/* Copyright (c) 2024, Hubert Kario, Red Hat ++ * Released under BSD 2-Clause License, see LICENSE for details ++ */ ++#include ++#include ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++/* For multiplication we're using schoolbook multiplication, ++ * so if we have two numbers, each with 6 "digits" (words) ++ * the multiplication is calculated as follows: ++ * A B C D E F ++ * x I J K L M N ++ * -------------- ++ * N*F ++ * N*E ++ * N*D ++ * N*C ++ * N*B ++ * N*A ++ * M*F ++ * M*E ++ * M*D ++ * M*C ++ * M*B ++ * M*A ++ * L*F ++ * L*E ++ * L*D ++ * L*C ++ * L*B ++ * L*A ++ * K*F ++ * K*E ++ * K*D ++ * K*C ++ * K*B ++ * K*A ++ * J*F ++ * J*E ++ * J*D ++ * J*C ++ * J*B ++ * J*A ++ * I*F ++ * I*E ++ * I*D ++ * I*C ++ * I*B ++ * + I*A ++ * ========================== ++ * N*B N*D N*F ++ * + N*A N*C N*E ++ * + M*B M*D M*F ++ * + M*A M*C M*E ++ * + L*B L*D L*F ++ * + L*A L*C L*E ++ * + K*B K*D K*F ++ * + K*A K*C K*E ++ * + J*B J*D J*F ++ * + J*A J*C J*E ++ * + I*B I*D I*F ++ * + I*A I*C I*E ++ * ++ * 1+1 1+3 1+5 ++ * 1+0 1+2 1+4 ++ * 0+1 0+3 0+5 ++ * 0+0 0+2 0+4 ++ * ++ * 0 1 2 3 4 5 6 ++ * which requires n^2 multiplications and 2n full length additions ++ * as we can keep every other result of limb multiplication in two separate ++ * limbs ++ */ ++ ++typedef mpi_limb_t limb_t; ++#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG ++#define LIMB_BIT_SIZE 64 ++#define LIMB_BYTE_SIZE 8 ++#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG ++#define LIMB_BIT_SIZE 32 ++#define LIMB_BYTE_SIZE 4 ++/* if we're on a 32 bit platform */ ++#else ++#define LIMB_BIT_SIZE 16 ++#define LIMB_BYTE_SIZE 2 ++/* ++ * if the compiler doesn't have either a 128bit data type nor a "return ++ * high 64 bits of multiplication" ++ */ ++#endif ++ ++/* add two limbs with carry in, return carry out */ ++static limb_t ++_add_limb (limb_t *ret, limb_t a, limb_t b, limb_t carry) ++{ ++ limb_t carry1, carry2, t; ++ add_ssaaaa (carry1, t, 0, a, 0, carry); ++ add_ssaaaa (carry2, t, 0, b, 0, t); ++ *ret = t; ++ return carry1 + carry2; ++} ++ ++/* add two numbers of the same size, return overflow ++ * ++ * add a to b, place result in ret; all arrays need to be n limbs long ++ * return overflow from addition (0 or 1) ++ */ ++static limb_t ++add (limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ limb_t c = 0; ++ for (ssize_t i = n - 1; i > -1; i--) ++ { ++ c = _add_limb (&ret[i], a[i], b[i], c); ++ } ++ return c; ++} ++ ++/* multiply two numbers of the same size ++ * ++ * multiply a by b, place result in ret; a and b need to be n limbs long ++ * ret needs to be 2*n limbs long, tmp needs to be 2 * n 2 limbs ++ * long ++ */ ++void ++mul_cs (limb_t *ret, limb_t *a, limb_t *b, size_t n, limb_t *tmp) ++{ ++ limb_t *r_odd, *r_even; ++ r_odd = tmp; ++ r_even = &tmp[2 * n]; ++ ++ for (size_t i = 0; i < 2 * n; i++) ++ { ++ ret[i] = 0; ++ } ++ ++ for (size_t i=0; i> 1); ++ shift_in = shift_out; ++ } ++} ++ ++/* copy from either a or b to ret based on flag ++ * when flag == 0, then copies from b ++ * when flag == 1, then copies from a ++ */ ++static void ++cselect (limb_t flag, limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ /* would be more efficient with non volatile mask, but then gcc ++ * generates code with jumps */ ++ limb_t mask1 = ct_limb_gen_mask (flag); ++ limb_t mask2 = ct_limb_gen_inv_mask (flag); ++ for (size_t i = 0; i < n; i++) ++ { ++ ret[i] = (mask1 & a[i]) | (mask2 & b[i]); ++ } ++} ++ ++static limb_t ++_sub_limb (limb_t *ret, limb_t a, limb_t b, limb_t borrow) ++{ ++ limb_t borrow1, borrow2, t; ++ sub_ddmmss (borrow1, t, 0, a, 0, borrow); ++ sub_ddmmss (borrow2, t, 0, t, 0, b); ++ *ret = t; ++ return -(borrow1 + borrow2); ++} ++ ++/* place the result of a - b into ret, return the borrow bit. ++ * All arrays need to be n limbs long ++ */ ++static limb_t ++sub (limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ limb_t borrow = 0; ++ for (ssize_t i=n-1; i>-1; i--) ++ { ++ borrow = _sub_limb (&ret[i], a[i], b[i], borrow); ++ } ++ return borrow; ++} ++ ++/* return the number of limbs necessary to allocate for the mod() tmp operand */ ++size_t ++mod_limb_numb (size_t anum, size_t modnum) ++{ ++ return (anum + modnum) * 3; ++} ++ ++/* calculate a % mod, place the result in ret ++ * size of a is defined by anum, size of ret and mod is modnum, ++ * size of tmp is returned by mod_limb_numb() ++ */ ++void ++mod_cs (limb_t *ret, limb_t *a, size_t anum, limb_t *mod, size_t modnum, limb_t *tmp) ++{ ++ limb_t *atmp, *modtmp, *rettmp; ++ limb_t res; ++ ++ memset (tmp, 0, mod_limb_numb(anum, modnum) * LIMB_BYTE_SIZE); ++ ++ atmp = tmp; ++ modtmp = &tmp[anum+modnum]; ++ rettmp = &tmp[(anum+modnum)*2]; ++ ++ for (size_t i=modnum; inlimbs < v->nlimbs) ++ { /* Swap U and V. */ ++ usize = v->nlimbs; ++ usign = v->sign; ++ usecure = mpi_is_secure (v); ++ up = v->d; ++ vsize = u->nlimbs; ++ vsign = u->sign; ++ vsecure = mpi_is_secure (u); ++ vp = u->d; ++ } ++ else ++ { ++ usize = u->nlimbs; ++ usign = u->sign; ++ usecure = mpi_is_secure (u); ++ up = u->d; ++ vsize = v->nlimbs; ++ vsign = v->sign; ++ vsecure = mpi_is_secure (v); ++ vp = v->d; ++ } ++ sign_product = usign ^ vsign; ++ wp = w->d; ++ ++ /* make sure u and v have the same length by extending the limbs to the larger one, now u */ ++ if (usize != vsize) ++ { ++ mpi_limb_t *tmp_vp = mpi_alloc_limb_space (usize, vsecure); ++ clean_vp = 1; ++ MPN_ZERO (tmp_vp, (usize - vsize)); ++ MPN_COPY (tmp_vp + (usize - vsize), vp, vsize); ++ vsize = usize; ++ vp = tmp_vp; ++ } ++ ++ /* w == u */ ++ /* Ensure W has space enough to store the result. */ ++ wsize = usize + vsize; ++ if (!mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v))) ++ { ++ /* w is not allocated in secure space but u or v is. To make sure ++ * that no temporary results are stored in w, we temporary use ++ * a newly allocated limb space for w */ ++ wp = mpi_alloc_limb_space( wsize, 1 ); ++ assign_wp = 2; /* mark it as 2 so that we can later copy it back to ++ * normal memory */ ++ } ++ else if (w->alloced < wsize ) ++ { ++ if (wp == up || wp == vp) ++ { ++ wp = mpi_alloc_limb_space (wsize, mpi_is_secure (w)); ++ assign_wp = 1; ++ } ++ else ++ { ++ mpi_resize(w, wsize ); ++ wp = w->d; ++ } ++ } ++ else ++ { /* Make U and V not overlap with W. */ ++ if (wp == up) ++ { ++ /* W and U are identical. Allocate temporary space for U. */ ++ tmp_limb_nlimbs = usize; ++ up = tmp_limb = mpi_alloc_limb_space (usize, usecure); ++ /* Is V identical too? Keep it identical with U. */ ++ if (wp == vp) ++ vp = up; ++ /* Copy to the temporary space. */ ++ MPN_COPY (up, wp, usize); ++ } ++ else if (wp == vp) ++ { ++ /* W and V are identical. Allocate temporary space for V. */ ++ tmp_limb_nlimbs = vsize; ++ vp = tmp_limb = mpi_alloc_limb_space (vsize, vsecure); ++ /* Copy to the temporary space. */ ++ MPN_COPY (vp, wp, vsize); ++ } ++ } ++ ++ if (!vsize) ++ wsize = 0; ++ else ++ { ++ mpi_limb_t *tmp = mpi_alloc_limb_space (wsize * 2, mpi_is_secure (w)); ++ mul_cs (wp, up, vp, vsize, tmp); ++ _gcry_mpi_free_limb_space (tmp, wsize * 2); ++ } ++ ++ if (clean_vp) ++ { ++ _gcry_mpi_free_limb_space (vp, vsize); ++ } ++ if (assign_wp) ++ { ++ if (assign_wp == 2) ++ { ++ /* copy the temp wp from secure memory back to normal memory */ ++ mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0); ++ MPN_COPY (tmp_wp, wp, wsize); ++ _gcry_mpi_free_limb_space (wp, 0); ++ wp = tmp_wp; ++ } ++ _gcry_mpi_assign_limb_space (w, wp, wsize); ++ } ++ w->nlimbs = wsize; ++ w->sign = sign_product; ++ if (tmp_limb) ++ _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs); ++} ++#endif /* WITH_MARVIN_WORKAROUND */ + + void + _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) +@@ -221,3 +348,45 @@ _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) + if (temp_m) + mpi_free(temp_m); + } ++ ++#ifdef WITH_MARVIN_WORKAROUND ++static void ++_gcry_mpi_mod_sec (gcry_mpi_t ret, gcry_mpi_t a, gcry_mpi_t mod) ++{ ++ size_t asize = a->nlimbs; ++ size_t modsize = mod->nlimbs; ++ size_t tmp_size = mod_limb_numb (asize, modsize); ++ mpi_limb_t *tmp_limb = mpi_alloc_limb_space (tmp_size, mpi_is_secure(a)); ++ mod_cs (ret->d, a->d, asize, mod->d, modsize, tmp_limb); ++ /* cut the length to the mod size */ ++ ret->nlimbs = mod->nlimbs; ++ _gcry_mpi_free_limb_space (tmp_limb, tmp_size); ++} ++ ++/* The constant time code uses different order of the limbs ... */ ++static void ++_gcry_mpi_reverse_sec (gcry_mpi_t w) ++{ ++ for (size_t i = 0; i < w->nlimbs/2; i++) ++ { ++ mpi_limb_t t = w->d[i]; ++ w->d[i] = w->d[w->nlimbs - i - 1]; ++ w->d[w->nlimbs - i - 1] = t; ++ } ++} ++ ++void ++_gcry_mpi_mulm_sec (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) ++{ ++ /* w == u */ ++ _gcry_mpi_reverse_sec (u); ++ _gcry_mpi_reverse_sec (v); ++ _gcry_mpi_reverse_sec (m); ++ _gcry_mpi_mul_sec (w, u, v); ++ _gcry_mpi_mod_sec (w, w, m); ++ ++ /* get them back to the order the rest of the code expects */ ++ _gcry_mpi_reverse_sec (w); /* -- this is the result */ ++ _gcry_mpi_reverse_sec (m); /* -- this might be still used by the calling function */ ++} ++#endif /* WITH_MARVIN_WORKAROUND */ +diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h +index 1b449281..7e9e9894 100644 +--- a/src/gcrypt-int.h ++++ b/src/gcrypt-int.h +@@ -453,6 +453,9 @@ void _gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); + void _gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); + void _gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); + void _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++#ifdef WITH_MARVIN_WORKAROUND ++void _gcry_mpi_mulm_sec (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++#endif /* WITH_MARVIN_WORKAROUND */ + void _gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt); + void _gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, + gcry_mpi_t dividend, gcry_mpi_t divisor, int round); +@@ -548,6 +551,9 @@ int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); + #define mpi_mul_2exp(w,u,v) _gcry_mpi_mul_2exp ((w),(u),(v)) + #define mpi_mul(w,u,v) _gcry_mpi_mul ((w),(u),(v)) + #define mpi_mulm(w,u,v,m) _gcry_mpi_mulm ((w),(u),(v),(m)) ++#ifdef WITH_MARVIN_WORKAROUND ++#define mpi_mulm_sec(w,u,v,m) _gcry_mpi_mulm_sec ((w),(u),(v),(m)) ++#endif /* WITH_MARVIN_WORKAROUND */ + #define mpi_powm(w,b,e,m) _gcry_mpi_powm ( (w), (b), (e), (m) ) + #define mpi_tdiv(q,r,a,m) _gcry_mpi_div ( (q), (r), (a), (m), 0) + #define mpi_fdiv(q,r,a,m) _gcry_mpi_div ( (q), (r), (a), (m), -1) +-- +2.46.0 + + +From 1b7b995c5f4cd48a3b98915826431efb41a927ce Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 26 Apr 2024 16:39:18 +0200 +Subject: [PATCH 3/7] Constant time conversion of the message to the SEXP + +* cipher/rsa.c (rsa_decrypt): Use constant time conversion to SEXP after + decryption. +* src/const-time.c (_gcry_ct_memcpy): Constant time memcpy. New. +* src/const-time.h (ct_lt): New. + (ct_char_gen{,_inv}_mask): New. +* src/sexp.c (do_vsexp_sscan): Introduce constant time version of %b +-- + +The current conversion of the message back to the SEXP buffer leaks the +length of the decrypted message. This introduces a constant-time variant +that should run for the same time for any input length. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa.c | 4 ++++ + src/const-time.c | 28 ++++++++++++++++++++++++++-- + src/const-time.h | 12 ++++++++++++ + src/sexp.c | 39 +++++++++++++++++++++++++++++++++------ + 4 files changed, 75 insertions(+), 8 deletions(-) + +diff --git a/cipher/rsa.c b/cipher/rsa.c +index 2f735f9c..52f2aa89 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -1519,7 +1519,11 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, nbits, plain); + mpi_free (plain); + plain = NULL; ++#ifdef WITH_MARVIN_WORKAROUND ++ rc_sexp = sexp_build (&result, NULL, "(value %c)", (int)unpadlen, unpad, (nbits + 7) / 8); ++#else + rc_sexp = sexp_build (&result, NULL, "(value %b)", (int)unpadlen, unpad); ++#endif /* WITH_MARVIN_WORKAROUND */ + *r_plain = sexp_null_cond (result, ct_is_not_zero (rc)); + dummy = sexp_null_cond (result, ct_is_zero (rc)); + sexp_release (dummy); +diff --git a/src/const-time.c b/src/const-time.c +index 0fb53a07..cecb1937 100644 +--- a/src/const-time.c ++++ b/src/const-time.c +@@ -77,8 +77,8 @@ _gcry_ct_memmov_cond (void *dst, const void *src, size_t len, + unsigned long op_enable) + { + /* Note: dual mask with AND/OR used for EM leakage mitigation */ +- unsigned char mask1 = ct_ulong_gen_mask(op_enable); +- unsigned char mask2 = ct_ulong_gen_inv_mask(op_enable); ++ volatile unsigned char mask1 = ct_ulong_gen_mask(op_enable); ++ volatile unsigned char mask2 = ct_ulong_gen_inv_mask(op_enable); + unsigned char *b_dst = dst; + const unsigned char *b_src = src; + size_t i; +@@ -86,3 +86,27 @@ _gcry_ct_memmov_cond (void *dst, const void *src, size_t len, + for (i = 0; i < len; i++) + b_dst[i] = (b_dst[i] & mask2) | (b_src[i] & mask1); + } ++ ++/* ++ * Copy LEN bytes from memory area SRC to memory area DST. The ++ * bytes are read up to the BUFFER_LEN size to keep the operation ++ * not dependent on the message length (both SRC and DST buffers ++ * need to have this size!). ++ */ ++void ++_gcry_ct_memcpy (void *dst, const void *src, size_t len, size_t buffer_len) ++{ ++ unsigned char mask_a, mask_b; ++ unsigned char *b_dst = dst; ++ const unsigned char *b_src = src; ++ unsigned int writing; ++ size_t i; ++ ++ for (i = 0; i < buffer_len; i++) ++ { ++ writing = ct_lt (i, len); ++ mask_b = ct_uchar_gen_inv_mask (writing); ++ mask_a = ct_uchar_gen_mask (writing); ++ b_dst[i] = (b_src[i] & mask_a) | (b_dst[i] & mask_b); ++ } ++} +diff --git a/src/const-time.h b/src/const-time.h +index 245967eb..74055a4b 100644 +--- a/src/const-time.h ++++ b/src/const-time.h +@@ -26,6 +26,7 @@ + #define ct_not_memequal _gcry_ct_not_memequal + #define ct_memequal _gcry_ct_memequal + #define ct_memmov_cond _gcry_ct_memmov_cond ++#define ct_memcpy _gcry_ct_memcpy + + + #ifndef HAVE_GCC_ASM_VOLATILE_MEMORY +@@ -33,6 +34,14 @@ extern volatile unsigned int _gcry_ct_vzero; + extern volatile unsigned int _gcry_ct_vone; + #endif + ++/* ++ * Return 1 if A < B and return 0 otherwise. ++ */ ++static inline int ++ct_lt (unsigned int a, unsigned int b) ++{ ++ return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(unsigned int)*8 - 1); ++} + + static inline size_t + ct_lt_s (size_t a, size_t b) +@@ -112,6 +121,7 @@ unsigned int _gcry_ct_memequal (const void *b1, const void *b2, size_t len); + #endif + DEFINE_CT_TYPE_GEN_MASK(uintptr, uintptr_t) + DEFINE_CT_TYPE_GEN_MASK(ulong, unsigned long) ++DEFINE_CT_TYPE_GEN_MASK(uchar, unsigned char) + + /* + * Return all bits set if A is 0 and return 1 otherwise. +@@ -137,6 +147,7 @@ DEFINE_CT_TYPE_GEN_MASK(int16, int16_t) + #endif + DEFINE_CT_TYPE_GEN_INV_MASK(uintptr, uintptr_t) + DEFINE_CT_TYPE_GEN_INV_MASK(ulong, unsigned long) ++DEFINE_CT_TYPE_GEN_INV_MASK(uchar, unsigned char) + + /* + * Return A when OP_ENABLED=1 +@@ -172,5 +183,6 @@ sexp_null_cond (gcry_sexp_t w, unsigned long op_enable) + */ + void _gcry_ct_memmov_cond (void *dst, const void *src, size_t len, + unsigned long op_enable); ++void _gcry_ct_memcpy (void *dst, const void *src, size_t len, size_t buffer_len); + + #endif /*GCRY_CONST_TIME_H*/ +diff --git a/src/sexp.c b/src/sexp.c +index c77d0212..8e6c847f 100644 +--- a/src/sexp.c ++++ b/src/sexp.c +@@ -31,6 +31,7 @@ + + #define GCRYPT_NO_MPI_MACROS 1 + #include "g10lib.h" ++#include "const-time.h" + + + /* Notes on the internal memory layout. +@@ -1079,6 +1080,10 @@ unquote_string (const char *string, size_t length, unsigned char *buf) + * %d - integer stored as string (no autoswitch to secure allocation) + * %b - memory buffer; this takes _two_ arguments: an integer with the + * length of the buffer and a pointer to the buffer. ++ * %c - memory buffer same as %b, but written in constant time; this ++ * takes _three_ arguments: an integer with the length of the buffer, ++ * a pointer to the buffer and the maximum length of the buffer ++ * to avoid potential side channel leaking the buffer length. + * %S - Copy an gcry_sexp_t here. The S-expression needs to be a + * regular one, starting with a parenthesis. + * (no autoswitch to secure allocation) +@@ -1204,7 +1209,7 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + { + switch (*p) + { +- case 'b': case 't': case 'v': case 'n': case 'f': ++ case 'b': case 'c': case 't': case 'v': case 'n': case 'f': + case 'r': case '"': case '\'': case '\\': + quoted_esc = 0; + break; +@@ -1538,14 +1543,27 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + memcpy (c.pos, astr, alen); + c.pos += alen; + } +- else if (*p == 'b') ++ else if (*p == 'b' || *p == 'c') + { + /* Insert a memory buffer. */ + const char *astr; +- int alen; ++ int alen, buflen = 0, reallen = 0; + + ARG_NEXT (alen, int); + ARG_NEXT (astr, const char *); ++ if (*p == 'c') ++ { ++ ARG_NEXT (buflen, int); ++ if (buflen < alen) ++ { ++ *erroff = p - buffer; ++ err = GPG_ERR_INV_ARG; ++ goto leave; ++ } ++ /* Do all the calculations with the buflen */ ++ reallen = alen; ++ alen = buflen; ++ } + + if (alen < 0) + { +@@ -1578,9 +1596,18 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + } + + *c.pos++ = ST_DATA; +- STORE_LEN (c.pos, alen); +- memcpy (c.pos, astr, alen); +- c.pos += alen; ++ if (*p == 'c') ++ { ++ STORE_LEN (c.pos, reallen); ++ ct_memcpy (c.pos, astr, reallen, buflen); ++ c.pos += reallen; ++ } ++ else ++ { ++ STORE_LEN (c.pos, alen); ++ memcpy (c.pos, astr, alen); ++ c.pos += alen; ++ } + } + else if (*p == 'd') + { +-- +2.46.0 + + +From 14008d6f9f3985461ea50a6760391086c9bbe72b Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Thu, 30 May 2024 17:50:36 +0200 +Subject: [PATCH 5/7] rsa: Implement constant-time conversion of MPI to string + +-- +* cipher/rsa-common.c (_gcry_rsa_pkcs1_decode_for_enc): Replace + _gcry_mpi_print() with constant time operation. + +The _gcry_mpi_print() does a lot of housekeeping on the provided MPI +including skipping all the leading zeroes. If the ciphertext decrypted +to many leading zeroes, the output from this function is much shorter +(could be even all zeroes), which would immediately fail. + +This implements the dummy conversion of the MPI with the knowledge that +the encrypted data will always have the fixed length, providing constant +time operation. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa-common.c | 35 ++++++++++++++++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c +index e45cb30d..a61d82e3 100644 +--- a/cipher/rsa-common.c ++++ b/cipher/rsa-common.c +@@ -28,6 +28,7 @@ + #include "cipher.h" + #include "pubkey-internal.h" + #include "const-time.h" ++#include "bufhelp.h" + + + /* Turn VALUE into an octet string and store it in an allocated buffer +@@ -199,7 +200,6 @@ gpg_err_code_t + _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + unsigned int nbits, gcry_mpi_t value) + { +- gcry_error_t err; + unsigned char *frame = NULL; + size_t nframe = (nbits+7) / 8; + size_t n, n0; +@@ -208,6 +208,36 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + + *r_result = NULL; + ++ { ++#ifdef WITH_MARVIN_WORKAROUND ++ /* Allocate more to fit the whole MPI and allow moving it later to the right place */ ++ size_t alloc_len = value->nlimbs * BYTES_PER_MPI_LIMB; ++ if ( !(frame = xtrymalloc_secure (alloc_len))) ++ return gpg_err_code_from_syserror (); ++ ++ /* shovel the MPI content to the buffer as it is */ ++ unsigned char *p = frame; ++ for (int i = value->nlimbs - 1; i >= 0; i--) ++ { ++ mpi_limb_t *alimb = &value->d[i]; ++#if BYTES_PER_MPI_LIMB == 4 ++ buf_put_be32 (p, *alimb); ++ p += 4; ++#elif BYTES_PER_MPI_LIMB == 8 ++ buf_put_be64 (p, *alimb); ++ p += 8; ++#else ++# error please implement for this limb size. ++#endif ++ } ++ /* Remove leading zeroes, but not all! Keep the buffer to the nframe length! ++ * -- valid PKCS#1.5 padding will never have different lengths, than modulus */ ++ memmov_independently (frame, frame + (alloc_len - nframe), nframe, alloc_len); ++ n = 0; ++ failed |= ct_not_equal_byte (frame[n++], 0x00); ++#else ++ gcry_error_t err; ++ + if ( !(frame = xtrymalloc_secure (nframe))) + return gpg_err_code_from_syserror (); + +@@ -235,6 +265,9 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + n = 0; + if (!frame[0]) + n++; ++#endif ++ } ++ + failed |= ct_not_equal_byte (frame[n++], 0x02); + + /* Find the terminating zero byte. */ +-- +2.46.0 + + +From 5c0b1707e48d21fa4d860b0bafdeaeb438885707 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 31 May 2024 15:03:29 +0200 +Subject: [PATCH 6/7] cipher: Use the constant time conversion also for OAEP + +-- +* cipher/rsa-common.c (mpi_to_string): New function + (_gcry_rsa_pkcs1_decode_for_enc): Use new function for MPI to string + conversion. + (_gcry_rsa_oaep_decode): Use the new function for MPI to string + conversion. +* cipher/rsa.c (rsa_decrypt): Use constant time conversion to S-exp for + OAEP padding. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa-common.c | 75 +++++++++++++++++++++++++++++++-------------- + cipher/rsa.c | 4 +++ + 2 files changed, 56 insertions(+), 23 deletions(-) + +diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c +index a61d82e3..82a9e083 100644 +--- a/cipher/rsa-common.c ++++ b/cipher/rsa-common.c +@@ -192,31 +192,26 @@ memmov_independently (void *dst, const void *src, size_t len, size_t buflen) + } + + +-/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding. +- NBITS is the size of the secret key. On success the result is +- stored as a newly allocated buffer at R_RESULT and its valid length at +- R_RESULTLEN. On error NULL is stored at R_RESULT. */ +-gpg_err_code_t +-_gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, +- unsigned int nbits, gcry_mpi_t value) ++static unsigned char * ++mpi_to_string(gcry_mpi_t value, size_t nframe) + { + unsigned char *frame = NULL; +- size_t nframe = (nbits+7) / 8; +- size_t n, n0; +- unsigned int failed = 0; +- unsigned int not_found = 1; ++ unsigned char *p; ++ size_t noff; ++ /* Allocate memory to fit the whole MPI limbs and allow moving it later to the right place */ ++ size_t alloc_len = value->nlimbs * BYTES_PER_MPI_LIMB; + +- *r_result = NULL; ++ /* for too short input, we need to allocate at least modulus length (which might still be valid in case of OAEP) */ ++ noff = (alloc_len < nframe) ? nframe - alloc_len : 0; ++ alloc_len = alloc_len + noff; + +- { +-#ifdef WITH_MARVIN_WORKAROUND +- /* Allocate more to fit the whole MPI and allow moving it later to the right place */ +- size_t alloc_len = value->nlimbs * BYTES_PER_MPI_LIMB; + if ( !(frame = xtrymalloc_secure (alloc_len))) +- return gpg_err_code_from_syserror (); ++ return NULL; + ++ if (noff) ++ memset (frame, 0, noff); ++ p = frame + noff; + /* shovel the MPI content to the buffer as it is */ +- unsigned char *p = frame; + for (int i = value->nlimbs - 1; i >= 0; i--) + { + mpi_limb_t *alimb = &value->d[i]; +@@ -230,9 +225,34 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + # error please implement for this limb size. + #endif + } +- /* Remove leading zeroes, but not all! Keep the buffer to the nframe length! +- * -- valid PKCS#1.5 padding will never have different lengths, than modulus */ ++ /* Move the MPI to the right place -- with the least significant bytes aligned to the modulus length ++ * -- this might keep some leading zeroes at the beginning of the buffer, but this might be valid for OAEP */ + memmov_independently (frame, frame + (alloc_len - nframe), nframe, alloc_len); ++ return frame; ++} ++ ++/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding. ++ NBITS is the size of the secret key. On success the result is ++ stored as a newly allocated buffer at R_RESULT and its valid length at ++ R_RESULTLEN. On error NULL is stored at R_RESULT. */ ++gpg_err_code_t ++_gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, ++ unsigned int nbits, gcry_mpi_t value) ++{ ++ unsigned char *frame = NULL; ++ size_t nframe = (nbits+7) / 8; ++ size_t n, n0; ++ unsigned int failed = 0; ++ unsigned int not_found = 1; ++ ++ *r_result = NULL; ++ ++ { ++#ifdef WITH_MARVIN_WORKAROUND ++ frame = mpi_to_string(value, nframe); ++ if (frame == NULL) ++ return gpg_err_code_from_syserror (); ++ + n = 0; + failed |= ct_not_equal_byte (frame[n++], 0x00); + #else +@@ -265,7 +285,7 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + n = 0; + if (!frame[0]) + n++; +-#endif ++#endif /* WITH_MARVIN_WORKAROUND */ + } + + failed |= ct_not_equal_byte (frame[n++], 0x02); +@@ -709,14 +729,23 @@ _gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen, + happen due to the leading zero in OAEP frames and due to the + following random octets (seed^mask) which may have leading zero + bytes. This all is needed to cope with our leading zeroes +- suppressing MPI implementation. The code implictly implements ++ suppressing MPI implementation. The code implicitly implements + Step 1b (bail out if NFRAME != N). */ ++#ifdef WITH_MARVIN_WORKAROUND ++ frame = mpi_to_string(value, nkey); ++ if (frame == NULL) ++ { ++ xfree (lhash); ++ return gpg_err_code_from_syserror (); ++ } ++#else + rc = octet_string_from_mpi (&frame, NULL, value, nkey); + if (rc) + { + xfree (lhash); + return GPG_ERR_ENCODING_PROBLEM; + } ++#endif /* WITH_MARVIN_WORKAROUND */ + nframe = nkey; + + /* Step 1c: Check that the key is long enough. */ +@@ -731,7 +760,7 @@ _gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen, + gcry_mpi_aprint above. */ + + /* Allocate space for SEED and DB. */ +- seed = xtrymalloc_secure (nframe - 1); ++ seed = xtrymalloc_secure (nframe); + if (!seed) + { + rc = gpg_err_code_from_syserror (); +diff --git a/cipher/rsa.c b/cipher/rsa.c +index 52f2aa89..c196724c 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -1537,7 +1537,11 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + plain, ctx.label, ctx.labellen); + mpi_free (plain); + plain = NULL; ++#ifdef WITH_MARVIN_WORKAROUND ++ rc_sexp = sexp_build (&result, NULL, "(value %c)", (int)unpadlen, unpad, (nbits + 7) / 8); ++#else + rc_sexp = sexp_build (&result, NULL, "(value %b)", (int)unpadlen, unpad); ++#endif /* WITH_MARVIN_WORKAROUND */ + *r_plain = sexp_null_cond (result, ct_is_not_zero (rc)); + dummy = sexp_null_cond (result, ct_is_zero (rc)); + sexp_release (dummy); +-- +2.46.0 + + +From 4dffeaeadf792931aee61e6f51f59cf911c0c1f5 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 29 Apr 2024 19:06:17 +0200 +Subject: [PATCH 7/7] Implement implicit rejection for PKCS#1.5 decipher + +-- +* cipher/pubkey-internal.h + (_gcry_rsa_pkcs1_decode_for_enc_implicit_rejection): New. +* pubkey-util.c (_gcry_pk_util_parse_flaglist): Parse the new flag + no-implicit-rejection. +* cipher/rsa-common.c (rsa_prf): New function. + (_gcry_rsa_pkcs1_decode_for_enc_implicit_rejection): New function. +* cipher/rsa.c (rsa_decrypt): Handle implicit rejection. +* src/cipher.h (pk_encoding): New flag. +* tests/pkcs1v2.c (extract_cmp_data): Allow quiet test. + (check_v15crypt): Add support for implicit rejection. +* tests/pkcs1v2-v15c.h: Add test vectors for implicit rejection. + +Signed-off-by: Jakub Jelen +--- + cipher/pubkey-internal.h | 8 ++ + cipher/pubkey-util.c | 9 ++ + cipher/rsa-common.c | 181 +++++++++++++++++++++++ + cipher/rsa.c | 81 +++++++++++ + src/cipher.h | 37 ++--- + src/const-time.c | 2 +- + src/const-time.h | 3 +- + tests/pkcs1v2-v15c.h | 304 +++++++++++++++++++++++++++++++++++++++ + tests/pkcs1v2.c | 124 +++++++++++----- + 9 files changed, 692 insertions(+), 57 deletions(-) + +diff --git a/cipher/pubkey-internal.h b/cipher/pubkey-internal.h +index acf45105..f66574fa 100644 +--- a/cipher/pubkey-internal.h ++++ b/cipher/pubkey-internal.h +@@ -55,6 +55,14 @@ _gcry_rsa_pkcs1_encode_for_enc (gcry_mpi_t *r_result, unsigned int nbits, + gpg_err_code_t + _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + unsigned int nbits, gcry_mpi_t value); ++#ifdef WITH_MARVIN_WORKAROUND ++gpg_err_code_t ++_gcry_rsa_pkcs1_decode_for_enc_implicit_rejection (unsigned char **r_result, ++ size_t *r_resultlen, ++ unsigned int nbits, ++ gcry_mpi_t value, ++ unsigned char *kdk); ++#endif /* WITH_MARVIN_WORKAROUND */ + gpg_err_code_t + _gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits, + const unsigned char *value, size_t valuelen); +diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c +index 68defea6..e760dd4c 100644 +--- a/cipher/pubkey-util.c ++++ b/cipher/pubkey-util.c +@@ -193,6 +193,15 @@ _gcry_pk_util_parse_flaglist (gcry_sexp_t list, + rc = GPG_ERR_INV_FLAG; + break; + ++#ifdef WITH_MARVIN_WORKAROUND ++ case 21: ++ if (!memcmp (s, "no-implicit-rejection", 21)) ++ flags |= PUBKEY_FLAG_NO_IMPLICIT_REJECTION; ++ else if (!igninvflag) ++ rc = GPG_ERR_INV_FLAG; ++ break; ++#endif /* WITH_MARVIN_WORKAROUND */ ++ + default: + if (!igninvflag) + rc = GPG_ERR_INV_FLAG; +diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c +index 82a9e083..e776a309 100644 +--- a/cipher/rsa-common.c ++++ b/cipher/rsa-common.c +@@ -318,6 +318,187 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + } + + ++#ifdef WITH_MARVIN_WORKAROUND ++#define SHA256_LEN 32 ++static gcry_err_code_t ++rsa_prf(unsigned char *out, size_t out_len, const char *label, size_t label_len, unsigned char *kdk, size_t nbits) ++{ ++ gcry_err_code_t rc = GPG_ERR_NO_ERROR; ++ size_t pos; ++ uint16_t iter = 0; ++ unsigned char be_iter[2]; ++ unsigned char be_bitlen[2]; ++ gcry_md_hd_t hd; ++ gcry_error_t err; ++ ++ be_bitlen[0] = (nbits >> 8) & 0xff; ++ be_bitlen[1] = nbits & 0xff; ++ ++ err = _gcry_md_open (&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); ++ if (err) ++ { ++ return GPG_ERR_INTERNAL; ++ } ++ err = _gcry_md_setkey (hd, kdk, SHA256_LEN); ++ if (err) ++ { ++ _gcry_md_close (hd); ++ return GPG_ERR_INTERNAL; ++ } ++ for (pos = 0; pos < out_len; pos += SHA256_LEN, iter++) ++ { ++ unsigned char *tmp; ++ ++ _gcry_md_reset(hd); ++ ++ be_iter[0] = (iter >> 8) & 0xff; ++ be_iter[1] = iter & 0xff; ++ _gcry_md_write (hd, be_iter, sizeof (be_iter)); ++ _gcry_md_write (hd, label, label_len); ++ _gcry_md_write (hd, be_bitlen, sizeof (be_bitlen)); ++ ++ tmp = _gcry_md_read(hd, 0); ++ if (pos + SHA256_LEN > out_len) ++ { ++ memcpy(out + pos, tmp, out_len - pos); ++ } ++ else ++ { ++ memcpy(out + pos, tmp, SHA256_LEN); ++ } ++ } ++ _gcry_md_close (hd); ++ return rc; ++} ++ ++ ++/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding. ++ NBITS is the size of the secret key. On success the result is ++ stored as a newly allocated buffer at R_RESULT and its valid length at ++ R_RESULTLEN. On error R_RESULT contains bogus value of random length. ++ For more information, see description of Implicit Rejection in Marvin paper ++ https://people.redhat.com/~hkario/marvin/marvin-attack-paper.pdf */ ++#define MAX_LEN_GEN_TRIES 128 ++gpg_err_code_t ++_gcry_rsa_pkcs1_decode_for_enc_implicit_rejection (unsigned char **r_result, ++ size_t *r_resultlen, ++ unsigned int nbits, ++ gcry_mpi_t value, ++ unsigned char *kdk) ++{ ++ unsigned char *frame = NULL; ++ size_t nframe = (nbits+7) / 8; ++ size_t n, n0; ++ unsigned int failed = 0; ++ unsigned int not_found = 1; ++ int i, j; ++ uint16_t len_mask; ++ uint16_t max_sep_offset; ++ unsigned char *synthetic = NULL; ++ unsigned long synthethic_length; ++ uint16_t len_candidate; ++ unsigned char candidate_lengths[MAX_LEN_GEN_TRIES * sizeof(len_candidate)]; ++ int synth_msg_index = 0, msg_index; ++ ++ *r_result = NULL; ++ ++ synthetic = xtrymalloc(nframe); ++ if (synthetic == NULL) ++ { ++ free (synthetic); ++ return gpg_err_code_from_syserror (); ++ } ++ ++ if (rsa_prf(synthetic, nframe, "message", 7, kdk, nframe * 8) < 0) ++ { ++ xfree (synthetic); ++ return GPG_ERR_INTERNAL; ++ } ++ ++ /* decide how long the random message should be */ ++ if (rsa_prf(candidate_lengths, sizeof(candidate_lengths), ++ "length", 6, kdk, MAX_LEN_GEN_TRIES * sizeof(len_candidate) * 8) < 0) ++ { ++ xfree (synthetic); ++ return GPG_ERR_INTERNAL; ++ } ++ ++ len_mask = max_sep_offset = nframe - 2 - 8; ++ len_mask |= len_mask >> 1; ++ len_mask |= len_mask >> 2; ++ len_mask |= len_mask >> 4; ++ len_mask |= len_mask >> 8; ++ ++ synthethic_length = 0; ++ for (i = 0; i < MAX_LEN_GEN_TRIES * (int)sizeof(len_candidate); ++ i += sizeof(len_candidate)) ++ { ++ len_candidate = (candidate_lengths[i] << 8) | candidate_lengths[i + 1]; ++ len_candidate &= len_mask; ++ ++ synthethic_length = ct_ulong_select( ++ len_candidate, synthethic_length, ++ ct_lt(len_candidate, max_sep_offset)); ++ } ++ ++ synth_msg_index = nframe - synthethic_length; ++ ++ /* we have alternative message ready, check the real one */ ++ /* mostly copy from _gcry_rsa_pkcs1_decode_for_enc */ ++ frame = mpi_to_string(value, nframe); ++ if (frame == NULL) ++ { ++ xfree (synthetic); ++ return gpg_err_code_from_syserror (); ++ } ++ ++ /* FRAME = 0x00 || 0x02 || PS || 0x00 || M */ ++ n = 0; ++ failed |= ct_not_equal_byte (frame[n++], 0x00); ++ failed |= ct_not_equal_byte (frame[n++], 0x02); ++ ++ /* Find the terminating zero byte. */ ++ n0 = n; ++ for (; n < nframe; n++) ++ { ++ not_found &= ct_not_equal_byte (frame[n], 0x00); ++ n0 += not_found; ++ } ++ ++ failed |= not_found; ++ n0 += ct_is_zero (not_found); /* Skip the zero byte. */ ++ /* the valid padding is at least 8 bytes -- the plaintext needs to start at index 11 or later */ ++ failed |= ct_lt_s (n0, 11); ++ ++ msg_index = ct_ulong_select (synth_msg_index, n0, failed); ++ ++ /* To avoid the need memmove (O(N*log(N))), we use separate buffer where we move either ++ * of the messages. We can now also use the msg_index safely as its timing is not ++ * possible to distinguish valid and invalid padding */ ++ for (i = msg_index, j = 0; i < nframe && j < nframe; i++, j++) ++ { ++ frame[j] = ct_uchar_select (synthetic[i], frame[i], failed); ++ } ++ ++ *r_resultlen = j; ++ *r_result = frame; ++ ++ if (DBG_CIPHER) ++ { ++ if (!failed) ++ log_printhex ("value extracted from PKCS#1 block type 2 encoded data", ++ frame, nframe - n0); ++ else ++ log_printhex ("Synthetic value from implicit rejection", ++ synthetic, synthethic_length); ++ } ++ ++ xfree (synthetic); ++ return 0; ++} ++#endif /* WITH_MARVIN_WORKAROUND */ ++ ++ + /* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorithm ALGO + using the pkcs#1 block type 1 padding. On success the result is + stored as a new MPI at R_RESULT. On error the value at R_RESULT is +diff --git a/cipher/rsa.c b/cipher/rsa.c +index c196724c..9c1ef1f7 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -1436,6 +1436,7 @@ rsa_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) + } + + ++#define SHA256_LEN 32 + static gcry_err_code_t + rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + +@@ -1451,6 +1452,9 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + unsigned int nbits = rsa_get_nbits (keyparms); + gcry_sexp_t result = NULL; + gcry_sexp_t dummy = NULL; ++#ifdef WITH_MARVIN_WORKAROUND ++ unsigned char kdk[SHA256_LEN]; ++#endif /* WITH_MARVIN_WORKAROUND */ + + rc = rsa_check_keysize (nbits); + if (rc) +@@ -1498,6 +1502,71 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + mpi_normalize (data); + mpi_fdiv_r (data, data, sk.n); + ++#ifdef WITH_MARVIN_WORKAROUND ++ /* Implicit rejection: Derive KDK */ ++ if (ctx.encoding == PUBKEY_ENC_PKCS1) ++ { ++ unsigned char *buf, *tmp; ++ unsigned int nbytes = (mpi_get_nbits (sk.n)+7)/8; ++ unsigned char key[SHA256_LEN]; ++ gcry_md_hd_t hd; ++ ++ /* (a) Convert `d` to big endian representation, left padded to the length of `n` */ ++ rc = _gcry_mpi_to_octet_string (&buf, NULL, sk.d, nbytes); ++ if (rc) ++ { ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ ++ /* (b) Hash it using SHA-256 */ ++ rc = _gcry_md_open (&hd, GCRY_MD_SHA256, 0); ++ if (rc) ++ { ++ xfree (buf); ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ _gcry_md_write (hd, buf, nbytes); ++ /* keep the buffer around -- it will be needed for the ciphertext */ ++ tmp = _gcry_md_read (hd, GCRY_MD_SHA256); ++ memcpy(key, tmp, SHA256_LEN); ++ _gcry_md_close (hd); ++ ++ /* (c) Use the hash as a SHA-256 HMAC key and ciphertext as a message */ ++ rc = _gcry_md_open (&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); ++ if (rc) ++ { ++ xfree (buf); ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ rc = _gcry_md_setkey (hd, key, sizeof (key)); ++ if (rc) ++ { ++ xfree (buf); ++ _gcry_md_close (hd); ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ ++ /* We need to convert the ciphertext to string, padded to the length of modulus */ ++ rc = _gcry_mpi_to_octet_string (NULL, buf, data, nbytes); ++ if (rc) ++ { ++ xfree (buf); ++ _gcry_md_close (hd); ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ _gcry_md_write (hd, buf, nbytes); ++ xfree (buf); ++ buf = _gcry_md_read (hd, 0); ++ memcpy(kdk, buf, SHA256_LEN); ++ _gcry_md_close (hd); ++ } ++#endif /* WITH_MARVIN_WORKAROUND */ ++ + /* Allocate MPI for the plaintext. */ + plain = mpi_snew (nbits); + +@@ -1516,6 +1585,18 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + switch (ctx.encoding) + { + case PUBKEY_ENC_PKCS1: ++#ifdef WITH_MARVIN_WORKAROUND ++ if (!(ctx.flags & PUBKEY_FLAG_NO_IMPLICIT_REJECTION)) ++ { ++ rc = _gcry_rsa_pkcs1_decode_for_enc_implicit_rejection (&unpad, &unpadlen, nbits, plain, kdk); ++ mpi_free (plain); ++ plain = NULL; ++ rc_sexp = sexp_build (&result, NULL, "(value %c)", (int)unpadlen, unpad, (nbits + 7) / 8); ++ *r_plain = result; ++ rc = ct_ulong_select (rc_sexp, rc, ct_is_zero (rc) & ct_is_not_zero (rc_sexp)); ++ break; ++ } ++#endif /* WITH_MARVIN_WORKAROUND */ + rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, nbits, plain); + mpi_free (plain); + plain = NULL; +diff --git a/src/cipher.h b/src/cipher.h +index 0a2551fe..e522f39b 100644 +--- a/src/cipher.h ++++ b/src/cipher.h +@@ -26,24 +26,25 @@ + + #include "../random/random.h" + +-#define PUBKEY_FLAG_NO_BLINDING (1 << 0) +-#define PUBKEY_FLAG_RFC6979 (1 << 1) +-#define PUBKEY_FLAG_FIXEDLEN (1 << 2) +-#define PUBKEY_FLAG_LEGACYRESULT (1 << 3) +-#define PUBKEY_FLAG_RAW_FLAG (1 << 4) +-#define PUBKEY_FLAG_TRANSIENT_KEY (1 << 5) +-#define PUBKEY_FLAG_USE_X931 (1 << 6) +-#define PUBKEY_FLAG_USE_FIPS186 (1 << 7) +-#define PUBKEY_FLAG_USE_FIPS186_2 (1 << 8) +-#define PUBKEY_FLAG_PARAM (1 << 9) +-#define PUBKEY_FLAG_COMP (1 << 10) +-#define PUBKEY_FLAG_NOCOMP (1 << 11) +-#define PUBKEY_FLAG_EDDSA (1 << 12) +-#define PUBKEY_FLAG_GOST (1 << 13) +-#define PUBKEY_FLAG_NO_KEYTEST (1 << 14) +-#define PUBKEY_FLAG_DJB_TWEAK (1 << 15) +-#define PUBKEY_FLAG_SM2 (1 << 16) +-#define PUBKEY_FLAG_PREHASH (1 << 17) ++#define PUBKEY_FLAG_NO_BLINDING (1 << 0) ++#define PUBKEY_FLAG_RFC6979 (1 << 1) ++#define PUBKEY_FLAG_FIXEDLEN (1 << 2) ++#define PUBKEY_FLAG_LEGACYRESULT (1 << 3) ++#define PUBKEY_FLAG_RAW_FLAG (1 << 4) ++#define PUBKEY_FLAG_TRANSIENT_KEY (1 << 5) ++#define PUBKEY_FLAG_USE_X931 (1 << 6) ++#define PUBKEY_FLAG_USE_FIPS186 (1 << 7) ++#define PUBKEY_FLAG_USE_FIPS186_2 (1 << 8) ++#define PUBKEY_FLAG_PARAM (1 << 9) ++#define PUBKEY_FLAG_COMP (1 << 10) ++#define PUBKEY_FLAG_NOCOMP (1 << 11) ++#define PUBKEY_FLAG_EDDSA (1 << 12) ++#define PUBKEY_FLAG_GOST (1 << 13) ++#define PUBKEY_FLAG_NO_KEYTEST (1 << 14) ++#define PUBKEY_FLAG_DJB_TWEAK (1 << 15) ++#define PUBKEY_FLAG_SM2 (1 << 16) ++#define PUBKEY_FLAG_PREHASH (1 << 17) ++#define PUBKEY_FLAG_NO_IMPLICIT_REJECTION (1 << 18) + + + enum pk_operation +diff --git a/src/const-time.c b/src/const-time.c +index cecb1937..2b6a4b4e 100644 +--- a/src/const-time.c ++++ b/src/const-time.c +@@ -96,7 +96,7 @@ _gcry_ct_memmov_cond (void *dst, const void *src, size_t len, + void + _gcry_ct_memcpy (void *dst, const void *src, size_t len, size_t buffer_len) + { +- unsigned char mask_a, mask_b; ++ volatile unsigned char mask_a, mask_b; + unsigned char *b_dst = dst; + const unsigned char *b_src = src; + unsigned int writing; +diff --git a/src/const-time.h b/src/const-time.h +index 74055a4b..5e656e15 100644 +--- a/src/const-time.h ++++ b/src/const-time.h +@@ -40,7 +40,7 @@ extern volatile unsigned int _gcry_ct_vone; + static inline int + ct_lt (unsigned int a, unsigned int b) + { +- return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(unsigned int)*8 - 1); ++ return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(unsigned int) * 8 - 1); + } + + static inline size_t +@@ -164,6 +164,7 @@ DEFINE_CT_TYPE_GEN_INV_MASK(uchar, unsigned char) + } + DEFINE_CT_TYPE_SELECT_FUNC(uintptr, uintptr_t) + DEFINE_CT_TYPE_SELECT_FUNC(ulong, unsigned long) ++DEFINE_CT_TYPE_SELECT_FUNC(uchar, unsigned char) + + /* + * Return NULL when OP_ENABLED=1 +diff --git a/tests/pkcs1v2-v15c.h b/tests/pkcs1v2-v15c.h +index 26c7b238..cb750d4f 100644 +--- a/tests/pkcs1v2-v15c.h ++++ b/tests/pkcs1v2-v15c.h +@@ -21,6 +21,7 @@ + const char *mesg; + const char *seed; + const char *encr; ++ const char *synt; + } m[20]; + } tbl[] = + { +@@ -3915,5 +3916,308 @@ + "25db1dd892b71bb74a5cf68263d8fd58f1a48e6c2fcb8c0b71a251cfc1a20157" + } + } ++ }, ++ { ++ "A 2048-bit RSA Test vectors for the Bleichenbacher workaround", ++ "c8cc839714098da56caa23640f93dc8997c16372968fc1b0c6df5113c1c94e8b21e48ad2297e65419011b4e6d8f5e73b1b78b257400321d1ef6b602d4ec8ce8d141c94905eb4ad306639a49206534b6e7f2607423e97dffd133c88d721399defbc7e96ccdcbd7f3aae1fe892712bfb4929817d511666440a1facb7a208f5ea165910add8a3f2d497202360ccb632024f0d07169c1918f316f794b143aef54ec87522a4c02978f9689980bffbf649c307e81819bff88409638d48bd94be152b59ff649fa0bd629d0ffa1813c3abf4b56bd3c2ea5465dffa14589292a9d8a24ad26be7ee0510741b6382d43c83d5bfa40a46613d062be445517dbcaf0cb4e1a769", ++ "010001", ++ "1455010e0f2d587663a666a6ff1ccdbbf0edd8100646d02a023922908992c4ad39e5565929726ef6508c3a71158ef0b6ff751d39d07580bb2d2f063210442d0603ff50dbbd7b35fe2c9bb19a47a1af85a4c24901e02ca8b58b7919b20edf32aacfbf51adb4bc4b61b9b7e968caa4d570f70ef18d8063228893e47d439efca793259bcf2cd108a3d8688cdf078e7ac799969f2339d2c1f522b969684629a933baaec2681625eab84f4e56f4447e9d88fb9a199cf71023e0e257b14441b33c84d3bc67ca8031d2612618103a7a0a40844262f75d8890cd616e51f9035488fd6e099de8ff6d65a4ff118254807c9f58d2fbba8ba151dc8c68be349c977a204e04c1", ++ { ++ { ++ "1. a random positive test case", ++ NULL, ++ "", ++ "8bfe264e85d3bdeaa6b8851b8e3b956ee3d226fd3f69063a86880173a273d9f283b2eebdd1ed35f7e02d91c571981b6737d5320bd8396b0f3ad5b019daec1b0aab3cbbc026395f4fd14f13673f2dfc81f9b660ec26ac381e6db3299b4e460b43fab9955df2b3cfaa20e900e19c856238fd371899c2bf2ce8c868b76754e5db3b036533fd603746be13c10d4e3e6022ebc905d20c2a7f32b215a4cd53b3f44ca1c327d2c2b651145821c08396c89071f665349c25e44d2733cd9305985ceef6430c3cf57af5fa224089221218fa34737c79c446d28a94c41c96e4e92ac53fbcf384dea8419ea089f8784445a492c812eb0d409467f75afd7d4d1078886205a066", ++ "6c6f72656d20697073756d20646f6c6f722073697420616d6574" ++ },{ ++ "2. a random negative test case decrypting to empty", ++ NULL, ++ "", ++ "20aaa8adbbc593a924ba1c5c7990b5c2242ae4b99d0fe636a19a4cf754edbcee774e472fe028160ed42634f8864900cb514006da642cae6ae8c7d087caebcfa6dad1551301e130344989a1d462d4164505f6393933450c67bc6d39d8f5160907cabc251b737925a1cf21e5c6aa5781b7769f6a2a583d97cce008c0f8b6add5f0b2bd80bee60237aa39bb20719fe75749f4bc4e42466ef5a861ae3a92395c7d858d430bfe38040f445ea93fa2958b503539800ffa5ce5f8cf51fa8171a91f36cb4f4575e8de6b4d3f096ee140b938fd2f50ee13f0d050222e2a72b0a3069ff3a6738e82c87090caa5aed4fcbe882c49646aa250b98f12f83c8d528113614a29e7", ++ "" ++ },{ ++ "3. invalid decrypting to max length message", ++ NULL, ++ "", ++ "48cceab10f39a4db32f60074feea473cbcdb7accf92e150417f76b44756b190e843e79ec12aa85083a21f5437e7bad0a60482e601198f9d86923239c8786ee728285afd0937f7dde12717f28389843d7375912b07b991f4fdb0190fced8ba665314367e8c5f9d2981d0f5128feeb46cb50fc237e64438a86df198dd0209364ae3a842d77532b66b7ef263b83b1541ed671b120dfd660462e2107a4ee7b964e734a7bd68d90dda61770658a3c242948532da32648687e0318286473f675b412d6468f013f14d760a358dfcad3cda2afeec5e268a37d250c37f722f468a70dfd92d7294c3c1ee1e7f8843b7d16f9f37ef35748c3ae93aa155cdcdfeb4e78567303", ++ "22d850137b9eebe092b24f602dc5bb7918c16bd89ddbf20467b119d205f9c2e4bd7d2592cf1e532106e0f33557565923c73a02d4f09c0c22bea89148183e60317f7028b3aa1f261f91c979393101d7e15f4067e63979b32751658ef769610fe97cf9cef3278b3117d384051c3b1d82c251c2305418c8f6840530e631aad63e70e20e025bcd8efb54c92ec6d3b106a2f8e64eeff7d38495b0fc50c97138af4b1c0a67a1c4e27b077b8439332edfa8608dfeae653cd6a628ac550395f7e74390e42c11682234870925eeaa1fa71b76cf1f2ee3bda69f6717033ff8b7c95c9799e7a3bea5e7e4a1c359772fb6b1c6e6c516661dfe30c3" ++ },{ ++ "4. invalid decrypting to message with length specified by second to last value from PRF", ++ NULL, ++ "", ++ "1439e08c3f84c1a7fec74ce07614b20e01f6fa4e8c2a6cffdc3520d8889e5d9a950c6425798f85d4be38d300ea5695f13ecd4cb389d1ff5b82484b494d6280ab7fa78e645933981cb934cce8bfcd114cc0e6811eefa47aae20af638a1cd163d2d3366186d0a07df0c81f6c9f3171cf3561472e98a6006bf75ddb457bed036dcce199369de7d94ef2c68e8467ee0604eea2b3009479162a7891ba5c40cab17f49e1c438cb6eaea4f76ce23cce0e483ff0e96fa790ea15be67671814342d0a23f4a20262b6182e72f3a67cd289711503c85516a9ed225422f98b116f1ab080a80abd6f0216df88d8cfd67c139243be8dd78502a7aaf6bc99d7da71bcdf627e7354", ++ "0f9b" ++ },{ ++ "5. invalid decrypting to message with length specified by third to last value from PRF", ++ NULL, ++ "", ++ "1690ebcceece2ce024f382e467cf8510e74514120937978576caf684d4a02ad569e8d76cbe365a060e00779de2f0865ccf0d923de3b4783a4e2c74f422e2f326086c390b658ba47f31ab013aa80f468c71256e5fa5679b24e83cd82c3d1e05e398208155de2212993cd2b8bab6987cf4cc1293f19909219439d74127545e9ed8a706961b8ee2119f6bfacafbef91b75a789ba65b8b833bc6149cf49b5c4d2c6359f62808659ba6541e1cd24bf7f7410486b5103f6c0ea29334ea6f4975b17387474fe920710ea61568d7b7c0a7916acf21665ad5a31c4eabcde44f8fb6120d8457afa1f3c85d517cda364af620113ae5a3c52a048821731922737307f77a1081", ++ "4f02" ++ },{ ++ "6. positive test with 11 byte long value", ++ NULL, ++ "", ++ "6213634593332c485cef783ea2846e3d6e8b0e005cd8293eaebbaa5079712fd681579bdfbbda138ae4d9d952917a03c92398ec0cb2bb0c6b5a8d55061fed0d0d8d72473563152648cfe640b335dc95331c21cb133a91790fa93ae44497c128708970d2beeb77e8721b061b1c44034143734a77be8220877415a6dba073c3871605380542a9f25252a4babe8331cdd53cf828423f3cc70b560624d0581fb126b2ed4f4ed358f0eb8065cf176399ac1a846a31055f9ae8c9c24a1ba050bc20842125bc1753158f8065f3adb9cc16bfdf83816bdf38b624f12022c5a6fbfe29bc91542be8c0208a770bcd677dc597f5557dc2ce28a11bf3e3857f158717a33f6592", ++ "6c6f72656d20697073756d" ++ },{ ++ "7. positive test with 11 byte long value and zero padded ciphertext", ++ NULL, ++ "", ++ "00a2e8f114ea8d05d12dc843e3cc3b2edc8229ff2a028bda29ba9d55e3cd02911902fef1f42a075bf05e8016e8567213d6f260fa49e360779dd81aeea3e04c2cb567e0d72b98bf754014561b7511e083d20e0bfb9cd23f8a0d3c88900c49d2fcd5843ff0765607b2026f28202a87aa94678aed22a0c20724541394cd8f44e373eba1d2bae98f516c1e2ba3d86852d064f856b1daf24795e767a2b90396e50743e3150664afab131fe40ea405dcf572dd1079af1d3f0392ccadcca0a12740dbb213b925ca2a06b1bc1383e83a658c82ba2e7427342379084d5f66b544579f07664cb26edd4f10fd913fdbc0de05ef887d4d1ec1ac95652397ea7fd4e4759fda8b", ++ "6c6f72656d20697073756d" ++ },{ ++ "8. positive test with 11 byte long value and zero truncated ciphertext", ++ NULL, ++ "", ++ "a2e8f114ea8d05d12dc843e3cc3b2edc8229ff2a028bda29ba9d55e3cd02911902fef1f42a075bf05e8016e8567213d6f260fa49e360779dd81aeea3e04c2cb567e0d72b98bf754014561b7511e083d20e0bfb9cd23f8a0d3c88900c49d2fcd5843ff0765607b2026f28202a87aa94678aed22a0c20724541394cd8f44e373eba1d2bae98f516c1e2ba3d86852d064f856b1daf24795e767a2b90396e50743e3150664afab131fe40ea405dcf572dd1079af1d3f0392ccadcca0a12740dbb213b925ca2a06b1bc1383e83a658c82ba2e7427342379084d5f66b544579f07664cb26edd4f10fd913fdbc0de05ef887d4d1ec1ac95652397ea7fd4e4759fda8b", ++ "6c6f72656d20697073756d" ++ },{ ++ "9. positive test with 11 byte long value and double zero padded ciphertext", ++ NULL, ++ "", ++ "00001f71879b426127f7dead621f7380a7098cf7d22173aa27991b143c46d53383c209bd0c9c00d84078037e715f6b98c65005a77120070522ede51d472c87ef94b94ead4c5428ee108a345561658301911ec5a8f7dd43ed4a3957fd29fb02a3529bf63f8040d3953490939bd8f78b2a3404b6fb5ff70a4bfdaac5c541d6bcce49c9778cc390be24cbef1d1eca7e870457241d3ff72ca44f9f56bdf31a890fa5eb3a9107b603ccc9d06a5dd911a664c82b6abd4fe036f8db8d5a070c2d86386ae18d97adc1847640c211d91ff5c3387574a26f8ef27ca7f48d2dd1f0c7f14b81cc9d33ee6853031d3ecf10a914ffd90947909c8011fd30249219348ebff76bfc", ++ "6c6f72656d20697073756d" ++ },{ ++ "10. a random negative test that generates an 11 byte long message", ++ NULL, ++ "", ++ "5f02f4b1f46935c742ebe62b6f05aa0a3286aab91a49b34780adde6410ab46f7386e05748331864ac98e1da63686e4babe3a19ed40a7f5ceefb89179596aab07ab1015e03b8f825084dab028b6731288f2e511a4b314b6ea3997d2e8fe2825cef8897cbbdfb6c939d441d6e04948414bb69e682927ef8576c9a7090d4aad0e74c520d6d5ce63a154720f00b76de8cc550b1aa14f016d63a7b6d6eaa1f7dbe9e50200d3159b3d099c900116bf4eba3b94204f18b1317b07529751abf64a26b0a0bf1c8ce757333b3d673211b67cc0653f2fe2620d57c8b6ee574a0323a167eab1106d9bc7fd90d415be5f1e9891a0e6c709f4fc0404e8226f8477b4e939b36eb2", ++ "af9ac70191c92413cb9f2d" ++ },{ ++ "11. an otherwise correct plaintext, but with wrong first byte (0x01 instead of 0x00), generates a random 11 byte long plaintext", ++ NULL, ++ "", ++ "9b2ec9c0c917c98f1ad3d0119aec6be51ae3106e9af1914d48600ab6a2c0c0c8ae02a2dc3039906ff3aac904af32ec798fd65f3ad1afa2e69400e7c1de81f5728f3b3291f38263bc7a90a0563e43ce7a0d4ee9c0d8a716621ca5d3d081188769ce1b131af7d35b13dea99153579c86db31fe07d5a2c14d621b77854e48a8df41b5798563af489a291e417b6a334c63222627376118c02c53b6e86310f728734ffc86ef9d7c8bf56c0c841b24b82b59f51aee4526ba1c4268506d301e4ebc498c6aebb6fd5258c876bf900bac8ca4d309dd522f6a6343599a8bc3760f422c10c72d0ad527ce4af1874124ace3d99bb74db8d69d2528db22c3a37644640f95c05f", ++ "a1f8c9255c35cfba403ccc" ++ },{ ++ "12. an otherwise correct plaintext, but with wrong second byte (0x01 instead of 0x02), generates a random 11 byte long plaintext", ++ NULL, ++ "", ++ "782c2b59a21a511243820acedd567c136f6d3090c115232a82a5efb0b178285f55b5ec2d2bac96bf00d6592ea7cdc3341610c8fb07e527e5e2d20cfaf2c7f23e375431f45e998929a02f25fd95354c33838090bca838502259e92d86d568bc2cdb132fab2a399593ca60a015dc2bb1afcd64fef8a3834e17e5358d822980dc446e845b3ab4702b1ee41fe5db716d92348d5091c15d35a110555a35deb4650a5a1d2c98025d42d4544f8b32aa6a5e02dc02deaed9a7313b73b49b0d4772a3768b0ea0db5846ace6569cae677bf67fb0acf3c255dc01ec8400c963b6e49b1067728b4e563d7e1e1515664347b92ee64db7efb5452357a02fff7fcb7437abc2e579", ++ "e6d700309ca0ed62452254" ++ },{ ++ "13. an invalid ciphertext, with a zero byte in first byte of ciphertext, decrypts to a random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "0096136621faf36d5290b16bd26295de27f895d1faa51c800dafce73d001d60796cd4e2ac3fa2162131d859cd9da5a0c8a42281d9a63e5f353971b72e36b5722e4ac444d77f892a5443deb3dca49fa732fe855727196e23c26eeac55eeced8267a209ebc0f92f4656d64a6c13f7f7ce544ebeb0f668fe3a6c0f189e4bcd5ea12b73cf63e0c8350ee130dd62f01e5c97a1e13f52fde96a9a1bc9936ce734fdd61f27b18216f1d6de87f49cf4f2ea821fb8efd1f92cdad529baf7e31aff9bff4074f2cad2b4243dd15a711adcf7de900851fbd6bcb53dac399d7c880531d06f25f7002e1aaf1722765865d2c2b902c7736acd27bc6cbd3e38b560e2eecf7d4b576", ++ "ba27b1842e7c21c0e7ef6a" ++ },{ ++ "14. an invalid ciphertext, with a zero byte removed from first byte of ciphertext, decrypts to a random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "96136621faf36d5290b16bd26295de27f895d1faa51c800dafce73d001d60796cd4e2ac3fa2162131d859cd9da5a0c8a42281d9a63e5f353971b72e36b5722e4ac444d77f892a5443deb3dca49fa732fe855727196e23c26eeac55eeced8267a209ebc0f92f4656d64a6c13f7f7ce544ebeb0f668fe3a6c0f189e4bcd5ea12b73cf63e0c8350ee130dd62f01e5c97a1e13f52fde96a9a1bc9936ce734fdd61f27b18216f1d6de87f49cf4f2ea821fb8efd1f92cdad529baf7e31aff9bff4074f2cad2b4243dd15a711adcf7de900851fbd6bcb53dac399d7c880531d06f25f7002e1aaf1722765865d2c2b902c7736acd27bc6cbd3e38b560e2eecf7d4b576", ++ "ba27b1842e7c21c0e7ef6a" ++ },{ ++ "15. an invalid ciphertext, with two zero bytes in first bytes of ciphertext, decrypts to a random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "0000587cccc6b264bdfe0dc2149a988047fa921801f3502ea64624c510c6033d2f427e3f136c26e88ea9f6519e86a542cec96aad1e5e9013c3cc203b6de15a69183050813af5c9ad79703136d4b92f50ce171eefc6aa7988ecf02f319ffc5eafd6ee7a137f8fce64b255bb1b8dd19cfe767d64fdb468b9b2e9e7a0c24dae03239c8c714d3f40b7ee9c4e59ac15b17e4d328f1100756bce17133e8e7493b54e5006c3cbcdacd134130c5132a1edebdbd01a0c41452d16ed7a0788003c34730d0808e7e14c797a21f2b45a8aa1644357fd5e988f99b017d9df37563a354c788dc0e2f9466045622fa3f3e17db63414d27761f57392623a2bef6467501c63e8d645", ++ "d5cf555b1d6151029a429a" ++ },{ ++ "16. an invalid ciphertext, with two zero bytes removed from first bytes of ciphertext, decrypts to a random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "587cccc6b264bdfe0dc2149a988047fa921801f3502ea64624c510c6033d2f427e3f136c26e88ea9f6519e86a542cec96aad1e5e9013c3cc203b6de15a69183050813af5c9ad79703136d4b92f50ce171eefc6aa7988ecf02f319ffc5eafd6ee7a137f8fce64b255bb1b8dd19cfe767d64fdb468b9b2e9e7a0c24dae03239c8c714d3f40b7ee9c4e59ac15b17e4d328f1100756bce17133e8e7493b54e5006c3cbcdacd134130c5132a1edebdbd01a0c41452d16ed7a0788003c34730d0808e7e14c797a21f2b45a8aa1644357fd5e988f99b017d9df37563a354c788dc0e2f9466045622fa3f3e17db63414d27761f57392623a2bef6467501c63e8d645", ++ "d5cf555b1d6151029a429a" ++ },{ ++ "17. and invalid ciphertext, otherwise valid but starting with 000002, decrypts to random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "1786550ce8d8433052e01ecba8b76d3019f1355b212ac9d0f5191b023325a7e7714b7802f8e9a17c4cb3cd3a84041891471b10ca1fcfb5d041d34c82e6d0011cf4dc76b90e9c2e0743590579d55bcd7857057152c4a8040361343d1d22ba677d62b011407c652e234b1d663af25e2386251d7409190f19fc8ec3f9374fdf1254633874ce2ec2bff40ad0cb473f9761ec7b68da45a4bd5e33f5d7dac9b9a20821df9406b653f78a95a6c0ea0a4d57f867e4db22c17bf9a12c150f809a7b72b6db86c22a8732241ebf3c6a4f2cf82671d917aba8bc61052b40ccddd743a94ea9b538175106201971cca9d136d25081739aaf6cd18b2aecf9ad320ea3f89502f955", ++ "3d4a054d9358209e9cbbb9" ++ },{ ++ "18. negative test with otherwise valid padding but a zero byte in first byte of padding", ++ NULL, ++ "", ++ "179598823812d2c58a7eb50521150a48bcca8b4eb53414018b6bca19f4801456c5e36a940037ac516b0d6412ba44ec6b4f268a55ef1c5ffbf18a2f4e3522bb7b6ed89774b79bffa22f7d3102165565642de0d43a955e96a1f2e80e5430671d7266eb4f905dc8ff5e106dc5588e5b0289e49a4913940e392a97062616d2bda38155471b7d360cfb94681c702f60ed2d4de614ea72bf1c53160e63179f6c5b897b59492bee219108309f0b7b8cb2b136c346a5e98b8b4b8415fb1d713bae067911e3057f1c335b4b7e39101eafd5d28f0189037e4334f4fdb9038427b1d119a6702aa8233319cc97d496cc289ae8c956ddc84042659a2d43d6aa22f12b81ab884e", ++ "1f037dd717b07d3e7f7359" ++ },{ ++ "19. negative test with otherwise valid padding but a zero byte at the eigth byte of padding", ++ NULL, ++ "", ++ "a7a340675a82c30e22219a55bc07cdf36d47d01834c1834f917f18b517419ce9de2a96460e745024436470ed85e94297b283537d52189c406a3f533cb405cc6a9dba46b482ce98b6e3dd52d8fce2237425617e38c11fbc46b61897ef200d01e4f25f5f6c4c5b38cd0de38ba11908b86595a8036a08a42a3d05b79600a97ac18ba368a08d6cf6ccb624f6e8002afc75599fba4de3d4f3ba7d208391ebe8d21f8282b18e2c10869eb2702e68f9176b42b0ddc9d763f0c86ba0ff92c957aaeab76d9ab8da52ea297ec11d92d770146faa1b300e0f91ef969b53e7d2907ffc984e9a9c9d11fb7d6cba91972059b46506b035efec6575c46d7114a6b935864858445f", ++ "63cb0bf65fc8255dd29e17" ++ },{ ++ "20. negative test with an otherwise valid plaintext but with missing separator byte", ++ NULL, ++ "", ++ "3d1b97e7aa34eaf1f4fc171ceb11dcfffd9a46a5b6961205b10b302818c1fcc9f4ec78bf18ea0cee7e9fa5b16fb4c611463b368b3312ac11cf9c06b7cf72b54e284848a508d3f02328c62c2999d0fb60929f81783c7a256891bc2ff4d91df2af96a24fc5701a1823af939ce6dbdc510608e3d41eec172ad2d51b9fc61b4217c923cadcf5bac321355ef8be5e5f090cdc2bd0c697d9058247db3ad613fdce87d2955a6d1c948a5160f93da21f731d74137f5d1f53a1923adb513d2e6e1589d44cc079f4c6ddd471d38ac82d20d8b1d21f8d65f3b6907086809f4123e08d86fb38729585de026a485d8f0e703fd4772f6668febf67df947b82195fa3867e3a3065", ++ "6f09a0b62699337c497b0b" ++ } ++ } ++ }, ++ { ++ "A 2049-bit RSA Test vectors for the Bleichenbacher workaround", ++ "0155f889556a1775f1c7a7786a50b18bc28c9e986ede5667cab39b84124e90eba75c1db083ac3e443bba94dc23560f75e3a81693a2a43bdc7426d8c4eafe68c85de0fe757f6e49bb9ed447e602430800dbb04ceb22e7fa57a18d338fb66026cdb467e70cc040e7d367ef403c7bf1e3df624650094631f21eafd2fb5bc915ff04379acd1112f732c0b46607c178d38a20f52eda509f2f9c0405d51069e80ccf941554d0470467505c3cf541ea0897dfc9f400cecb298ffc753372d9f6933af174cc40ed96d467031733b97f8cddd3f92bc3a03ea8576c417f24007b5e4f7501105b544de9fadcdffadf98dfb4bb05b8199f3f85acfd91f7a9a094b9a383f5049097", ++ "010001", ++ "0119c2b3f50a7ad6152679d7ff510958ac2d8ca6f0028592f332d55a16736178a8e67f17e705ce300e3e87547251006013f974d0a3db49ef344ca5a26a34c0450704d0e422e0ce23a69425c15fefb6f26e106eeff64cc8b9d7442e4da4e8c85008eaeb365859a2294fa3937bc26be56332e7d81e2c160ef635cc528aa7be55e633a723dbc1e16ba29e52b29aef2f9e5654fdc0666bb0fc254acbe80e63874f0f5f020782e3c9dcfc2520d0c9c4a7b634e4503fbb493e1aafeeb3f88bd7a13398725dae6fe399e775cd5d4cf09fc838347c4c98dab1a4883cce620513615afaa10a63368e6d7b79df4166ab162739ef515a4402ee1e0601c5a55bc71df0e30edf81", ++ { ++ { ++ "1. malformed that generates length specified by 3rd last value from PRF", ++ NULL, ++ "", ++ "00b26f6404b82649629f2704494282443776929122e279a9cf30b0c6fe8122a0a9042870d97cc8ef65490fe58f031eb2442352191f5fbc311026b5147d32df914599f38b825ebb824af0d63f2d541a245c5775d1c4b78630e4996cc5fe413d38455a776cf4edcc0aa7fccb31c584d60502ed2b77398f536e137ff7ba6430e9258e21c2db5b82f5380f566876110ac4c759178900fbad7ab70ea07b1daf7a1639cbb4196543a6cbe8271f35dddb8120304f6eef83059e1c5c5678710f904a6d760c4d1d8ad076be17904b9e69910040b47914a0176fb7eea0c06444a6c4b86d674d19a556a1de5490373cb01ce31bbd15a5633362d3d2cd7d4af1b4c5121288b894", ++ "42" ++ },{ ++ "2. simple positive test case", ++ NULL, ++ "", ++ "013300edbf0bb3571e59889f7ed76970bf6d57e1c89bbb6d1c3991d9df8e65ed54b556d928da7d768facb395bbcc81e9f8573b45cf8195dbd85d83a59281cddf4163aec11b53b4140053e3bd109f787a7c3cec31d535af1f50e0598d85d96d91ea01913d07097d25af99c67464ebf2bb396fb28a9233e56f31f7e105d71a23e9ef3b736d1e80e713d1691713df97334779552fc94b40dd733c7251bc522b673d3ec9354af3dd4ad44fa71c0662213a57ada1d75149697d0eb55c053aaed5ffd0b815832f454179519d3736fb4faf808416071db0d0f801aca8548311ee708c131f4be658b15f6b54256872c2903ac708bd43b017b073b5707bc84c2cd9da70e967", ++ "6c6f72656d20697073756d" ++ },{ ++ "3. positive test case with null padded ciphertext", ++ NULL, ++ "", ++ "0002aadf846a329fadc6760980303dbd87bfadfa78c2015ce4d6c5782fd9d3f1078bd3c0a2c5bfbdd1c024552e5054d98b5bcdc94e476dd280e64d650089326542ce7c61d4f1ab40004c2e6a88a883613568556a10f3f9edeab67ae8dddc1e6b0831c2793d2715de943f7ce34c5c05d1b09f14431fde566d17e76c9feee90d86a2c158616ec81dda0c642f58c0ba8fa4495843124a7235d46fb4069715a51bf710fd024259131ba94da73597ace494856c94e7a3ec261545793b0990279b15fa91c7fd13dbfb1df2f221dab9fa9f7c1d21e48aa49f6aaecbabf5ee76dc6c2af2317ffb4e303115386a97f8729afc3d0c89419669235f1a3a69570e0836c79fc162", ++ "6c6f72656d20697073756d" ++ },{ ++ "4. positive test case with null truncated ciphertext", ++ NULL, ++ "", ++ "02aadf846a329fadc6760980303dbd87bfadfa78c2015ce4d6c5782fd9d3f1078bd3c0a2c5bfbdd1c024552e5054d98b5bcdc94e476dd280e64d650089326542ce7c61d4f1ab40004c2e6a88a883613568556a10f3f9edeab67ae8dddc1e6b0831c2793d2715de943f7ce34c5c05d1b09f14431fde566d17e76c9feee90d86a2c158616ec81dda0c642f58c0ba8fa4495843124a7235d46fb4069715a51bf710fd024259131ba94da73597ace494856c94e7a3ec261545793b0990279b15fa91c7fd13dbfb1df2f221dab9fa9f7c1d21e48aa49f6aaecbabf5ee76dc6c2af2317ffb4e303115386a97f8729afc3d0c89419669235f1a3a69570e0836c79fc162", ++ "6c6f72656d20697073756d" ++ },{ ++ "5. positive test case with double null padded ciphertext", ++ NULL, ++ "", ++ "0000f36da3b72d8ff6ded74e7efd08c01908f3f5f0de7b55eab92b5f875190809c39d4162e1e6649618f854fd84aeab03970d16bb814e999852c06de38d82b95c0f32e2a7b5714021fe303389be9c0eac24c90a6b7210f929d390fabf903d44e04110bb7a7fd6c383c275804721efa6d7c93aa64c0bb2b18d97c5220a846c66a4895ae52adddbe2a9996825e013585adcec4b32ba61d782737bd343e5fabd68e8a95b8b1340318559860792dd70dffbe05a1052b54cbfb48cfa7bb3c19cea52076bddac5c25ee276f153a610f6d06ed696d192d8ae4507ffae4e5bdda10a625d6b67f32f7cffcd48dee2431fe66f6105f9d17e611cdcc674868e81692a360f4052", ++ "6c6f72656d20697073756d" ++ },{ ++ "6. positive test case with double null truncated ciphertext", ++ NULL, ++ "", ++ "f36da3b72d8ff6ded74e7efd08c01908f3f5f0de7b55eab92b5f875190809c39d4162e1e6649618f854fd84aeab03970d16bb814e999852c06de38d82b95c0f32e2a7b5714021fe303389be9c0eac24c90a6b7210f929d390fabf903d44e04110bb7a7fd6c383c275804721efa6d7c93aa64c0bb2b18d97c5220a846c66a4895ae52adddbe2a9996825e013585adcec4b32ba61d782737bd343e5fabd68e8a95b8b1340318559860792dd70dffbe05a1052b54cbfb48cfa7bb3c19cea52076bddac5c25ee276f153a610f6d06ed696d192d8ae4507ffae4e5bdda10a625d6b67f32f7cffcd48dee2431fe66f6105f9d17e611cdcc674868e81692a360f4052", ++ "6c6f72656d20697073756d" ++ },{ ++ "7. a random negative test case that generates an 11 byte long message", ++ NULL, ++ "", ++ "00f910200830fc8fff478e99e145f1474b312e2512d0f90b8cef77f8001d09861688c156d1cbaf8a8957f7ebf35f724466952d0524cad48aad4fba1e45ce8ea27e8f3ba44131b7831b62d60c0762661f4c1d1a88cd06263a259abf1ba9e6b0b172069afb86a7e88387726f8ab3adb30bfd6b3f6be6d85d5dfd044e7ef052395474a9cbb1c3667a92780b43a22693015af6c513041bdaf87d43b24ddd244e791eeaea1066e1f4917117b3a468e22e0f7358852bb981248de4d720add2d15dccba6280355935b67c96f9dcb6c419cc38ab9f6fba2d649ef2066e0c34c9f788ae49babd9025fa85b21113e56ce4f43aa134c512b030dd7ac7ce82e76f0be9ce09ebca", ++ "1189b6f5498fd6df532b00" ++ },{ ++ "8. otherwise correct plaintext, but with wrong first byte (0x01 instead of 0x00)", ++ NULL, ++ "", ++ "002c9ddc36ba4cf0038692b2d3a1c61a4bb3786a97ce2e46a3ba74d03158aeef456ce0f4db04dda3fe062268a1711250a18c69778a6280d88e133a16254e1f0e30ce8dac9b57d2e39a2f7d7be3ee4e08aec2fdbe8dadad7fdbf442a29a8fb40857407bf6be35596b8eefb5c2b3f58b894452c2dc54a6123a1a38d642e23751746597e08d71ac92704adc17803b19e131b4d1927881f43b0200e6f95658f559f912c889b4cd51862784364896cd6e8618f485a992f82997ad6a0917e32ae5872eaf850092b2d6c782ad35f487b79682333c1750c685d7d32ab3e1538f31dcaa5e7d5d2825875242c83947308dcf63ba4bfff20334c9c140c837dbdbae7a8dee72ff", ++ "f6d0f5b78082fe61c04674" ++ },{ ++ "9. otherwise correct plaintext, but with wrong second byte (0x01 instead of 0x02)", ++ NULL, ++ "", ++ "00c5d77826c1ab7a34d6390f9d342d5dbe848942e2618287952ba0350d7de6726112e9cebc391a0fae1839e2bf168229e3e0d71d4161801509f1f28f6e1487ca52df05c466b6b0a6fbbe57a3268a970610ec0beac39ec0fa67babce1ef2a86bf77466dc127d7d0d2962c20e66593126f276863cd38dc6351428f884c1384f67cad0a0ffdbc2af16711fb68dc559b96b37b4f04cd133ffc7d79c43c42ca4948fa895b9daeb853150c8a5169849b730cc77d68b0217d6c0e3dbf38d751a1998186633418367e7576530566c23d6d4e0da9b038d0bb5169ce40133ea076472d055001f0135645940fd08ea44269af2604c8b1ba225053d6db9ab43577689401bdc0f3", ++ "1ab287fcef3ff17067914d" ++ },{ ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ } ++ } ++ }, ++ { ++ "RSA decrypt with 3072 bit keys", ++ "afd71caad5e9f5b8c6c367070a47f19d7e66aede18a5b2741fb3c4d33434560692a2d909ef6888ec602ff6b93af258ee74303c301afcd4edbec43311ddc8ddbf00ddbbe386d33b8d0e22b1b44936dc489871b85237b34ce747ad8fdb0c4e4d1daa7aadf07385c5c8732ccb7d5a49e2e50c883c7d7ac10ed6a74d9ac90df9129905a17d4a087210fc78b6d04b1eb969482c11a6eeb79c50e5b16f3f254f7571528b2f1716ab816d6eca0727bdea98059329730eb8c33ce71d61dd4ac393b6256e07ac1d124f0200d1c3e05a4c1bc7f1ed2fc83e57199cfe5908b10087e27fbd97d2c24214619c7147c8fbefca39bc256762a6823531f7e234d68eae7a0d9faf10dd15e9523780c7d5ae58094ad525a9063b4c33f95e1006da2eb12d3743689495c1f2023e407353c5eb3e4ca1c48cff81a10900d14820eb801af4f1a596c4b9ce9a531fcf8a54d9ffd724258b6eec20108df6fdfd76d4ae03ba7ea598dcb0e4a280849587286f4d7f256ce85e5eb5679b1dacc1f9095649b72e5fa072aeb00379", ++ "010001", ++ "2517eacb3afef4bffae60398df9957a5d2a154a83368d8e15842b2f59ee09f79197bd2ef1e9addaf8786f6b4127447405e3042b21f2f50b7aa73771680c3bbcb6c225a5d5ff6b56c471c1882a0a33b0af165a3ed6c249dc7783e6bc758ac37e6572d33fe325078ed952650f2eb9604902ef99a511a1119d13c4fc9a43a175dcdfbfb1a1400fe17093b69cd3cdb895f65432ea2195f90511c7336b58a685dacff2daf4c5e92e565b1665ae60e512baa9965b808d5ff119ceb7cd692cbf920067afacd809f66be706da26810ac790db156c948e6fe581bc9849157f4da493f3a64b0c6e119e031b107f8436ce29160b458b8f9f1095fdeb19263384ff5387557bc4f10b4034de841703bad2c1e769c23853eb630a36d1061dd46e2a6bbaf743a97f0b32c36f50c1a3722def3a394d91c2e078bf09d795ecde5e56b8202f974026f75fc56e9a0dd6a88f2e7cb78ef1298cc6c65207ca45bd37188807b4fcdb1e60dd8e5b85648fb7efa8b6fdd448f39741a8d9809fe163af3de45bac24a5a841c81", ++ { ++ { ++ "1. a random invalid ciphertext that generates an empty synthethic one", ++ NULL, ++ "", ++ "5e956cd9652f4a2ece902931013e09662b6a9257ad1e987fb75f73a0606df2a4b04789770820c2e02322c4e826f767bd895734a01e20609c3be4517a7a2a589ea1cdc137beb73eb38dac781b52e863de9620f79f9b90fd5b953651fcbfef4a9f1cc07421d511a87dd6942caab6a5a0f4df473e62defb529a7de1509ab99c596e1dff1320402298d8be73a896cc86c38ae3f2f576e9ea70cc28ad575cb0f854f0be43186baa9c18e29c47c6ca77135db79c811231b7c1730955887d321fdc06568382b86643cf089b10e35ab23e827d2e5aa7b4e99ff2e914f302351819eb4d1693243b35f8bf1d42d08f8ec4acafa35f747a4a975a28643ec630d8e4fa5be59d81995660a14bb64c1fea5146d6b11f92da6a3956dd5cb5e0d747cf2ea23f81617769185336263d46ef4c144b754de62a6337342d6c85a95f19f015724546ee3fc4823eca603dbc1dc01c2d5ed50bd72d8e96df2dc048edde0081284068283fc5e73a6139851abf2f29977d0b3d160c883a42a37efba1be05c1a0b1741d7ddf59", ++ "" ++ },{ ++ "2. a random invalid that has PRF output with a length one byte too long", ++ NULL, ++ "", ++ "7db0390d75fcf9d4c59cf27b264190d856da9abd11e92334d0e5f71005cfed865a711dfa28b791188374b61916dbc11339bf14b06f5f3f68c206c5607380e13da3129bfb744157e1527dd6fdf6651248b028a496ae1b97702d44706043cdaa7a59c0f41367303f21f268968bf3bd2904db3ae5239b55f8b438d93d7db9d1666c071c0857e2ec37757463769c54e51f052b2a71b04c2869e9e7049a1037b8429206c99726f07289bac18363e7eb2a5b417f47c37a55090cda676517b3549c873f2fe95da9681752ec9864b069089a2ed2f340c8b04ee00079055a817a3355b46ac7dc00d17f4504ccfbcfcadb0c04cb6b22069e179385ae1eafabad5521bac2b8a8ee1dfff59a22eb3fdacfc87175d10d7894cfd869d056057dd9944b869c1784fcc27f731bc46171d39570fbffbadf082d33f6352ecf44aca8d9478e53f5a5b7c852b401e8f5f74da49da91e65bdc97765a9523b7a0885a6f8afe5759d58009fbfa837472a968e6ae92026a5e0202a395483095302d6c3985b5f5831c521a271", ++ "56a3bea054e01338be9b7d7957539c" ++ },{ ++ "3. a random invalid that generates a synthethic of maximum size", ++ NULL, ++ "", ++ "1715065322522dff85049800f6a29ab5f98c465020467414b2a44127fe9446da47fa18047900f99afe67c2df6f50160bb8e90bff296610fde632b3859d4d0d2e644f23835028c46cca01b84b88231d7e03154edec6627bcba23de76740d839851fa12d74c8f92e540c73fe837b91b7d699b311997d5f0f7864c486d499c3a79c111faaacbe4799597a25066c6200215c3d158f3817c1aa57f18bdaad0be1658da9da93f5cc6c3c4dd72788af57adbb6a0c26f42d32d95b8a4f95e8c6feb2f8a5d53b19a50a0b7cbc25e055ad03e5ace8f3f7db13e57759f67b65d143f08cca15992c6b2aae643390483de111c2988d4e76b42596266005103c8de6044fb7398eb3c28a864fa672de5fd8774510ff45e05969a11a4c7d3f343e331190d2dcf24fb9154ba904dc94af98afc5774a9617d0418fe6d13f8245c7d7626c176138dd698a23547c25f27c2b98ea4d8a45c7842b81888e4cc14e5b72e9cf91f56956c93dbf2e5f44a8282a7813157fc481ff1371a0f66b31797e81ebdb09a673d4db96d6", ++ "7b036fcd6243900e4236c894e2462c17738acc87e01a76f4d95cb9a328d9acde81650283b8e8f60a217e3bdee835c7b222ad4c85d0acdb9a309bd2a754609a65dec50f3aa04c6d5891034566b9563d42668ede1f8992b17753a2132e28970584e255efc8b45a41c5dbd7567f014acec5fe6fdb6d484790360a913ebb9defcd74ff377f2a8ba46d2ed85f733c9a3da08eb57ecedfafda806778f03c66b2c5d2874cec1c291b2d49eb194c7b5d0dd2908ae90f4843268a2c45563092ade08acb6ab481a08176102fc803fbb2f8ad11b0e1531bd37df543498daf180b12017f4d4d426ca29b4161075534bfb914968088a9d13785d0adc0e2580d3548494b2a9e91605f2b27e6cc701c796f0de7c6f471f6ab6cb9272a1ed637ca32a60d117505d82af3c1336104afb537d01a8f70b510e1eebf4869cb976c419473795a66c7f5e6e20a8094b1bb603a74330c537c5c0698c31538bd2e138c1275a1bdf24c5fa8ab3b7b526324e7918a382d1363b3d463764222150e04" ++ },{ ++ "4. a positive test case that decrypts to 9 byte long value", ++ NULL, ++ "", ++ "6c60845a854b4571f678941ae35a2ac03f67c21e21146f9db1f2306be9f136453b86ad55647d4f7b5c9e62197aaff0c0e40a3b54c4cde14e774b1c5959b6c2a2302896ffae1f73b00b862a20ff4304fe06cea7ff30ecb3773ca9af27a0b54547350d7c07dfb0a39629c7e71e83fc5af9b2adbaf898e037f1de696a3f328cf45af7ec9aff7173854087fb8fbf34be981efbd8493f9438d1b2ba2a86af082662aa46ae9adfbec51e5f3d9550a4dd1dcb7c8969c9587a6edc82a8cabbc785c40d9fbd12064559fb769450ac3e47e87bc046148130d7eaa843e4b3ccef3675d0630500803cb7ffee3882378c1a404e850c3e20707bb745e42b13c18786c4976076ed9fa8fd0ff15e571bef02cbbe2f90c908ac3734a433b73e778d4d17fcc28f49185ebc6e8536a06d293202d94496453bfdf1c2c7833a3f99fa38ca8a81f42eaa529d603b890308a319c0ab63a35ff8ebac965f6278f5a7e5d622be5d5fe55f0ca3ec993d55430d2bf59c5d3e860e90c16d91a04596f6fdf60d89ed95d88c036dde", ++ "666f7274792074776f" ++ },{ ++ "5. a positive test case with null padded ciphertext", ++ NULL, ++ "", ++ "00f4d565a3286784dbb85327db8807ae557ead229f92aba945cecda5225f606a7d6130edeeb6f26724d1eff1110f9eb18dc3248140ee3837e6688391e78796c526791384f045e21b6b853fb6342a11f309eb77962f37ce23925af600847fbd30e6e07e57de50b606e6b7f288cc777c1a6834f27e6edace508452128916eef7788c8bb227e3548c6a761cc4e9dd1a3584176dc053ba3500adb1d5e1611291654f12dfc5722832f635db3002d73f9defc310ace62c63868d341619c7ee15b20243b3371e05078e11219770c701d9f341af35df1bc729de294825ff2e416aa11526612852777eb131f9c45151eb144980d70608d2fc4043477368369aa0fe487a48bd57e66b00c3c58f941549f5ec050fca64449debe7a0c4ac51e55cb71620a70312aa4bd85fac1410c9c7f9d6ec610b7d11bf8faeffa20255d1a1bead9297d0aa8765cd2805847d639bc439f4a6c896e2008f746f9590ff4596de5ddde000ed666c452c978043ff4298461eb5a26d5e63d821438627f91201924bf7f2aeee1727", ++ "666f7274792074776f" ++ },{ ++ "6. a positive test case with double null padded ciphertext", ++ NULL, ++ "", ++ "00001ec97ac981dfd9dcc7a7389fdfa9d361141dac80c23a060410d472c16094e6cdffc0c3684d84aa402d7051dfccb2f6da33f66985d2a259f5b7fbf39ac537e95c5b7050eb18844a0513abef812cc8e74a3c5240009e6e805dcadf532bc1a2702d5acc9e585fad5b89d461fcc1397351cdce35171523758b171dc041f412e42966de7f94856477356d06f2a6b40e3ff0547562a4d91bbf1338e9e049facbee8b20171164505468cd308997447d3dc4b0acb49e7d368fedd8c734251f30a83491d2506f3f87318cc118823244a393dc7c5c739a2733d93e1b13db6840a9429947357f47b23fbe39b7d2d61e5ee26f9946c4632f6c4699e452f412a26641d4751135400713cd56ec66f0370423d55d2af70f5e7ad0adea8e4a0d904a01e4ac272eba4af1a029dd53eb71f115bf31f7a6c8b19a6523adeecc0d4c3c107575e38572a8f8474ccad163e46e2e8b08111132aa97a16fb588c9b7e37b3b3d7490381f3c55d1a9869a0fd42cd86fed59ecec78cb6b2dfd06a497f5afe3419691314ba0", ++ "666f7274792074776f" ++ },{ ++ "7. a positive test case with double null truncated ciphertext", ++ NULL, ++ "", ++ "1ec97ac981dfd9dcc7a7389fdfa9d361141dac80c23a060410d472c16094e6cdffc0c3684d84aa402d7051dfccb2f6da33f66985d2a259f5b7fbf39ac537e95c5b7050eb18844a0513abef812cc8e74a3c5240009e6e805dcadf532bc1a2702d5acc9e585fad5b89d461fcc1397351cdce35171523758b171dc041f412e42966de7f94856477356d06f2a6b40e3ff0547562a4d91bbf1338e9e049facbee8b20171164505468cd308997447d3dc4b0acb49e7d368fedd8c734251f30a83491d2506f3f87318cc118823244a393dc7c5c739a2733d93e1b13db6840a9429947357f47b23fbe39b7d2d61e5ee26f9946c4632f6c4699e452f412a26641d4751135400713cd56ec66f0370423d55d2af70f5e7ad0adea8e4a0d904a01e4ac272eba4af1a029dd53eb71f115bf31f7a6c8b19a6523adeecc0d4c3c107575e38572a8f8474ccad163e46e2e8b08111132aa97a16fb588c9b7e37b3b3d7490381f3c55d1a9869a0fd42cd86fed59ecec78cb6b2dfd06a497f5afe3419691314ba0", ++ "666f7274792074776f" ++ },{ ++ "8. a random negative test case that generates a 9 byte long message", ++ NULL, ++ "", ++ "5c8555f5cef627c15d37f85c7f5fd6e499264ea4b8e3f9112023aeb722eb38d8eac2be3751fd5a3785ab7f2d59fa3728e5be8c3de78a67464e30b21ee23b5484bb3cd06d0e1c6ad25649c8518165653eb80488bfb491b20c04897a6772f69292222fc5ef50b5cf9efc6d60426a449b6c489569d48c83488df629d695653d409ce49a795447fcec2c58a1a672e4a391401d428baaf781516e11e323d302fcf20f6eab2b2dbe53a48c987e407c4d7e1cb41131329138313d330204173a4f3ff06c6fadf970f0ed1005d0b27e35c3d11693e0429e272d583e57b2c58d24315c397856b34485dcb077665592b747f889d34febf2be8fce66c265fd9fc3575a6286a5ce88b4b413a08efc57a07a8f57a999605a837b0542695c0d189e678b53662ecf7c3d37d9dbeea585eebfaf79141118e06762c2381fe27ca6288edddc19fd67cd64f16b46e06d8a59ac530f22cd83cc0bc4e37feb52015cbb2283043ccf5e78a4eb7146827d7a466b66c8a4a4826c1bad68123a7f2d00fc1736525ff90c058f56", ++ "257906ca6de8307728" ++ },{ ++ "9. a random negative test case that generates a 9 byte long message based on second to last value from PRF", ++ NULL, ++ "", ++ "758c215aa6acd61248062b88284bf43c13cb3b3d02410be4238607442f1c0216706e21a03a2c10eb624a63322d854da195c017b76fea83e274fa371834dcd2f3b7accf433fc212ad76c0bac366e1ed32e25b279f94129be7c64d6e162adc08ccebc0cfe8e926f01c33ab9c065f0e0ac83ae5137a4cb66702615ad68a35707d8676d2740d7c1a954680c83980e19778ed11eed3a7c2dbdfc461a9bbef671c1bc00c882d361d29d5f80c42bdf5efec886c34138f83369c6933b2ac4e93e764265351b4a0083f040e14f511f09b22f96566138864e4e6ff24da4810095da98e0585410951538ced2f757a277ff8e17172f06572c9024eeae503f176fd46eb6c5cd9ba07af11cde31dccac12eb3a4249a7bfd3b19797ad1656984bfcbf6f74e8f99d8f1ac420811f3d166d87f935ef15ae858cf9e72c8e2b547bf16c3fb09a8c9bf88fd2e5d38bf24ed610896131a84df76b9f920fe76d71fff938e9199f3b8cd0c11fd0201f9139d7673a871a9e7d4adc3bbe360c8813617cd60a90128fbe34c9d5", ++ "043383c929060374ed" ++ },{ ++ "10. a random negative test that generates message based on 3rd last value from PRF", ++ NULL, ++ "", ++ "7b22d5e62d287968c6622171a1f75db4b0fd15cdf3134a1895d235d56f8d8fe619f2bf4868174a91d7601a82975d2255190d28b869141d7c395f0b8c4e2be2b2c1b4ffc12ce749a6f6803d4cfe7fba0a8d6949c04151f981c0d84592aa2ff25d1bd3ce5d10cb03daca6b496c6ad40d30bfa8acdfd02cdb9326c4bdd93b949c9dc46caa8f0e5f429785bce64136a429a3695ee674b647452bea1b0c6de9c5f1e8760d5ef6d5a9cfff40457b023d3c233c1dcb323e7808103e73963b2eafc928c9eeb0ee3294955415c1ddd9a1bb7e138fecd79a3cb89c57bd2305524624814aaf0fd1acbf379f7f5b39421f12f115ba488d380586095bb53f174fae424fa4c8e3b299709cd344b9f949b1ab57f1c645d7ed3c8f81d5594197355029fee8960970ff59710dc0e5eb50ea6f4c3938e3f89ed7933023a2c2ddffaba07be147f686828bd7d520f300507ed6e71bdaee05570b27bc92741108ac2eb433f028e138dd6d63067bc206ea2d826a7f41c0d613daed020f0f30f4e272e9618e0a8c39018a83", ++ "70263fa6050534b9e0" ++ },{ ++ "11. an otherwise valid plaintext, but with wrong first byte (0x01 instead of 0x00)", ++ NULL, ++ "", ++ "6db80adb5ff0a768caf1378ecc382a694e7d1bde2eff4ba12c48aaf794ded7a994a5b2b57acec20dbec4ae385c9dd531945c0f197a5496908725fc99d88601a17d3bb0b2d38d2c1c3100f39955a4cb3dbed5a38bf900f23d91e173640e4ec655c84fdfe71fcdb12a386108fcf718c9b7af37d39703e882436224c877a2235e8344fba6c951eb7e2a4d1d1de81fb463ac1b880f6cc0e59ade05c8ce35179ecd09546731fc07b141d3d6b342a97ae747e61a9130f72d37ac5a2c30215b6cbd66c7db893810df58b4c457b4b54f34428247d584e0fa71062446210db08254fb9ead1ba1a393c724bd291f0cf1a7143f32df849051dc896d7d176fef3b57ab6dffd626d0c3044e9edb2e3d012ace202d2581df01bec7e9aa0727a6650dd373d374f0bc0f4a611f8139dfe97d63e70c6188f4df5b672e47c51d8aa567097293fbff127c75ec690b43407578b73c85451710a0cece58fd497d7f7bd36a8a92783ef7dc6265dff52aac8b70340b996508d39217f2783ce6fc91a1cc94bb2ac487b84f62", ++ "6d8d3a094ff3afff4c" ++ },{ ++ "12. an otherwise valid plaintext, but with wrong second byte (0x01 instead of 0x02)", ++ NULL, ++ "", ++ "417328c034458563079a4024817d0150340c34e25ae16dcad690623f702e5c748a6ebb3419ff48f486f83ba9df35c05efbd7f40613f0fc996c53706c30df6bba6dcd4a40825f96133f3c21638a342bd4663dffbd0073980dac47f8c1dd8e97ce1412e4f91f2a8adb1ac2b1071066efe8d718bbb88ca4a59bd61500e826f2365255a409bece0f972df97c3a55e09289ef5fa815a2353ef393fd1aecfc888d611c16aec532e5148be15ef1bf2834b8f75bb26db08b66d2baad6464f8439d1986b533813321dbb180080910f233bcc4dd784fb21871aef41be08b7bfad4ecc3b68f228cb5317ac6ec1227bc7d0e452037ba918ee1da9fdb8393ae93b1e937a8d4691a17871d5092d2384b6190a53df888f65b951b05ed4ad57fe4b0c6a47b5b22f32a7f23c1a234c9feb5d8713d949686760680da4db454f4acad972470033472b9864d63e8d23eefc87ebcf464ecf33f67fbcdd48eab38c5292586b36aef5981ed2fa07b2f9e23fc57d9eb71bfff4111c857e9fff23ceb31e72592e70c874b4936", ++ "c6ae80ffa80bc184b0" ++ },{ ++ "13. an otherwise valid plaintext, but with zero byte in first byte of padding", ++ NULL, ++ "", ++ "8542c626fe533467acffcd4e617692244c9b5a3bf0a215c5d64891ced4bf4f9591b4b2aedff9843057986d81631b0acb3704ec2180e5696e8bd15b217a0ec36d2061b0e2182faa3d1c59bd3f9086a10077a3337a3f5da503ec3753535ffd25b837a12f2541afefd0cffb0224b8f874e4bed13949e105c075ed44e287c5ae03b155e06b90ed247d2c07f1ef3323e3508cce4e4074606c54172ad74d12f8c3a47f654ad671104bf7681e5b061862747d9afd37e07d8e0e2291e01f14a95a1bb4cbb47c304ef067595a3947ee2d722067e38a0f046f43ec29cac6a8801c6e3e9a2331b1d45a7aa2c6af3205be382dd026e389614ee095665a611ab2e8dced2ee1c9d08ac9de11aef5b3803fc9a9ce8231ec87b5fed386fb92ee3db995a89307bcba844bd0a691c29ae51216e949dfc813133cb06a07265fd807bcb3377f6adb0a481d9b7f442003115895939773e6b95371c4febef29edae946fa245e7c50729e2e558cfaad773d1fd5f67b457a6d9d17a847c6fcbdb103a86f35f228cefc06cea0", ++ "a8a9301daa01bb25c7" ++ },{ ++ "14. an otherwise valid plaintext, but with zero byte in eight byte of padding", ++ NULL, ++ "", ++ "449dfa237a70a99cb0351793ec8677882021c2aa743580bf6a0ea672055cffe8303ac42855b1d1f3373aae6af09cb9074180fc963e9d1478a4f98b3b4861d3e7f0aa8560cf603711f139db77667ca14ba3a1acdedfca9ef4603d6d7eb0645bfc805304f9ad9d77d34762ce5cd84bd3ec9d35c30e3be72a1e8d355d5674a141b5530659ad64ebb6082e6f73a80832ab6388912538914654d34602f4b3b1c78589b4a5d964b2efcca1dc7004c41f6cafcb5a7159a7fc7c0398604d0edbd4c8f4f04067da6a153a05e7cbeea13b5ee412400ef7d4f3106f4798da707ec37a11286df2b7a204856d5ff773613fd1e453a7114b78e347d3e8078e1cb3276b3562486ba630bf719697e0073a123c3e60ebb5c7a1ccff4279faffa2402bc1109f8d559d6766e73591943dfcf25ba10c3762f02af85187799b8b4b135c3990793a6fd32642f1557405ba55cc7cf7336a0e967073c5fa50743f9cc5e3017c172d9898d2af83345e71b3e0c22ab791eacb6484a32ec60ebc226ec9deaee91b1a0560c2b571", ++ "6c716fe01d44398018" ++ },{ ++ "15. an otherwise valid plaintext, but with null separator missing", ++ NULL, ++ "", ++ "a7a5c99e50da48769ecb779d9abe86ef9ec8c38c6f43f17c7f2d7af608a4a1bd6cf695b47e97c191c61fb5a27318d02f495a176b9fae5a55b5d3fabd1d8aae4957e3879cb0c60f037724e11be5f30f08fc51c033731f14b44b414d11278cd3dba7e1c8bfe208d2b2bb7ec36366dacb6c88b24cd79ab394adf19dbbc21dfa5788bacbadc6a62f79cf54fd8cf585c615b5c0eb94c35aa9de25321c8ffefb8916bbaa2697cb2dd82ee98939df9b6704cee77793edd2b4947d82e00e5749664970736c59a84197bd72b5c71e36aae29cd39af6ac73a368edbc1ca792e1309f442aafcd77c992c88f8e4863149f221695cb7b0236e75b2339a02c4ea114854372c306b9412d8eedb600a31532002f2cea07b4df963a093185e4607732e46d753b540974fb5a5c3f9432df22e85bb17611370966c5522fd23f2ad3484341ba7fd8885fc8e6d379a611d13a2aca784fba2073208faad2137bf1979a0fa146c1880d4337db3274269493bab44a1bcd0681f7227ffdf589c2e925ed9d36302509d1109ba4", ++ "aa2de6cde4e2442884" ++ },{ ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ } ++ } + } + }; +diff --git a/tests/pkcs1v2.c b/tests/pkcs1v2.c +index ab070a94..a2153728 100644 +--- a/tests/pkcs1v2.c ++++ b/tests/pkcs1v2.c +@@ -82,7 +82,7 @@ data_from_hex (const char *string, size_t *r_length) + + static int + extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected, +- const char *description) ++ const char *description, int quiet) + { + gcry_sexp_t l1; + const void *a; +@@ -96,13 +96,15 @@ extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected, + b = data_from_hex (expected, &blen); + if (!a) + { +- info ("%s: parameter \"%s\" missing in key\n", description, name); ++ if (!quiet) ++ info ("%s: parameter \"%s\" missing in key\n", description, name); + rc = 1; + } + else if ( alen != blen || memcmp (a, b, alen) ) + { +- info ("%s: parameter \"%s\" does not match expected value\n", +- description, name); ++ if (!quiet) ++ info ("%s: parameter \"%s\" does not match expected value\n", ++ description, name); + rc = 1; + } + gcry_free (b); +@@ -192,7 +194,7 @@ check_oaep (void) + else + { + if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr, +- tbl[tno].m[mno].desc)) ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("encrypt result:\n", ciph); + fail ("mismatch in gcry_pk_encrypt\n"); +@@ -223,7 +225,7 @@ check_oaep (void) + else + { + if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg, +- tbl[tno].m[mno].desc)) ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("decrypt result:\n", plain); + fail ("mismatch in gcry_pk_decrypt\n"); +@@ -326,7 +328,7 @@ check_pss (void) + else + { + if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign, +- tbl[tno].m[mno].desc)) ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("sign result:\n", sig); + fail ("mismatch in gcry_pk_sign\n"); +@@ -429,45 +431,89 @@ check_v15crypt (void) + size_t mesg_len, seed_len, encr_len; + gcry_sexp_t plain, ciph; + ++ if (tbl[tno].m[mno].desc == NULL) ++ break; ++ + if (verbose) + info ("running test: %s\n", tbl[tno].m[mno].desc); + +- mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); +- seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); ++ if (tbl[tno].m[mno].mesg) ++ { ++ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); ++ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); ++ ++ err = gcry_sexp_build (&plain, NULL, ++ "(data (flags pkcs1)" ++ "(value %b)(random-override %b))", ++ (int)mesg_len, mesg, ++ (int)seed_len, seed); ++ if (err) ++ die ("constructing plain data failed: %s\n", gpg_strerror (err)); ++ gcry_free (mesg); ++ gcry_free (seed); ++ ++ err = gcry_pk_encrypt (&ciph, plain, pub_key); ++ if (err) ++ { ++ show_sexp ("plain:\n", ciph); ++ fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err)); ++ } ++ else ++ { ++ if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr, ++ tbl[tno].m[mno].desc, 0)) ++ { ++ show_sexp ("encrypt result:\n", ciph); ++ fail ("mismatch in gcry_pk_encrypt\n"); ++ } ++ gcry_sexp_release (ciph); ++ ciph = NULL; ++ } ++ gcry_sexp_release (plain); ++ plain = NULL; ++ } + +- err = gcry_sexp_build (&plain, NULL, +- "(data (flags pkcs1)(hash-algo sha1)" +- "(value %b)(random-override %b))", +- (int)mesg_len, mesg, +- (int)seed_len, seed); ++ /* Now test the decryption. */ ++ encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len); ++ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); ++ ++#ifdef WITH_MARVIN_WORKAROUND ++ /* First try without implicit rejection -- this should fail for invalid inputs */ ++ err = gcry_sexp_build (&ciph, NULL, ++ "(enc-val (flags pkcs1 no-implicit-rejection)" ++ "(rsa (a %b)))", ++ (int)encr_len, encr); + if (err) +- die ("constructing plain data failed: %s\n", gpg_strerror (err)); +- gcry_free (mesg); +- gcry_free (seed); ++ die ("constructing cipher data failed: %s\n", gpg_strerror (err)); + +- err = gcry_pk_encrypt (&ciph, plain, pub_key); ++ err = gcry_pk_decrypt (&plain, ciph, sec_key); + if (err) + { +- show_sexp ("plain:\n", ciph); +- fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err)); ++ /* If the message is not set, the padding is invalid and failure is expected */ ++ if (tbl[tno].m[mno].mesg != NULL) ++ { ++ show_sexp ("ciph:\n", ciph); ++ fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err)); ++ } + } + else + { +- if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr, +- tbl[tno].m[mno].desc)) ++ /* If the message is not set, it is in the synthetic field */ ++ const char *msg = tbl[tno].m[mno].mesg; ++ if (msg == NULL) ++ msg = tbl[tno].m[mno].synt; ++ if (extract_cmp_data (plain, "value", msg, ++ tbl[tno].m[mno].desc, 0)) + { +- show_sexp ("encrypt result:\n", ciph); +- fail ("mismatch in gcry_pk_encrypt\n"); ++ show_sexp ("decrypt result:\n", plain); ++ fail ("mismatch in gcry_pk_decrypt.\n"); + } +- gcry_sexp_release (ciph); +- ciph = NULL; ++ gcry_sexp_release (plain); ++ plain = NULL; + } +- gcry_sexp_release (plain); +- plain = NULL; +- +- /* Now test the decryption. */ +- seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); +- encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len); ++ gcry_sexp_release (ciph); ++ ciph = NULL; ++#endif /* WITH_MARVIN_WORKAROUND */ + + err = gcry_sexp_build (&ciph, NULL, + "(enc-val (flags pkcs1)(hash-algo sha1)" +@@ -484,15 +530,19 @@ check_v15crypt (void) + } + else + { +- if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg, +- tbl[tno].m[mno].desc)) ++ /* If the message is not set, expect the synthetic message here */ ++ const char *msg = tbl[tno].m[mno].mesg; ++ if (msg == NULL) ++ msg = tbl[tno].m[mno].synt; ++ if (extract_cmp_data (plain, "value", msg, ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("decrypt result:\n", plain); +- fail ("mismatch in gcry_pk_decrypt\n"); ++ fail ("mismatch in gcry_pk_decrypt. Expected %s\n", msg); + } +- gcry_sexp_release (plain); +- plain = NULL; + } ++ gcry_sexp_release (plain); ++ plain = NULL; + gcry_sexp_release (ciph); + ciph = NULL; + } +@@ -584,7 +634,7 @@ check_v15sign (void) + else + { + if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign, +- tbl[tno].m[mno].desc)) ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("sign result:\n", sig); + fail ("mismatch in gcry_pk_sign\n"); +-- +2.46.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index 2c08d1c..de9064d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -27,6 +27,8 @@ Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch # https://dev.gnupg.org/T7220 Patch3: libgcrypt-1.11.0-cf-protection.patch Patch4: libgcrypt-1.11.0-pac-bti-protection.patch +# https://gitlab.com/redhat-crypto/libgcrypt/libgcrypt-mirror/-/merge_requests/19/ +Patch5: libgcrypt-1.11.0-marvin.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -65,6 +67,7 @@ applications using libgcrypt. %patch 2 -p1 %patch 3 -p1 %patch 4 -p1 +%patch 5 -p1 %build # should be all algorithms except SM3 and SM4, aria @@ -85,6 +88,7 @@ autoreconf -f --disable-O-flag-munging \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ + --enable-marvin-workaround \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool %make_build From 2e86b5c745b3e499f55c4db0e0befd6f945e84c1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Aug 2024 09:05:52 +0200 Subject: [PATCH 209/214] 1.11.0-4 --- libgcrypt.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index de9064d..cf992f5 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.0 -Release: 3%{?dist} +Release: 4%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -181,6 +181,12 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Oct 29 2024 Jakub Jelen - 1.11.0-4 +- Run annocheck as part of the build +- Use upstream CF protection patches +- Fix PAC/BTI protection for Aarch64 +- Fix CVE-2024-2236 (#2274128) + * Thu Jul 25 2024 Jakub Jelen - 1.11.0-3 - Disable -O flag munging and remove needles modification of LTO flags. From 2f265169e5cb5e83f7901ffa6d5a7348cf475e1e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 17 Jan 2025 11:17:27 +0000 Subject: [PATCH 210/214] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index cf992f5..eb5c8cb 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.0 -Release: 4%{?dist} +Release: 5%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -181,6 +181,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Fri Jan 17 2025 Fedora Release Engineering - 1.11.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Tue Oct 29 2024 Jakub Jelen - 1.11.0-4 - Run annocheck as part of the build - Use upstream CF protection patches From 5f28c0a7f0829efa11968a3d4fabfd0460979cb1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 13 May 2025 10:25:59 +0200 Subject: [PATCH 211/214] 1.11.1-1 --- .gitignore | 2 + ...e-SHA3-s390x-acceleration-for-CSHAKE.patch | 63 ---- libgcrypt-1.11.0-cf-protection.patch | 328 ------------------ libgcrypt-1.11.0-marvin.patch | 13 +- libgcrypt-1.11.0-pac-bti-protection.patch | 229 ------------ libgcrypt.spec | 20 +- sources | 4 +- 7 files changed, 18 insertions(+), 641 deletions(-) delete mode 100644 libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch delete mode 100644 libgcrypt-1.11.0-cf-protection.patch delete mode 100644 libgcrypt-1.11.0-pac-bti-protection.patch diff --git a/.gitignore b/.gitignore index 069ccb4..544f5c1 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.10.3.tar.bz2.sig /libgcrypt-1.11.0.tar.bz2 /libgcrypt-1.11.0.tar.bz2.sig +/libgcrypt-1.11.1.tar.bz2 +/libgcrypt-1.11.1.tar.bz2.sig diff --git a/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch b/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch deleted file mode 100644 index 0267ea0..0000000 --- a/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 2486d9b5ae015c1786cb84466a751da4bc0d7122 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Thu, 20 Jun 2024 20:10:09 +0300 -Subject: [PATCH] Disable SHA3 s390x acceleration for CSHAKE - -* cipher/keccak.c (keccak_final_s390x): Add assert check for -expected SHAKE suffix. -(_gcry_cshake_customize, cshake_hash_buffers): Disable s390x -acceleration when selecting CSHAKE suffix. --- - -Signed-off-by: Jussi Kivilinna ---- - cipher/keccak.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/cipher/keccak.c b/cipher/keccak.c -index aaf83a62..44cc9f71 100644 ---- a/cipher/keccak.c -+++ b/cipher/keccak.c -@@ -745,6 +745,8 @@ keccak_final_s390x (void *context) - } - else - { -+ gcry_assert(ctx->suffix == SHAKE_DELIMITED_SUFFIX); -+ - klmd_shake_execute (ctx->kimd_func, &ctx->state, NULL, 0, ctx->buf, - ctx->count); - ctx->count = 0; -@@ -1497,9 +1499,14 @@ _gcry_cshake_customize (void *context, struct gcry_cshake_customization *p) - /* No customization */ - return 0; - -+ ctx->suffix = CSHAKE_DELIMITED_SUFFIX; -+#ifdef USE_S390X_CRYPTO -+ /* CSHAKE suffix is not supported by s390x/kimd. */ -+ ctx->kimd_func = 0; -+#endif -+ - len_written = cshake_input_n (ctx, p->n, p->n_len); - cshake_input_s (ctx, p->s, p->s_len, len_written); -- ctx->suffix = CSHAKE_DELIMITED_SUFFIX; - return 0; - } - -@@ -1536,9 +1543,14 @@ cshake_hash_buffers (const gcry_md_spec_t *spec, void *outbuf, size_t nbytes, - size_t s_len = iov[1].len; - size_t len; - -+ ctx.suffix = CSHAKE_DELIMITED_SUFFIX; -+#ifdef USE_S390X_CRYPTO -+ /* CSHAKE suffix is not supported by s390x/kimd. */ -+ ctx.kimd_func = 0; -+#endif -+ - len = cshake_input_n (&ctx, n, n_len); - cshake_input_s (&ctx, s, s_len, len); -- ctx.suffix = CSHAKE_DELIMITED_SUFFIX; - } - iovcnt -= 2; - iov += 2; --- -2.43.0 diff --git a/libgcrypt-1.11.0-cf-protection.patch b/libgcrypt-1.11.0-cf-protection.patch deleted file mode 100644 index ece660e..0000000 --- a/libgcrypt-1.11.0-cf-protection.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 7ee2e73495d051ca09dd57c90132a7a9cc53bc62 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Fri, 26 Jul 2024 11:00:30 +0300 -Subject: [PATCH] asm-common-amd64: add missing CFI directives for large memory - model code - -* cipher/asm-common-amd64.h [__code_model_large__] -(GET_EXTERN_POINTER): Add CFI_PUSH/CFI_POP directives. --- - -Signed-off-by: Jussi Kivilinna ---- - cipher/asm-common-amd64.h | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h -index 870fef9a..3fa065e8 100644 ---- a/cipher/asm-common-amd64.h -+++ b/cipher/asm-common-amd64.h -@@ -59,14 +59,18 @@ - # ifdef __code_model_large__ - # define GET_EXTERN_POINTER(name, reg) \ - pushq %r15; \ -+ CFI_PUSH(%r15); \ - pushq %r14; \ -+ CFI_PUSH(%r14); \ - 1: leaq 1b(%rip), reg; \ - movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \ - movabsq $name@GOT, %r15; \ - addq %r14, reg; \ - popq %r14; \ -+ CFI_POP(%r14); \ - movq (reg, %r15), reg; \ -- popq %r15; -+ popq %r15; \ -+ CFI_POP(%r15); - # else - # define GET_EXTERN_POINTER(name, reg) movq name@GOTPCREL(%rip), reg - # endif --- -2.45.2 - -From dd42a4e03e066c49a6d83e0d3a07e4261d77121a Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Sat, 27 Jul 2024 08:16:56 +0300 -Subject: [PATCH] Do not build i386 assembly on x86-64 - -* configure.ac: Enable building i386 "rijndael-vaes" only -on i?86 host instead of x86 MPI arch ("i?86 + x86-64"). --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - configure.ac | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/configure.ac b/configure.ac -index d3dffb4b..1e182552 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3025,6 +3025,11 @@ if test "$found" = "1" ; then - AC_DEFINE(USE_AES, 1, [Defined if this module should be included]) - - case "${host}" in -+ i?86-*-*) -+ # Build with the VAES/AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-i386.lo" -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-avx2-i386.lo" -+ ;; - x86_64-*-*) - # Build with the assembly implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-amd64.lo" -@@ -3089,10 +3094,6 @@ if test "$found" = "1" ; then - - # Build with the Padlock implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-padlock.lo" -- -- # Build with the VAES/AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-i386.lo" -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-avx2-i386.lo" - ;; - esac - fi --- -2.45.2 - -From 5797d75e3b916caf504bed73a8629c6c168be58d Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Sat, 27 Jul 2024 08:50:57 +0300 -Subject: [PATCH] Do not build amd64 assembly on i386 - -* configure.ac: Build "serpent-avx2-amd64" and -"camellia-*-amd64" only on x86-64. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - configure.ac | 50 +++++++++++++++++++++++++++----------------------- - 1 file changed, 27 insertions(+), 23 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 1e182552..191aa38d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3133,14 +3133,14 @@ if test "$found" = "1" ; then - x86_64-*-*) - # Build with the SSE2 implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-sse2-amd64.lo" -+ -+ if test x"$avx2support" = xyes ; then -+ # Build with the AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" -+ fi - ;; - esac - -- if test x"$avx2support" = xyes ; then -- # Build with the AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" -- fi -- - if test x"$avx512support" = xyes ; then - # Build with the AVX512 implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx512-x86.lo" -@@ -3186,28 +3186,32 @@ if test "$found" = "1" ; then - ;; - esac - -- if test x"$avxsupport" = xyes ; then -- if test x"$aesnisupport" = xyes ; then -- # Build with the AES-NI/AVX implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx-amd64.lo" -- fi -- fi -+ case "${host}" in -+ x86_64-*-*) -+ if test x"$avxsupport" = xyes ; then -+ if test x"$aesnisupport" = xyes ; then -+ # Build with the AES-NI/AVX implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx-amd64.lo" -+ fi -+ fi - -- if test x"$avx2support" = xyes ; then -- if test x"$aesnisupport" = xyes ; then -- # Build with the AES-NI/AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx2-amd64.lo" -+ if test x"$avx2support" = xyes ; then -+ if test x"$aesnisupport" = xyes ; then -+ # Build with the AES-NI/AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx2-amd64.lo" - -- # Build with the VAES/AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-vaes-avx2-amd64.lo" -+ # Build with the VAES/AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-vaes-avx2-amd64.lo" - -- # Build with the GFNI/AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx2-amd64.lo" -+ # Build with the GFNI/AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx2-amd64.lo" - -- # Build with the GFNI/AVX512 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx512-amd64.lo" -- fi -- fi -+ # Build with the GFNI/AVX512 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx512-amd64.lo" -+ fi -+ fi -+ ;; -+ esac - fi - - LIST_MEMBER(idea, $enabled_ciphers) --- -2.45.2 - -From d69e6a29b986cf1cb21e09d337a0de2564ef34f2 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Fri, 26 Jul 2024 10:59:12 +0300 -Subject: [PATCH] Add CET support for x86-64 assembly - -* cipher/asm-common-amd64.h (ENDBRANCH): New. -(CFI_STARTPROC): Add ENDBRANCH. -[__CET__] (note.gnu.property): Add CET property section. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - cipher/asm-common-amd64.h | 30 ++++++++++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - -diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h -index 3fa065e8..465ef62b 100644 ---- a/cipher/asm-common-amd64.h -+++ b/cipher/asm-common-amd64.h -@@ -76,9 +76,15 @@ - # endif - #endif - -+#ifdef __CET__ -+#define ENDBRANCH endbr64 -+#else -+#define ENDBRANCH /*_*/ -+#endif -+ - #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES - /* CFI directives to emit DWARF stack unwinding information. */ --# define CFI_STARTPROC() .cfi_startproc -+# define CFI_STARTPROC() .cfi_startproc; ENDBRANCH - # define CFI_ENDPROC() .cfi_endproc - # define CFI_REMEMBER_STATE() .cfi_remember_state - # define CFI_RESTORE_STATE() .cfi_restore_state -@@ -146,7 +152,7 @@ - DW_SLEB128_28BIT(rsp_offs) - - #else --# define CFI_STARTPROC() -+# define CFI_STARTPROC() ENDBRANCH - # define CFI_ENDPROC() - # define CFI_REMEMBER_STATE() - # define CFI_RESTORE_STATE() -@@ -214,4 +220,24 @@ - vpopcntb xmm16, xmm16; /* Supported only by newer AVX512 CPUs. */ \ - vpxord ymm16, ymm16, ymm16; - -+#ifdef __CET__ -+/* Generate CET property for all assembly files including this header. */ -+ELF(.section .note.gnu.property,"a") -+ELF(.align 8) -+ELF(.long 1f - 0f) -+ELF(.long 4f - 1f) -+ELF(.long 5) -+ELF(0:) -+ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ -+ELF(1:) -+ELF(.align 8) -+ELF(.long 0xc0000002) -+ELF(.long 3f - 2f) -+ELF(2:) -+ELF(.long 0x3) -+ELF(3:) -+ELF(.align 8) -+ELF(4:) -+#endif -+ - #endif /* GCRY_ASM_COMMON_AMD64_H */ --- -2.45.2 - -From 64ec13d11b08fbe31cc6f83e9464e7e251d41019 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Fri, 26 Jul 2024 11:09:37 +0300 -Subject: [PATCH] Add CET support for i386 assembly - -* cipher/asm-common-i386.h (ENDBRANCH): New. -(CFI_STARTPROC): Add ENDBRANCH. -[__CET__] (note.gnu.property): Add CET property section. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - cipher/asm-common-i386.h | 30 ++++++++++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - -diff --git a/cipher/asm-common-i386.h b/cipher/asm-common-i386.h -index d746ebc4..346a8ff2 100644 ---- a/cipher/asm-common-i386.h -+++ b/cipher/asm-common-i386.h -@@ -59,9 +59,15 @@ - movl name##@GOT(%reg), %reg; - #endif - -+#ifdef __CET__ -+#define ENDBRANCH endbr32 -+#else -+#define ENDBRANCH /*_*/ -+#endif -+ - #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES - /* CFI directives to emit DWARF stack unwinding information. */ --# define CFI_STARTPROC() .cfi_startproc -+# define CFI_STARTPROC() .cfi_startproc; ENDBRANCH - # define CFI_ENDPROC() .cfi_endproc - # define CFI_REMEMBER_STATE() .cfi_remember_state - # define CFI_RESTORE_STATE() .cfi_restore_state -@@ -121,7 +127,7 @@ - DW_SLEB128_28BIT(esp_offs) - - #else --# define CFI_STARTPROC() -+# define CFI_STARTPROC() ENDBRANCH - # define CFI_ENDPROC() - # define CFI_REMEMBER_STATE() - # define CFI_RESTORE_STATE() -@@ -158,4 +164,24 @@ - vpopcntb xmm7, xmm7; /* Supported only by newer AVX512 CPUs. */ \ - vpxord ymm7, ymm7, ymm7; - -+#ifdef __CET__ -+/* Generate CET property for all assembly files including this header. */ -+ELF(.section .note.gnu.property,"a") -+ELF(.align 4) -+ELF(.long 1f - 0f) -+ELF(.long 4f - 1f) -+ELF(.long 5) -+ELF(0:) -+ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ -+ELF(1:) -+ELF(.align 4) -+ELF(.long 0xc0000002) -+ELF(.long 3f - 2f) -+ELF(2:) -+ELF(.long 0x3) -+ELF(3:) -+ELF(.align 4) -+ELF(4:) -+#endif -+ - #endif /* GCRY_ASM_COMMON_AMD64_H */ --- -2.45.2 - diff --git a/libgcrypt-1.11.0-marvin.patch b/libgcrypt-1.11.0-marvin.patch index d2998f0..78b6809 100644 --- a/libgcrypt-1.11.0-marvin.patch +++ b/libgcrypt-1.11.0-marvin.patch @@ -759,17 +759,17 @@ index 245967eb..74055a4b 100644 static inline size_t ct_lt_s (size_t a, size_t b) @@ -112,6 +121,7 @@ unsigned int _gcry_ct_memequal (const void *b1, const void *b2, size_t len); - #endif DEFINE_CT_TYPE_GEN_MASK(uintptr, uintptr_t) DEFINE_CT_TYPE_GEN_MASK(ulong, unsigned long) + DEFINE_CT_TYPE_GEN_MASK(int16, int16_t) +DEFINE_CT_TYPE_GEN_MASK(uchar, unsigned char) /* * Return all bits set if A is 0 and return 1 otherwise. @@ -137,6 +147,7 @@ DEFINE_CT_TYPE_GEN_MASK(int16, int16_t) - #endif DEFINE_CT_TYPE_GEN_INV_MASK(uintptr, uintptr_t) DEFINE_CT_TYPE_GEN_INV_MASK(ulong, unsigned long) + DEFINE_CT_TYPE_GEN_INV_MASK(int16, int16_t) +DEFINE_CT_TYPE_GEN_INV_MASK(uchar, unsigned char) /* @@ -1582,9 +1582,9 @@ index 74055a4b..5e656e15 100644 static inline size_t @@ -164,6 +164,7 @@ DEFINE_CT_TYPE_GEN_INV_MASK(uchar, unsigned char) - } DEFINE_CT_TYPE_SELECT_FUNC(uintptr, uintptr_t) DEFINE_CT_TYPE_SELECT_FUNC(ulong, unsigned long) + DEFINE_CT_TYPE_SELECT_FUNC(int16, int16_t) +DEFINE_CT_TYPE_SELECT_FUNC(uchar, unsigned char) /* @@ -1969,7 +1969,7 @@ index ab070a94..a2153728 100644 { show_sexp ("sign result:\n", sig); fail ("mismatch in gcry_pk_sign\n"); -@@ -429,45 +431,89 @@ check_v15crypt (void) +@@ -429,44 +431,89 @@ check_v15crypt (void) size_t mesg_len, seed_len, encr_len; gcry_sexp_t plain, ciph; @@ -2018,7 +2018,7 @@ index ab070a94..a2153728 100644 + } - err = gcry_sexp_build (&plain, NULL, -- "(data (flags pkcs1)(hash-algo sha1)" +- "(data (flags pkcs1)" - "(value %b)(random-override %b))", - (int)mesg_len, mesg, - (int)seed_len, seed); @@ -2076,14 +2076,13 @@ index ab070a94..a2153728 100644 - plain = NULL; - - /* Now test the decryption. */ -- seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); - encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len); + gcry_sexp_release (ciph); + ciph = NULL; +#endif /* WITH_MARVIN_WORKAROUND */ err = gcry_sexp_build (&ciph, NULL, - "(enc-val (flags pkcs1)(hash-algo sha1)" + "(enc-val (flags pkcs1)" @@ -484,15 +530,19 @@ check_v15crypt (void) } else diff --git a/libgcrypt-1.11.0-pac-bti-protection.patch b/libgcrypt-1.11.0-pac-bti-protection.patch deleted file mode 100644 index 3c713ab..0000000 --- a/libgcrypt-1.11.0-pac-bti-protection.patch +++ /dev/null @@ -1,229 +0,0 @@ -From afdd68b162103820edb72ad170f8ee26f206b396 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Sun, 4 Aug 2024 18:51:34 +0300 -Subject: [PATCH] Add PAC/BTI support for AArch64 assembly - -* cipher/asm-common-aarch64.h (AARCH64_BTI_PROPERTY_FLAG) -(AARCH64_HINT_BTI_C, AARCH64_PAC_PROPERTY_FLAG) -(note.gnu.property): New. -(CFI_STARTPROC): Add AARCH64_HINT_BTI_C. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - cipher/asm-common-aarch64.h | 50 +++++++++++++++++++++++++++++++++++-- - 1 file changed, 48 insertions(+), 2 deletions(-) - -diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h -index 3a72d7c4..ff65ea6a 100644 ---- a/cipher/asm-common-aarch64.h -+++ b/cipher/asm-common-aarch64.h -@@ -45,9 +45,25 @@ - add reg, reg, #:lo12:name ; - #endif - -+#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 -+# define AARCH64_BTI_PROPERTY_FLAG (1 << 0) -+# define AARCH64_HINT_BTI_C \ -+ hint #34 -+#else -+# define AARCH64_BTI_PROPERTY_FLAG 0 /* No BTI */ -+# define AARCH64_HINT_BTI_C /*_*/ -+#endif -+ -+#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 3) != 0 -+/* PAC enabled, signed with either A or B key. */ -+# define AARCH64_PAC_PROPERTY_FLAG (1 << 1) -+#else -+# define AARCH64_PAC_PROPERTY_FLAG 0 /* No PAC */ -+#endif -+ - #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES - /* CFI directives to emit DWARF stack unwinding information. */ --# define CFI_STARTPROC() .cfi_startproc -+# define CFI_STARTPROC() .cfi_startproc; AARCH64_HINT_BTI_C - # define CFI_ENDPROC() .cfi_endproc - # define CFI_REMEMBER_STATE() .cfi_remember_state - # define CFI_RESTORE_STATE() .cfi_restore_state -@@ -89,7 +105,7 @@ - DW_SLEB128_28BIT(rsp_offs) - - #else --# define CFI_STARTPROC() -+# define CFI_STARTPROC() AARCH64_HINT_BTI_C - # define CFI_ENDPROC() - # define CFI_REMEMBER_STATE() - # define CFI_RESTORE_STATE() -@@ -129,4 +145,34 @@ - ldp d8, d9, [sp], #16; \ - CFI_ADJUST_CFA_OFFSET(-16); - -+#if (AARCH64_BTI_PROPERTY_FLAG | AARCH64_PAC_PROPERTY_FLAG) -+/* Generate PAC/BTI property for all assembly files including this header. -+ * -+ * libgcrypt support these extensions: -+ * - Armv8.3-A Pointer Authentication (PAC): -+ * As currently all AArch64 assembly functions are leaf functions and do -+ * not store/load link register LR, we just mark PAC as supported. -+ * -+ * - Armv8.5-A Branch Target Identification (BTI): -+ * All AArch64 assembly functions get branch target instruction through -+ * CFI_STARTPROC macro. -+ */ -+ELF(.section .note.gnu.property,"a") -+ELF(.balign 8) -+ELF(.long 1f - 0f) -+ELF(.long 4f - 1f) -+ELF(.long 5) -+ELF(0:) -+ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ -+ELF(1:) -+ELF(.balign 8) -+ELF(.long 0xc0000000) -+ELF(.long 3f - 2f) -+ELF(2:) -+ELF(.long (AARCH64_BTI_PROPERTY_FLAG | AARCH64_PAC_PROPERTY_FLAG)) -+ELF(3:) -+ELF(.balign 8) -+ELF(4:) -+#endif -+ - #endif /* GCRY_ASM_COMMON_AARCH64_H */ --- -2.43.0 - -From 07706d69f238f6a3bfc3f74145686a02decbee9c Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Mon, 5 Aug 2024 20:18:05 +0300 -Subject: [PATCH] Do not build 32-bit ARM assembly on Aarch64 - -* configure.ac: Build "serpent-armv7-neon", "salsa20-armv7-neon", -"chacha20-armv7-neon", "sha512-armv7-neon" and "keccak-armv7-neon" -only on 32-bit ARM. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - configure.ac | 54 ++++++++++++++++++++++++++++------------------------ - 1 file changed, 29 insertions(+), 25 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 191aa38d..2b6ddb7b 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3139,17 +3139,18 @@ if test "$found" = "1" ; then - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" - fi - ;; -+ arm*-*-*) -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-armv7-neon.lo" -+ fi -+ ;; - esac - - if test x"$avx512support" = xyes ; then - # Build with the AVX512 implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx512-x86.lo" - fi -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(rfc2268, $enabled_ciphers) -@@ -3230,12 +3231,13 @@ if test "$found" = "1" ; then - # Build with the assembly implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-amd64.lo" - ;; -+ arm*-*-*) -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-armv7-neon.lo" -+ fi -+ ;; - esac -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(gost28147, $enabled_ciphers) -@@ -3256,6 +3258,12 @@ if test "$found" = "1" ; then - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-amd64-avx2.lo" - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-amd64-avx512.lo" - ;; -+ arm*-*-*) -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-armv7-neon.lo" -+ fi -+ ;; - aarch64-*-*) - # Build with the assembly implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-aarch64.lo" -@@ -3282,11 +3290,6 @@ if test "$found" = "1" ; then - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-s390x.lo" - ;; - esac -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(sm4, $enabled_ciphers) -@@ -3491,6 +3494,11 @@ if test "$found" = "1" ; then - arm*-*-*) - # Build with the assembly implementation - GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-arm.lo" -+ -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-armv7-neon.lo" -+ fi - ;; - aarch64-*-*) - # Build with the assembly implementation -@@ -3510,11 +3518,6 @@ if test "$found" = "1" ; then - # Build with the crypto extension implementation - GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-ppc.lo" - esac -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(sha3, $enabled_digests) -@@ -3527,12 +3530,13 @@ if test "$found" = "1" ; then - # Build with the assembly implementation - GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-amd64-avx512.lo" - ;; -+ arm*-*-*) -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-armv7-neon.lo" -+ fi -+ ;; - esac -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(tiger, $enabled_digests) --- -2.43.0 - diff --git a/libgcrypt.spec b/libgcrypt.spec index eb5c8cb..4e539f6 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,19 +14,14 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.11.0 -Release: 5%{?dist} +Version: 1.11.1 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: https://gnupg.org/signature_key.asc # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch -# https://dev.gnupg.org/T7167 -Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch -# https://dev.gnupg.org/T7220 -Patch3: libgcrypt-1.11.0-cf-protection.patch -Patch4: libgcrypt-1.11.0-pac-bti-protection.patch # https://gitlab.com/redhat-crypto/libgcrypt/libgcrypt-mirror/-/merge_requests/19/ Patch5: libgcrypt-1.11.0-marvin.patch @@ -64,9 +59,6 @@ applications using libgcrypt. %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' %setup -q %patch 1 -p1 -%patch 2 -p1 -%patch 3 -p1 -%patch 4 -p1 %patch 5 -p1 %build @@ -98,10 +90,11 @@ make check # try in faked FIPS mode too LIBGCRYPT_FORCE_FIPS_MODE=1 make check -PROFILE=%{?dist} annocheck --ignore-unknown --verbose --profile=${PROFILE:1} $RPM_BUILD_ROOT%{gcrylibdir}/libgcrypt.so.20.5.0 +%define libpath $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname}.?.? + +PROFILE=%{?dist} annocheck --ignore-unknown --verbose --profile=${PROFILE:1} %{libpath} # Add generation of HMAC checksums of the final stripped binaries -%define libpath $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname}.?.? %define __spec_install_post \ %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ @@ -181,6 +174,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue May 13 2025 Jakub Jelen - 1.11.1-1 +- New upstream release (#2364878) + * Fri Jan 17 2025 Fedora Release Engineering - 1.11.0-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/sources b/sources index 4ef369d..a713620 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.11.0.tar.bz2) = 8e093e69e3c45d30838625ca008e995556f0d5b272de1c003d44ef94633bcc0d0ef5d95e8725eb531bfafb4490ac273488633e0c801200d4666194f86c3e270e -SHA512 (libgcrypt-1.11.0.tar.bz2.sig) = 8c5ceb50d70ccdedcc1ff4b31a65a07198567b85f582e3e67699cc3e5d012bebf7b1d4903652d11905a9cd845976ad7d3642474804777d0bdc46c6847d92fe38 +SHA512 (libgcrypt-1.11.1.tar.bz2) = 85846d62ce785e4250a2bf8a2b13ec24837e48ab8e10d537ad4a18d650d2cca747f82fd1501feab47ad3114b9593b36c9fa7a892f48139e2a71ef61295a47678 +SHA512 (libgcrypt-1.11.1.tar.bz2.sig) = a9b9e2466f32623f417574537656f776baf9a933fba96fd969dda26b6bf13864ee5765112654b269f79a7f20a4a0712cf8cec7be759966088045bca040e01edc From 891b7aeee36921d11a6a54959d7be5c3db613b1d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 24 Jul 2025 19:41:03 +0000 Subject: [PATCH 212/214] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 4e539f6..c4fac5c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.1 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -174,6 +174,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 24 2025 Fedora Release Engineering - 1.11.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Tue May 13 2025 Jakub Jelen - 1.11.1-1 - New upstream release (#2364878) From baffb13bdca386a97d06e7e8f758bbe182e4ba31 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Jul 2025 12:52:21 +0200 Subject: [PATCH 213/214] Migrate STI tests to fmf + update the test to actually work Resolves: #2382944 --- .fmf/version | 1 + tests/smoke-test/main.fmf | 25 +++++++++++++++++++++++ tests/smoke-test/runtest.sh | 40 ++++++++++++++++--------------------- tests/tests.yml | 20 ------------------- 4 files changed, 43 insertions(+), 43 deletions(-) create mode 100644 .fmf/version create mode 100644 tests/smoke-test/main.fmf delete mode 100644 tests/tests.yml diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/tests/smoke-test/main.fmf b/tests/smoke-test/main.fmf new file mode 100644 index 0000000..70bd1ba --- /dev/null +++ b/tests/smoke-test/main.fmf @@ -0,0 +1,25 @@ +summary: Test calls upstream test suite. +test: ./runtest.sh +enabled: true +framework: beakerlib +require: + - library(distribution/fips) +recommend: + - libgcrypt + - nfs-utils + - rpm-build + - autoconf + - automake + - libtool + - gawk + - gcc-c++ + - libgpg-error-devel + - pkgconfig + - texinfo + - fipscheck + - libkcapi-fipscheck + - crypto-policies-scripts + - bc + - annobin-annocheck + - gnupg2 +duration: 45m diff --git a/tests/smoke-test/runtest.sh b/tests/smoke-test/runtest.sh index ddd0182..0f5bc82 100755 --- a/tests/smoke-test/runtest.sh +++ b/tests/smoke-test/runtest.sh @@ -54,41 +54,35 @@ rlJournalStart rlRun "pushd $TOPDIR" 0 rlRun "rm -rf BUILD/libgcrypt-*" 0-255 rlRun "rpmbuild -vv -bc SPECS/libgcrypt.spec" 0 - rlRun "pushd BUILD/libgcrypt-*" 0 + libgcrypt_dir="libgcrypt-`rpm -q --qf "%{VERSION}\n" libgcrypt | head -1`" + if [ -d "BUILD/$libgcrypt_dir-build" ]; then + BUILDDIR="BUILD/$libgcrypt_dir-build/$libgcrypt_dir" + else + BUILDDIR="BUILD/$libgcrypt_dir" + fi + rlRun "pushd $BUILDDIR" 0 rlRun "fipshmac src/.libs/libgcrypt.so.??" 0 rlRun "popd" rlRun "popd" rlPhaseEnd rlPhaseStartTest "Upstream testsuite" - rlRun "pushd $TOPDIR/BUILD/libgcrypt-*" 0 + rlRun "pushd $TOPDIR/$BUILDDIR" 0 exp_fails=() - if [[ $fipsMode = 'enabled' ]]; then - if rlIsFedora 33; then - exp_fails+=("basic") - exp_fails+=("basic-disable-all-hwf") - exp_fails+=("t-kdf") - exp_fails+=("t-secmem") - elif rlIsFedora 34; then - exp_fails+=("basic") - exp_fails+=("basic-disable-all-hwf") - exp_fails+=("t-kdf") - exp_fails+=("t-secmem") - exp_fails+=("t-x448") - elif rlIsFedora 35; then # Fedora-35 - exp_fails+=("curves") - fi - fi + rlRun "echo 'Expecting ${#exp_fails[@]} fails'" exp_exitcode=0 if [[ ${#exp_fails[@]} -gt 0 ]]; then exp_exitcode=2; fi rlRun "make check &> $TmpDir/make_check.out" $exp_exitcode rlRun "grep ^FAIL: $TmpDir/make_check.out" 0,1 "Print fails" if [[ ${#exp_fails[@]} -gt 0 ]]; then - for f in "${exp_fails[@]}"; do - rlAssertGrep "^FAIL: $f\$" $TmpDir/make_check.out + for f in $(grep '^FAIL:' $TmpDir/make_check.out | awk -F ': ' '{print $2}'); do + if [[ "${exp_fails[@]}" =~ "$f" ]]; then + rlLog "$f failure is expected" + else + rlFail "$f failure is not expected" + fi done - [[ $(grep -c '^FAIL:' $TmpDir/make_check.out) -eq ${#exp_fails[@]} ]] || rlFail "Unexpected fails present" else rlRun "grep \"All [0-9]\+ tests passed\" $TmpDir/make_check.out" 0 \ "All tests passed" @@ -119,12 +113,12 @@ rlJournalStart for i in `seq 1 $N_SAMPLES`; do # run with HW optimizations ENAbled rm -f $HWF_DENY_FILE - $TOPDIR/BUILD/libgcrypt-*/tests/bench-slope $alg_type $algorithm |grep "$alg_line" >>$algorithm.ena + $TOPDIR/$BUILDDIR/tests/bench-slope $alg_type $algorithm |grep "$alg_line" >>$algorithm.ena # run with HW optimizations DISabled # this looks idiotic, but I wasn't able to make --disable-hwf work echo "all" >$HWF_DENY_FILE - $TOPDIR/BUILD/libgcrypt-*/tests/bench-slope $dis_arg $alg_type $algorithm |grep "$alg_line" >>$algorithm.dis + $TOPDIR/$BUILDDIR/tests/bench-slope $dis_arg $alg_type $algorithm |grep "$alg_line" >>$algorithm.dis done rlLogInfo "Performance measurements finished" rlRun "cat $algorithm.ena" diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index dd115e9..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,20 +0,0 @@ -- hosts: localhost - tags: - - classic - - container - roles: - - role: standard-test-beakerlib - tests: - - smoke-test - required_packages: - - fipscheck - - gawk - - gcc-c++ - - libgcrypt - - libgpg-error-devel - - libselinux-utils - - nfs-utils - - pkgconfig - - rpm-build - - texinfo - - wget From 42572cdcf22a43f0d0c562e7b9f97d046a9d97e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 3 Nov 2025 10:29:58 +0100 Subject: [PATCH 214/214] 1.11.2-1 --- .gitignore | 2 ++ libgcrypt.spec | 7 +++++-- sources | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 544f5c1..552f393 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.11.0.tar.bz2.sig /libgcrypt-1.11.1.tar.bz2 /libgcrypt-1.11.1.tar.bz2.sig +/libgcrypt-1.11.2.tar.bz2 +/libgcrypt-1.11.2.tar.bz2.sig diff --git a/libgcrypt.spec b/libgcrypt.spec index c4fac5c..23ec779 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,8 +14,8 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.11.1 -Release: 2%{?dist} +Version: 1.11.2 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -174,6 +174,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Mon Nov 03 2025 Jakub Jelen - 1.11.2-1 +- New upstream release (#2406804) + * Thu Jul 24 2025 Fedora Release Engineering - 1.11.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index a713620..90c992c 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.11.1.tar.bz2) = 85846d62ce785e4250a2bf8a2b13ec24837e48ab8e10d537ad4a18d650d2cca747f82fd1501feab47ad3114b9593b36c9fa7a892f48139e2a71ef61295a47678 -SHA512 (libgcrypt-1.11.1.tar.bz2.sig) = a9b9e2466f32623f417574537656f776baf9a933fba96fd969dda26b6bf13864ee5765112654b269f79a7f20a4a0712cf8cec7be759966088045bca040e01edc +SHA512 (libgcrypt-1.11.2.tar.bz2) = b706cea602cc8f0896e57ce979643bf78974b05faec27c1b053b773c57d8b04250e30e95a4ef5899e1df981d01d8d08f0a36e10b5820a5ec4183e74c02e5f1f0 +SHA512 (libgcrypt-1.11.2.tar.bz2.sig) = e63d240a9b97aa218c98c5baa72a30321ae85412d4a8748e36578bd9498fe8c8ee2ba84835d1783cdfc1e5dfb66b0a89409d6263e9c06f4cd11e919d4bce0cd2