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 001/118] 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 002/118] - 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 003/118] - 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 004/118] 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 005/118] 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 006/118] 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 007/118] 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 008/118] 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 009/118] 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 016bcc3e54b3022d0910c2942f5aab08b2881e4b Mon Sep 17 00:00:00 2001
From: Tomas Mraz
Date: Tue, 24 Oct 2017 11:22:10 +0200
Subject: [PATCH 010/118] new upstream version 1.7.9
---
.gitignore | 1 +
libgcrypt.spec | 5 ++++-
sources | 2 +-
3 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/.gitignore b/.gitignore
index 782e573..f823426 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.7.9-hobbled.tar.xz
diff --git a/libgcrypt.spec b/libgcrypt.spec
index f36f19d..fc93056 100644
--- a/libgcrypt.spec
+++ b/libgcrypt.spec
@@ -1,5 +1,5 @@
Name: libgcrypt
-Version: 1.7.8
+Version: 1.7.9
Release: 1%{?dist}
URL: http://www.gnupg.org/
Source0: libgcrypt-%{version}-hobbled.tar.xz
@@ -196,6 +196,9 @@ exit 0
%license COPYING
%changelog
+* Tue Oct 24 2017 Tomáš Mráz 1.7.9-1
+- new upstream version 1.7.9
+
* Thu Jun 29 2017 Tomáš Mráz 1.7.8-1
- new upstream version 1.7.8
diff --git a/sources b/sources
index 33c4cb4..64378c1 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (libgcrypt-1.7.8-hobbled.tar.xz) = 19c13ebdbd24657a9694702f91f045f5fb91b7b68eb4361a6abbb0c1bb90403cf8657d650cf97f9fd61d7ed571682181b34d35777d634187bfd0a78b2857efe1
+SHA512 (libgcrypt-1.7.9-hobbled.tar.xz) = 691138921366b8a4588dc96c6ecfd73d17b7a5114ab8fb06b510fa5f9a04e6ff3eba448b7809bf0e9017311882ccab25ff5e1c6569b790b22ddf7296f5c37dbf
From e16cfed1d68392a0917e8a0ce3014567dc033edf Mon Sep 17 00:00:00 2001
From: Tomas Mraz
Date: Mon, 4 Dec 2017 09:53:29 +0100
Subject: [PATCH 011/118] 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 012/118] 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 013/118] 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 014/118] 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 015/118] 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 016/118] 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 017/118] 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 018/118] 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 019/118] 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 020/118] 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 021/118] - 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 022/118] 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 023/118] 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 024/118] 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 025/118] 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 026/118] 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 027/118] - 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 028/118] 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 029/118] - 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 030/118] 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 031/118] 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 032/118] - 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 033/118] 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 034/118] 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 035/118] 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 036/118] 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 037/118] 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 038/118] 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 039/118] 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 040/118] 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 041/118] 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 042/118] 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 043/118] 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 044/118] 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 045/118] - 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 046/118] 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 047/118] 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 048/118] 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 049/118] 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 050/118] 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 051/118] 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 052/118] 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 053/118] 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 054/118] 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 055/118] 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