From 8c18517a2519c8acbf705612db701c063990ff59 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Thu, 23 Jan 2020 15:47:41 +0100 Subject: [PATCH 01/88] 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 02/88] - 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 03/88] 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 04/88] 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 05/88] 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 06/88] 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 07/88] 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 08/88] 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 09/88] 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 10/88] 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 11/88] 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 12/88] 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 13/88] 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 14/88] 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 15/88] - 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 16/88] 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 17/88] 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 18/88] 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 19/88] 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 20/88] 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 21/88] 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 22/88] 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 23/88] 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 24/88] 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 25/88] libgcrypt-1.9.1-1 --- .gitignore | 1 + ecc-curves.c | 28 +++++++++++++--- libgcrypt-1.7.3-fips-reqs.patch | 35 -------------------- libgcrypt-1.8.4-fips-keygen.patch | 9 +++-- libgcrypt-1.8.4-tests-fipsmode.patch | 2 +- libgcrypt-1.8.4-use-poll.patch | 6 ++-- libgcrypt-1.9.0-kdf-missing-terminator.patch | 31 ----------------- libgcrypt.spec | 11 +++--- sources | 2 +- 9 files changed, 37 insertions(+), 88 deletions(-) delete mode 100644 libgcrypt-1.7.3-fips-reqs.patch delete mode 100644 libgcrypt-1.9.0-kdf-missing-terminator.patch diff --git a/.gitignore b/.gitignore index fed427b..0288827 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.6-hobbled.tar.xz /libgcrypt-1.8.7-hobbled.tar.xz /libgcrypt-1.9.0-hobbled.tar.xz +/libgcrypt-1.9.1-hobbled.tar.xz diff --git a/ecc-curves.c b/ecc-curves.c index 4242117..a974bcf 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -1064,13 +1064,18 @@ mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags, if ((n+7)/8 != len) { - if ((n+7)/8 < len && ec->dialect == ECC_DIALECT_ED25519) + if (ec->dialect == ECC_DIALECT_ED25519) { /* * GnuPG (<= 2.2) or OpenPGP implementations with no * SOS support may remove zeros at the beginning. * Recover those zeros. */ + /* + * Also, GnuPG (<= 2.2) may add additional zero at + * the beginning, when private key is moved from + * OpenPGP to gpg-agent. Remove such a zero-prefix. + */ const unsigned char *buf; unsigned char *value; @@ -1078,13 +1083,26 @@ mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags, if (!buf) return GPG_ERR_INV_OBJ; - value = xtrycalloc_secure (1, len); + value = xtrymalloc_secure (len); if (!value) return gpg_err_code_from_syserror (); - memset (value, 0, len - (n+7)/8); - memcpy (value + len - (n+7)/8, buf, (n+7)/8); - mpi_set_opaque (ec->d, value, len); + if ((n+7)/8 < len) + /* Recover zeros. */ + { + memset (value, 0, len - (n+7)/8); + memcpy (value + len - (n+7)/8, buf, (n+7)/8); + } + else if ((n+7)/8 == len + 1) + /* Remove a zero. */ + memcpy (value, buf+1, len); + else + { + xfree (value); + return GPG_ERR_INV_OBJ; + } + + mpi_set_opaque (ec->d, value, len*8); } else { diff --git a/libgcrypt-1.7.3-fips-reqs.patch b/libgcrypt-1.7.3-fips-reqs.patch deleted file mode 100644 index ef7f765..0000000 --- a/libgcrypt-1.7.3-fips-reqs.patch +++ /dev/null @@ -1,35 +0,0 @@ -diff -up libgcrypt-1.7.3/src/visibility.c.fips-reqs libgcrypt-1.7.3/src/visibility.c ---- libgcrypt-1.7.3/src/visibility.c.fips-reqs 2016-03-23 12:59:34.000000000 +0100 -+++ libgcrypt-1.7.3/src/visibility.c 2016-11-22 16:29:36.992042480 +0100 -@@ -1288,6 +1288,8 @@ gcry_kdf_derive (const void *passphrase, - unsigned long iterations, - size_t keysize, void *keybuffer) - { -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); - return gpg_error (_gcry_kdf_derive (passphrase, passphraselen, algo, hashalgo, - salt, saltlen, iterations, - keysize, keybuffer)); -@@ -1343,6 +1345,13 @@ void - gcry_mpi_randomize (gcry_mpi_t w, - unsigned int nbits, enum gcry_random_level level) - { -+ if (!fips_is_operational ()) -+ { -+ (void)fips_not_operational (); -+ fips_signal_fatal_error ("called in non-operational state"); -+ fips_noreturn (); -+ } -+ - _gcry_mpi_randomize (w, nbits, level); - } - -@@ -1368,6 +1377,8 @@ gcry_prime_generate (gcry_mpi_t *prime, - gcry_random_level_t random_level, - unsigned int flags) - { -+ if (!fips_is_operational ()) -+ return gpg_error (fips_not_operational ()); - return gpg_error (_gcry_prime_generate (prime, prime_bits, factor_bits, - factors, cb_func, cb_arg, - random_level, flags)); diff --git a/libgcrypt-1.8.4-fips-keygen.patch b/libgcrypt-1.8.4-fips-keygen.patch index 9d3a647..a3e241f 100644 --- a/libgcrypt-1.8.4-fips-keygen.patch +++ b/libgcrypt-1.8.4-fips-keygen.patch @@ -1,16 +1,15 @@ diff -up libgcrypt-1.8.4/cipher/dsa.c.fips-keygen libgcrypt-1.8.4/cipher/dsa.c --- libgcrypt-1.8.4/cipher/dsa.c.fips-keygen 2017-11-23 19:16:58.000000000 +0100 +++ libgcrypt-1.8.4/cipher/dsa.c 2019-02-12 14:29:25.629513989 +0100 -@@ -457,11 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un +@@ -457,13 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un &prime_q, &prime_p, r_counter, r_seed, r_seedlen); - else -- ec = _gcry_generate_fips186_3_prime (nbits, qbits, NULL, 0, + else if (!domain->p || !domain->q) -+ ec = _gcry_generate_fips186_3_prime (nbits, qbits, -+ initial_seed.seed, -+ initial_seed.seedlen, + ec = _gcry_generate_fips186_3_prime (nbits, qbits, + initial_seed.seed, + initial_seed.seedlen, &prime_q, &prime_p, r_counter, r_seed, r_seedlen, NULL); diff --git a/libgcrypt-1.8.4-tests-fipsmode.patch b/libgcrypt-1.8.4-tests-fipsmode.patch index d6e29d1..a415d18 100644 --- a/libgcrypt-1.8.4-tests-fipsmode.patch +++ b/libgcrypt-1.8.4-tests-fipsmode.patch @@ -142,7 +142,7 @@ diff -up libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode libgcrypt-1.8.4/tests/pub " (use-fips186)" " (transient-key)" " (derive-parms" -- " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", +- " (seed #f770a4598ff756931fc529764513b103ce57d85f4ad8c5cf297c9b4d48241c5b#))))", + " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", 0, 1); if (rc) diff --git a/libgcrypt-1.8.4-use-poll.patch b/libgcrypt-1.8.4-use-poll.patch index d55b6a3..01dcf82 100644 --- a/libgcrypt-1.8.4-use-poll.patch +++ b/libgcrypt-1.8.4-use-poll.patch @@ -6,9 +6,9 @@ diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndli #include #include +#include - #if defined(__linux__) || !defined(HAVE_GETENTROPY) - #ifdef HAVE_SYSCALL - # include + #if defined(__APPLE__) && defined(__MACH__) + extern int getentropy (void *buf, size_t buflen) __attribute__ ((weak_import)); + #define HAVE_GETENTROPY @@ -241,9 +242,8 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) diff --git a/libgcrypt-1.9.0-kdf-missing-terminator.patch b/libgcrypt-1.9.0-kdf-missing-terminator.patch deleted file mode 100644 index 1d60f3f..0000000 --- a/libgcrypt-1.9.0-kdf-missing-terminator.patch +++ /dev/null @@ -1,31 +0,0 @@ -From: Jussi Kivilinna -Date: Tue, 19 Jan 2021 18:04:30 +0000 (+0200) -Subject: kdf: add missing null-terminator for self-test test-vector array -X-Git-Url: http://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=commitdiff_plain;h=c6425a5537294dfe2beaafc9105f7af4ceac677f - -kdf: add missing null-terminator for self-test test-vector array - -* cipher/kdf.c (selftest_pbkdf2): Add null-terminator to TV array. --- - -This was causing kdf self-test to fail on s390x builds. - -GnuPG-bug-id: 5254 -Signed-off-by: Jussi Kivilinna ---- - -diff --git a/cipher/kdf.c b/cipher/kdf.c -index 3d707bd0..b916a3f8 100644 ---- a/cipher/kdf.c -+++ b/cipher/kdf.c -@@ -452,7 +452,8 @@ selftest_pbkdf2 (int extended, selftest_report_func_t report) - "\x34\x8c\x89\xdb\xcb\xd3\x2b\x2f\x32\xd8\x14\xb8\x11\x6e\x84\xcf" - "\x2b\x17\x34\x7e\xbc\x18\x00\x18\x1c\x4e\x2a\x1f\xb8\xdd\x53\xe1" - "\xc6\x35\x51\x8c\x7d\xac\x47\xe9" -- } -+ }, -+ { NULL } - }; - const char *what; - const char *errtxt; - diff --git a/libgcrypt.spec b/libgcrypt.spec index 3cc62db..971a4b1 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.9.0 +Version: 1.9.1 Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -36,8 +36,6 @@ Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch Patch14: libgcrypt-1.7.3-ecc-test-fix.patch # Run the FIPS mode initialization in the shared library constructor Patch18: libgcrypt-1.8.3-fips-ctor.patch -# Block some operations if in FIPS non-operational state -Patch22: libgcrypt-1.7.3-fips-reqs.patch # Do not try to open /dev/urandom if getrandom() works Patch24: libgcrypt-1.8.5-getrandom.patch # Continuous FIPS entropy test @@ -46,8 +44,6 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch -# Missing terminator in the kdf vectors causing s390x builds failing -Patch31: libgcrypt-1.9.0-kdf-missing-terminator.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -92,12 +88,10 @@ applications using libgcrypt. %patch13 -p1 -b .gccopt %patch14 -p1 -b .eccfix %patch18 -p1 -b .fips-ctor -%patch22 -p1 -b .fips-reqs %patch24 -p1 -b .getrandom %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module -%patch31 -p1 -b .kdf-terminator cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ @@ -207,6 +201,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Fri Jan 29 2021 Jakub Jelen - 1.9.1-1 +- New upstream release (#1922156, #1922097) + * Wed Jan 20 2021 Jakub Jelen - 1.9.0-1 - New upstream release (#1917878) diff --git a/sources b/sources index 69b2536..3fb2e74 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.0-hobbled.tar.xz) = d4ea9a1b732b05f605f0c99dd2b1e9747539bf2b6a8ff2fad7ab5350888f68b7f0b94bdd9253356ec9c8e6d3b87b5c76bc8dc4fbb3950acd8354b691f1f2ad3e +SHA512 (libgcrypt-1.9.1-hobbled.tar.xz) = 87c474c7b5054d7d6c75ca0d2458b2be197d7b8131b1e0a2017f391287a9e7bca666a9ac743c24210df869839518294c0091858245c96d10c5856f2473f35943 From af59e404ea6d424994d28f56e5067c555a5c6a98 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 17 Feb 2021 13:01:13 +0100 Subject: [PATCH 26/88] libgcrypt-1.9.2-1 --- .gitignore | 1 + libgcrypt-1.8.4-use-poll.patch | 4 ++-- libgcrypt.spec | 5 ++++- sources | 2 +- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 0288827..9fe7a79 100644 --- a/.gitignore +++ b/.gitignore @@ -25,3 +25,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.8.7-hobbled.tar.xz /libgcrypt-1.9.0-hobbled.tar.xz /libgcrypt-1.9.1-hobbled.tar.xz +/libgcrypt-1.9.2-hobbled.tar.xz diff --git a/libgcrypt-1.8.4-use-poll.patch b/libgcrypt-1.8.4-use-poll.patch index 01dcf82..8032992 100644 --- a/libgcrypt-1.8.4-use-poll.patch +++ b/libgcrypt-1.8.4-use-poll.patch @@ -7,8 +7,8 @@ diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndli #include +#include #if defined(__APPLE__) && defined(__MACH__) - extern int getentropy (void *buf, size_t buflen) __attribute__ ((weak_import)); - #define HAVE_GETENTROPY + #include + #ifdef __MAC_10_11 @@ -241,9 +242,8 @@ _gcry_rndlinux_gather_random (void (*add return with something we will actually use 100ms. */ while (length) diff --git a/libgcrypt.spec b/libgcrypt.spec index 971a4b1..470bf62 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.9.1 +Version: 1.9.2 Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz @@ -201,6 +201,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Feb 17 2021 Jakub Jelen - 1.9.2-1 +- New upstream release (#1929630) + * Fri Jan 29 2021 Jakub Jelen - 1.9.1-1 - New upstream release (#1922156, #1922097) diff --git a/sources b/sources index 3fb2e74..9ebeb2d 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.1-hobbled.tar.xz) = 87c474c7b5054d7d6c75ca0d2458b2be197d7b8131b1e0a2017f391287a9e7bca666a9ac743c24210df869839518294c0091858245c96d10c5856f2473f35943 +SHA512 (libgcrypt-1.9.2-hobbled.tar.xz) = b89f1e2ea76a6efb5e503264b4ebd843f410e188cf4fad4da4607ae77b247349f031e1e8e4340f4d3d0b03197f110e14dcca9d693f8971c086f6d8be3de403e6 From 713d2850dd617b21469c65af6de98f1e1fcc57bf Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 29 Mar 2021 19:45:10 +0200 Subject: [PATCH 27/88] Fix OCB tag creation on s390x --- libgcrypt-1.9.2-s390x-ocb.patch | 253 ++++++++++++++++++++++++++++++++ libgcrypt.spec | 3 + 2 files changed, 256 insertions(+) create mode 100644 libgcrypt-1.9.2-s390x-ocb.patch diff --git a/libgcrypt-1.9.2-s390x-ocb.patch b/libgcrypt-1.9.2-s390x-ocb.patch new file mode 100644 index 0000000..e7ff8e3 --- /dev/null +++ b/libgcrypt-1.9.2-s390x-ocb.patch @@ -0,0 +1,253 @@ +From 56da81ac47209dc41af08a129f5e0c15538261b2 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Thu, 25 Mar 2021 19:33:44 +0200 +Subject: [PATCH 1/3] tests/basic: add decryption check to + check_ocb_cipher_checksum + +* tests/basic.c (check_ocb_cipher_checksum): Add decryption. +-- + +GnuPG-bug-id: T5356 +Signed-off-by: Jussi Kivilinna +--- + tests/basic.c | 32 +++++++++++++++++++++++++++++++- + 1 file changed, 31 insertions(+), 1 deletion(-) + +diff --git a/tests/basic.c b/tests/basic.c +index 9a7e33cc..b39b901a 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -6800,9 +6800,10 @@ check_ocb_cipher_checksum (int algo, int keylen) + const size_t buflen = 128 * 16; + unsigned char *inbuf, *outbuf; + gpg_error_t err = 0; +- gcry_cipher_hd_t hde, hde2; ++ gcry_cipher_hd_t hde, hde2, hdd; + unsigned char tag[16]; + unsigned char tag2[16]; ++ unsigned char tag3[16]; + int i; + + inbuf = xmalloc(buflen); +@@ -6833,6 +6834,8 @@ check_ocb_cipher_checksum (int algo, int keylen) + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) + err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); ++ if (!err) ++ err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); + if (err) + { + fail ("cipher-ocb, gcry_cipher_open failed (checksum, algo %d): %s\n", +@@ -6843,24 +6846,30 @@ check_ocb_cipher_checksum (int algo, int keylen) + err = gcry_cipher_setkey (hde, key, keylen); + if (!err) + err = gcry_cipher_setkey (hde2, key, keylen); ++ if (!err) ++ err = gcry_cipher_setkey (hdd, key, keylen); + if (err) + { + fail ("cipher-ocb, gcry_cipher_setkey failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); ++ gcry_cipher_close (hdd); + goto out_free; + } + + err = gcry_cipher_setiv (hde, nonce, 12); + if (!err) + err = gcry_cipher_setiv (hde2, nonce, 12); ++ if (!err) ++ err = gcry_cipher_setiv (hdd, nonce, 12); + if (err) + { + fail ("cipher-ocb, gcry_cipher_setiv failed (checksum, algo %d): %s\n", + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); ++ gcry_cipher_close (hdd); + goto out_free; + } + +@@ -6876,6 +6885,14 @@ check_ocb_cipher_checksum (int algo, int keylen) + if (!err) + err = gcry_cipher_encrypt (hde2, outbuf + i, 16, inbuf + i, 16); + } ++ if (!err) ++ { ++ err = gcry_cipher_final (hdd); ++ } ++ if (!err) ++ { ++ err = gcry_cipher_decrypt (hdd, outbuf, buflen, outbuf, buflen); ++ } + + if (err) + { +@@ -6883,6 +6900,7 @@ check_ocb_cipher_checksum (int algo, int keylen) + algo, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hde2); ++ gcry_cipher_close (hdd); + goto out_free; + } + +@@ -6899,14 +6917,26 @@ check_ocb_cipher_checksum (int algo, int keylen) + fail ("cipher_ocb, gcry_cipher_gettag failed (checksum2, algo %d): %s\n", + algo, gpg_strerror (err)); + } ++ err = gcry_cipher_gettag (hdd, tag3, 16); ++ if (err) ++ { ++ fail ("cipher_ocb, gcry_cipher_gettag failed (checksum3, algo %d): %s\n", ++ algo, gpg_strerror (err)); ++ } + if (memcmp (tag, tag2, 16)) + { + mismatch (tag, 16, tag2, 16); + fail ("cipher-ocb, encrypt tag mismatch (checksum, algo %d)\n", algo); + } ++ if (memcmp (tag, tag3, 16)) ++ { ++ mismatch (tag, 16, tag3, 16); ++ fail ("cipher-ocb, decrypt tag mismatch (checksum, algo %d)\n", algo); ++ } + + gcry_cipher_close (hde); + gcry_cipher_close (hde2); ++ gcry_cipher_close (hdd); + + out_free: + xfree(inbuf); +-- +2.27.0 + +From 21c273cecfd58408b8d3287f5bc8c246c3010313 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Thu, 25 Mar 2021 19:43:41 +0200 +Subject: [PATCH 2/3] tests/basic: OCB large buffer check: make input buffer + non-repeatable + +* tests/basic.c (check_ocb_cipher_largebuf_split): Use SHA1 to +initialize input buffer. +(check_ocb_cipher): Update largebuf test vectors. +-- + +GnuPG-bug-id: T5356 +Signed-off-by: Jussi Kivilinna +--- + tests/basic.c | 36 +++++++++++++++++++++++------------- + 1 file changed, 23 insertions(+), 13 deletions(-) + +diff --git a/tests/basic.c b/tests/basic.c +index b39b901a..f9ada8ef 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -6630,8 +6630,18 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, + return; + } + +- for (i = 0; i < buflen; i++) +- inbuf[i] = (unsigned int)(i + 181081) * 5039U; ++ for (i = 0; i < buflen; i += 16) ++ { ++ unsigned char hash[20]; ++ unsigned char ctr[4]; ++ ++ ctr[0] = (i >> 0) & 0xff; ++ ctr[1] = (i >> 8) & 0xff; ++ ctr[2] = (i >> 16) & 0xff; ++ ctr[3] = (i >> 24) & 0xff; ++ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, ctr, sizeof(ctr)); ++ memcpy(inbuf + i, hash, 16); ++ } + + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) +@@ -7200,27 +7210,27 @@ check_ocb_cipher (void) + + /* Check large buffer encryption/decryption. */ + check_ocb_cipher_largebuf(GCRY_CIPHER_AES, 16, +- "\xc1\x5b\xf1\x80\xa4\xd5\xea\xfd\xae\x17\xa6\xcd\x6b\x10\xa8\xea"); ++ "\x4a\x00\x7f\x8d\xbe\x38\x32\x48\xb2\x2f\x7f\x27\xd8\x15\x7f\xb0"); + check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32, +- "\x2b\xb7\x25\x6b\x77\xc7\xfb\x21\x5c\xc9\x6c\x36\x17\x1a\x1a\xd5"); ++ "\xec\xc5\xe9\x2b\x24\x91\xba\x64\xbc\xe3\x62\xb6\x83\x20\xad\xbd"); + check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16, +- "\xe0\xae\x3f\x29\x3a\xee\xd8\xe3\xf2\x20\xc1\xa2\xd8\x72\x12\xd9"); ++ "\xd5\xbd\x76\xec\x75\x4a\xab\x6c\x13\xec\x87\x95\x11\xd4\xf0\x3d"); + check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24, +- "\xd7\x98\x71\xcf\x19\x5c\xa3\x3d\x6c\xfc\xc9\xbe\x9f\x13\x6b\xbd"); ++ "\xde\xdd\x6b\xbf\xce\x15\x01\x39\x7c\xc5\x69\x19\x72\xa2\x67\x23"); + check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32, +- "\x03\xf6\xec\x1a\x0e\xae\x66\x24\x2b\xba\x26\x0f\xb3\xb3\x1f\xb9"); ++ "\x0c\xf3\xd5\x82\x20\x73\xee\x0f\xbd\x6b\x32\x38\xf9\x10\xef\xe5"); + check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16, +- "\x1c\xf9\xc7\xfc\x3a\x32\xac\xc7\x5e\x0a\xc2\x5c\x90\xd6\xf6\xf9"); ++ "\x54\x87\x68\xb6\x17\xe6\xd7\xa6\x76\x0d\x7e\x9f\x57\x8b\xec\x88"); + check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32, +- "\x53\x02\xc8\x0d\x4e\x9a\x44\x9e\x43\xd4\xaa\x06\x30\x93\xcc\x16"); ++ "\x0b\xc3\x93\x52\xfa\x97\x22\xe6\x88\x6e\x29\x4d\x77\x35\x48\x84"); + check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16, +- "\xd3\x64\xac\x40\x48\x88\x77\xe2\x41\x26\x4c\xde\x21\x29\x21\x8d"); ++ "\x7e\x49\x3b\xd6\xde\x6e\x9e\x53\x67\xcd\x00\xad\xc9\xd9\xa5\xbc"); + check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24, +- "\x99\xeb\x35\xb0\x62\x4e\x7b\xf1\x5e\x9f\xed\x32\x78\x90\x0b\xd0"); ++ "\x1e\x33\x0e\x06\xc8\x27\x6a\x0b\x41\x5e\x93\xae\x39\xf4\x50\x12"); + check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32, +- "\x71\x66\x2f\x68\xbf\xdd\xcc\xb1\xbf\x81\x56\x5f\x01\x73\xeb\x44"); ++ "\x6b\x4c\x3f\x8f\x77\x75\xf2\x4d\xaf\xde\x2c\x5f\x1a\x80\xb8\x4d"); + check_ocb_cipher_largebuf(GCRY_CIPHER_SM4, 16, +- "\x2c\x0b\x31\x0b\xf4\x71\x9b\x01\xf4\x18\x5d\xf1\xe9\x3d\xed\x6b"); ++ "\x3c\x32\x54\x5d\xc5\x17\xa1\x16\x3f\x8e\xc7\x1d\x8d\x8b\x2d\xb0"); + + /* Check that the AAD data is correctly buffered. */ + check_ocb_cipher_splitaad (); +-- +2.27.0 + +From 68bb0ddc5504c9c0f3f52259a4085bb2fc1a02ad Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Thu, 25 Mar 2021 19:52:23 +0200 +Subject: [PATCH 3/3] rijndael-s390x: fix checksum calculation in OCB + decryption + +* cipher/rijndael-s390x.c (aes_s390x_ocb_dec): Calculate checksum +after decryption instead of inlining. +-- + +OCB decryption was missing checksum inlining in 64 block loop. + +GnuPG-bug-id: T5356 +Signed-off-by: Jussi Kivilinna +--- + cipher/rijndael-s390x.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/cipher/rijndael-s390x.c b/cipher/rijndael-s390x.c +index aea65c5a..c3da9fb2 100644 +--- a/cipher/rijndael-s390x.c ++++ b/cipher/rijndael-s390x.c +@@ -777,9 +777,7 @@ aes_s390x_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, + OCB_INPUT_4((n) + 12); + + #define OCB_OUTPUT(n) \ +- cipher_block_xor_1 (&blocks[n], outbuf + (n) * BLOCKSIZE, BLOCKSIZE); \ +- cipher_block_xor_1 (c->u_ctr.ctr, &blocks[n], BLOCKSIZE); \ +- cipher_block_cpy (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE); ++ cipher_block_xor_1 (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE); + + #define OCB_OUTPUT_4(n) \ + OCB_OUTPUT((n) + 0); OCB_OUTPUT((n) + 1); OCB_OUTPUT((n) + 2); \ +@@ -895,6 +893,8 @@ aes_s390x_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, + if (max_blocks_used) + wipememory (&blocks, max_blocks_used * BLOCKSIZE); + ++ aes_s390x_ocb_checksum (c->u_ctr.ctr, outbuf_arg, nblocks_arg); ++ + return 0; + } + +-- +2.27.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index 470bf62..d854c4a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -44,6 +44,8 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch +# Unbreak gnupg2 build on s390x: https://dev.gnupg.org/T5356 +Patch31: libgcrypt-1.9.2-s390x-ocb.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -92,6 +94,7 @@ applications using libgcrypt. %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module +%patch31 -p1 -b .s390x-ocb cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ From 643055c06da6b5f5d720aba61a57827bab556995 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 29 Mar 2021 19:47:55 +0200 Subject: [PATCH 28/88] libgcrypt-1.9.2-2 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index d854c4a..e93314f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.2 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -204,6 +204,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Mon Mar 29 2021 Jakub Jelen - 1.9.2-2 +- Fix OCB tag creation on s390x (failing gnupg2 tests) + * Wed Feb 17 2021 Jakub Jelen - 1.9.2-1 - New upstream release (#1929630) From 2e2a35ecb333567f912ce2460ff3b27d2b22927f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 15 Apr 2021 10:58:31 +0200 Subject: [PATCH 29/88] Fix coverity reports --- libgcrypt-1.9.2-coverity.patch | 55 ++++++++++++++++++++++++++++++++++ libgcrypt.spec | 3 ++ 2 files changed, 58 insertions(+) create mode 100644 libgcrypt-1.9.2-coverity.patch diff --git a/libgcrypt-1.9.2-coverity.patch b/libgcrypt-1.9.2-coverity.patch new file mode 100644 index 0000000..6673081 --- /dev/null +++ b/libgcrypt-1.9.2-coverity.patch @@ -0,0 +1,55 @@ +commit a8d6c6c1b258548260748eefba0532fd35c8ce47 +Author: NIIBE Yutaka +Date: Thu Apr 15 16:08:24 2021 +0900 + + cipher: Fix memory leaks for EdDSA. + + * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Free the point Q. + (_gcry_ecc_eddsa_verify): Avoid memory leaks for points and MPIs. + + -- + + GnuPG-bug-id: 5385 + Co-authored-by: Jakub Jelen + Signed-off-by: NIIBE Yutaka + +diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c +index 2a1a8907..8b32545a 100644 +--- a/cipher/ecc-eddsa.c ++++ b/cipher/ecc-eddsa.c +@@ -641,7 +641,10 @@ _gcry_ecc_eddsa_genkey (mpi_ec_t ec, int flags) + ec->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8); + rc = _gcry_ecc_eddsa_compute_h_d (&hash_d, ec); + if (rc) +- goto leave; ++ { ++ point_free (&Q); ++ goto leave; ++ } + + _gcry_mpi_set_buffer (a, hash_d, b, 0); + xfree (hash_d); +@@ -991,11 +994,6 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec, + if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in)) + return GPG_ERR_INV_DATA; + +- point_init (&Ia); +- point_init (&Ib); +- h = mpi_new (0); +- s = mpi_new (0); +- + b = (ec->nbits+7)/8; + + if (ec->nbits == 255) +@@ -1005,6 +1003,11 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec, + else + return GPG_ERR_NOT_IMPLEMENTED; + ++ point_init (&Ia); ++ point_init (&Ib); ++ h = mpi_new (0); ++ s = mpi_new (0); ++ + /* Encode and check the public key. */ + rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0, + &encpk, &encpklen); diff --git a/libgcrypt.spec b/libgcrypt.spec index e93314f..99c21cb 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -46,6 +46,8 @@ Patch27: libgcrypt-1.8.3-md-fips-enforce.patch Patch30: libgcrypt-1.8.5-fips-module.patch # Unbreak gnupg2 build on s390x: https://dev.gnupg.org/T5356 Patch31: libgcrypt-1.9.2-s390x-ocb.patch +# Coverity reported issues https://dev.gnupg.org/T5385 +Patch32: libgcrypt-1.9.2-coverity.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -95,6 +97,7 @@ applications using libgcrypt. %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module %patch31 -p1 -b .s390x-ocb +%patch32 -p1 -b .coverity cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} tests/ From a8c423ec7b73afeab9f832791a871bd0e327896d Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 15 Apr 2021 10:59:36 +0200 Subject: [PATCH 30/88] libgcrypt-1.9.2-3 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 99c21cb..ed7666d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.2 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -207,6 +207,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Apr 15 2021 Jakub Jelen - 1.9.2-3 +- Fix issues reported by coverity + * Mon Mar 29 2021 Jakub Jelen - 1.9.2-2 - Fix OCB tag creation on s390x (failing gnupg2 tests) From e8a3eea4344c56843ef6f1844b549bb63059b6a4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Apr 2021 11:35:10 +0200 Subject: [PATCH 31/88] libgcrypt-1.9.3-1 --- hobble-libgcrypt | 1 + keygrip.c | 341 ++++++++++++++++++++++++++++++++ libgcrypt-1.9.2-coverity.patch | 55 ------ libgcrypt-1.9.2-s390x-ocb.patch | 253 ------------------------ libgcrypt.spec | 16 +- 5 files changed, 349 insertions(+), 317 deletions(-) create mode 100644 keygrip.c delete mode 100644 libgcrypt-1.9.2-coverity.patch delete mode 100644 libgcrypt-1.9.2-s390x-ocb.patch diff --git a/hobble-libgcrypt b/hobble-libgcrypt index cc53cc1..3c76f73 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -9,3 +9,4 @@ set -e -x rm -f cipher/ecc-curves.c rm -f tests/curves.c rm -f tests/t-mpi-point.c +rm -f tests/keygrip.c diff --git a/keygrip.c b/keygrip.c new file mode 100644 index 0000000..56fbba8 --- /dev/null +++ b/keygrip.c @@ -0,0 +1,341 @@ +/* keygrip.c - verifies that keygrips are calculated as expected + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include + +#define PGM "keygrip" +#include "t-common.h" + +static int repetitions; + + + +static void +print_hex (const char *text, const void *buf, size_t n) +{ + const unsigned char *p = buf; + + fputs (text, stdout); + for (; n; n--, p++) + printf ("%02X", *p); + putchar ('\n'); +} + + + + +static struct +{ + int algo; + const char *key; + const unsigned char grip[20]; +} key_grips[] = + { + { + GCRY_PK_RSA, + "(private-key" + " (rsa" + " (n #00B6B509596A9ECABC939212F891E656A626BA07DA8521A9CAD4C08E640C04052FBB87F424EF1A0275A48A9299AC9DB69ABE3D0124E6C756B1F7DFB9B842D6251AEA6EE85390495CADA73D671537FCE5850A932F32BAB60AB1AC1F852C1F83C625E7A7D70CDA9EF16D5C8E47739D77DF59261ABE8454807FF441E143FBD37F8545#)" + " (e #010001#)" + " (d #077AD3DE284245F4806A1B82B79E616FBDE821C82D691A65665E57B5FAD3F34E67F401E7BD2E28699E89D9C496CF821945AE83AC7A1231176A196BA6027E77D85789055D50404A7A2A95B1512F91F190BBAEF730ED550D227D512F89C0CDB31AC06FA9A19503DDF6B66D0B42B9691BFD6140EC1720FFC48AE00C34796DC899E5#)" + " (p #00D586C78E5F1B4BF2E7CD7A04CA091911706F19788B93E44EE20AAF462E8363E98A72253ED845CCBF2481BB351E8557C85BCFFF0DABDBFF8E26A79A0938096F27#)" + " (q #00DB0CDF60F26F2A296C88D6BF9F8E5BE45C0DDD713C96CC73EBCB48B061740943F21D2A93D6E42A7211E7F02A95DCED6C390A67AD21ECF739AE8A0CA46FF2EBB3#)" + " (u #33149195F16912DB20A48D020DBC3B9E3881B39D722BF79378F6340F43148A6E9FC5F53E2853B7387BA4443BA53A52FCA8173DE6E85B42F9783D4A7817D0680B#)))", + "\x32\xCF\xFA\x85\xB1\x79\x1F\xBB\x26\x14\xE9\x1A\xFD\xF3\xAF\xE3\x32\x08\x2E\x25" + }, + { + GCRY_PK_DSA, + " (public-key" + " (dsa" + " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" + " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" + " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" + " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)))", + "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" + + }, + { + GCRY_PK_DSA, + "(private-key" + " (dsa" + " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" + " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" + " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" + " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)" + " (x #0087F9E91BFBCC1163DE71ED86D557708E32F8ADDE#)))", + "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa(flags param)" + " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" + " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)" + " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" + " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" + " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa(flags param)" + " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" + " (curve \"NIST P-256\")" + " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" + " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" + " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa" + " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" + " (curve \"NIST P-256\")" + " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" + " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" + " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (h #000000000000000000000000000000000000000000000000000000000000000001#)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa" + " (curve secp256r1)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve secp256r1)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { /* Ed25519 standard */ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Ed25519)" + " (q #04" + " 1CC662926E7EFF4982B7FB8B928E61CD74CCDD85277CC57196C3AD20B611085F" + " 47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)" + " ))", + "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8" + "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1" + }, + { /* Ed25519+EdDSA */ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Ed25519)(flags eddsa)" + " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" + " ))", + "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" + "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" + }, + { /* Ed25519+EdDSA (with compression prefix) */ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Ed25519)(flags eddsa)" + " (q #40" + " 773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" + " ))", + "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" + "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" + }, + { /* Ed25519+EdDSA (same but uncompressed)*/ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Ed25519)(flags eddsa)" + " (q #04" + " 629ad237d1ed04dcd4abe1711dd699a1cf51b1584c4de7a4ef8b8a640180b26f" + " 5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)" + " ))", + "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" + "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" + }, + { /* Cv25519 */ + GCRY_PK_ECC, + "(public-key" + " (ecc" + " (curve Curve25519)(flags djb-tweak)" + " (q #40" + " 918C1733127F6BF2646FAE3D081A18AE77111C903B906310B077505EFFF12740#)" + " ))", + "\x0F\x89\xA5\x65\xD3\xEA\x18\x7C\xE8\x39" + "\x33\x23\x98\xF5\xD4\x80\x67\x7D\xF4\x9C" + }, + { /* Random key */ + GCRY_PK_RSA, + "(shadowed-private-key" + " (rsa" + " (n #00B493C79928398DA9D99AC0E949FE6EB62F683CB974FFFBFBC01066F5C9A89B" + " D3DC48EAD7C65F36EA943C2B2C865C26C4884FF9EDFDA8C99C855B737D77EEF6" + " B85DBC0CCEC0E900C1F89A6893A2A93E8B31028469B6927CEB2F08687E547C68" + " 6B0A2F7E50A194FF7AB7637E03DE0912EF7F6E5F1EC37625BD1620CCC2E7A564" + " 31E168CDAFBD1D9E61AE47A69A6FA03EF22F844528A710B2392F262B95A3078C" + " F321DC8325F92A5691EF69F34FD0DE0B22C79D29DC87723FCADE463829E8E5F7" + " D196D73D6C9C180F6A6A0DDBF7B9D8F7FA293C36163B12199EF6A1A95CAE4051" + " E3069C522CC6C4A7110F663A5DAD20F66C13A1674D050088208FAE4F33B3AB51" + " 03#)" + " (e #00010001#)" + " (shadowed t1-v1" + " (#D2760001240102000005000123350000# OPENPGP.1)" + ")))", + "\xE5\x6E\xE6\xEE\x5A\x2F\xDC\x3E\x98\x9D" + "\xFE\x49\xDA\xF5\x67\x43\xE3\x27\x28\x33" + } + }; + + +static void +check (void) +{ + unsigned char buf[20]; + unsigned char *ret; + gcry_error_t err; + gcry_sexp_t sexp; + unsigned int i; + int repn; + + for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++) + { + if (gcry_pk_test_algo (key_grips[i].algo)) + { + if (verbose) + fprintf (stderr, "algo %d not available; test skipped\n", + key_grips[i].algo); + continue; + } + err = gcry_sexp_sscan (&sexp, NULL, key_grips[i].key, + strlen (key_grips[i].key)); + if (err) + die ("scanning data %d failed: %s\n", i, gpg_strerror (err)); + + if (debug) + info ("check(%d): s-exp='%s'\n", i, key_grips[i].key); + + for (repn=0; repn < repetitions; repn++) + { + ret = gcry_pk_get_keygrip (sexp, buf); + if (!ret) + die ("gcry_pk_get_keygrip failed for %d\n", i); + + if ( memcmp (key_grips[i].grip, buf, sizeof (buf)) ) + { + print_hex ("keygrip: ", buf, sizeof buf); + die ("keygrip for %d does not match\n", i); + } + else if (debug && !repn) + print_hex ("keygrip: ", buf, sizeof buf); + } + + gcry_sexp_release (sexp); + } +} + + + +static void +progress_handler (void *cb_data, const char *what, int printchar, + int current, int total) +{ + (void)cb_data; + (void)what; + (void)current; + (void)total; + + putchar (printchar); +} + +int +main (int argc, char **argv) +{ + int last_argc = -1; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--verbose")) + { + verbose = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose = 1; + debug = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--repetitions")) + { + argc--; argv++; + if (argc) + { + repetitions = atoi(*argv); + argc--; argv++; + } + } + } + + if (repetitions < 1) + repetitions = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_set_progress_handler (progress_handler, NULL); + + xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + if (debug) + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); + + check (); + + return 0; +} diff --git a/libgcrypt-1.9.2-coverity.patch b/libgcrypt-1.9.2-coverity.patch deleted file mode 100644 index 6673081..0000000 --- a/libgcrypt-1.9.2-coverity.patch +++ /dev/null @@ -1,55 +0,0 @@ -commit a8d6c6c1b258548260748eefba0532fd35c8ce47 -Author: NIIBE Yutaka -Date: Thu Apr 15 16:08:24 2021 +0900 - - cipher: Fix memory leaks for EdDSA. - - * cipher/ecc-eddsa.c (_gcry_ecc_eddsa_genkey): Free the point Q. - (_gcry_ecc_eddsa_verify): Avoid memory leaks for points and MPIs. - - -- - - GnuPG-bug-id: 5385 - Co-authored-by: Jakub Jelen - Signed-off-by: NIIBE Yutaka - -diff --git a/cipher/ecc-eddsa.c b/cipher/ecc-eddsa.c -index 2a1a8907..8b32545a 100644 ---- a/cipher/ecc-eddsa.c -+++ b/cipher/ecc-eddsa.c -@@ -641,7 +641,10 @@ _gcry_ecc_eddsa_genkey (mpi_ec_t ec, int flags) - ec->d = _gcry_mpi_set_opaque (NULL, dbuf, dlen*8); - rc = _gcry_ecc_eddsa_compute_h_d (&hash_d, ec); - if (rc) -- goto leave; -+ { -+ point_free (&Q); -+ goto leave; -+ } - - _gcry_mpi_set_buffer (a, hash_d, b, 0); - xfree (hash_d); -@@ -991,11 +994,6 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec, - if (!mpi_is_opaque (input) || !mpi_is_opaque (r_in) || !mpi_is_opaque (s_in)) - return GPG_ERR_INV_DATA; - -- point_init (&Ia); -- point_init (&Ib); -- h = mpi_new (0); -- s = mpi_new (0); -- - b = (ec->nbits+7)/8; - - if (ec->nbits == 255) -@@ -1005,6 +1003,11 @@ _gcry_ecc_eddsa_verify (gcry_mpi_t input, mpi_ec_t ec, - else - return GPG_ERR_NOT_IMPLEMENTED; - -+ point_init (&Ia); -+ point_init (&Ib); -+ h = mpi_new (0); -+ s = mpi_new (0); -+ - /* Encode and check the public key. */ - rc = _gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0, - &encpk, &encpklen); diff --git a/libgcrypt-1.9.2-s390x-ocb.patch b/libgcrypt-1.9.2-s390x-ocb.patch deleted file mode 100644 index e7ff8e3..0000000 --- a/libgcrypt-1.9.2-s390x-ocb.patch +++ /dev/null @@ -1,253 +0,0 @@ -From 56da81ac47209dc41af08a129f5e0c15538261b2 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Thu, 25 Mar 2021 19:33:44 +0200 -Subject: [PATCH 1/3] tests/basic: add decryption check to - check_ocb_cipher_checksum - -* tests/basic.c (check_ocb_cipher_checksum): Add decryption. --- - -GnuPG-bug-id: T5356 -Signed-off-by: Jussi Kivilinna ---- - tests/basic.c | 32 +++++++++++++++++++++++++++++++- - 1 file changed, 31 insertions(+), 1 deletion(-) - -diff --git a/tests/basic.c b/tests/basic.c -index 9a7e33cc..b39b901a 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -6800,9 +6800,10 @@ check_ocb_cipher_checksum (int algo, int keylen) - const size_t buflen = 128 * 16; - unsigned char *inbuf, *outbuf; - gpg_error_t err = 0; -- gcry_cipher_hd_t hde, hde2; -+ gcry_cipher_hd_t hde, hde2, hdd; - unsigned char tag[16]; - unsigned char tag2[16]; -+ unsigned char tag3[16]; - int i; - - inbuf = xmalloc(buflen); -@@ -6833,6 +6834,8 @@ check_ocb_cipher_checksum (int algo, int keylen) - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); -+ if (!err) -+ err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); - if (err) - { - fail ("cipher-ocb, gcry_cipher_open failed (checksum, algo %d): %s\n", -@@ -6843,24 +6846,30 @@ check_ocb_cipher_checksum (int algo, int keylen) - err = gcry_cipher_setkey (hde, key, keylen); - if (!err) - err = gcry_cipher_setkey (hde2, key, keylen); -+ if (!err) -+ err = gcry_cipher_setkey (hdd, key, keylen); - if (err) - { - fail ("cipher-ocb, gcry_cipher_setkey failed (checksum, algo %d): %s\n", - algo, gpg_strerror (err)); - gcry_cipher_close (hde); - gcry_cipher_close (hde2); -+ gcry_cipher_close (hdd); - goto out_free; - } - - err = gcry_cipher_setiv (hde, nonce, 12); - if (!err) - err = gcry_cipher_setiv (hde2, nonce, 12); -+ if (!err) -+ err = gcry_cipher_setiv (hdd, nonce, 12); - if (err) - { - fail ("cipher-ocb, gcry_cipher_setiv failed (checksum, algo %d): %s\n", - algo, gpg_strerror (err)); - gcry_cipher_close (hde); - gcry_cipher_close (hde2); -+ gcry_cipher_close (hdd); - goto out_free; - } - -@@ -6876,6 +6885,14 @@ check_ocb_cipher_checksum (int algo, int keylen) - if (!err) - err = gcry_cipher_encrypt (hde2, outbuf + i, 16, inbuf + i, 16); - } -+ if (!err) -+ { -+ err = gcry_cipher_final (hdd); -+ } -+ if (!err) -+ { -+ err = gcry_cipher_decrypt (hdd, outbuf, buflen, outbuf, buflen); -+ } - - if (err) - { -@@ -6883,6 +6900,7 @@ check_ocb_cipher_checksum (int algo, int keylen) - algo, gpg_strerror (err)); - gcry_cipher_close (hde); - gcry_cipher_close (hde2); -+ gcry_cipher_close (hdd); - goto out_free; - } - -@@ -6899,14 +6917,26 @@ check_ocb_cipher_checksum (int algo, int keylen) - fail ("cipher_ocb, gcry_cipher_gettag failed (checksum2, algo %d): %s\n", - algo, gpg_strerror (err)); - } -+ err = gcry_cipher_gettag (hdd, tag3, 16); -+ if (err) -+ { -+ fail ("cipher_ocb, gcry_cipher_gettag failed (checksum3, algo %d): %s\n", -+ algo, gpg_strerror (err)); -+ } - if (memcmp (tag, tag2, 16)) - { - mismatch (tag, 16, tag2, 16); - fail ("cipher-ocb, encrypt tag mismatch (checksum, algo %d)\n", algo); - } -+ if (memcmp (tag, tag3, 16)) -+ { -+ mismatch (tag, 16, tag3, 16); -+ fail ("cipher-ocb, decrypt tag mismatch (checksum, algo %d)\n", algo); -+ } - - gcry_cipher_close (hde); - gcry_cipher_close (hde2); -+ gcry_cipher_close (hdd); - - out_free: - xfree(inbuf); --- -2.27.0 - -From 21c273cecfd58408b8d3287f5bc8c246c3010313 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Thu, 25 Mar 2021 19:43:41 +0200 -Subject: [PATCH 2/3] tests/basic: OCB large buffer check: make input buffer - non-repeatable - -* tests/basic.c (check_ocb_cipher_largebuf_split): Use SHA1 to -initialize input buffer. -(check_ocb_cipher): Update largebuf test vectors. --- - -GnuPG-bug-id: T5356 -Signed-off-by: Jussi Kivilinna ---- - tests/basic.c | 36 +++++++++++++++++++++++------------- - 1 file changed, 23 insertions(+), 13 deletions(-) - -diff --git a/tests/basic.c b/tests/basic.c -index b39b901a..f9ada8ef 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -6630,8 +6630,18 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, - return; - } - -- for (i = 0; i < buflen; i++) -- inbuf[i] = (unsigned int)(i + 181081) * 5039U; -+ for (i = 0; i < buflen; i += 16) -+ { -+ unsigned char hash[20]; -+ unsigned char ctr[4]; -+ -+ ctr[0] = (i >> 0) & 0xff; -+ ctr[1] = (i >> 8) & 0xff; -+ ctr[2] = (i >> 16) & 0xff; -+ ctr[3] = (i >> 24) & 0xff; -+ gcry_md_hash_buffer (GCRY_MD_SHA1, hash, ctr, sizeof(ctr)); -+ memcpy(inbuf + i, hash, 16); -+ } - - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) -@@ -7200,27 +7210,27 @@ check_ocb_cipher (void) - - /* Check large buffer encryption/decryption. */ - check_ocb_cipher_largebuf(GCRY_CIPHER_AES, 16, -- "\xc1\x5b\xf1\x80\xa4\xd5\xea\xfd\xae\x17\xa6\xcd\x6b\x10\xa8\xea"); -+ "\x4a\x00\x7f\x8d\xbe\x38\x32\x48\xb2\x2f\x7f\x27\xd8\x15\x7f\xb0"); - check_ocb_cipher_largebuf(GCRY_CIPHER_AES256, 32, -- "\x2b\xb7\x25\x6b\x77\xc7\xfb\x21\x5c\xc9\x6c\x36\x17\x1a\x1a\xd5"); -+ "\xec\xc5\xe9\x2b\x24\x91\xba\x64\xbc\xe3\x62\xb6\x83\x20\xad\xbd"); - check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA128, 16, -- "\xe0\xae\x3f\x29\x3a\xee\xd8\xe3\xf2\x20\xc1\xa2\xd8\x72\x12\xd9"); -+ "\xd5\xbd\x76\xec\x75\x4a\xab\x6c\x13\xec\x87\x95\x11\xd4\xf0\x3d"); - check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA192, 24, -- "\xd7\x98\x71\xcf\x19\x5c\xa3\x3d\x6c\xfc\xc9\xbe\x9f\x13\x6b\xbd"); -+ "\xde\xdd\x6b\xbf\xce\x15\x01\x39\x7c\xc5\x69\x19\x72\xa2\x67\x23"); - check_ocb_cipher_largebuf(GCRY_CIPHER_CAMELLIA256, 32, -- "\x03\xf6\xec\x1a\x0e\xae\x66\x24\x2b\xba\x26\x0f\xb3\xb3\x1f\xb9"); -+ "\x0c\xf3\xd5\x82\x20\x73\xee\x0f\xbd\x6b\x32\x38\xf9\x10\xef\xe5"); - check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 16, -- "\x1c\xf9\xc7\xfc\x3a\x32\xac\xc7\x5e\x0a\xc2\x5c\x90\xd6\xf6\xf9"); -+ "\x54\x87\x68\xb6\x17\xe6\xd7\xa6\x76\x0d\x7e\x9f\x57\x8b\xec\x88"); - check_ocb_cipher_largebuf(GCRY_CIPHER_TWOFISH, 32, -- "\x53\x02\xc8\x0d\x4e\x9a\x44\x9e\x43\xd4\xaa\x06\x30\x93\xcc\x16"); -+ "\x0b\xc3\x93\x52\xfa\x97\x22\xe6\x88\x6e\x29\x4d\x77\x35\x48\x84"); - check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT128, 16, -- "\xd3\x64\xac\x40\x48\x88\x77\xe2\x41\x26\x4c\xde\x21\x29\x21\x8d"); -+ "\x7e\x49\x3b\xd6\xde\x6e\x9e\x53\x67\xcd\x00\xad\xc9\xd9\xa5\xbc"); - check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT192, 24, -- "\x99\xeb\x35\xb0\x62\x4e\x7b\xf1\x5e\x9f\xed\x32\x78\x90\x0b\xd0"); -+ "\x1e\x33\x0e\x06\xc8\x27\x6a\x0b\x41\x5e\x93\xae\x39\xf4\x50\x12"); - check_ocb_cipher_largebuf(GCRY_CIPHER_SERPENT256, 32, -- "\x71\x66\x2f\x68\xbf\xdd\xcc\xb1\xbf\x81\x56\x5f\x01\x73\xeb\x44"); -+ "\x6b\x4c\x3f\x8f\x77\x75\xf2\x4d\xaf\xde\x2c\x5f\x1a\x80\xb8\x4d"); - check_ocb_cipher_largebuf(GCRY_CIPHER_SM4, 16, -- "\x2c\x0b\x31\x0b\xf4\x71\x9b\x01\xf4\x18\x5d\xf1\xe9\x3d\xed\x6b"); -+ "\x3c\x32\x54\x5d\xc5\x17\xa1\x16\x3f\x8e\xc7\x1d\x8d\x8b\x2d\xb0"); - - /* Check that the AAD data is correctly buffered. */ - check_ocb_cipher_splitaad (); --- -2.27.0 - -From 68bb0ddc5504c9c0f3f52259a4085bb2fc1a02ad Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Thu, 25 Mar 2021 19:52:23 +0200 -Subject: [PATCH 3/3] rijndael-s390x: fix checksum calculation in OCB - decryption - -* cipher/rijndael-s390x.c (aes_s390x_ocb_dec): Calculate checksum -after decryption instead of inlining. --- - -OCB decryption was missing checksum inlining in 64 block loop. - -GnuPG-bug-id: T5356 -Signed-off-by: Jussi Kivilinna ---- - cipher/rijndael-s390x.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/cipher/rijndael-s390x.c b/cipher/rijndael-s390x.c -index aea65c5a..c3da9fb2 100644 ---- a/cipher/rijndael-s390x.c -+++ b/cipher/rijndael-s390x.c -@@ -777,9 +777,7 @@ aes_s390x_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, - OCB_INPUT_4((n) + 12); - - #define OCB_OUTPUT(n) \ -- cipher_block_xor_1 (&blocks[n], outbuf + (n) * BLOCKSIZE, BLOCKSIZE); \ -- cipher_block_xor_1 (c->u_ctr.ctr, &blocks[n], BLOCKSIZE); \ -- cipher_block_cpy (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE); -+ cipher_block_xor_1 (outbuf + (n) * BLOCKSIZE, &blocks[n], BLOCKSIZE); - - #define OCB_OUTPUT_4(n) \ - OCB_OUTPUT((n) + 0); OCB_OUTPUT((n) + 1); OCB_OUTPUT((n) + 2); \ -@@ -895,6 +893,8 @@ aes_s390x_ocb_dec (gcry_cipher_hd_t c, void *outbuf_arg, - if (max_blocks_used) - wipememory (&blocks, max_blocks_used * BLOCKSIZE); - -+ aes_s390x_ocb_checksum (c->u_ctr.ctr, outbuf_arg, nblocks_arg); -+ - return 0; - } - --- -2.27.0 - diff --git a/libgcrypt.spec b/libgcrypt.spec index ed7666d..6868655 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.9.2 -Release: 3%{?dist} +Version: 1.9.3 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -19,6 +19,7 @@ Source4: ecc-curves.c Source5: curves.c Source6: t-mpi-point.c Source7: random.conf +Source8: keygrip.c # make FIPS hmac compatible with fipscheck - non upstreamable # update on soname bump Patch2: libgcrypt-1.8.5-use-fipscheck.patch @@ -44,10 +45,6 @@ Patch26: libgcrypt-1.8.3-fips-enttest.patch Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch -# Unbreak gnupg2 build on s390x: https://dev.gnupg.org/T5356 -Patch31: libgcrypt-1.9.2-s390x-ocb.patch -# Coverity reported issues https://dev.gnupg.org/T5385 -Patch32: libgcrypt-1.9.2-coverity.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -96,11 +93,9 @@ applications using libgcrypt. %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch30 -p1 -b .fips-module -%patch31 -p1 -b .s390x-ocb -%patch32 -p1 -b .coverity cp %{SOURCE4} cipher/ -cp %{SOURCE5} %{SOURCE6} tests/ +cp %{SOURCE5} %{SOURCE6} %{SOURCE8} tests/ %build # This package has a configure test which uses ASMs, but does not link the @@ -207,6 +202,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Apr 20 2021 Jakub Jelen - 1.9.3-1 +- New upstream release (#1951325) + * Thu Apr 15 2021 Jakub Jelen - 1.9.2-3 - Fix issues reported by coverity From 7f23c523ef2056aa95c01404dfcc8d6a8ee73d69 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Apr 2021 11:38:50 +0200 Subject: [PATCH 32/88] forgotten sources --- .gitignore | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 9fe7a79..69b0cfb 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.9.0-hobbled.tar.xz /libgcrypt-1.9.1-hobbled.tar.xz /libgcrypt-1.9.2-hobbled.tar.xz +/libgcrypt-1.9.3-hobbled.tar.xz diff --git a/sources b/sources index 9ebeb2d..cbff218 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.2-hobbled.tar.xz) = b89f1e2ea76a6efb5e503264b4ebd843f410e188cf4fad4da4607ae77b247349f031e1e8e4340f4d3d0b03197f110e14dcca9d693f8971c086f6d8be3de403e6 +SHA512 (libgcrypt-1.9.3-hobbled.tar.xz) = c469bbfbcb87b31133e431da5bb4764824ccc4509d26fb6da200d50455282f4ca84fd51e86ae32d57d859ae5509104479a3b575f9ee9094707fa23f1ab5e68c1 From b9da031d089079959adf7eaab6668681783a8873 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 20 Apr 2021 11:48:05 +0200 Subject: [PATCH 33/88] Reupload sources without bogus build artifacts --- libgcrypt.spec | 1 + sources | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6868655..6aac689 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -7,6 +7,7 @@ Source0: libgcrypt-%{version}-hobbled.tar.xz # cipher support. We have to remove it in the tarball we ship with # the hobble-libgcrypt script. # (We replace it with RH approved ECC in Source4-5) +# rm -rf libgcrypt-x.y.z # make sure there are no leftover files # tar -xf libgcrypt-x.y.z.tar.bz2 # pushd libgcrypt-x.y.z && ../hobble-libgcrypt && popd # tar -cvJf libgcrypt-x.y.z-hobbled.tar.xz libgcrypt-x.y.z diff --git a/sources b/sources index cbff218..84854e4 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.3-hobbled.tar.xz) = c469bbfbcb87b31133e431da5bb4764824ccc4509d26fb6da200d50455282f4ca84fd51e86ae32d57d859ae5509104479a3b575f9ee9094707fa23f1ab5e68c1 +SHA512 (libgcrypt-1.9.3-hobbled.tar.xz) = 5c6f3ee57ec496af6d82000979a79d220a5b9be7a3a9d064d727ff7e54cf107e5b398d9ec8d822594a7fe53bc0d4324e96a5b41d55a77f103109620b88c61f1a From ca49edafdd5ce709b72cc68b435c78a46d34143a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 27 Apr 2021 20:32:31 +0200 Subject: [PATCH 34/88] Restore Intel CET support after upstream release (#1954049) --- libgcrypt-1.8.5-intel-cet.patch | 34 +++++++++++++++++++++++++++++++++ libgcrypt.spec | 3 +++ 2 files changed, 37 insertions(+) create mode 100644 libgcrypt-1.8.5-intel-cet.patch diff --git a/libgcrypt-1.8.5-intel-cet.patch b/libgcrypt-1.8.5-intel-cet.patch new file mode 100644 index 0000000..a19d2f1 --- /dev/null +++ b/libgcrypt-1.8.5-intel-cet.patch @@ -0,0 +1,34 @@ +From b04c0a86b19856071c29d2a6285f3240c606ee7a Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Tue, 27 Apr 2021 09:08:41 -0700 +Subject: [PATCH] Always include in cipher assembly codes + +* cipher/poly1305-s390x.S: Always include . + +When Intel CET is enabled, we need to include in assembly codes +to mark Intel CET support even if it is empty. We should always include + in cipher assembly codes so that they will be marked for +Intel CET support when compiling for x86-64 and i686. + +Signed-off-by: H.J. Lu +--- + cipher/poly1305-s390x.S | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cipher/poly1305-s390x.S b/cipher/poly1305-s390x.S +index 844245f6..28bed560 100644 +--- a/cipher/poly1305-s390x.S ++++ b/cipher/poly1305-s390x.S +@@ -18,8 +18,8 @@ + * License along with this program; if not, see . + */ + +-#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9 + #include ++#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9 + #if defined(HAVE_GCC_INLINE_ASM_S390X) + + #include "asm-poly1305-s390x.h" +-- +GitLab + diff --git a/libgcrypt.spec b/libgcrypt.spec index 6aac689..c7f8e15 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -44,6 +44,8 @@ Patch24: libgcrypt-1.8.5-getrandom.patch Patch26: libgcrypt-1.8.3-fips-enttest.patch # Disable non-approved FIPS hashes in the enforced FIPS mode Patch27: libgcrypt-1.8.3-md-fips-enforce.patch +# Missing Intel CET support in the library (#1954049) +Patch28: libgcrypt-1.8.5-intel-cet.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch @@ -93,6 +95,7 @@ applications using libgcrypt. %patch24 -p1 -b .getrandom %patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce +%patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module cp %{SOURCE4} cipher/ From ecb230f86117ffb00d77262e08b26796f3e4921a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 28 Apr 2021 09:12:52 +0200 Subject: [PATCH 35/88] libgcrypt-1.9.3-2 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index c7f8e15..ca19c19 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.3 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -206,6 +206,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Apr 28 2021 Jakub Jelen - 1.9.3-2 +- Restore the CET protection (#1954049) + * Tue Apr 20 2021 Jakub Jelen - 1.9.3-1 - New upstream release (#1951325) From b67b214174440014c8f035fcaefd0b57d420d9b0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 15 Jun 2021 13:34:41 +0200 Subject: [PATCH 36/88] Fix for CVE-2021-33560 (#1970098]) --- libgcrypt-1.9.3-CVE-2021-33560.patch | 100 +++++++++++++++++++++++++++ libgcrypt.spec | 3 + 2 files changed, 103 insertions(+) create mode 100644 libgcrypt-1.9.3-CVE-2021-33560.patch diff --git a/libgcrypt-1.9.3-CVE-2021-33560.patch b/libgcrypt-1.9.3-CVE-2021-33560.patch new file mode 100644 index 0000000..2161840 --- /dev/null +++ b/libgcrypt-1.9.3-CVE-2021-33560.patch @@ -0,0 +1,100 @@ +commit 3462280f2e23e16adf3ed5176e0f2413d8861320 +Author: NIIBE Yutaka +Date: Fri May 21 11:15:07 2021 +0900 + + cipher: Fix ElGamal encryption for other implementations. + + * cipher/elgamal.c (gen_k): Remove support of smaller K. + (do_encrypt): Never use smaller K. + (sign): Folllow the change of gen_k. + + -- + + Cherry-pick master commit of: + 632d80ef30e13de6926d503aa697f92b5dbfbc5e + + This change basically reverts encryption changes in two commits: + + 74386120dad6b3da62db37f7044267c8ef34689b + 78531373a342aeb847950f404343a05e36022065 + + Use of smaller K for ephemeral key in ElGamal encryption is only good, + when we can guarantee that recipient's key is generated by our + implementation (or compatible). + + For detail, please see: + + Luca De Feo, Bertram Poettering, Alessandro Sorniotti, + "On the (in)security of ElGamal in OpenPGP"; + in the proceedings of CCS'2021. + + CVE-id: CVE-2021-33560 + GnuPG-bug-id: 5328 + Suggested-by: Luca De Feo, Bertram Poettering, Alessandro Sorniotti + Signed-off-by: NIIBE Yutaka + +diff --git a/cipher/elgamal.c b/cipher/elgamal.c +index 9835122f..eead4502 100644 +--- a/cipher/elgamal.c ++++ b/cipher/elgamal.c +@@ -66,7 +66,7 @@ static const char *elg_names[] = + + + static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie); +-static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k); ++static gcry_mpi_t gen_k (gcry_mpi_t p); + static gcry_err_code_t generate (ELG_secret_key *sk, unsigned nbits, + gcry_mpi_t **factors); + static int check_secret_key (ELG_secret_key *sk); +@@ -189,11 +189,10 @@ test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie ) + + /**************** + * Generate a random secret exponent k from prime p, so that k is +- * relatively prime to p-1. With SMALL_K set, k will be selected for +- * better encryption performance - this must never be used signing! ++ * relatively prime to p-1. + */ + static gcry_mpi_t +-gen_k( gcry_mpi_t p, int small_k ) ++gen_k( gcry_mpi_t p ) + { + gcry_mpi_t k = mpi_alloc_secure( 0 ); + gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) ); +@@ -202,18 +201,7 @@ gen_k( gcry_mpi_t p, int small_k ) + unsigned int nbits, nbytes; + char *rndbuf = NULL; + +- if (small_k) +- { +- /* Using a k much lesser than p is sufficient for encryption and +- * it greatly improves the encryption performance. We use +- * Wiener's table and add a large safety margin. */ +- nbits = wiener_map( orig_nbits ) * 3 / 2; +- if( nbits >= orig_nbits ) +- BUG(); +- } +- else +- nbits = orig_nbits; +- ++ nbits = orig_nbits; + + nbytes = (nbits+7)/8; + if( DBG_CIPHER ) +@@ -492,7 +480,7 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey ) + * error code. + */ + +- k = gen_k( pkey->p, 1 ); ++ k = gen_k( pkey->p ); + mpi_powm (a, pkey->g, k, pkey->p); + + /* b = (y^k * input) mod p +@@ -608,7 +596,7 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey ) + * + */ + mpi_sub_ui(p_1, p_1, 1); +- k = gen_k( skey->p, 0 /* no small K ! */ ); ++ k = gen_k( skey->p ); + mpi_powm( a, skey->g, k, skey->p ); + mpi_mul(t, skey->x, a ); + mpi_subm(t, input, t, p_1 ); diff --git a/libgcrypt.spec b/libgcrypt.spec index ca19c19..2eb80a0 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -48,6 +48,8 @@ Patch27: libgcrypt-1.8.3-md-fips-enforce.patch Patch28: libgcrypt-1.8.5-intel-cet.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch +# Fix for CVE-2021-33560 +Patch31: libgcrypt-1.9.3-CVE-2021-33560.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -97,6 +99,7 @@ applications using libgcrypt. %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module +%patch31 -p1 -b .CVE-2021-33560 cp %{SOURCE4} cipher/ cp %{SOURCE5} %{SOURCE6} %{SOURCE8} tests/ From 0fd2314056ad4eeb59e0b445c1f4f9ca5e44d72b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 15 Jun 2021 13:35:35 +0200 Subject: [PATCH 37/88] libgcrypt-1.9.3-3 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 2eb80a0..3106772 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.3 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -209,6 +209,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Tue Jun 15 2021 Jakub Jelen - 1.9.3-3 +- Fix for CVE-2021-33560 (#1970098) + * Wed Apr 28 2021 Jakub Jelen - 1.9.3-2 - Restore the CET protection (#1954049) From dcaae6dd48a041eb5abdc953a0edb6ab0453e62a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 9 Jul 2021 09:46:38 +0200 Subject: [PATCH 38/88] Skip the x448 test in FIPS mode --- libgcrypt-1.8.4-tests-fipsmode.patch | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/libgcrypt-1.8.4-tests-fipsmode.patch b/libgcrypt-1.8.4-tests-fipsmode.patch index a415d18..fa235f8 100644 --- a/libgcrypt-1.8.4-tests-fipsmode.patch +++ b/libgcrypt-1.8.4-tests-fipsmode.patch @@ -160,6 +160,19 @@ diff -up libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode libgcrypt-1.8.4/tests/ start_timer (); check_cv25519 (); +diff -up libgcrypt-1.8.4/tests/t-x448.c.tests-fipsmode libgcrypt-1.8.4/tests/t-x448.c +--- libgcrypt-1.8.4/tests/t-x448.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 ++++ libgcrypt-1.8.4/tests/t-x448.c 2019-02-12 14:02:35.935705390 +0100 +@@ -560,6 +560,9 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); ++ /* x448 isn't supported in fips mode */ ++ if (gcry_fips_mode_active()) ++ return 77; + + start_timer (); + check_x448 (); diff -up libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode libgcrypt-1.8.4/tests/t-secmem.c --- libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode 2017-11-23 19:19:54.000000000 +0100 +++ libgcrypt-1.8.4/tests/t-secmem.c 2019-02-12 11:51:02.462190538 +0100 From af286f213cd486a2391838c1c5f95c70e7e9481d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 22 Jul 2021 11:25:34 +0000 Subject: [PATCH 39/88] - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3106772..5b0e0aa 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.3 -Release: 3%{?dist} +Release: 4%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -209,6 +209,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Jul 22 2021 Fedora Release Engineering - 1.9.3-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild + * Tue Jun 15 2021 Jakub Jelen - 1.9.3-3 - Fix for CVE-2021-33560 (#1970098) From 21fe8b5f7138176ed66a55bbc631bb1d405201a9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 13 Jul 2021 22:56:49 +0200 Subject: [PATCH 40/88] Aggregate FIPS test patches for upstream submission and backport whats already in --- libgcrypt-1.7.3-ecc-test-fix.patch | 122 -- libgcrypt-1.8.3-fips-ctor.patch | 13 + libgcrypt-1.8.3-md-fips-enforce.patch | 19 + libgcrypt-1.8.4-tests-fipsmode.patch | 198 --- libgcrypt-1.9.3-fips-tests.patch | 1804 +++++++++++++++++++++++++ libgcrypt.spec | 5 +- 6 files changed, 1837 insertions(+), 324 deletions(-) delete mode 100644 libgcrypt-1.7.3-ecc-test-fix.patch delete mode 100644 libgcrypt-1.8.4-tests-fipsmode.patch create mode 100644 libgcrypt-1.9.3-fips-tests.patch diff --git a/libgcrypt-1.7.3-ecc-test-fix.patch b/libgcrypt-1.7.3-ecc-test-fix.patch deleted file mode 100644 index 8ce7aa9..0000000 --- a/libgcrypt-1.7.3-ecc-test-fix.patch +++ /dev/null @@ -1,122 +0,0 @@ -diff -up libgcrypt-1.7.3/tests/benchmark.c.eccfix libgcrypt-1.7.3/tests/benchmark.c ---- libgcrypt-1.7.3/tests/benchmark.c.eccfix 2016-07-14 11:19:17.000000000 +0200 -+++ libgcrypt-1.7.3/tests/benchmark.c 2016-11-22 16:21:00.109004197 +0100 -@@ -1412,7 +1412,7 @@ ecc_bench (int iterations, int print_hea - { - #if USE_ECC - gpg_error_t err; -- const char *p_sizes[] = { "192", "224", "256", "384", "521", "Ed25519", -+ const char *p_sizes[] = { "224", "256", "384", "521", "Ed25519", - "gost256", "gost512" }; - int testno; - -diff -up libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix libgcrypt-1.7.3/tests/dsa-rfc6979.c ---- libgcrypt-1.7.3/tests/dsa-rfc6979.c.eccfix 2016-02-18 09:38:03.000000000 +0100 -+++ libgcrypt-1.7.3/tests/dsa-rfc6979.c 2016-11-22 16:22:11.804674008 +0100 -@@ -210,16 +210,6 @@ check_dsa_rfc6979 (void) - " ))" - }, - { -- "ECDSA, 192 bits (prime field)", -- "(private-key" -- " (ecdsa" -- " (curve \"NIST P-192\")" -- " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" -- " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" -- " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" -- " ))" -- }, -- { - "ECDSA, 224 bits (prime field)", - "(private-key" - " (ecdsa" -@@ -443,89 +433,6 @@ check_dsa_rfc6979 (void) - "C9F0BDABCC0D880BB137A994CC7F3980CE91CC10FAF529FC46565B15CEA854E1" - }, - { -- "ECDSA, 192 bits (prime field)", -- "With SHA-1, message = \"sample\"", -- "sha1", "sample", -- "37D7CA00D2C7B0E5E412AC03BD44BA837FDD5B28CD3B0021", -- "98C6BD12B23EAF5E2A2045132086BE3EB8EBD62ABF6698FF", -- "57A22B07DEA9530F8DE9471B1DC6624472E8E2844BC25B64" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-224, message = \"sample\"", -- "sha224", "sample", -- "4381526B3FC1E7128F202E194505592F01D5FF4C5AF015D8", -- "A1F00DAD97AEEC91C95585F36200C65F3C01812AA60378F5", -- "E07EC1304C7C6C9DEBBE980B9692668F81D4DE7922A0F97A" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-256, message = \"sample\"", -- "sha256", "sample", -- "32B1B6D7D42A05CB449065727A84804FB1A3E34D8F261496", -- "4B0B8CE98A92866A2820E20AA6B75B56382E0F9BFD5ECB55", -- "CCDB006926EA9565CBADC840829D8C384E06DE1F1E381B85" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-384, message = \"sample\"", -- "sha384", "sample", -- "4730005C4FCB01834C063A7B6760096DBE284B8252EF4311", -- "DA63BF0B9ABCF948FBB1E9167F136145F7A20426DCC287D5", -- "C3AA2C960972BD7A2003A57E1C4C77F0578F8AE95E31EC5E" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-512, message = \"sample\"", -- "sha512", "sample", -- "A2AC7AB055E4F20692D49209544C203A7D1F2C0BFBC75DB1", -- "4D60C5AB1996BD848343B31C00850205E2EA6922DAC2E4B8", -- "3F6E837448F027A1BF4B34E796E32A811CBB4050908D8F67" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-1, message = \"test\"", -- "sha1", "test", -- "D9CF9C3D3297D3260773A1DA7418DB5537AB8DD93DE7FA25", -- "0F2141A0EBBC44D2E1AF90A50EBCFCE5E197B3B7D4DE036D", -- "EB18BC9E1F3D7387500CB99CF5F7C157070A8961E38700B7" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-224, message = \"test\"", -- "sha224", "test", -- "F5DC805F76EF851800700CCE82E7B98D8911B7D510059FBE", -- "6945A1C1D1B2206B8145548F633BB61CEF04891BAF26ED34", -- "B7FB7FDFC339C0B9BD61A9F5A8EAF9BE58FC5CBA2CB15293" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-256, message = \"test\"", -- "sha256", "test", -- "5C4CE89CF56D9E7C77C8585339B006B97B5F0680B4306C6C", -- "3A718BD8B4926C3B52EE6BBE67EF79B18CB6EB62B1AD97AE", -- "5662E6848A4A19B1F1AE2F72ACD4B8BBE50F1EAC65D9124F" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-384, message = \"test\"", -- "sha384", "test", -- "5AFEFB5D3393261B828DB6C91FBC68C230727B030C975693", -- "B234B60B4DB75A733E19280A7A6034BD6B1EE88AF5332367", -- "7994090B2D59BB782BE57E74A44C9A1C700413F8ABEFE77A" -- }, -- { -- "ECDSA, 192 bits (prime field)", -- "With SHA-512, message = \"test\"", -- "sha512", "test", -- "0758753A5254759C7CFBAD2E2D9B0792EEE44136C9480527", -- "FE4F4AE86A58B6507946715934FE2D8FF9D95B6B098FE739", -- "74CF5605C98FBA0E1EF34D4B5A1577A7DCF59457CAE52290" -- }, -- -- -- -- { - "ECDSA, 224 bits (prime field)", - "With SHA-1, message = \"sample\"", - "sha1", "sample", diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch index adecbe4..a5d3467 100644 --- a/libgcrypt-1.8.3-fips-ctor.patch +++ b/libgcrypt-1.8.3-fips-ctor.patch @@ -58,3 +58,16 @@ diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c _gcry_set_preferred_rng_type (0); _gcry_set_enforced_fips_mode (); } +diff --git a/tests/t-secmem.c b/tests/t-secmem.c +index 2b769134..1d33bbfd 100644 +--- a/tests/t-secmem.c ++++ b/tests/t-secmem.c +@@ -54,7 +54,7 @@ test_secmem (void) + + /* Allocating another 2k should fail for the default 16k pool. */ + b = gcry_malloc_secure (chunk_size*4); +- if (b) ++ if (b && !gcry_fips_mode_active ()) + fail ("allocation did not fail as expected\n"); + + for (i=0; i < DIM(a); i++) diff --git a/libgcrypt-1.8.3-md-fips-enforce.patch b/libgcrypt-1.8.3-md-fips-enforce.patch index eed7fa5..3b730a1 100644 --- a/libgcrypt-1.8.3-md-fips-enforce.patch +++ b/libgcrypt-1.8.3-md-fips-enforce.patch @@ -16,3 +16,22 @@ diff -up libgcrypt-1.8.3/cipher/md.c.fips-enforce libgcrypt-1.8.3/cipher/md.c err = GPG_ERR_DIGEST_ALGO; } } +diff --git a/tests/t-kdf.c b/tests/t-kdf.c +index 7a48e98a..48309b9a 100644 +--- a/tests/t-kdf.c ++++ b/tests/t-kdf.c +@@ -1104,6 +1104,13 @@ check_pbkdf2 (void) + GCRY_KDF_PBKDF2, tv[tvidx].hashalgo, + tv[tvidx].salt, tv[tvidx].saltlen, + tv[tvidx].c, tv[tvidx].dklen, outbuf); ++ if (gcry_fips_mode_active() && tvidx > 6) ++ { ++ if (!err) ++ fail ("pbkdf2 test %d unexpectedly passed in FIPS mode: %s\n", ++ tvidx, gpg_strerror (err)); ++ continue; ++ } + if (err) + fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); + else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) + diff --git a/libgcrypt-1.8.4-tests-fipsmode.patch b/libgcrypt-1.8.4-tests-fipsmode.patch deleted file mode 100644 index fa235f8..0000000 --- a/libgcrypt-1.8.4-tests-fipsmode.patch +++ /dev/null @@ -1,198 +0,0 @@ -diff -up libgcrypt-1.8.4/tests/basic.c.tests-fipsmode libgcrypt-1.8.4/tests/basic.c ---- libgcrypt-1.8.4/tests/basic.c.tests-fipsmode 2018-04-17 17:29:40.000000000 +0200 -+++ libgcrypt-1.8.4/tests/basic.c 2019-02-12 13:30:48.935791024 +0100 -@@ -6964,7 +6964,7 @@ check_ciphers (void) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_EAX, 0); - if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_CCM_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_CCM, 0); -- if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) -+ if (!in_fips_mode && gcry_cipher_get_algo_blklen (algos[i]) == GCRY_GCM_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_GCM, 0); - if (gcry_cipher_get_algo_blklen (algos[i]) == GCRY_OCB_BLOCK_LEN) - check_one_cipher (algos[i], GCRY_CIPHER_MODE_OCB, 0); -@@ -7010,12 +7010,18 @@ check_cipher_modes(void) - check_cfb_cipher (); - check_ofb_cipher (); - check_ccm_cipher (); -- check_gcm_cipher (); -- check_poly1305_cipher (); -- check_ocb_cipher (); -+ if (!in_fips_mode) -+ { -+ check_gcm_cipher (); -+ check_poly1305_cipher (); -+ check_ocb_cipher (); -+ } - check_xts_cipher (); - check_eax_cipher (); -- check_gost28147_cipher (); -+ if (!in_fips_mode) -+ { -+ check_gost28147_cipher (); -+ } - check_stream_cipher (); - check_stream_cipher_large_block (); - -@@ -10001,7 +10007,7 @@ check_mac (void) - show_mac_not_available (algos[i].algo); - continue; - } -- if (gcry_mac_test_algo (algos[i].algo) && in_fips_mode) -+ if ((algos[i].algo == GCRY_MAC_GMAC_AES || gcry_mac_test_algo (algos[i].algo)) && in_fips_mode) - { - if (verbose) - fprintf (stderr, " algorithm %d not available in fips mode\n", -@@ -11095,8 +11101,6 @@ main (int argc, char **argv) - /* If we are in fips mode do some more tests. */ - gcry_md_hd_t md; - -- /* First trigger a self-test. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("not in operational state after self-test\n"); - -@@ -11121,15 +11125,6 @@ main (int argc, char **argv) - gcry_md_close (md); - if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("expected error state but still in operational state\n"); -- else -- { -- /* Now run a self-test and to get back into -- operational state. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); -- if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) -- fail ("did not reach operational after error " -- "and self-test\n"); -- } - } - } - -diff -up libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode libgcrypt-1.8.4/tests/benchmark.c ---- libgcrypt-1.8.4/tests/benchmark.c.tests-fipsmode 2019-02-12 11:31:44.859603883 +0100 -+++ libgcrypt-1.8.4/tests/benchmark.c 2019-02-12 14:10:40.271999352 +0100 -@@ -872,8 +872,10 @@ cipher_bench ( const char *algoname ) - && algo != GCRY_CIPHER_CHACHA20) - continue; - -- if (modes[modeidx].req_blocksize > 0 -- && blklen != modes[modeidx].req_blocksize) -+ if ((modes[modeidx].req_blocksize > 0 -+ && blklen != modes[modeidx].req_blocksize) -+ || (in_fips_mode -+ && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM)) - { - printf (" %7s %7s", "-", "-" ); - continue; -diff -up libgcrypt-1.8.4/tests/bench-slope.c.tests-fipsmode libgcrypt-1.8.4/tests/bench-slope.c ---- libgcrypt-1.8.4/tests/bench-slope.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/tests/bench-slope.c 2019-02-12 14:14:33.618763325 +0100 -@@ -1338,7 +1338,7 @@ cipher_bench_one (int algo, struct bench - return; - - /* GCM has restrictions for block-size */ -- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) -+ if (mode.mode == GCRY_CIPHER_MODE_GCM && (gcry_fips_mode_active () || blklen != GCRY_GCM_BLOCK_LEN)) - return; - - /* XTS has restrictions for block-size */ -diff -up libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode libgcrypt-1.8.4/tests/pubkey.c ---- libgcrypt-1.8.4/tests/pubkey.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/tests/pubkey.c 2019-02-12 13:52:25.658746415 +0100 -@@ -504,15 +504,30 @@ get_dsa_key_with_domain_new (gcry_sexp_t - rc = gcry_sexp_new - (&key_spec, - "(genkey (dsa (transient-key)(domain" -- "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" -- "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" -- "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" -- "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" -- "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" -- "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" -- "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" -- "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" -- "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" -+ " (p #a85378d8fd3f8d72ec7418080da21317e43ec4b62ba8c862" -+ " 3b7e4d04441dd1a0658662596493ca8e9e8fbb7e34aaddb6" -+ " 2e5d67b6d09a6e61b769e7c352aa2b10e20ca0636963b552" -+ " 3e86470decbbeda027e797e7b67635d4d49c30700e74af8a" -+ " 0ff156a801af57a26e7078f1d82f74908ecb6d07e70b3503" -+ " eed94fa32cf17a7fc3d6cf40dc7b00830e6a2566dc073e34" -+ " 3312517c6aa5152b4bfecd2e551fee346318a153423c996b" -+ " 0d5dcb9102aedd38798616f1f1e0d6c403525b1f9b3d4dc7" -+ " 66de2dfc4a56d7b8ba5963d60f3e16318870ad436952e557" -+ " 65374eab85e8ec17d6b9a4547b9b5f2752f3105be809b23a" -+ " 2c8d7469db02e24d592394a7dba069e9#)" -+ " (q #d277044e50f5a4e3f510a50a0b84fdffbca047ed27602056" -+ " 7441a0a5#)" -+ " (g #13d754e21fd241655da891c522a65a72a89bdc64ec9b54a8" -+ " 21ed4a898b490e0c4fcb72192a4a20f541f3f2925399f0ba" -+ " ecf929aafbf79dfe4332393b32cd2e2fcf272f32a627434a" -+ " 0df242b75b414df372121e53a553f222f836b000f016485b" -+ " 6bd0898451801dcd8de64cd5365696ffc532d528c506620a" -+ " 942a0305046d8f1876341f1e570bc3974ba6b9a438e97023" -+ " 02a2e6e67bfd06d32bc679962271d7b40cd72f386e64e0d7" -+ " ef86ca8ca5d14228dc2a4f16e3189886b5990674f4200f3a" -+ " 4cf65a3f0ddba1fa672dff2f5e143d10e4e97ae84f6da095" -+ " 35d5b9df259181a79b63b069e949972b02ba36b3586aab7e" -+ " 45f322f82e4e85ca3ab85591b3c2a966#)" - ")))", 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); -@@ -595,7 +610,7 @@ get_dsa_key_fips186_with_seed_new (gcry_ - " (use-fips186)" - " (transient-key)" - " (derive-parms" -- " (seed #f770a4598ff756931fc529764513b103ce57d85f4ad8c5cf297c9b4d48241c5b#))))", -+ " (seed #8b4c4d671fff82e8ed932260206d0571e3a1c2cee8cd94cb73fe58f9b67488fa#))))", - 0, 1); - if (rc) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); -diff -up libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode libgcrypt-1.8.4/tests/t-cv25519.c ---- libgcrypt-1.8.4/tests/t-cv25519.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/tests/t-cv25519.c 2019-02-12 14:02:35.935705390 +0100 -@@ -560,6 +560,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); -+ /* Curve25519 isn't supported in fips mode */ -+ if (gcry_fips_mode_active()) -+ return 77; - - start_timer (); - check_cv25519 (); -diff -up libgcrypt-1.8.4/tests/t-x448.c.tests-fipsmode libgcrypt-1.8.4/tests/t-x448.c ---- libgcrypt-1.8.4/tests/t-x448.c.tests-fipsmode 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/tests/t-x448.c 2019-02-12 14:02:35.935705390 +0100 -@@ -560,6 +560,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); -+ /* x448 isn't supported in fips mode */ -+ if (gcry_fips_mode_active()) -+ return 77; - - start_timer (); - check_x448 (); -diff -up libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode libgcrypt-1.8.4/tests/t-secmem.c ---- libgcrypt-1.8.4/tests/t-secmem.c.tests-fipsmode 2017-11-23 19:19:54.000000000 +0100 -+++ libgcrypt-1.8.4/tests/t-secmem.c 2019-02-12 11:51:02.462190538 +0100 -@@ -174,7 +174,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0)); -- gcry_set_outofcore_handler (outofcore_handler, NULL); -+ if (!gcry_fips_mode_active ()) -+ gcry_set_outofcore_handler (outofcore_handler, NULL); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - - /* Libgcrypt prints a warning when the first overflow is allocated; -@@ -184,7 +185,8 @@ main (int argc, char **argv) - - - test_secmem (); -- test_secmem_overflow (); -+ if (!gcry_fips_mode_active ()) -+ test_secmem_overflow (); - /* FIXME: We need to improve the tests, for example by registering - * our own log handler and comparing the output of - * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */ diff --git a/libgcrypt-1.9.3-fips-tests.patch b/libgcrypt-1.9.3-fips-tests.patch new file mode 100644 index 0000000..1ddc64f --- /dev/null +++ b/libgcrypt-1.9.3-fips-tests.patch @@ -0,0 +1,1804 @@ +commit 57cf83834bc00a7431378aabda692bf700e4876c +Author: Jussi Kivilinna +Date: Sat Apr 17 17:06:40 2021 +0300 + + tests/bench-slope: add ECC benchmarking + + * tests/bench-slope.c (bench_print_result_nsec_per_iteration): New. + (bench_print_header_nsec_per_iteration): New. + (kdf_bench_one, kdf_bench): Use new print helper functions. + [USE_ECC]: New ECC benchmarks. + (ecc_bench): New. + (print_help): Add 'ecc' option. + (main): Add ECC benchmarks. + -- + + Signed-off-by: Jussi Kivilinna + +diff --git a/tests/bench-slope.c b/tests/bench-slope.c +index c8647b6b..9b4a139a 100644 +--- a/tests/bench-slope.c ++++ b/tests/bench-slope.c +@@ -783,6 +783,54 @@ bench_print_result (double nsecs_per_byte) + bench_print_result_std (nsecs_per_byte); + } + ++static void ++bench_print_result_nsec_per_iteration (double nsecs_per_iteration) ++{ ++ double cycles_per_iteration; ++ char nsecpiter_buf[16]; ++ char cpiter_buf[16]; ++ char mhz_buf[16]; ++ ++ strcpy(cpiter_buf, csv_mode ? "" : "-"); ++ strcpy(mhz_buf, csv_mode ? "" : "-"); ++ ++ double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); ++ ++ /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ ++ if (bench_ghz > 0.0) ++ { ++ cycles_per_iteration = nsecs_per_iteration * bench_ghz; ++ double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); ++ double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); ++ } ++ ++ if (csv_mode) ++ { ++ if (auto_ghz) ++ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", ++ current_section_name, ++ current_algo_name ? current_algo_name : "", ++ current_mode_name ? current_mode_name : "", ++ nsecpiter_buf, ++ cpiter_buf, ++ mhz_buf); ++ else ++ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", ++ current_section_name, ++ current_algo_name ? current_algo_name : "", ++ current_mode_name ? current_mode_name : "", ++ nsecpiter_buf, ++ cpiter_buf); ++ } ++ else ++ { ++ if (auto_ghz) ++ printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); ++ else ++ printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); ++ } ++} ++ + static void + bench_print_section (const char *section_name, const char *print_name) + { +@@ -819,6 +867,28 @@ bench_print_header (int algo_width, const char *algo_name) + } + } + ++static void ++bench_print_header_nsec_per_iteration (int algo_width, const char *algo_name) ++{ ++ if (csv_mode) ++ { ++ gcry_free (current_algo_name); ++ current_algo_name = gcry_xstrdup (algo_name); ++ } ++ else ++ { ++ if (algo_width < 0) ++ printf (" %-*s | ", -algo_width, algo_name); ++ else ++ printf (" %-*s | ", algo_width, algo_name); ++ ++ if (auto_ghz) ++ printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); ++ else ++ printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); ++ } ++} ++ + static void + bench_print_algo (int algo_width, const char *algo_name) + { +@@ -1991,11 +2061,7 @@ kdf_bench_one (int algo, int subalgo) + struct bench_kdf_mode mode = { &kdf_ops }; + struct bench_obj obj = { 0 }; + double nsecs_per_iteration; +- double cycles_per_iteration; + char algo_name[32]; +- char nsecpiter_buf[16]; +- char cpiter_buf[16]; +- char mhz_buf[16]; + + mode.algo = algo; + mode.subalgo = subalgo; +@@ -2030,45 +2096,7 @@ kdf_bench_one (int algo, int subalgo) + obj.priv = &mode; + + nsecs_per_iteration = do_slope_benchmark (&obj); +- +- strcpy(cpiter_buf, csv_mode ? "" : "-"); +- strcpy(mhz_buf, csv_mode ? "" : "-"); +- +- double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); +- +- /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ +- if (bench_ghz > 0.0) +- { +- cycles_per_iteration = nsecs_per_iteration * bench_ghz; +- double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); +- double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); +- } +- +- if (csv_mode) +- { +- if (auto_ghz) +- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", +- current_section_name, +- current_algo_name ? current_algo_name : "", +- current_mode_name ? current_mode_name : "", +- nsecpiter_buf, +- cpiter_buf, +- mhz_buf); +- else +- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", +- current_section_name, +- current_algo_name ? current_algo_name : "", +- current_mode_name ? current_mode_name : "", +- nsecpiter_buf, +- cpiter_buf); +- } +- else +- { +- if (auto_ghz) +- printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); +- else +- printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); +- } ++ bench_print_result_nsec_per_iteration (nsecs_per_iteration); + } + + void +@@ -2079,14 +2107,7 @@ kdf_bench (char **argv, int argc) + + bench_print_section ("kdf", "KDF"); + +- if (!csv_mode) +- { +- printf (" %-*s | ", 24, ""); +- if (auto_ghz) +- printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); +- else +- printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); +- } ++ bench_print_header_nsec_per_iteration (24, ""); + + if (argv && argc) + { +@@ -2116,13 +2137,571 @@ kdf_bench (char **argv, int argc) + } + + ++/************************************************************ ECC benchmarks. */ ++ ++#if USE_ECC ++enum bench_ecc_algo ++{ ++ ECC_ALGO_ED25519 = 0, ++ ECC_ALGO_ED448, ++ ECC_ALGO_NIST_P192, ++ ECC_ALGO_NIST_P224, ++ ECC_ALGO_NIST_P256, ++ ECC_ALGO_NIST_P384, ++ ECC_ALGO_NIST_P521, ++ ECC_ALGO_SECP256K1, ++ __MAX_ECC_ALGO ++}; ++ ++enum bench_ecc_operation ++{ ++ ECC_OPER_MULT = 0, ++ ECC_OPER_KEYGEN, ++ ECC_OPER_SIGN, ++ ECC_OPER_VERIFY, ++ __MAX_ECC_OPER ++}; ++ ++struct bench_ecc_oper ++{ ++ enum bench_ecc_operation oper; ++ const char *name; ++ struct bench_ops *ops; ++ ++ enum bench_ecc_algo algo; ++}; ++ ++struct bench_ecc_mult_hd ++{ ++ gcry_ctx_t ec; ++ gcry_mpi_t k, x, y; ++ gcry_mpi_point_t G, Q; ++}; ++ ++struct bench_ecc_hd ++{ ++ gcry_sexp_t key_spec; ++ gcry_sexp_t data; ++ gcry_sexp_t pub_key; ++ gcry_sexp_t sec_key; ++ gcry_sexp_t sig; ++}; ++ ++ ++static const char * ++ecc_algo_name (int algo) ++{ ++ switch (algo) ++ { ++ case ECC_ALGO_ED25519: ++ return "Ed25519"; ++ case ECC_ALGO_ED448: ++ return "Ed448"; ++ case ECC_ALGO_NIST_P192: ++ return "NIST-P192"; ++ case ECC_ALGO_NIST_P224: ++ return "NIST-P224"; ++ case ECC_ALGO_NIST_P256: ++ return "NIST-P256"; ++ case ECC_ALGO_NIST_P384: ++ return "NIST-P384"; ++ case ECC_ALGO_NIST_P521: ++ return "NIST-P521"; ++ case ECC_ALGO_SECP256K1: ++ return "secp256k1"; ++ default: ++ return NULL; ++ } ++} ++ ++static const char * ++ecc_algo_curve (int algo) ++{ ++ switch (algo) ++ { ++ case ECC_ALGO_ED25519: ++ return "Ed25519"; ++ case ECC_ALGO_ED448: ++ return "Ed448"; ++ case ECC_ALGO_NIST_P192: ++ return "NIST P-192"; ++ case ECC_ALGO_NIST_P224: ++ return "NIST P-224"; ++ case ECC_ALGO_NIST_P256: ++ return "NIST P-256"; ++ case ECC_ALGO_NIST_P384: ++ return "NIST P-384"; ++ case ECC_ALGO_NIST_P521: ++ return "NIST P-521"; ++ case ECC_ALGO_SECP256K1: ++ return "secp256k1"; ++ default: ++ return NULL; ++ } ++} ++ ++static int ++ecc_nbits (int algo) ++{ ++ switch (algo) ++ { ++ case ECC_ALGO_ED25519: ++ return 255; ++ case ECC_ALGO_ED448: ++ return 448; ++ case ECC_ALGO_NIST_P192: ++ return 192; ++ case ECC_ALGO_NIST_P224: ++ return 224; ++ case ECC_ALGO_NIST_P256: ++ return 256; ++ case ECC_ALGO_NIST_P384: ++ return 384; ++ case ECC_ALGO_NIST_P521: ++ return 521; ++ case ECC_ALGO_SECP256K1: ++ return 256; ++ default: ++ return 0; ++ } ++} ++ ++static int ++ecc_map_name (const char *name) ++{ ++ int i; ++ ++ for (i = 0; i < __MAX_ECC_ALGO; i++) ++ { ++ if (strcmp(ecc_algo_name(i), name) == 0) ++ { ++ return i; ++ } ++ } ++ ++ return -1; ++} ++ ++ ++static int ++bench_ecc_mult_init (struct bench_obj *obj) ++{ ++ struct bench_ecc_oper *oper = obj->priv; ++ struct bench_ecc_mult_hd *hd; ++ int p_size = ecc_nbits (oper->algo); ++ gpg_error_t err; ++ gcry_mpi_t p; ++ ++ obj->min_bufsize = 1; ++ obj->max_bufsize = 4; ++ obj->step_size = 1; ++ obj->num_measure_repetitions = ++ num_measurement_repetitions / obj->max_bufsize; ++ ++ while (obj->num_measure_repetitions == 0) ++ { ++ if (obj->max_bufsize == 2) ++ { ++ obj->num_measure_repetitions = 2; ++ } ++ else ++ { ++ obj->max_bufsize--; ++ obj->num_measure_repetitions = ++ num_measurement_repetitions / obj->max_bufsize; ++ } ++ } ++ ++ hd = calloc (1, sizeof(*hd)); ++ if (!hd) ++ return -1; ++ ++ err = gcry_mpi_ec_new (&hd->ec, NULL, ecc_algo_curve(oper->algo)); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_mpi_ec_new failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ hd->G = gcry_mpi_ec_get_point ("g", hd->ec, 1); ++ hd->Q = gcry_mpi_point_new (0); ++ hd->x = gcry_mpi_new (0); ++ hd->y = gcry_mpi_new (0); ++ hd->k = gcry_mpi_new (p_size); ++ gcry_mpi_randomize (hd->k, p_size, GCRY_WEAK_RANDOM); ++ p = gcry_mpi_ec_get_mpi ("p", hd->ec, 1); ++ gcry_mpi_mod (hd->k, hd->k, p); ++ gcry_mpi_release (p); ++ ++ obj->hd = hd; ++ return 0; ++} ++ ++static void ++bench_ecc_mult_free (struct bench_obj *obj) ++{ ++ struct bench_ecc_mult_hd *hd = obj->hd; ++ ++ gcry_mpi_release (hd->k); ++ gcry_mpi_release (hd->y); ++ gcry_mpi_release (hd->x); ++ gcry_mpi_point_release (hd->Q); ++ gcry_mpi_point_release (hd->G); ++ gcry_ctx_release (hd->ec); ++ free (hd); ++ obj->hd = NULL; ++} ++ ++static void ++bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) ++{ ++ struct bench_ecc_mult_hd *hd = obj->hd; ++ size_t i; ++ ++ (void)buf; ++ ++ for (i = 0; i < num_iter; i++) ++ { ++ gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec); ++ if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec)) ++ { ++ fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n"); ++ exit (1); ++ } ++ } ++} ++ ++ ++static int ++bench_ecc_init (struct bench_obj *obj) ++{ ++ struct bench_ecc_oper *oper = obj->priv; ++ struct bench_ecc_hd *hd; ++ int p_size = ecc_nbits (oper->algo); ++ gpg_error_t err; ++ gcry_mpi_t x; ++ ++ obj->min_bufsize = 1; ++ obj->max_bufsize = 4; ++ obj->step_size = 1; ++ obj->num_measure_repetitions = ++ num_measurement_repetitions / obj->max_bufsize; ++ ++ while (obj->num_measure_repetitions == 0) ++ { ++ if (obj->max_bufsize == 2) ++ { ++ obj->num_measure_repetitions = 2; ++ } ++ else ++ { ++ obj->max_bufsize--; ++ obj->num_measure_repetitions = ++ num_measurement_repetitions / obj->max_bufsize; ++ } ++ } ++ ++ hd = calloc (1, sizeof(*hd)); ++ if (!hd) ++ return -1; ++ ++ x = gcry_mpi_new (p_size); ++ gcry_mpi_randomize (x, p_size, GCRY_WEAK_RANDOM); ++ ++ switch (oper->algo) ++ { ++ default: ++ return -1; ++ ++ case ECC_ALGO_ED25519: ++ err = gcry_sexp_build (&hd->key_spec, NULL, ++ "(genkey (ecdsa (curve \"Ed25519\")" ++ "(flags eddsa)))"); ++ if (err) ++ break; ++ err = gcry_sexp_build (&hd->data, NULL, ++ "(data (flags eddsa)(hash-algo sha512)" ++ " (value %m))", x); ++ break; ++ ++ case ECC_ALGO_ED448: ++ err = gcry_sexp_build (&hd->key_spec, NULL, ++ "(genkey (ecdsa (curve \"Ed448\")" ++ "(flags eddsa)))"); ++ if (err) ++ break; ++ err = gcry_sexp_build (&hd->data, NULL, ++ "(data (flags eddsa)(hash-algo shake256)" ++ " (value %m))", x); ++ break; ++ ++ case ECC_ALGO_NIST_P192: ++ case ECC_ALGO_NIST_P224: ++ case ECC_ALGO_NIST_P256: ++ case ECC_ALGO_NIST_P384: ++ case ECC_ALGO_NIST_P521: ++ err = gcry_sexp_build (&hd->key_spec, NULL, ++ "(genkey (ECDSA (nbits %d)))", p_size); ++ if (err) ++ break; ++ err = gcry_sexp_build (&hd->data, NULL, ++ "(data (flags raw) (value %m))", x); ++ break; ++ } ++ ++ gcry_mpi_release (x); ++ ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_sexp_build failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ ++ obj->hd = hd; ++ return 0; ++} ++ ++static void ++bench_ecc_free (struct bench_obj *obj) ++{ ++ struct bench_ecc_hd *hd = obj->hd; ++ ++ gcry_sexp_release (hd->sig); ++ gcry_sexp_release (hd->pub_key); ++ gcry_sexp_release (hd->sec_key); ++ gcry_sexp_release (hd->data); ++ gcry_sexp_release (hd->key_spec); ++ free (hd); ++ obj->hd = NULL; ++} ++ ++static void ++bench_ecc_keygen (struct bench_ecc_hd *hd) ++{ ++ gcry_sexp_t key_pair; ++ gpg_error_t err; ++ ++ err = gcry_pk_genkey (&key_pair, hd->key_spec); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_pk_genkey failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ ++ hd->pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); ++ if (!hd->pub_key) ++ { ++ fprintf (stderr, PGM ": public part missing in key\n"); ++ exit (1); ++ } ++ hd->sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); ++ if (!hd->sec_key) ++ { ++ fprintf (stderr, PGM ": private part missing in key\n"); ++ exit (1); ++ } ++ ++ gcry_sexp_release (key_pair); ++} ++ ++static void ++bench_ecc_keygen_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) ++{ ++ struct bench_ecc_hd *hd = obj->hd; ++ size_t i; ++ ++ (void)buf; ++ ++ for (i = 0; i < num_iter; i++) ++ { ++ bench_ecc_keygen (hd); ++ gcry_sexp_release (hd->pub_key); ++ gcry_sexp_release (hd->sec_key); ++ } ++ ++ hd->pub_key = NULL; ++ hd->sec_key = NULL; ++} ++ ++static void ++bench_ecc_sign_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) ++{ ++ struct bench_ecc_hd *hd = obj->hd; ++ gpg_error_t err; ++ size_t i; ++ ++ (void)buf; ++ ++ bench_ecc_keygen (hd); ++ ++ for (i = 0; i < num_iter; i++) ++ { ++ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ gcry_sexp_release (hd->sig); ++ } ++ ++ gcry_sexp_release (hd->pub_key); ++ gcry_sexp_release (hd->sec_key); ++ hd->sig = NULL; ++ hd->pub_key = NULL; ++ hd->sec_key = NULL; ++} ++ ++static void ++bench_ecc_verify_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) ++{ ++ struct bench_ecc_hd *hd = obj->hd; ++ gpg_error_t err; ++ int i; ++ ++ (void)buf; ++ ++ bench_ecc_keygen (hd); ++ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ ++ for (i = 0; i < num_iter; i++) ++ { ++ err = gcry_pk_verify (hd->sig, hd->data, hd->pub_key); ++ if (err) ++ { ++ fprintf (stderr, PGM ": gcry_pk_verify failed: %s\n", ++ gpg_strerror (err)); ++ exit (1); ++ } ++ } ++ ++ gcry_sexp_release (hd->sig); ++ gcry_sexp_release (hd->pub_key); ++ gcry_sexp_release (hd->sec_key); ++ hd->sig = NULL; ++ hd->pub_key = NULL; ++ hd->sec_key = NULL; ++} ++ ++ ++static struct bench_ops ecc_mult_ops = { ++ &bench_ecc_mult_init, ++ &bench_ecc_mult_free, ++ &bench_ecc_mult_do_bench ++}; ++ ++static struct bench_ops ecc_keygen_ops = { ++ &bench_ecc_init, ++ &bench_ecc_free, ++ &bench_ecc_keygen_do_bench ++}; ++ ++static struct bench_ops ecc_sign_ops = { ++ &bench_ecc_init, ++ &bench_ecc_free, ++ &bench_ecc_sign_do_bench ++}; ++ ++static struct bench_ops ecc_verify_ops = { ++ &bench_ecc_init, ++ &bench_ecc_free, ++ &bench_ecc_verify_do_bench ++}; ++ ++ ++static struct bench_ecc_oper ecc_operations[] = { ++ { ECC_OPER_MULT, "mult", &ecc_mult_ops }, ++ { ECC_OPER_KEYGEN, "keygen", &ecc_keygen_ops }, ++ { ECC_OPER_SIGN, "sign", &ecc_sign_ops }, ++ { ECC_OPER_VERIFY, "verify", &ecc_verify_ops }, ++ { 0, NULL, NULL } ++}; ++ ++ ++static void ++cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper) ++{ ++ struct bench_ecc_oper oper = *poper; ++ struct bench_obj obj = { 0 }; ++ double result; ++ ++ if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT) ++ return; ++ ++ oper.algo = algo; ++ ++ bench_print_mode (14, oper.name); ++ ++ obj.ops = oper.ops; ++ obj.priv = &oper; ++ ++ result = do_slope_benchmark (&obj); ++ bench_print_result_nsec_per_iteration (result); ++} ++ ++ ++static void ++_ecc_bench (int algo) ++{ ++ const char *algo_name; ++ int i; ++ ++ algo_name = ecc_algo_name (algo); ++ ++ bench_print_header_nsec_per_iteration (14, algo_name); ++ ++ for (i = 0; ecc_operations[i].name; i++) ++ cipher_ecc_one (algo, &ecc_operations[i]); ++ ++ bench_print_footer (14); ++} ++#endif ++ ++ ++void ++ecc_bench (char **argv, int argc) ++{ ++#if USE_ECC ++ int i, algo; ++ ++ bench_print_section ("ecc", "ECC"); ++ ++ if (argv && argc) ++ { ++ for (i = 0; i < argc; i++) ++ { ++ algo = ecc_map_name (argv[i]); ++ if (algo >= 0) ++ _ecc_bench (algo); ++ } ++ } ++ else ++ { ++ for (i = 0; i < __MAX_ECC_ALGO; i++) ++ _ecc_bench (i); ++ } ++#else ++ (void)argv; ++ (void)argc; ++#endif ++} ++ + /************************************************************** Main program. */ + + void + print_help (void) + { + static const char *help_lines[] = { +- "usage: bench-slope [options] [hash|mac|cipher|kdf [algonames]]", ++ "usage: bench-slope [options] [hash|mac|cipher|kdf|ecc [algonames]]", + "", + " options:", + " --cpu-mhz Set CPU speed for calculating cycles", +@@ -2304,6 +2883,7 @@ main (int argc, char **argv) + mac_bench (NULL, 0); + cipher_bench (NULL, 0); + kdf_bench (NULL, 0); ++ ecc_bench (NULL, 0); + } + else if (!strcmp (*argv, "hash")) + { +@@ -2337,6 +2917,14 @@ main (int argc, char **argv) + warm_up_cpu (); + kdf_bench ((argc == 0) ? NULL : argv, argc); + } ++ else if (!strcmp (*argv, "ecc")) ++ { ++ argc--; ++ argv++; ++ ++ warm_up_cpu (); ++ ecc_bench ((argc == 0) ? NULL : argv, argc); ++ } + else + { + fprintf (stderr, PGM ": unknown argument: %s\n", *argv); + +commit 9911069388e762d2a85bc2a11ca6cfcc4c895e4f +Author: Jussi Kivilinna +Date: Wed Jun 16 20:27:01 2021 +0300 + + bench-slope: add X25519 and X448 scalar multiplication + + * tests/bench-slope.c (ECC_ALGO_X25519, ECC_ALGO_X448): New. + (ecc_algo_name, ecc_algo_curve, ecc_nbits): Add X25519 and X448. + (bench_ecc_mult_do_bench): Pass Y as NULL to ec_get_affine with + X25519 and X448. + (cipher_ecc_one): Run only multiplication bench for X25519 and X448. + -- + + Signed-off-by: Jussi Kivilinna + +diff --git a/tests/bench-slope.c b/tests/bench-slope.c +index 9b4a139a..35272094 100644 +--- a/tests/bench-slope.c ++++ b/tests/bench-slope.c +@@ -2144,6 +2144,8 @@ enum bench_ecc_algo + { + ECC_ALGO_ED25519 = 0, + ECC_ALGO_ED448, ++ ECC_ALGO_X25519, ++ ECC_ALGO_X448, + ECC_ALGO_NIST_P192, + ECC_ALGO_NIST_P224, + ECC_ALGO_NIST_P256, +@@ -2197,6 +2199,10 @@ ecc_algo_name (int algo) + return "Ed25519"; + case ECC_ALGO_ED448: + return "Ed448"; ++ case ECC_ALGO_X25519: ++ return "X25519"; ++ case ECC_ALGO_X448: ++ return "X448"; + case ECC_ALGO_NIST_P192: + return "NIST-P192"; + case ECC_ALGO_NIST_P224: +@@ -2223,6 +2229,10 @@ ecc_algo_curve (int algo) + return "Ed25519"; + case ECC_ALGO_ED448: + return "Ed448"; ++ case ECC_ALGO_X25519: ++ return "Curve25519"; ++ case ECC_ALGO_X448: ++ return "X448"; + case ECC_ALGO_NIST_P192: + return "NIST P-192"; + case ECC_ALGO_NIST_P224: +@@ -2249,6 +2259,10 @@ ecc_nbits (int algo) + return 255; + case ECC_ALGO_ED448: + return 448; ++ case ECC_ALGO_X25519: ++ return 255; ++ case ECC_ALGO_X448: ++ return 448; + case ECC_ALGO_NIST_P192: + return 192; + case ECC_ALGO_NIST_P224: +@@ -2355,15 +2369,26 @@ bench_ecc_mult_free (struct bench_obj *obj) + static void + bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) + { ++ struct bench_ecc_oper *oper = obj->priv; + struct bench_ecc_mult_hd *hd = obj->hd; ++ gcry_mpi_t y; + size_t i; + + (void)buf; + ++ if (oper->algo == ECC_ALGO_X25519 || oper->algo == ECC_ALGO_X448) ++ { ++ y = NULL; ++ } ++ else ++ { ++ y = hd->y; ++ } ++ + for (i = 0; i < num_iter; i++) + { + gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec); +- if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec)) ++ if (gcry_mpi_ec_get_affine (hd->x, y, hd->Q, hd->ec)) + { + fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n"); + exit (1); +@@ -2634,7 +2659,8 @@ cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper) + struct bench_obj obj = { 0 }; + double result; + +- if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT) ++ if ((algo == ECC_ALGO_X25519 || algo == ECC_ALGO_X448 || ++ algo == ECC_ALGO_SECP256K1) && oper.oper != ECC_OPER_MULT) + return; + + oper.algo = algo; + + +From bd49a4fa915b8a078c341b35f5a51fcb2a004c35 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 12 Jul 2021 21:35:18 +0200 +Subject: [PATCH 1/8] mac: Disable AES GMAC in FIPS mode + +* cipher/mac-gmac.c (_gcry_mac_type_spec_gmac_aes): Remove FIPS flag +-- +The GMAC does not work in FIPS mode until libgcrypt will have internal +IV generator. + +Signed-off-by: Jakub Jelen +--- + cipher/mac-gmac.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/cipher/mac-gmac.c b/cipher/mac-gmac.c +index e04c6d1e..1d59d085 100644 +--- a/cipher/mac-gmac.c ++++ b/cipher/mac-gmac.c +@@ -157,7 +157,7 @@ static gcry_mac_spec_ops_t gmac_ops = { + + #if USE_AES + gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = { +- GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES", ++ GCRY_MAC_GMAC_AES, {0, 0}, "GMAC_AES", + &gmac_ops + }; + #endif +-- +2.31.1 + + +From fd0e1c3e7f6062579869d345875d6ef823706e56 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 12 Jul 2021 21:36:34 +0200 +Subject: [PATCH 2/8] tests: Do not expect GCM work in FIPS + +* tests/basic.c (check_one_cipher_core): Expect GCM ciphers to fail in + FIPS mode + (check_cipher_modes): Skip GCM ciphers tests as they fail quite late + in gcry_cipher_gettag(). +-- + +Signed-off-by: Jakub Jelen +--- + tests/basic.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/tests/basic.c b/tests/basic.c +index 0572c46e..d7b7f496 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -9510,6 +9510,13 @@ check_one_cipher_core (int algo, int mode, int flags, + + clutter_vector_registers(); + err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain); ++ if (in_fips_mode && mode == GCRY_CIPHER_MODE_GCM) ++ { ++ if (!err) ++ fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt is expected to " ++ "fail in FIPS mode: %s\n", pass, algo, mode, gpg_strerror (err)); ++ goto err_out_free; ++ } + if (err) + { + fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", +@@ -10257,7 +10264,12 @@ check_cipher_modes(void) + check_cfb_cipher (); + check_ofb_cipher (); + check_ccm_cipher (); +- check_gcm_cipher (); ++ if (!in_fips_mode) ++ { ++ /* This will have to go through modifications as the GCM fails in fips ++ * as late as in gcry_cipher_gettag, but we want to allow it in the end */ ++ check_gcm_cipher (); ++ } + check_poly1305_cipher (); + check_ocb_cipher (); + check_xts_cipher (); +-- +2.31.1 + + +From ccbb1694693080822858e2065cf88ab43ec03fbc Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 09:18:52 +0200 +Subject: [PATCH 3/8] tests: Skip unsupported mechanisms in FIPS mode + +* tests/bench-slope.c (cipher_bench_one): Skip GCM mode in FIPS mode + (ecc_algo_fips_allowed): New function + (_ecc_bench): Skip algorithms disabled in FIPS mode + (main): Check for FIPS mode +* tests/benchmark.c (cipher_bench): Skip GCM in FIPS mode +-- +In FIPS mode, not all the curves are allowed. This is already checked in +other parts of the code base, but not in the benchmark test. + +Signed-off-by: Jakub Jelen +--- + tests/bench-slope.c | 33 +++++++++++++++++++++++++++++++-- + tests/benchmark.c | 4 ++++ + 2 files changed, 35 insertions(+), 2 deletions(-) + +diff --git a/tests/bench-slope.c b/tests/bench-slope.c +index 35272094..5bdb391e 100644 +--- a/tests/bench-slope.c ++++ b/tests/bench-slope.c +@@ -70,6 +70,7 @@ static double bench_ghz; + /* Current accuracy of auto-detected CPU Ghz. */ + static double bench_ghz_diff; + ++static int in_fips_mode = 0; + + /*************************************** Default parameters for measurements. */ + +@@ -1642,8 +1643,8 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode) + if (mode.mode == GCRY_CIPHER_MODE_CCM && blklen != GCRY_CCM_BLOCK_LEN) + return; + +- /* GCM has restrictions for block-size */ +- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) ++ /* GCM has restrictions for block-size; not allowed in FIPS mode */ ++ if (mode.mode == GCRY_CIPHER_MODE_GCM && (in_fips_mode || blklen != GCRY_GCM_BLOCK_LEN)) + return; + + /* XTS has restrictions for block-size */ +@@ -2190,6 +2191,27 @@ struct bench_ecc_hd + }; + + ++static int ++ecc_algo_fips_allowed (int algo) ++{ ++ switch (algo) ++ { ++ case ECC_ALGO_NIST_P224: ++ case ECC_ALGO_NIST_P256: ++ case ECC_ALGO_NIST_P384: ++ case ECC_ALGO_NIST_P521: ++ return 1; ++ case ECC_ALGO_SECP256K1: ++ case ECC_ALGO_ED25519: ++ case ECC_ALGO_ED448: ++ case ECC_ALGO_X25519: ++ case ECC_ALGO_X448: ++ case ECC_ALGO_NIST_P192: ++ default: ++ return 0; ++ } ++} ++ + static const char * + ecc_algo_name (int algo) + { +@@ -2681,6 +2703,10 @@ _ecc_bench (int algo) + const char *algo_name; + int i; + ++ /* Skip not allowed mechanisms */ ++ if (!ecc_algo_fips_allowed(algo)) ++ return; ++ + algo_name = ecc_algo_name (algo); + + bench_print_header_nsec_per_iteration (14, algo_name); +@@ -2899,6 +2925,9 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; ++ + if (in_regression_test) + fputs ("Note: " PGM " running in quick regression test mode.\n", stdout); + +diff --git a/tests/benchmark.c b/tests/benchmark.c +index 605b50c6..24141371 100644 +--- a/tests/benchmark.c ++++ b/tests/benchmark.c +@@ -943,6 +943,10 @@ cipher_bench ( const char *algoname ) + && algo != GCRY_CIPHER_CHACHA20) + continue; + ++ /* GCM is not available in FIPS mode */ ++ if (in_fips_mode && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM) ++ continue; ++ + if (modes[modeidx].req_blocksize > 0 + && blklen != modes[modeidx].req_blocksize) + { +-- +2.31.1 + + +From 744baa85722da10d7374c6eca6b08b8197819ab6 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 09:20:18 +0200 +Subject: [PATCH 4/8] tests: Expect curves 25519/448 to fail in FIPS mode + +* tests/t-cv25519.c (test_cv_hl): Expect the operation to fail in FIPS + mode. + (test_cv_x25519, test_it): Ditto. + (main) Detect FIPS mode. +* tests/t-ed25519.c (one_test): Expect the operation to fail in FIPS + mode. + (main) Detect FIPS mode. +* tests/t-ed448.c (one_test): Expect the operation to fail in FIPS + mode. + (main) Detect FIPS mode. +* tests/t-x448.c (test_cv_hl): Expect the operation to fail in FIPS + mode. + (test_cv_x448, test_cv): Ditto. + (main) Detect FIPS mode. +-- +The ed25519, ed448, cv25519 and cv448 curves are not available in FIPS +mode. Some of the tests already skipped these, but it is always better +to make sure thy are failing, rather than just skipping these. + +Signed-off-by: Jakub Jelen +--- + tests/t-cv25519.c | 37 +++++++++++++++++++++++++++++++++++-- + tests/t-ed25519.c | 18 ++++++++++++++---- + tests/t-ed448.c | 18 ++++++++++++++---- + tests/t-x448.c | 41 +++++++++++++++++++++++++++++++++++++---- + 4 files changed, 100 insertions(+), 14 deletions(-) + +diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c +index 0de50a02..b4126f4c 100644 +--- a/tests/t-cv25519.c ++++ b/tests/t-cv25519.c +@@ -33,6 +33,7 @@ + #include "t-common.h" + #define N_TESTS 18 + ++static int in_fips_mode = 0; + + static void + print_mpi (const char *text, gcry_mpi_t a) +@@ -188,7 +189,17 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, + xfree (buffer); + buffer = NULL; + +- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) ++ err = gcry_pk_encrypt (&s_result, s_data, s_pk); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_pk_encrypt failed for test %d: %s", testno, + gpg_strerror (err)); + +@@ -281,7 +292,17 @@ test_cv_x25519 (int testno, const char *k_str, const char *u_str, + goto leave; + } + +- if ((err = gcry_ecc_mul_point (algo, result, scalar, point))) ++ err = gcry_ecc_mul_point (algo, result, scalar, point); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_ecc_mul_point failed for test %d: %s", testno, + gpg_strerror (err)); + +@@ -335,6 +356,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) + info ("Running test %d: iteration=%d\n", testno, iter); + + gcry_mpi_ec_new (&ctx, NULL, "Curve25519"); ++ if (in_fips_mode) ++ { ++ if (ctx) ++ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ return; ++ } + Q = gcry_mpi_point_new (0); + + if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32) +@@ -640,6 +670,9 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; ++ + start_timer (); + check_cv25519 (); + stop_timer (); +diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c +index a5271c25..567bc797 100644 +--- a/tests/t-ed25519.c ++++ b/tests/t-ed25519.c +@@ -36,6 +36,7 @@ + static int sign_with_pk; + static int no_verify; + static int custom_data_file; ++static int in_fips_mode = 0; + + + static void +@@ -271,7 +272,17 @@ one_test (int testno, const char *sk, const char *pk, + goto leave; + } + +- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) ++ err = gcry_pk_sign (&s_sig, s_msg, s_sk); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); + if (debug) + show_sexp ("sig=", s_sig); +@@ -481,9 +492,8 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + +- /* Ed25519 isn't supported in fips mode */ +- if (gcry_fips_mode_active()) +- return 77; ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; + + start_timer (); + check_ed25519 (fname); +diff --git a/tests/t-ed448.c b/tests/t-ed448.c +index 1f445ffc..f38cd10c 100644 +--- a/tests/t-ed448.c ++++ b/tests/t-ed448.c +@@ -36,6 +36,7 @@ + static int sign_with_pk; + static int no_verify; + static int custom_data_file; ++static int in_fips_mode = 0; + + + static void +@@ -302,7 +303,17 @@ one_test (int testno, int ph, const char *sk, const char *pk, + } + } + +- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) ++ err = gcry_pk_sign (&s_sig, s_msg, s_sk); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); + if (debug) + show_sexp ("sig=", s_sig); +@@ -521,9 +532,8 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + +- /* Ed448 isn't supported in fips mode */ +- if (gcry_fips_mode_active()) +- return 77; ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; + + start_timer (); + check_ed448 (fname); +diff --git a/tests/t-x448.c b/tests/t-x448.c +index 5c3cbeb9..cc4b10fc 100644 +--- a/tests/t-x448.c ++++ b/tests/t-x448.c +@@ -34,6 +34,7 @@ + #include "t-common.h" + #define N_TESTS 9 + ++static int in_fips_mode = 0; + + static void + print_mpi (const char *text, gcry_mpi_t a) +@@ -179,8 +180,18 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, + xfree (buffer); + buffer = NULL; + +- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) +- fail ("gcry_pk_encrypt failed for test %d: %s", testno, ++ err = gcry_pk_encrypt (&s_result, s_data, s_pk); ++ if (in_fips_mode) ++ { ++ if (!err) ++ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) ++ fail ("gcry_pk_encrypt goto leavefailed for test %d: %s", testno, + gpg_strerror (err)); + + s_tmp = gcry_sexp_find_token (s_result, "s", 0); +@@ -257,7 +268,17 @@ test_cv_x448 (int testno, const char *k_str, const char *u_str, + goto leave; + } + +- if ((err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point))) ++ err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point); ++ if (in_fips_mode) ++ { ++ if (err != GPG_ERR_NOT_SUPPORTED) ++ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d: %s", ++ testno, gpg_strerror (err)); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ goto leave; ++ } ++ if (err) + fail ("gcry_ecc_mul_point failed for test %d: %s", testno, + gpg_strerror (err)); + +@@ -296,7 +317,7 @@ test_cv (int testno, const char *k_str, const char *u_str, + static void + test_it (int testno, const char *k_str, int iter, const char *result_str) + { +- gcry_ctx_t ctx; ++ gcry_ctx_t ctx = NULL; + gpg_error_t err; + void *buffer = NULL; + size_t buflen; +@@ -311,6 +332,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) + info ("Running test %d: iteration=%d\n", testno, iter); + + gcry_mpi_ec_new (&ctx, NULL, "X448"); ++ if (in_fips_mode) ++ { ++ if (ctx) ++ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", ++ testno); ++ if (verbose > 1) ++ info ("not executed in FIPS mode\n"); ++ return; ++ } + Q = gcry_mpi_point_new (0); + + if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 56) +@@ -583,6 +613,9 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); + ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; ++ + start_timer (); + check_x448 (); + stop_timer (); +-- +2.31.1 + + +From d3a603cd4a0ff2a8df35f5bb39efd64c52b2b2c5 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 10:11:42 +0200 +Subject: [PATCH 5/8] tests: Expect the 192b ECDSA tests to fail in fips mode + +* tests/dsa-rfc6979.c (check_dsa_rfc6979): Expect ECDSA 192b keys to + fail in FIPS mode. + (main): Detect FIPS mode. +-- +The 192b ECDSA curve is not FIPS approved so it does not work. This adds +a flag to the list of the keys to mark if it is expected to work in FIPS +mode. + +Signed-off-by: Jakub Jelen +--- + tests/dsa-rfc6979.c | 24 +++++++++++++++++------- + 1 file changed, 17 insertions(+), 7 deletions(-) + +diff --git a/tests/dsa-rfc6979.c b/tests/dsa-rfc6979.c +index 7d3d2080..0f124575 100644 +--- a/tests/dsa-rfc6979.c ++++ b/tests/dsa-rfc6979.c +@@ -33,6 +33,7 @@ + #define PGM "dsa-rfc6979" + #include "t-common.h" + ++static int in_fips_mode = 0; + + static void + show_sexp (const char *prefix, gcry_sexp_t a) +@@ -111,6 +112,7 @@ check_dsa_rfc6979 (void) + static struct { + const char *name; + const char *key; ++ int fips; + } keys[] = { + { + "DSA, 1024 bits", +@@ -130,7 +132,7 @@ check_dsa_rfc6979 (void) + " 92195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D" + " 4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E6" + " 82F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B#)" +- " ))" ++ " ))", 1 + }, + { + "DSA, 2048 bits", +@@ -162,7 +164,7 @@ check_dsa_rfc6979 (void) + " 687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D1" + " 23AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA" + " 74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)" +- " ))" ++ " ))", 1 + }, + { + "ECDSA, 192 bits (prime field)", +@@ -172,7 +174,7 @@ check_dsa_rfc6979 (void) + " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" + " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" + " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" +- " ))" ++ " ))", 0 + }, + { + "ECDSA, 224 bits (prime field)", +@@ -183,7 +185,7 @@ check_dsa_rfc6979 (void) + " 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C" + " EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)" + " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)" +- " ))" ++ " ))", 1 + }, + { + "ECDSA, 256 bits (prime field)", +@@ -194,7 +196,7 @@ check_dsa_rfc6979 (void) + " 60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6" + " 7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)" + " (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)" +- " ))" ++ " ))", 1 + }, + { + "ECDSA, 384 bits (prime field)", +@@ -208,7 +210,7 @@ check_dsa_rfc6979 (void) + " 288B231C3AE0D4FE7344FD2533264720#)" + " (d #6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8" + " 96D5724E4C70A825F872C9EA60D2EDF5#)" +- " ))" ++ " ))", 1 + }, + { + "ECDSA, 521 bits (prime field)", +@@ -225,7 +227,7 @@ check_dsa_rfc6979 (void) + " (d #FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75" + " CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B8" + " 3538#)" +- " ))" ++ " ))", 1 + }, + { NULL } + }; +@@ -937,6 +939,12 @@ check_dsa_rfc6979 (void) + die ("building data sexp failed: %s\n", gpg_strerror (err)); + + err = gcry_pk_sign (&sig, data, seckey); ++ if (in_fips_mode && !keys[i].fips) ++ { ++ if (!err) ++ fail ("signing should not work in FIPS mode: %s\n", gpg_strerror (err)); ++ continue; ++ } + if (err) + fail ("signing failed: %s\n", gpg_strerror (err)); + +@@ -972,6 +980,8 @@ main (int argc, char **argv) + die ("version mismatch; pgm=%s, library=%s\n", + GCRYPT_VERSION,gcry_check_version (NULL)); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; + if (debug) + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); + /* No valuable keys are create, so we can speed up our RNG. */ +-- +2.31.1 + + +From d4a52861e7d0d1871f4c1d32bc0815f0824eb9ab Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 10:32:33 +0200 +Subject: [PATCH 6/8] tests: Skip secmem overflow test in FIPS mode + +* tests/t-secmem.c (main): Skip overflow tests in FIPS mode because they + are fatal and there is no way to override the outofcore handler. +-- + +Signed-off-by: Jakub Jelen +--- + tests/t-secmem.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +diff --git a/tests/t-secmem.c b/tests/t-secmem.c +index 2b769134..692c0f1a 100644 +--- a/tests/t-secmem.c ++++ b/tests/t-secmem.c +@@ -37,6 +37,7 @@ + #define MINIMUM_POOL_SIZE 16384 + static size_t pool_size; + static size_t chunk_size; ++static int in_fips_mode = 0; + + static void + test_secmem (void) +@@ -182,8 +183,11 @@ main (int argc, char **argv) + xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0)); ++ /* This is ignored in FIPS Mode */ + gcry_set_outofcore_handler (outofcore_handler, NULL); + xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; + + /* Libgcrypt prints a warning when the first overflow is allocated; + * we do not want to see that. */ +@@ -192,7 +196,8 @@ main (int argc, char **argv) + + + test_secmem (); +- test_secmem_overflow (); ++ if (!in_fips_mode) ++ test_secmem_overflow (); + /* FIXME: We need to improve the tests, for example by registering + * our own log handler and comparing the output of + * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */ +-- +2.31.1 + + +From fc6de9c7b48ab45deb8ea84d1c768e4f056edb08 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 10:52:00 +0200 +Subject: [PATCH 7/8] tests: Transient DSA keys work in FIPS mode + +* tests/pubkey.c (check_run): Enable tests with DSA transient keys which + work in FIPS. +-- + +Signed-off-by: Jakub Jelen +--- + tests/pubkey.c | 15 ++++++--------- + 1 file changed, 6 insertions(+), 9 deletions(-) + +diff --git a/tests/pubkey.c b/tests/pubkey.c +index 754952ee..cd51e0a2 100644 +--- a/tests/pubkey.c ++++ b/tests/pubkey.c +@@ -680,15 +680,12 @@ check_run (void) + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + +- if (!gcry_fips_mode_active ()) +- { +- if (verbose) +- fprintf (stderr, "Generating transient DSA key.\n"); +- get_dsa_key_new (&pkey, &skey, 1); +- /* Fixme: Add a check function for DSA keys. */ +- gcry_sexp_release (pkey); +- gcry_sexp_release (skey); +- } ++ if (verbose) ++ fprintf (stderr, "Generating transient DSA key.\n"); ++ get_dsa_key_new (&pkey, &skey, 1); ++ /* Fixme: Add a check function for DSA keys. */ ++ gcry_sexp_release (pkey); ++ gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key (FIPS 186).\n"); +-- +2.31.1 + + +From e68b538008063938b9b054f18e56e9f27bb3a720 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Tue, 13 Jul 2021 10:53:13 +0200 +Subject: [PATCH 8/8] tests: Generating DSA from domain should fail in FIPS + mode + +* tests/pubkey.c (get_dsa_key_with_domain_new): Expect failure in FIPS + mode + (check_x931_derived_key): Simplify testing for FIPS mode. + (main): Check for fips mode. +-- + +Signed-off-by: Jakub Jelen +--- + tests/pubkey.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/tests/pubkey.c b/tests/pubkey.c +index cd51e0a2..7209f44e 100644 +--- a/tests/pubkey.c ++++ b/tests/pubkey.c +@@ -29,6 +29,7 @@ + #define PGM "pubkey" + #include "t-common.h" + ++static int in_fips_mode; + + /* Sample RSA keys, taken from basic.c. */ + +@@ -518,6 +519,14 @@ get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); ++ if (in_fips_mode) ++ { ++ if (!rc) ++ die ("generating DSA key should fail in FIPS mode: %s\n", gcry_strerror (rc)); ++ *pkey = NULL; ++ *skey = NULL; ++ return; ++ } + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + +@@ -899,7 +908,7 @@ check_x931_derived_key (int what) + err = _gcry_pk_util_get_nbits(key_spec, &nbits); + if (err) + die ("nbits not found\n"); +- if (gcry_fips_mode_active() && nbits < 2048) ++ if (in_fips_mode && nbits < 2048) + { + info("RSA key test with %d bits skipped in fips mode\n", nbits); + goto leave; +@@ -1186,6 +1195,9 @@ main (int argc, char **argv) + /* No valuable keys are create, so we can speed up our RNG. */ + xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); + ++ if (gcry_fips_mode_active ()) ++ in_fips_mode = 1; ++ + for (i=0; i < 2; i++) + check_run (); + +@@ -1193,7 +1205,7 @@ main (int argc, char **argv) + check_x931_derived_key (i); + + check_ecc_sample_key (); +- if (!gcry_fips_mode_active ()) ++ if (!in_fips_mode) + check_ed25519ecdsa_sample_key (); + + return !!error_count; +-- +2.31.1 + +commit 61c87070abc4baeb9d847db015e6a3031f349483 +Author: NIIBE Yutaka +Date: Wed Jul 7 15:52:06 2021 +0900 + + tests: Skip unavailable ciphers in FIPS mode. + + * tests/basic.c (_check_poly1305_cipher): + (check_ocb_cipher_largebuf_split): Skip unavailable ciphers when + IN_FIPS_MODE. + (check_ocb_cipher_checksum, check_gost28147_cipher_basic): Likewise. + + -- + + GnuPG-bug-id: 5520 + Signed-off-by: NIIBE Yutaka + +diff --git a/tests/basic.c b/tests/basic.c +index 0a1e8293..43ef122e 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -5026,6 +5026,14 @@ _check_poly1305_cipher (unsigned int step) + + for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) + { ++ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ tv[i].algo); ++ continue; ++ } ++ + if (verbose) + fprintf (stderr, " checking POLY1305 mode for %s [%i]\n", + gcry_cipher_algo_name (tv[i].algo), +@@ -6643,6 +6651,14 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, + memcpy(inbuf + i, hash, 16); + } + ++ if (gcry_cipher_test_algo (algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ algo); ++ goto out_free; ++ } ++ + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) + err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); +@@ -6841,6 +6857,14 @@ check_ocb_cipher_checksum (int algo, int keylen) + blk[byteidx] |= 1 << bitpos; + } + ++ if (gcry_cipher_test_algo (algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ algo); ++ goto out_free; ++ } ++ + err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); + if (!err) + err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); +@@ -7651,6 +7675,15 @@ check_gost28147_cipher_basic (enum gcry_cipher_algos algo) + + if (verbose) + fprintf (stderr, " Starting GOST28147 cipher checks.\n"); ++ ++ if (gcry_cipher_test_algo (algo) && in_fips_mode) ++ { ++ if (verbose) ++ fprintf (stderr, " algorithm %d not available in fips mode\n", ++ algo); ++ return; ++ } ++ + keylen = gcry_cipher_get_algo_keylen(algo); + if (!keylen) + { +commit b98ca3f798abd17696f52163665204c4e83d9092 +Author: Jussi Kivilinna +Date: Wed Jul 7 18:21:27 2021 +0300 + + tests/basic: use SHA256 instead of RMD160 for SHAKE extract testing + + * tests/basic.c (check_one_md): Use GCRY_MD_SHA256 as 'crcalgo' for + SHAKE128/SHAKE256 testing. + -- + + RMD160 was used to calculate output checksum from two SHAKE extract + streams, which are run with different extract buffer size but for + same total length and with same input. Patch switches to use SHA256 + for checksumming for FIPS support. + + GnuPG-bug-id: 5520 + Signed-off-by: Jussi Kivilinna + +diff --git a/tests/basic.c b/tests/basic.c +index bc34bb99..eb6d1514 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -10395,7 +10395,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen, + + if (*data == '!' && !data[1]) + { +- int crcalgo = GCRY_MD_RMD160; ++ int crcalgo = GCRY_MD_SHA256; + gcry_md_hd_t crc1, crc2; + size_t startlen; + size_t piecelen; +commit ccb076e8aabb9c49e7026258b3a36a8422f6bbe4 +Author: NIIBE Yutaka +Date: Wed Jul 7 16:29:48 2021 +0900 + + tests: Fix tests/basic.c for FIPS mode. + + * tests/basic.c (main): Use bare gcry_control for + GCRYCTL_FORCE_FIPS_MODE. + + -- + + GnuPG-bug-id: 5520 + Signed-off-by: NIIBE Yutaka + +diff --git a/tests/basic.c b/tests/basic.c +index 43ef122e..bc34bb99 100644 +--- a/tests/basic.c ++++ b/tests/basic.c +@@ -14610,7 +14610,7 @@ main (int argc, char **argv) + gcry_md_hd_t md; + + /* First trigger a self-test. */ +- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); ++ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("not in operational state after self-test\n"); + +@@ -14639,7 +14639,7 @@ main (int argc, char **argv) + { + /* Now run a self-test and to get back into + operational state. */ +- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); ++ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("did not reach operational after error " + "and self-test\n"); diff --git a/libgcrypt.spec b/libgcrypt.spec index 5b0e0aa..5b355fa 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -27,15 +27,13 @@ Patch2: libgcrypt-1.8.5-use-fipscheck.patch # modify FIPS RSA and DSA keygen to comply with requirements Patch5: libgcrypt-1.8.4-fips-keygen.patch # fix the tests to work correctly in the FIPS mode -Patch6: libgcrypt-1.8.4-tests-fipsmode.patch +Patch6: libgcrypt-1.9.3-fips-tests.patch # update the CAVS tests Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness Patch11: libgcrypt-1.8.4-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch -# fix tests to work with approved ECC -Patch14: libgcrypt-1.7.3-ecc-test-fix.patch # Run the FIPS mode initialization in the shared library constructor Patch18: libgcrypt-1.8.3-fips-ctor.patch # Do not try to open /dev/urandom if getrandom() works @@ -92,7 +90,6 @@ applications using libgcrypt. %patch7 -p1 -b .cavs %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt -%patch14 -p1 -b .eccfix %patch18 -p1 -b .fips-ctor %patch24 -p1 -b .getrandom %patch26 -p1 -b .fips-enttest From ef01d2c6d0905a778d45dfa31eb3b11a47adbf5a Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 23 Aug 2021 14:03:10 +0200 Subject: [PATCH 41/88] libgcrypt-1.9.4-1 --- .gitignore | 1 + curves.c | 133 ++- ecc-curves.c | 60 +- hobble-libgcrypt | 1 - libgcrypt-1.9.3-CVE-2021-33560.patch | 100 --- libgcrypt.spec | 13 +- sources | 2 +- t-mpi-point.c | 1213 -------------------------- 8 files changed, 178 insertions(+), 1345 deletions(-) delete mode 100644 libgcrypt-1.9.3-CVE-2021-33560.patch delete mode 100644 t-mpi-point.c diff --git a/.gitignore b/.gitignore index 69b0cfb..870812f 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,4 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.9.1-hobbled.tar.xz /libgcrypt-1.9.2-hobbled.tar.xz /libgcrypt-1.9.3-hobbled.tar.xz +/libgcrypt-1.9.4-hobbled.tar.xz diff --git a/curves.c b/curves.c index 5441b53..1b190d1 100644 --- a/curves.c +++ b/curves.c @@ -33,7 +33,7 @@ #include "t-common.h" /* Number of curves defined in ../cipger/ecc-curves.c */ -#define N_CURVES 19 +#define N_CURVES 20 /* A real world sample public key. */ static char const sample_key_1[] = @@ -99,6 +99,119 @@ check_matching (void) static void check_get_params (void) { + static struct { + int algo; + const char *name; + int error_expected; + } tv[] = + { + { GCRY_PK_ECC, "Ed25519" }, + { GCRY_PK_ECC, "1.3.6.1.4.1.11591.15.1" }, + { GCRY_PK_ECC, "1.3.101.112" }, + + { GCRY_PK_ECC, "Curve25519" }, + { GCRY_PK_ECC, "1.3.6.1.4.1.3029.1.5.1" }, + { GCRY_PK_ECC, "1.3.101.110" }, + { GCRY_PK_ECC, "X25519" }, + + { GCRY_PK_ECC, "Ed448" }, + { GCRY_PK_ECC, "X448" }, + { GCRY_PK_ECC, "1.3.101.113" }, + { GCRY_PK_ECC, "1.3.101.111" }, + + { GCRY_PK_ECC, "NIST P-192" }, + { GCRY_PK_ECC, "1.2.840.10045.3.1.1" }, + { GCRY_PK_ECC, "prime192v1" }, + { GCRY_PK_ECC, "secp192r1" }, + { GCRY_PK_ECC, "nistp192" }, + + { GCRY_PK_ECC, "NIST P-224" }, + { GCRY_PK_ECC, "secp224r1" }, + { GCRY_PK_ECC, "1.3.132.0.33" }, + { GCRY_PK_ECC, "nistp224" }, + + { GCRY_PK_ECC, "NIST P-256" }, + { GCRY_PK_ECC, "1.2.840.10045.3.1.7" }, + { GCRY_PK_ECC, "prime256v1" }, + { GCRY_PK_ECC, "secp256r1" }, + { GCRY_PK_ECC, "nistp256" }, + + { GCRY_PK_ECC, "NIST P-384" }, + { GCRY_PK_ECC, "secp384r1" }, + { GCRY_PK_ECC, "1.3.132.0.34" }, + { GCRY_PK_ECC, "nistp384" }, + + { GCRY_PK_ECC, "NIST P-521" }, + { GCRY_PK_ECC, "secp521r1" }, + { GCRY_PK_ECC, "1.3.132.0.35" }, + { GCRY_PK_ECC, "nistp521" }, + + { GCRY_PK_ECC, "GOST2001-test" }, + { GCRY_PK_ECC, "1.2.643.2.2.35.0" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "1.2.643.2.2.35.1" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, + { GCRY_PK_ECC, "1.2.643.2.2.35.2" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "1.2.643.2.2.35.3" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-XchA" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-XchB" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "1.2.643.2.2.36.0" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "1.2.643.2.2.36.1" }, + + /* Noet that GOST2012-256-tc26-A" is only in the curve alias + * list but has no parameter entry. */ + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.2" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, + { GCRY_PK_ECC, "GOST2012-256-tc26-B" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.3" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, + { GCRY_PK_ECC, "GOST2012-256-tc26-C" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.4" }, + { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, + { GCRY_PK_ECC, "GOST2012-256-tc26-D" }, + + { GCRY_PK_ECC, "GOST2012-512-test" }, + { GCRY_PK_ECC, "GOST2012-test" }, + { GCRY_PK_ECC, "GOST2012-512-test" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.0" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-A" }, + { GCRY_PK_ECC, "GOST2012-tc26-A" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-B" }, + { GCRY_PK_ECC, "GOST2012-tc26-B" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-A" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.1" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-B" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.2" }, + { GCRY_PK_ECC, "GOST2012-512-tc26-C" }, + { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.3" }, + + { GCRY_PK_ECC, "secp256k1" }, + { GCRY_PK_ECC, "1.3.132.0.10" }, + + { GCRY_PK_ECC, "sm2p256v1" }, + { GCRY_PK_ECC, "1.2.156.10197.1.301" }, + + /* Check also the ECC algo mapping. */ + { GCRY_PK_ECDSA, "Ed25519" }, + { GCRY_PK_EDDSA, "Ed25519" }, + { GCRY_PK_ECDH, "Ed25519" }, + { GCRY_PK_ECDSA, "Curve25519" }, + { GCRY_PK_EDDSA, "Curve25519" }, + { GCRY_PK_ECDH, "Curve25519" }, + { GCRY_PK_ECC, "NoSuchCurve", 1 }, + { GCRY_PK_RSA, "rsa", 1 }, + { GCRY_PK_ELG, "elg", 1 }, + { GCRY_PK_DSA, "dsa", 1 } + }; + int idx; gcry_sexp_t param; const char *name; @@ -114,6 +227,24 @@ check_get_params (void) sample_key_1_curve, name); gcry_sexp_release (param); + + /* Some simple tests */ + for (idx=0; idx < DIM (tv); idx++) + { + param = gcry_pk_get_param (tv[idx].algo, tv[idx].name); + if (!param) + { + if (!tv[idx].error_expected) + fail ("get_param: test %d (%s) failed\n", idx, tv[idx].name); + } + else + { + if (tv[idx].error_expected) + fail ("get_param: test %d (%s) failed (error expected)\n", + idx, tv[idx].name); + } + gcry_sexp_release (param); + } } diff --git a/ecc-curves.c b/ecc-curves.c index a974bcf..5236b19 100644 --- a/ecc-curves.c +++ b/ecc-curves.c @@ -55,6 +55,11 @@ static const struct { "Ed448", "1.3.101.113" }, /* rfc8410 */ { "X448", "1.3.101.111" }, /* rfc8410 */ + { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */ + { "NIST P-192", "prime192v1" }, /* X9.62 name. */ + { "NIST P-192", "secp192r1" }, /* SECP name. */ + { "NIST P-192", "nistp192" }, /* rfc5656. */ + { "NIST P-224", "secp224r1" }, { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */ { "NIST P-224", "nistp224" }, /* rfc5656. */ @@ -194,6 +199,35 @@ static const ecc_domain_parms_t domain_parms[] = "8DF3F6EDB8027E2346430D211312C4B150677AF76FD7223D457B5B1A", 4, }, +#if 0 /* No real specs yet found. */ + { + /* x^2 + y^2 = 1 + 3617x^2y^2 mod 2^414 - 17 */ + "Curve3617", + "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" + "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF", + MPI_EC_EDWARDS, 0, + "0x01", + "0x0e21", + "0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB3CC92414CF" + "706022B36F1C0338AD63CF181B0E71A5E106AF79", + "0x1A334905141443300218C0631C326E5FCD46369F44C03EC7F57FF35498A4AB4D" + "6D6BA111301A73FAA8537C64C4FD3812F3CBC595", + "0x22", + 8 + }, +#endif /*0*/ + { + "NIST P-192", 192, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xfffffffffffffffffffffffffffffffeffffffffffffffff", + "0xfffffffffffffffffffffffffffffffefffffffffffffffc", + "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", + "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", + + "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", + "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", + 1 + }, { "NIST P-224", 224, 1, MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, @@ -1243,45 +1277,27 @@ _gcry_mpi_ec_new (gcry_ctx_t *r_ctx, gcry_sexp_t _gcry_ecc_get_param_sexp (const char *name) { - unsigned int nbits; elliptic_curve_t E; - mpi_ec_t ctx; - gcry_mpi_t g_x, g_y; gcry_mpi_t pkey[5]; gcry_sexp_t result; - int i; memset (&E, 0, sizeof E); - if (_gcry_ecc_fill_in_curve (0, name, &E, &nbits)) + if (_gcry_ecc_fill_in_curve (0, name, &E, NULL)) return NULL; - g_x = mpi_new (0); - g_y = mpi_new (0); - ctx = _gcry_mpi_ec_p_internal_new (E.model, - E.dialect, - 0, - E.p, E.a, E.b); - if (_gcry_mpi_ec_get_affine (g_x, g_y, &E.G, ctx)) - log_fatal ("ecc get param: Failed to get affine coordinates\n"); - _gcry_mpi_ec_free (ctx); - _gcry_mpi_point_free_parts (&E.G); - pkey[0] = E.p; pkey[1] = E.a; pkey[2] = E.b; - pkey[3] = _gcry_ecc_ec2os (g_x, g_y, E.p); + pkey[3] = _gcry_ecc_ec2os (E.G.x, E.G.y, E.p); pkey[4] = E.n; - mpi_free (g_x); - mpi_free (g_y); - if (sexp_build (&result, NULL, "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)))", pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], E.h)) result = NULL; - for (i=0; i < DIM (pkey); i++) - _gcry_mpi_release (pkey[i]); + _gcry_ecc_curve_free (&E); + _gcry_mpi_release (pkey[3]); return result; } diff --git a/hobble-libgcrypt b/hobble-libgcrypt index 3c76f73..1aa88dc 100755 --- a/hobble-libgcrypt +++ b/hobble-libgcrypt @@ -8,5 +8,4 @@ set -e -x rm -f cipher/ecc-curves.c rm -f tests/curves.c -rm -f tests/t-mpi-point.c rm -f tests/keygrip.c diff --git a/libgcrypt-1.9.3-CVE-2021-33560.patch b/libgcrypt-1.9.3-CVE-2021-33560.patch deleted file mode 100644 index 2161840..0000000 --- a/libgcrypt-1.9.3-CVE-2021-33560.patch +++ /dev/null @@ -1,100 +0,0 @@ -commit 3462280f2e23e16adf3ed5176e0f2413d8861320 -Author: NIIBE Yutaka -Date: Fri May 21 11:15:07 2021 +0900 - - cipher: Fix ElGamal encryption for other implementations. - - * cipher/elgamal.c (gen_k): Remove support of smaller K. - (do_encrypt): Never use smaller K. - (sign): Folllow the change of gen_k. - - -- - - Cherry-pick master commit of: - 632d80ef30e13de6926d503aa697f92b5dbfbc5e - - This change basically reverts encryption changes in two commits: - - 74386120dad6b3da62db37f7044267c8ef34689b - 78531373a342aeb847950f404343a05e36022065 - - Use of smaller K for ephemeral key in ElGamal encryption is only good, - when we can guarantee that recipient's key is generated by our - implementation (or compatible). - - For detail, please see: - - Luca De Feo, Bertram Poettering, Alessandro Sorniotti, - "On the (in)security of ElGamal in OpenPGP"; - in the proceedings of CCS'2021. - - CVE-id: CVE-2021-33560 - GnuPG-bug-id: 5328 - Suggested-by: Luca De Feo, Bertram Poettering, Alessandro Sorniotti - Signed-off-by: NIIBE Yutaka - -diff --git a/cipher/elgamal.c b/cipher/elgamal.c -index 9835122f..eead4502 100644 ---- a/cipher/elgamal.c -+++ b/cipher/elgamal.c -@@ -66,7 +66,7 @@ static const char *elg_names[] = - - - static int test_keys (ELG_secret_key *sk, unsigned int nbits, int nodie); --static gcry_mpi_t gen_k (gcry_mpi_t p, int small_k); -+static gcry_mpi_t gen_k (gcry_mpi_t p); - static gcry_err_code_t generate (ELG_secret_key *sk, unsigned nbits, - gcry_mpi_t **factors); - static int check_secret_key (ELG_secret_key *sk); -@@ -189,11 +189,10 @@ test_keys ( ELG_secret_key *sk, unsigned int nbits, int nodie ) - - /**************** - * Generate a random secret exponent k from prime p, so that k is -- * relatively prime to p-1. With SMALL_K set, k will be selected for -- * better encryption performance - this must never be used signing! -+ * relatively prime to p-1. - */ - static gcry_mpi_t --gen_k( gcry_mpi_t p, int small_k ) -+gen_k( gcry_mpi_t p ) - { - gcry_mpi_t k = mpi_alloc_secure( 0 ); - gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(p) ); -@@ -202,18 +201,7 @@ gen_k( gcry_mpi_t p, int small_k ) - unsigned int nbits, nbytes; - char *rndbuf = NULL; - -- if (small_k) -- { -- /* Using a k much lesser than p is sufficient for encryption and -- * it greatly improves the encryption performance. We use -- * Wiener's table and add a large safety margin. */ -- nbits = wiener_map( orig_nbits ) * 3 / 2; -- if( nbits >= orig_nbits ) -- BUG(); -- } -- else -- nbits = orig_nbits; -- -+ nbits = orig_nbits; - - nbytes = (nbits+7)/8; - if( DBG_CIPHER ) -@@ -492,7 +480,7 @@ do_encrypt(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_public_key *pkey ) - * error code. - */ - -- k = gen_k( pkey->p, 1 ); -+ k = gen_k( pkey->p ); - mpi_powm (a, pkey->g, k, pkey->p); - - /* b = (y^k * input) mod p -@@ -608,7 +596,7 @@ sign(gcry_mpi_t a, gcry_mpi_t b, gcry_mpi_t input, ELG_secret_key *skey ) - * - */ - mpi_sub_ui(p_1, p_1, 1); -- k = gen_k( skey->p, 0 /* no small K ! */ ); -+ k = gen_k( skey->p ); - mpi_powm( a, skey->g, k, skey->p ); - mpi_mul(t, skey->x, a ); - mpi_subm(t, input, t, p_1 ); diff --git a/libgcrypt.spec b/libgcrypt.spec index 5b355fa..a90a8ba 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt -Version: 1.9.3 -Release: 4%{?dist} +Version: 1.9.4 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -18,7 +18,6 @@ Source3: hobble-libgcrypt # Approved ECC support Source4: ecc-curves.c Source5: curves.c -Source6: t-mpi-point.c Source7: random.conf Source8: keygrip.c # make FIPS hmac compatible with fipscheck - non upstreamable @@ -46,8 +45,6 @@ Patch27: libgcrypt-1.8.3-md-fips-enforce.patch Patch28: libgcrypt-1.8.5-intel-cet.patch # FIPS module is redefined a little bit (implicit by kernel FIPS mode) Patch30: libgcrypt-1.8.5-fips-module.patch -# Fix for CVE-2021-33560 -Patch31: libgcrypt-1.9.3-CVE-2021-33560.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -96,10 +93,9 @@ applications using libgcrypt. %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module -%patch31 -p1 -b .CVE-2021-33560 cp %{SOURCE4} cipher/ -cp %{SOURCE5} %{SOURCE6} %{SOURCE8} tests/ +cp %{SOURCE5} %{SOURCE8} tests/ %build # This package has a configure test which uses ASMs, but does not link the @@ -206,6 +202,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Mon Aug 23 2021 Jakub Jelen - 1.9.4-1 +- New upstream release (#1996467) + * Thu Jul 22 2021 Fedora Release Engineering - 1.9.3-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_35_Mass_Rebuild diff --git a/sources b/sources index 84854e4..8d0f1cb 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (libgcrypt-1.9.3-hobbled.tar.xz) = 5c6f3ee57ec496af6d82000979a79d220a5b9be7a3a9d064d727ff7e54cf107e5b398d9ec8d822594a7fe53bc0d4324e96a5b41d55a77f103109620b88c61f1a +SHA512 (libgcrypt-1.9.4-hobbled.tar.xz) = 80b1b2159ec3c7795450037d76d81b737f2734f1cff72c8aa6ac8c1a5654ece4fce0aabfbed0cce99d123747831db135df0d040f67081052cb2363bf52f5d4e6 diff --git a/t-mpi-point.c b/t-mpi-point.c deleted file mode 100644 index 9a6190e..0000000 --- a/t-mpi-point.c +++ /dev/null @@ -1,1213 +0,0 @@ -/* t-mpi-point.c - Tests for mpi point functions - * Copyright (C) 2013 g10 Code GmbH - * - * This file is part of Libgcrypt. - * - * Libgcrypt is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Libgcrypt is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . - */ - -#ifdef HAVE_CONFIG_H -# include -#endif -#include -#include -#include -#include -#include - -#define PGM "t-mpi-point" -#include "t-common.h" - -static struct -{ - const char *desc; /* Description of the curve. */ - const char *p; /* Order of the prime field. */ - const char *a, *b; /* The coefficients. */ - const char *n; /* The order of the base point. */ - const char *g_x, *g_y; /* Base point. */ - const char *h; /* Cofactor. */ -} test_curve[] = - { - { - "NIST P-224", - "0xffffffffffffffffffffffffffffffff000000000000000000000001", - "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", - "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", - "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , - - "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", - "0x01" - }, - { - "NIST P-256", - "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", - "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", - "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - - "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", - "0x01" - }, - { - "NIST P-384", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000ffffffff", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000fffffffc", - "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" - "c656398d8a2ed19d2a85c8edd3ec2aef", - "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" - "581a0db248b0a77aecec196accc52973", - - "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" - "5502f25dbf55296c3a545e3872760ab7", - "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f", - "0x01" - }, - { - "NIST P-521", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", - "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" - "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", - "0x1fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - - "0xc6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d3d" - "baa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", - "0x11839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e6" - "62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", - "0x01" - }, - { - "Ed25519", - "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEC", - "0x52036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978A3", - "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", - "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658", - "0x08" - }, - { NULL, NULL, NULL, NULL, NULL, NULL } - }; - -/* A sample public key for NIST P-256. */ -static const char sample_p256_q[] = - "04" - "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E" - "E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; -static const char sample_p256_q_x[] = - "42B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146E"; -static const char sample_p256_q_y[] = - "00E86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E"; - - -/* A sample public key for Ed25519. */ -static const char sample_ed25519_q[] = - "04" - "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce" - "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7"; -static const char sample_ed25519_q_x[] = - "55d0e09a2b9d34292297e08d60d0f620c513d47253187c24b12786bd777645ce"; -static const char sample_ed25519_q_y[] = - "1a5107f7681a02af2523a6daf372e10e3a0764c9d3fe4bd5b70ab18201985ad7"; -static const char sample_ed25519_q_eddsa[] = - "d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a"; -static const char sample_ed25519_d[] = - "9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60"; - - -static void -print_mpi_2 (const char *text, const char *text2, gcry_mpi_t a) -{ - gcry_error_t err; - char *buf; - void *bufaddr = &buf; - - err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); - if (err) - fprintf (stderr, "%s%s: [error printing number: %s]\n", - text, text2? text2:"", gpg_strerror (err)); - else - { - fprintf (stderr, "%s%s: %s\n", text, text2? text2:"", buf); - gcry_free (buf); - } -} - - -static void -print_mpi (const char *text, gcry_mpi_t a) -{ - print_mpi_2 (text, NULL, a); -} - - -static void -print_point (const char *text, gcry_mpi_point_t a) -{ - gcry_mpi_t x, y, z; - - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - gcry_mpi_point_get (x, y, z, a); - print_mpi_2 (text, ".x", x); - print_mpi_2 (text, ".y", y); - print_mpi_2 (text, ".z", z); - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); -} - - -static void -print_sexp (const char *prefix, gcry_sexp_t a) -{ - char *buf; - size_t size; - - if (prefix) - fputs (prefix, stderr); - size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); - buf = gcry_xmalloc (size); - - gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); - fprintf (stderr, "%.*s", (int)size, buf); - gcry_free (buf); -} - - -static gcry_mpi_t -hex2mpi (const char *string) -{ - gpg_error_t err; - gcry_mpi_t val; - - err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); - if (err) - die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err)); - return val; -} - - -/* Convert STRING consisting of hex characters into its binary - representation and return it as an allocated buffer. The valid - length of the buffer is returned at R_LENGTH. The string is - delimited by end of string. The function returns NULL on - error. */ -static void * -hex2buffer (const char *string, size_t *r_length) -{ - const char *s; - unsigned char *buffer; - size_t length; - - buffer = xmalloc (strlen(string)/2+1); - length = 0; - for (s=string; *s; s +=2 ) - { - if (!hexdigitp (s) || !hexdigitp (s+1)) - return NULL; /* Invalid hex digits. */ - ((unsigned char*)buffer)[length++] = xtoi_2 (s); - } - *r_length = length; - return buffer; -} - - -static gcry_mpi_t -hex2mpiopa (const char *string) -{ - char *buffer; - size_t buflen; - gcry_mpi_t val; - - buffer = hex2buffer (string, &buflen); - if (!buffer) - die ("hex2mpiopa '%s' failed: parser error\n", string); - val = gcry_mpi_set_opaque (NULL, buffer, buflen*8); - if (!buffer) - die ("hex2mpiopa '%s' failed: set_opaque error\n", string); - return val; -} - - -/* Compare A to B, where B is given as a hex string. */ -static int -cmp_mpihex (gcry_mpi_t a, const char *b) -{ - gcry_mpi_t bval; - int res; - - if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE)) - bval = hex2mpiopa (b); - else - bval = hex2mpi (b); - res = gcry_mpi_cmp (a, bval); - gcry_mpi_release (bval); - return res; -} - - -/* Wrapper to emulate the libgcrypt internal EC context allocation - function. */ -static gpg_error_t -ec_p_new (gcry_ctx_t *r_ctx, gcry_mpi_t p, gcry_mpi_t a) -{ - gpg_error_t err; - gcry_sexp_t sexp; - - if (p && a) - err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m)(a %m))", p, a); - else if (p) - err = gcry_sexp_build (&sexp, NULL, "(ecdsa (p %m))", p); - else if (a) - err = gcry_sexp_build (&sexp, NULL, "(ecdsa (a %m))", a); - else - err = gcry_sexp_build (&sexp, NULL, "(ecdsa)"); - if (err) - return err; - err = gcry_mpi_ec_new (r_ctx, sexp, NULL); - gcry_sexp_release (sexp); - return err; -} - - - -static void -set_get_point (void) -{ - gcry_mpi_point_t point, point2; - gcry_mpi_t x, y, z; - - wherestr = "set_get_point"; - info ("checking point setting functions\n"); - - point = gcry_mpi_point_new (0); - x = gcry_mpi_set_ui (NULL, 17); - y = gcry_mpi_set_ui (NULL, 42); - z = gcry_mpi_set_ui (NULL, 11371); - gcry_mpi_point_get (x, y, z, point); - if (gcry_mpi_cmp_ui (x, 0) - || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) - fail ("new point not initialized to (0,0,0)\n"); - gcry_mpi_point_snatch_get (x, y, z, point); - point = NULL; - if (gcry_mpi_cmp_ui (x, 0) - || gcry_mpi_cmp_ui (y, 0) || gcry_mpi_cmp_ui (z, 0)) - fail ("snatch_get failed\n"); - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); - - point = gcry_mpi_point_new (0); - x = gcry_mpi_set_ui (NULL, 17); - y = gcry_mpi_set_ui (NULL, 42); - z = gcry_mpi_set_ui (NULL, 11371); - gcry_mpi_point_set (point, x, y, z); - gcry_mpi_set_ui (x, 23); - gcry_mpi_set_ui (y, 24); - gcry_mpi_set_ui (z, 25); - gcry_mpi_point_get (x, y, z, point); - if (gcry_mpi_cmp_ui (x, 17) - || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) - fail ("point_set/point_get failed\n"); - gcry_mpi_point_snatch_set (point, x, y, z); - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - gcry_mpi_point_get (x, y, z, point); - if (gcry_mpi_cmp_ui (x, 17) - || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) - fail ("point_snatch_set/point_get failed\n"); - - point2 = gcry_mpi_point_copy (point); - - gcry_mpi_point_get (x, y, z, point2); - if (gcry_mpi_cmp_ui (x, 17) - || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) - fail ("point_copy failed (1)\n"); - - gcry_mpi_point_release (point); - - gcry_mpi_point_get (x, y, z, point2); - if (gcry_mpi_cmp_ui (x, 17) - || gcry_mpi_cmp_ui (y, 42) || gcry_mpi_cmp_ui (z, 11371)) - fail ("point_copy failed (2)\n"); - - gcry_mpi_point_release (point2); - - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); -} - - -static void -context_alloc (void) -{ - gpg_error_t err; - gcry_ctx_t ctx; - gcry_mpi_t p, a; - - wherestr = "context_alloc"; - info ("checking context functions\n"); - - p = gcry_mpi_set_ui (NULL, 1); - a = gcry_mpi_set_ui (NULL, 1); - err = ec_p_new (&ctx, p, a); - if (err) - die ("ec_p_new returned an error: %s\n", gpg_strerror (err)); - gcry_mpi_release (p); - gcry_mpi_release (a); - gcry_ctx_release (ctx); - - p = NULL; - a = gcry_mpi_set_ui (NULL, 0); - - err = ec_p_new (&ctx, p, a); - if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (1)\n"); - - gcry_mpi_release (a); - a = NULL; - err = ec_p_new (&ctx, p, a); - if (!err || gpg_err_code (err) != GPG_ERR_EINVAL) - fail ("ec_p_new: bad parameter detection failed (2)\n"); - -} - - -static int -get_and_cmp_mpi (const char *name, const char *mpistring, const char *desc, - gcry_ctx_t ctx) -{ - gcry_mpi_t mpi; - - mpi = gcry_mpi_ec_get_mpi (name, ctx, 1); - if (!mpi) - { - fail ("error getting parameter '%s' of curve '%s'\n", name, desc); - return 1; - } - if (debug) - print_mpi (name, mpi); - if (cmp_mpihex (mpi, mpistring)) - { - fail ("parameter '%s' of curve '%s' does not match\n", name, desc); - gcry_mpi_release (mpi); - return 1; - } - gcry_mpi_release (mpi); - return 0; -} - - -static int -get_and_cmp_point (const char *name, - const char *mpi_x_string, const char *mpi_y_string, - const char *desc, gcry_ctx_t ctx) -{ - gcry_mpi_point_t point; - gcry_mpi_t x, y, z; - int result = 0; - - point = gcry_mpi_ec_get_point (name, ctx, 1); - if (!point) - { - fail ("error getting point parameter '%s' of curve '%s'\n", name, desc); - return 1; - } - if (debug) - print_point (name, point); - - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - gcry_mpi_point_snatch_get (x, y, z, point); - if (cmp_mpihex (x, mpi_x_string)) - { - fail ("x coordinate of '%s' of curve '%s' does not match\n", name, desc); - result = 1; - } - if (cmp_mpihex (y, mpi_y_string)) - { - fail ("y coordinate of '%s' of curve '%s' does not match\n", name, desc); - result = 1; - } - if (cmp_mpihex (z, "01")) - { - fail ("z coordinate of '%s' of curve '%s' is not 1\n", name, desc); - result = 1; - } - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); - return result; -} - - -static void -context_param (void) -{ - gpg_error_t err; - int idx; - gcry_ctx_t ctx = NULL; - gcry_mpi_t q, d; - gcry_sexp_t keyparam; - - wherestr = "context_param"; - - info ("checking standard curves\n"); - for (idx=0; test_curve[idx].desc; idx++) - { - /* P-192 and Ed25519 are not supported in fips mode */ - if (gcry_fips_mode_active()) - { - if (!strcmp(test_curve[idx].desc, "NIST P-192") - || !strcmp(test_curve[idx].desc, "Ed25519")) - { - info ("skipping %s in fips mode\n", test_curve[idx].desc ); - continue; - } - } - - gcry_ctx_release (ctx); - err = gcry_mpi_ec_new (&ctx, NULL, test_curve[idx].desc); - if (err) - { - fail ("can't create context for curve '%s': %s\n", - test_curve[idx].desc, gpg_strerror (err)); - continue; - } - if (get_and_cmp_mpi ("p", test_curve[idx].p, test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_mpi ("a", test_curve[idx].a, test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_mpi ("b", test_curve[idx].b, test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_mpi ("g.x",test_curve[idx].g_x, test_curve[idx].desc,ctx)) - continue; - if (get_and_cmp_mpi ("g.y",test_curve[idx].g_y, test_curve[idx].desc,ctx)) - continue; - if (get_and_cmp_mpi ("n", test_curve[idx].n, test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_point ("g", test_curve[idx].g_x, test_curve[idx].g_y, - test_curve[idx].desc, ctx)) - continue; - if (get_and_cmp_mpi ("h", test_curve[idx].h, test_curve[idx].desc, ctx)) - continue; - - } - - info ("checking sample public key (nistp256)\n"); - q = hex2mpi (sample_p256_q); - err = gcry_sexp_build (&keyparam, NULL, - "(public-key(ecc(curve %s)(q %m)))", - "NIST P-256", q); - if (err) - die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (q); - - /* We can't call gcry_pk_testkey because it is only implemented for - private keys. */ - /* err = gcry_pk_testkey (keyparam); */ - /* if (err) */ - /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ - /* gpg_strerror (err)); */ - - gcry_ctx_release (ctx); - err = gcry_mpi_ec_new (&ctx, keyparam, NULL); - if (err) - fail ("gcry_mpi_ec_new failed for sample public key (nistp256): %s\n", - gpg_strerror (err)); - else - { - gcry_sexp_t sexp; - - get_and_cmp_mpi ("q", sample_p256_q, "nistp256", ctx); - get_and_cmp_point ("q", sample_p256_q_x, sample_p256_q_y, "nistp256", - ctx); - - /* Delete Q. */ - err = gcry_mpi_ec_set_mpi ("q", NULL, ctx); - if (err) - fail ("clearing Q for nistp256 failed: %s\n", gpg_strerror (err)); - if (gcry_mpi_ec_get_mpi ("q", ctx, 0)) - fail ("clearing Q for nistp256 did not work\n"); - - /* Set Q again. */ - q = hex2mpi (sample_p256_q); - err = gcry_mpi_ec_set_mpi ("q", q, ctx); - if (err) - fail ("setting Q for nistp256 failed: %s\n", gpg_strerror (err)); - get_and_cmp_mpi ("q", sample_p256_q, "nistp256(2)", ctx); - gcry_mpi_release (q); - - /* Get as s-expression. */ - err = gcry_pubkey_get_sexp (&sexp, 0, ctx); - if (err) - fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); - else if (debug) - print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); - gcry_sexp_release (sexp); - - err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); - if (err) - fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", - gpg_strerror (err)); - else if (debug) - print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); - gcry_sexp_release (sexp); - - err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); - if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) - fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", - gpg_strerror (err)); - gcry_sexp_release (sexp); - } - - /* Skipping Ed25519 if in FIPS mode (it isn't supported) */ - if (gcry_fips_mode_active()) - goto cleanup; - - info ("checking sample public key (Ed25519)\n"); - q = hex2mpi (sample_ed25519_q); - gcry_sexp_release (keyparam); - err = gcry_sexp_build (&keyparam, NULL, - "(public-key(ecc(curve %s)(flags eddsa)(q %m)))", - "Ed25519", q); - if (err) - die ("gcry_sexp_build failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (q); - - /* We can't call gcry_pk_testkey because it is only implemented for - private keys. */ - /* err = gcry_pk_testkey (keyparam); */ - /* if (err) */ - /* fail ("gcry_pk_testkey failed for sample public key: %s\n", */ - /* gpg_strerror (err)); */ - - gcry_ctx_release (ctx); - err = gcry_mpi_ec_new (&ctx, keyparam, NULL); - if (err) - fail ("gcry_mpi_ec_new failed for sample public key: %s\n", - gpg_strerror (err)); - else - { - gcry_sexp_t sexp; - - get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519", ctx); - get_and_cmp_point ("q", sample_ed25519_q_x, sample_ed25519_q_y, - "Ed25519", ctx); - get_and_cmp_mpi ("q@eddsa", sample_ed25519_q_eddsa, "Ed25519", ctx); - - /* Set d to see whether Q is correctly re-computed. */ - d = hex2mpi (sample_ed25519_d); - err = gcry_mpi_ec_set_mpi ("d", d, ctx); - if (err) - fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (d); - get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(recompute Q)", ctx); - - /* Delete Q by setting d and then clearing d. The clearing is - required so that we can check whether Q has been cleared and - because further tests only expect a public key. */ - d = hex2mpi (sample_ed25519_d); - err = gcry_mpi_ec_set_mpi ("d", d, ctx); - if (err) - fail ("setting d for Ed25519 failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (d); - err = gcry_mpi_ec_set_mpi ("d", NULL, ctx); - if (err) - fail ("setting d for Ed25519 failed(2): %s\n", gpg_strerror (err)); - if (gcry_mpi_ec_get_mpi ("q", ctx, 0)) - fail ("setting d for Ed25519 did not reset Q\n"); - - /* Set Q again. We need to use an opaque MPI here because - sample_ed25519_q is in uncompressed format which can only be - auto-detected if passed opaque. */ - q = hex2mpiopa (sample_ed25519_q); - err = gcry_mpi_ec_set_mpi ("q", q, ctx); - if (err) - fail ("setting Q for Ed25519 failed: %s\n", gpg_strerror (err)); - gcry_mpi_release (q); - get_and_cmp_mpi ("q", sample_ed25519_q, "Ed25519(2)", ctx); - - /* Get as s-expression. */ - err = gcry_pubkey_get_sexp (&sexp, 0, ctx); - if (err) - fail ("gcry_pubkey_get_sexp(0) failed: %s\n", gpg_strerror (err)); - else if (debug) - print_sexp ("Result of gcry_pubkey_get_sexp (0):\n", sexp); - gcry_sexp_release (sexp); - - err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_PUBKEY, ctx); - if (err) - fail ("gcry_pubkey_get_sexp(GET_PUBKEY) failed: %s\n", - gpg_strerror (err)); - else if (debug) - print_sexp ("Result of gcry_pubkey_get_sexp (GET_PUBKEY):\n", sexp); - gcry_sexp_release (sexp); - - err = gcry_pubkey_get_sexp (&sexp, GCRY_PK_GET_SECKEY, ctx); - if (gpg_err_code (err) != GPG_ERR_NO_SECKEY) - fail ("gcry_pubkey_get_sexp(GET_SECKEY) returned wrong error: %s\n", - gpg_strerror (err)); - gcry_sexp_release (sexp); - - } - - cleanup: - gcry_ctx_release (ctx); - gcry_sexp_release (keyparam); -} - - - - -/* Create a new point from (X,Y,Z) given as hex strings. */ -gcry_mpi_point_t -make_point (const char *x, const char *y, const char *z) -{ - gcry_mpi_point_t point; - - point = gcry_mpi_point_new (0); - gcry_mpi_point_snatch_set (point, hex2mpi (x), hex2mpi (y), hex2mpi (z)); - - return point; -} - - -/* This tests checks that the low-level EC API yields the same result - as using the high level API. The values have been taken from a - test run using the high level API. */ -static void -basic_ec_math (void) -{ - gpg_error_t err; - gcry_ctx_t ctx; - gcry_mpi_t P, A; - gcry_mpi_point_t G, Q; - gcry_mpi_t d; - gcry_mpi_t x, y, z; - - wherestr = "basic_ec_math"; - info ("checking basic math functions for EC\n"); - - P = hex2mpi ("0xfffffffffffffffffffffffffffffffeffffffffffffffff"); - A = hex2mpi ("0xfffffffffffffffffffffffffffffffefffffffffffffffc"); - G = make_point ("188DA80EB03090F67CBF20EB43A18800F4FF0AFD82FF1012", - "7192B95FFC8DA78631011ED6B24CDD573F977A11E794811", - "1"); - d = hex2mpi ("D4EF27E32F8AD8E2A1C6DDEBB1D235A69E3CEF9BCE90273D"); - Q = gcry_mpi_point_new (0); - - err = ec_p_new (&ctx, P, A); - if (err) - die ("ec_p_new failed: %s\n", gpg_strerror (err)); - - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - - { - /* A quick check that multiply by zero works. */ - gcry_mpi_t tmp; - - tmp = gcry_mpi_new (0); - gcry_mpi_ec_mul (Q, tmp, G, ctx); - gcry_mpi_release (tmp); - gcry_mpi_point_get (x, y, z, Q); - if (gcry_mpi_cmp_ui (z, 0)) - fail ("multiply a point by zero failed\n"); - } - - gcry_mpi_ec_mul (Q, d, G, ctx); - - if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) - fail ("failed to get affine coordinates\n"); - if (cmp_mpihex (x, "008532093BA023F4D55C0424FA3AF9367E05F309DC34CDC3FE") - || cmp_mpihex (y, "00C13CA9E617C6C8487BFF6A726E3C4F277913D97117939966")) - fail ("computed affine coordinates of public key do not match\n"); - if (debug) - { - print_mpi ("q.x", x); - print_mpi ("q.y", y); - } - - gcry_mpi_release (z); - gcry_mpi_release (y); - gcry_mpi_release (x); - gcry_mpi_point_release (Q); - gcry_mpi_release (d); - gcry_mpi_point_release (G); - gcry_mpi_release (A); - gcry_mpi_release (P); - gcry_ctx_release (ctx); -} - - -/* This is the same as basic_ec_math but uses more advanced - features. */ -static void -basic_ec_math_simplified (void) -{ -} - - -/* Check the math used with Twisted Edwards curves. */ -static void -twistededwards_math (void) -{ - gpg_error_t err; - gcry_ctx_t ctx; - gcry_mpi_point_t G, Q; - gcry_mpi_t k; - gcry_mpi_t w, a, x, y, z, p, n, b, I; - - wherestr = "twistededwards_math"; - info ("checking basic Twisted Edwards math\n"); - - err = gcry_mpi_ec_new (&ctx, NULL, "Ed25519"); - if (err) - die ("gcry_mpi_ec_new failed: %s\n", gpg_strerror (err)); - - k = hex2mpi - ("2D3501E723239632802454EE5DDC406EFB0BDF18486A5BDE9C0390A9C2984004" - "F47252B628C953625B8DEB5DBCB8DA97AA43A1892D11FA83596F42E0D89CB1B6"); - G = gcry_mpi_ec_get_point ("g", ctx, 1); - if (!G) - die ("gcry_mpi_ec_get_point(G) failed\n"); - Q = gcry_mpi_point_new (0); - - - w = gcry_mpi_new (0); - a = gcry_mpi_new (0); - x = gcry_mpi_new (0); - y = gcry_mpi_new (0); - z = gcry_mpi_new (0); - I = gcry_mpi_new (0); - p = gcry_mpi_ec_get_mpi ("p", ctx, 1); - n = gcry_mpi_ec_get_mpi ("n", ctx, 1); - b = gcry_mpi_ec_get_mpi ("b", ctx, 1); - - /* Check: 2^{p-1} mod p == 1 */ - gcry_mpi_sub_ui (a, p, 1); - gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, p); - if (gcry_mpi_cmp_ui (w, 1)) - fail ("failed assertion: 2^{p-1} mod p == 1\n"); - - /* Check: p % 4 == 1 */ - gcry_mpi_mod (w, p, GCRYMPI_CONST_FOUR); - if (gcry_mpi_cmp_ui (w, 1)) - fail ("failed assertion: p %% 4 == 1\n"); - - /* Check: 2^{n-1} mod n == 1 */ - gcry_mpi_sub_ui (a, n, 1); - gcry_mpi_powm (w, GCRYMPI_CONST_TWO, a, n); - if (gcry_mpi_cmp_ui (w, 1)) - fail ("failed assertion: 2^{n-1} mod n == 1\n"); - - /* Check: b^{(p-1)/2} mod p == p-1 */ - gcry_mpi_sub_ui (a, p, 1); - gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_TWO, -1); - gcry_mpi_powm (w, b, x, p); - gcry_mpi_abs (w); - if (gcry_mpi_cmp (w, a)) - fail ("failed assertion: b^{(p-1)/2} mod p == p-1\n"); - - /* I := 2^{(p-1)/4} mod p */ - gcry_mpi_sub_ui (a, p, 1); - gcry_mpi_div (x, NULL, a, GCRYMPI_CONST_FOUR, -1); - gcry_mpi_powm (I, GCRYMPI_CONST_TWO, x, p); - - /* Check: I^2 mod p == p-1 */ - gcry_mpi_powm (w, I, GCRYMPI_CONST_TWO, p); - if (gcry_mpi_cmp (w, a)) - fail ("failed assertion: I^2 mod p == p-1\n"); - - /* Check: G is on the curve */ - if (!gcry_mpi_ec_curve_point (G, ctx)) - fail ("failed assertion: G is on the curve\n"); - - /* Check: nG == (0,1) */ - gcry_mpi_ec_mul (Q, n, G, ctx); - if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) - fail ("failed to get affine coordinates\n"); - if (gcry_mpi_cmp_ui (x, 0) || gcry_mpi_cmp_ui (y, 1)) - fail ("failed assertion: nG == (0,1)\n"); - - /* Now two arbitrary point operations taken from the ed25519.py - sample data. */ - gcry_mpi_release (a); - a = hex2mpi - ("4f71d012df3c371af3ea4dc38385ca5bb7272f90cb1b008b3ed601c76de1d496" - "e30cbf625f0a756a678d8f256d5325595cccc83466f36db18f0178eb9925edd3"); - gcry_mpi_ec_mul (Q, a, G, ctx); - if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) - fail ("failed to get affine coordinates\n"); - if (cmp_mpihex (x, ("157f7361c577aad36f67ed33e38dc7be" - "00014fecc2165ca5cee9eee19fe4d2c1")) - || cmp_mpihex (y, ("5a69dbeb232276b38f3f5016547bb2a2" - "4025645f0b820e72b8cad4f0a909a092"))) - { - fail ("sample point multiply failed:\n"); - print_mpi ("r", a); - print_mpi ("Rx", x); - print_mpi ("Ry", y); - } - - gcry_mpi_release (a); - a = hex2mpi - ("2d3501e723239632802454ee5ddc406efb0bdf18486a5bde9c0390a9c2984004" - "f47252b628c953625b8deb5dbcb8da97aa43a1892d11fa83596f42e0d89cb1b6"); - gcry_mpi_ec_mul (Q, a, G, ctx); - if (gcry_mpi_ec_get_affine (x, y, Q, ctx)) - fail ("failed to get affine coordinates\n"); - if (cmp_mpihex (x, ("6218e309d40065fcc338b3127f468371" - "82324bd01ce6f3cf81ab44e62959c82a")) - || cmp_mpihex (y, ("5501492265e073d874d9e5b81e7f8784" - "8a826e80cce2869072ac60c3004356e5"))) - { - fail ("sample point multiply failed:\n"); - print_mpi ("r", a); - print_mpi ("Rx", x); - print_mpi ("Ry", y); - } - - - gcry_mpi_release (I); - gcry_mpi_release (b); - gcry_mpi_release (n); - gcry_mpi_release (p); - gcry_mpi_release (w); - gcry_mpi_release (a); - gcry_mpi_release (x); - gcry_mpi_release (y); - gcry_mpi_release (z); - gcry_mpi_point_release (Q); - gcry_mpi_point_release (G); - gcry_mpi_release (k); - gcry_ctx_release (ctx); -} - - -/* Check the point on curve function. */ -static void -point_on_curve (void) -{ - static struct { - const char *curve; - int oncurve; /* Point below is on the curve. */ - const char *qx; - const char *qy; - } t[] = { - { - "NIST P-256", 0, - "015B4F6775D68D4D2E2192C6B8027FC5A3D49957E453CB251155AA3FF5D3EC9974", - "4BC4C87B57A25E1056831208AB5B8F091142F891E9FF19F1E090B030DF1087B3" - }, { - "NIST P-256", 0, - "D22C316E7EBE7B293BD66808E000806F0754398A5D72A4F9BBC21C26EAC0A651", - "3C8DB80CC3CDE5E530D040536E6A58AAB41C33FA70B30896943513FF3690132D" - }, { - "NIST P-256", 0, - "0130F7E7BC52854CA493A0DE87DC4AB3B4343758F2B634F15B10D70DBC0A5A5291", - "86F9CA73C25CE86D54CB21C181AECBB52A5971334FF5040F76CAE9845ED46023" - }, { - "NIST P-256", 1, - "14957B602C7849F28858C7407696F014BC091D6D68C449560B7A38147D6E6A9B", - "A8E09EFEECFE00C797A0848F38B61992D30C61FAB13021E88C8BD3545B3A6C63" - }, { - "NIST P-256", 0, - "923DE4957241DD97780841C76294DB0D4F5DC04C3045081174764D2D32AD2D53", - "01B4B1A2027C02F0F520A3B01E4CE3C668BF481346A74499C5D1044A53E210B600" - }, { - "NIST P-256", 1, - "9021DFAB8B4DAEAADA634AAA26D6E5FFDF8C0476FF5CA31606C870A1B933FB36", - "9AFC65EEB24E46C7B75712EF29A981CB09FAC56E2B81D3ED024748CCAB1CB77E" - }, { - "NIST P-256", 0, - "011529F0B26DE5E0EB2DA4BFB6C149C802CB52EE479DD666553286928A4005E990", - "0EBC63DB2104884456DC0AA81A3F4E99D93B7AE2CD4B1489655EA9BE6289CF9E" - }, { - "NIST P-256", 1, - "216EC5DE8CA989199D31F0DFCD381DCC9270A0785365EC3E34CA347C070A87BE", - "87A88897BA763509ECC1DBE28D9D37F6F4E70E3B99B1CD3C0B934D4190968A6D" - }, { - "NIST P-256", 1, - "7ABAA44ACBC6016FDB52A6F45F6178E65CBFC35F9920D99149CA9999612CE945", - "88F7684BDCDA31EAFB6CAD859F8AB29B5D921D7DB2B34DF7E40CE36235F45B63" - }, { - "NIST P-256", 0, - "E765B4272D211DD0064189B55421FB76BB3A7756364A6CB1627FAED848157A84", - "C13171CFFB243E06B203F0996BBDD16F52292AD11F2DA81106E9C2FD87F4FA0F" - }, { - "NIST P-256", 0, - "EE4999DFC3A1871EE7A592BE26A09BEC9D9B561613EE9EFB6ED42F17985C9CDC", - "8399E967338A7A618336AF70DA67D9CAC1C19267809652F5C5183C8B129E0902" - }, { - "NIST P-256", 0, - "F755D0CF2642A2C7FBACCC8E9E442B8B047A99C6E052B2FA5AB0544B36B4D51C", - "AA080F17657B6565D9A4D94BD260B54D92FEE8DC4A78C4FC9C19209933AF39B0" - } , { - "NIST P-384", 0, - "CBFC7DBEBF15BEAD682549757F9BBA0E3F67669DF13FCE0EBE8024B725B38B00" - "83EC46A8F2FF3203C5C7F8C7E722A5EF", - "0548FE281BEAB18FD1AB86F59B0CA524479A4A81373C83B78AFFD801FAC75922" - "96470753DCF46173C9AA4A8A4C2FBE51" - }, { - "NIST P-384", 0, - "1DC8E054A883DB81EAEDE6C487B26816C927B8196780525A6CA8F675D2557752" - "02CE06CCBE705EA8A38AA2894D4BEEE6", - "010191050E867AFAA96A199FE9C591CF8B853D81486786DA889124881FB39D2F" - "8E0875F4C4BB1E3D0F8535C7A52306FB82" - }, { - "NIST P-384", 1, - "2539FC368CE1D5E464B6C0FBB12D557B712327DB086975255AD7D17F7E7E4F23" - "D719ED4116E2CC907AEB92CF22331A60", - "8843FDBA742CB64323E49CEBE8DD74908CFC9C3AA0015662DFBB7219E92CF32E" - "9FC63F61EF19DE9B3CEA98D163ABF254" - }, { - "NIST P-384", 0, - "0B786DACF400D43575394349EDD9F9CD145FC7EF737A3C5F69B253BE7639DB24" - "EC2F0CA62FF1F90B6515DE356EC2A404", - "225D6B2939CC7F7133F43353946A682C68DAC6BB75EE9CF6BD9A1609FA915692" - "72F4D3A87E88529754E109BB9B61B03B" - }, { - "NIST P-384", 0, - "76C660C9F58CF2051F9F8B06049694AB6FE418009DE6F0A0833BC690CEC06CC2" - "9A440AD51C94CF5BC28817C8C6E2D302", - "012974E5D9E55304ED294AB6C7A3C65B663E67ABC5E6F6C0F6498B519F2F6CA1" - "8306976291F3ADC0B5ABA42DED376EA9A5" - }, { - "NIST P-384", 0, - "23D758B1EDB8E12E9E707C53C131A19D9464B20EE05C99766F5ABDF9F906AD03" - "B958BF28B022E54E320672C4BAD4EEC0", - "01E9E72870C88F4C82A5AB3CC8A3398E8F006BF3EC05FFBB1EFF8AEE88020FEA" - "9E558E9F58ED1D324C9DCBCB4E8F2A5970" - }, { - "NIST P-384", 0, - "D062B96D5A10F715ACF361F99262ABF0F7693A8BB60ECB1DF459CF95750E4293" - "18BCB9FC60499D009F949298F3F9F47B", - "9089C6328E4B39A73D7EE6FAE1A77E48CE354B83BBCE432082C32C8FD6784B86" - "CFE9C552E2E720F5DA5806503D3784CD" - }, { - "NIST P-384", 0, - "2A951D4D6EB35C43D94866280D37365B82441BC84D62CBFF3365CAB1FD0A3E20" - "823CA8F84D2BBF4EA687885437DE7839", - "01CC7D762AFE613F7B5568BC516568A421159C40599E8D52DE10E8F9488931E1" - "69F3656C322DE45C4A70DC6DB9A661E599" - }, { - "NIST P-384", 1, - "A4BAEE6CDAF3AEB69032B3FBA811707C54F5753670DA5173D891547E8CBAEEF3" - "89B92C9A55573A596123415FBFA26991", - "3241EA716583C11C71BB30AF6C5E3A6637956F17ADBBE641BAB52E8539F9FC7B" - "F3B04F46DBFFE08151E0F0950CC70081" - }, { - "NIST P-384", 0, - "5C0E18B0DE3261BCBCFC7B702C2D75CF481336BFBADF420BADC616235C1966AB" - "4C0F876575DDEC1BDB3F3F04061C9AE4", - "E90C78550D1C922F1D8161D8C9C0576E29BD09CA665376FA887D13FA8DF48352" - "D7BBEEFB803F6CC8FC7895E47F348D33" - }, { - "NIST P-384", 1, - "2015864CD50F0A1A50E6401F44191665C19E4AD4B4903EA9EB464E95D1070E36" - "F1D8325E45734D5A0FDD103F4DF6F83E", - "5FB3E9A5C59DD5C5262A8176CB7032A00AE33AED08485884A3E5D68D9EEB990B" - "F26E8D87EC175577E782AD51A6A12C02" - }, { - "NIST P-384", 1, - "56EBF5310EEF5A5D8D001F570A18625383ECD4882B3FC738A69874E7C9D8F89C" - "187BECA23369DFD6C15CC0DA0629958F", - "C1230B349FB662CB762563DB8F9FCB32D5CCA16120681C474D67D279CCA6F6DB" - "73DE6AA96140B5C457B7486E06D318CE" - }, { - "NIST P-521", 0, - "01E4D82EE5CD6DA37080252295EFA273BBBA6952012D0120EAF131E73F1E5024" - "36E3324624471040030E1C345D65490ECEE9B64E03B15B6C7EB69A39C618BAFEED70", - "03EE3A3C88A6933B7B16016BE4CC4E3BF5EA0625CB3DB2604CDCBBD02CABBC90" - "8904D9DB42998F6C5101D4D4318ACFC9643C9CD641F636D1810ED86F1840EA74F3C0" - }, { - "NIST P-521", 0, - "01F3DFCB5433387B6B2E3F74177F4F3D7300F05E1AD49DE112630E27B1C8A437" - "1E742CB020E0039B5477FC897D17332034F9660B3066764EFF5FB440EB8856E782E3", - "02D337616C9D202DC5E290C486F5855CBD6A8470AE62CA96245834CF49257D8D" - "96D4041B15007650DEE668C00DDBF749054256C571F60980AC74D0DBCA7FB96C2F48" - }, { - "NIST P-521", 1, - "822A846606DC9E96452CAC373567A8B57D9ACA15B177F75DD7EF10C635F52CE4" - "EF6ABEEDB90D3F48F50A0C9015A95C955A25C45DE8413DE3BF899B6B1E62CF7CB8", - "0102771B5F3EC8C36838CEC04DCBC28AD1E38C37DAB0EA89B5EE92D21F7A35CE" - "ABC8B155EDC70154D6DFA2E77EC1D8C4A3406A6BD0ECF8F1EE2AC33A02464CB70C97" - }, { - "NIST P-521", 0, - "F733D48467912D1FFE46CF442F27FDD218D190E7B8A829D822DA3B6BAF9B987E" - "5B4BCCE34499248F59EEAF74F63ED15FF73F243C6FC3FD5E5842F6A3BA34C2022D", - "0281AAAD1B7EEBABEB6EC67932CB7E95717AFA3B4CF7A2DB151CD537C419C3A5" - "156ED9160758190B47696CDC15E81BBAD12975283907A571604DB23F702AEA4B38FF" - }, { - "NIST P-521", 0, - "03B1B274175AAEB5907152E5114CCAEADA28A7ADD4A2B1831C3D8302E8596489" - "E2C98B9B8D0CAE98C03BB11E28CE66D4736449758AF58BAFE40EF5A5FA22C9A43117", - "94C5951F81D544E959EDFC5DC1D5F42FE427871D4FB91A43A0B4A6BEA6B35B9E" - "BC5FB444C70BE4FD47B4ED16704F8C86EF019FC47C7FF2271F8B0DDEA9E2D3BCDD" - }, { - "NIST P-521", 1, - "F2248C318055DE37CD706D4FCAF7E7D96737A4A7B6B8067A66DCD58B6B8DFC55" - "90ECE67F6AA67F9C51B57E7B023075F2F42909BF47361CB6881C10F55FB7215B56", - "0162F735CE6A2ADA54CAF96A12D6888C02DE0A74638CF34CE39DABBACA4D651B" - "7E6ED1A65B551B36BAE7BE474BB6E6905ED0E33C7BA2021885027C7C6E40C5613004" - }, { - "NIST P-521", 0, - "9F08E97FEADCF0A391CA1EA4D97B5FE62D3B164593E12027EB967BD6E1FA841A" - "9831158DF164BCAD0BF3ADA96127745E25F349BDDD52EEA1654892B35960C9C023", - "AE2A25F5440F258AFACA6925C4C9F7AEAD3CB67153C4FACB31AC33F58B43A78C" - "B14F682FF726CEE2A6B6F6B481AEEB29A9B3150F02D1CFB764672BA8294C477291" - }, { - "NIST P-521", 0, - "01047B52014748C904980716953206A93F0D01B34CA94A997407FA93FE304F86" - "17BB6E402B2BB8B434C2671ECE953ABE7BADB75713CD9DF950943A33A9A19ACCDABE", - "7433533F098037DEA616337986887D01C5CC8DEC3DC1FDB9CDF7287EF27CC125" - "54FCF3A5E212DF9DAD9F8A3A7173B23FC6E15930704F3AEE1B074BDDB0ED6823E4" - }, { - "NIST P-521", 0, - "01C2A9EBF51592FE6589F618EAADA1697D9B2EC7CE5D48C9E80FC597642B23F1" - "F0EBE953449762BD3F094F57791D9850AFE98BBDA9872BE399B7BDD617860076BB03", - "0B822E27692F63DB8E12C59BB3CCA172B9BBF613CAE5F9D1474186E45E8B26FF" - "962084E1C6BE74821EDBB60941A3B75516F603719563433383812BFEA89EC14B89" - }, { - "NIST P-521", 0, - "99390F342C3F0D46E80C5B65C61E8AA8ACA0B6D4E1352404586364A05D8398E9" - "2BC71A644E8663F0A9B87D0B3ACAEE32F2AB9B321317AD23059D045EBAB91C5D93", - "82FCF93AE4467EB57766F2B150E736636727E7282500CD482DA70D153D195F2B" - "DF9B96D689A0DC1BB9137B41557A33F202F1B71840544CBEFF03072E77E4BB6F0B" - }, { - "NIST P-521", 1, - "018E48E80594FF5496D8CC7DF8A19D6AA18805A4EF4490038AED6A1E9AA18056" - "D0244A97DCF6D132C6804E3F4F369922119544B4C057D783C848FB798B48730A382C", - "01AF510B4F5E1C40BC9C110216D35E7C6D7A2BEE52914FC98258676288449901" - "F27A07EE91DF2D5D79259712906C3E18A990CBF35BCAC41A952820CE2BA8D0220080" - }, { - "NIST P-521", 1, - "ADCEF3539B4BC831DC0AFD173137A4426152058AFBAE06A17FCB89F4DB6E48B5" - "335CB88F8E4DB475A1E390E5656072F06605BFB84CBF9795B7992ECA04A8E10CA1", - "01BCB985AFD6404B9EDA49B6190AAA346BF7D5909CA440C0F7E505C62FAC8635" - "31D3EB7B2AC4DD4F4404E4B12E9D6D3C596179587F3724B1EFFF684CFDB4B21826B9" - } - }; - gpg_error_t err; - int tidx; - const char *lastcurve = NULL; - gcry_ctx_t ctx = NULL; - gcry_mpi_t qx = NULL; - gcry_mpi_t qy = NULL; - gcry_mpi_point_t Q; - int oncurve; - - wherestr = "point_on_curve"; - for (tidx=0; tidx < DIM (t); tidx++) - { - if (!t[tidx].curve) - { - if (!lastcurve || !ctx) - die ("invalid test vectors at idx %d\n", tidx); - } - else if (!ctx || !lastcurve || strcmp (t[tidx].curve, lastcurve)) - { - lastcurve = t[tidx].curve; - gcry_ctx_release (ctx); - err = gcry_mpi_ec_new (&ctx, NULL, lastcurve); - if (err) - die ("error creating context for curve %s at idx %d: %s\n", - lastcurve, tidx, gpg_strerror (err)); - - info ("checking points on curve %s\n", lastcurve); - } - - gcry_mpi_release (qx); - gcry_mpi_release (qy); - qx = hex2mpi (t[tidx].qx); - qy = hex2mpi (t[tidx].qy); - - Q = gcry_mpi_point_set (NULL, qx, qy, GCRYMPI_CONST_ONE); - if (!Q) - die ("gcry_mpi_point_set(Q) failed at idx %d\n", tidx); - - oncurve = gcry_mpi_ec_curve_point (Q, ctx); - - if (t[tidx].oncurve && !oncurve) - { - fail ("point expected on curve but not identified as such (i=%d):\n", - tidx); - print_point (" Q", Q); - } - else if (!t[tidx].oncurve && oncurve) - { - fail ("point not expected on curve but identified as such (i=%d):\n", - tidx); - print_point (" Q", Q); - } - gcry_mpi_point_release (Q); - } - - gcry_mpi_release (qx); - gcry_mpi_release (qy); - gcry_ctx_release (ctx); -} - - -int -main (int argc, char **argv) -{ - - if (argc > 1 && !strcmp (argv[1], "--verbose")) - verbose = 1; - else if (argc > 1 && !strcmp (argv[1], "--debug")) - verbose = debug = 1; - - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - - xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - - set_get_point (); - context_alloc (); - context_param (); - basic_ec_math (); - point_on_curve (); - - /* The tests are for P-192 and ed25519 which are not supported in - FIPS mode. */ - if (!gcry_fips_mode_active()) - { - basic_ec_math_simplified (); - twistededwards_math (); - } - - info ("All tests completed. Errors: %d\n", error_count); - return error_count ? 1 : 0; -} From 02e6d9b5f1047a4901bd459e25a1dbf59653f6b0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 Oct 2021 11:46:31 +0200 Subject: [PATCH 42/88] Remove a no longer needed patch --- libgcrypt-1.8.3-fips-enttest.patch | 113 ----------------------------- libgcrypt.spec | 3 - 2 files changed, 116 deletions(-) delete mode 100644 libgcrypt-1.8.3-fips-enttest.patch diff --git a/libgcrypt-1.8.3-fips-enttest.patch b/libgcrypt-1.8.3-fips-enttest.patch deleted file mode 100644 index 34e54bf..0000000 --- a/libgcrypt-1.8.3-fips-enttest.patch +++ /dev/null @@ -1,113 +0,0 @@ -diff -up libgcrypt-1.8.3/random/random-drbg.c.fips-enttest libgcrypt-1.8.3/random/random-drbg.c ---- libgcrypt-1.8.3/random/random-drbg.c.fips-enttest 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/random/random-drbg.c 2019-06-24 10:04:23.219547141 +0200 -@@ -317,6 +317,7 @@ struct drbg_state_s - gcry_cipher_hd_t ctr_handle; /* CTR mode cipher handle */ - int seeded:1; /* DRBG fully seeded? */ - int pr:1; /* Prediction resistance enabled? */ -+ int ent_primed:1; /* Previous entropy data primed? */ - /* Taken from libgcrypt ANSI X9.31 DRNG: We need to keep track of the - * process which did the initialization so that we can detect a fork. - * The volatile modifier is required so that the compiler does not -@@ -324,6 +325,7 @@ struct drbg_state_s - pid_t seed_init_pid; - const struct drbg_state_ops_s *d_ops; - const struct drbg_core_s *core; -+ unsigned char ent_hash[64]; /* Hash of previous entropy data */ - struct drbg_test_data_s *test_data; - }; - -@@ -610,11 +612,13 @@ drbg_get_entropy (drbg_state_t drbg, uns - size_t len) - { - int rc = 0; -+ unsigned char newhash[64]; - - /* Perform testing as defined in 11.3.2 */ - if (drbg->test_data && drbg->test_data->fail_seed_source) - return -1; - -+redo: - read_cb_buffer = buffer; - read_cb_size = len; - read_cb_len = 0; -@@ -634,6 +638,27 @@ drbg_get_entropy (drbg_state_t drbg, uns - #else - rc = -1; - #endif -+ -+ /* to avoid storing the actual entropy obtained for indefinite -+ time, we just store the SHA-512 hash of the entropy gathered -+ */ -+ _gcry_md_hash_buffer (GCRY_MD_SHA512, newhash, buffer, len); -+ -+ if (!drbg->ent_primed) -+ { -+ memcpy (drbg->ent_hash, newhash, sizeof (drbg->ent_hash)); -+ drbg->ent_primed = 1; -+ goto redo; -+ } -+ -+ if (memcmp (newhash, drbg->ent_hash, sizeof (drbg->ent_hash)) == 0) -+ { -+ fips_signal_error ("Entropy source failed the continuous test"); -+ return -1; /* continuous entropy test failed */ -+ } -+ -+ memcpy (drbg->ent_hash, newhash, sizeof (drbg->ent_hash)); -+ - return rc; - } - -@@ -1341,26 +1366,38 @@ drbg_seed (drbg_state_t drbg, drbg_strin - } - else - { -+ int nonce = 0; - /* Gather entropy equal to the security strength of the DRBG. - * With a derivation function, a nonce is required in addition - * to the entropy. A nonce must be at least 1/2 of the security - * strength of the DRBG in size. Thus, entropy * nonce is 3/2 - * of the strength. The consideration of a nonce is only -- * applicable during initial seeding. */ -+ * applicable during initial seeding. -+ * To avoid pulling different length of data from entropy -+ * source, we use 2 * strength for initial seeding. */ - entropylen = drbg_sec_strength (drbg->core->flags); - if (!entropylen) - return GPG_ERR_GENERAL; - if (0 == reseed) -- /* make sure we round up strength/2 in -- * case it is not divisible by 2 */ -- entropylen = ((entropylen + 1) / 2) * 3; -+ { -+ nonce = 1; -+ } - dbg (("DRBG: (re)seeding with %lu bytes of entropy\n", entropylen)); -- entropy = xcalloc_secure (1, entropylen); -+ entropy = xcalloc_secure (nonce + 1, entropylen); - if (!entropy) - return GPG_ERR_ENOMEM; - ret = drbg_get_entropy (drbg, entropy, entropylen); - if (ret) - goto out; -+ if (nonce) -+ { -+ ret = drbg_get_entropy (drbg, entropy + entropylen, entropylen); -+ if (ret) -+ goto out; -+ /* make sure we round up strength/2 in -+ * case it is not divisible by 2 */ -+ entropylen = 2 * entropylen; -+ } - drbg_string_fill (&data1, entropy, entropylen); - } - -@@ -1597,6 +1634,7 @@ drbg_instantiate (drbg_state_t drbg, - drbg->core = &drbg_cores[coreref]; - drbg->pr = pr; - drbg->seeded = 0; -+ drbg->ent_primed = 0; - if (drbg->core->flags & DRBG_HMAC) - drbg->d_ops = &drbg_hmac_ops; - else if (drbg->core->flags & DRBG_HASH_MASK) diff --git a/libgcrypt.spec b/libgcrypt.spec index a90a8ba..f09a85d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -37,8 +37,6 @@ Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch Patch18: libgcrypt-1.8.3-fips-ctor.patch # Do not try to open /dev/urandom if getrandom() works Patch24: libgcrypt-1.8.5-getrandom.patch -# Continuous FIPS entropy test -Patch26: libgcrypt-1.8.3-fips-enttest.patch # Disable non-approved FIPS hashes in the enforced FIPS mode Patch27: libgcrypt-1.8.3-md-fips-enforce.patch # Missing Intel CET support in the library (#1954049) @@ -89,7 +87,6 @@ applications using libgcrypt. %patch13 -p1 -b .gccopt %patch18 -p1 -b .fips-ctor %patch24 -p1 -b .getrandom -%patch26 -p1 -b .fips-enttest %patch27 -p1 -b .fips-enforce %patch28 -p1 -b .intel-cet %patch30 -p1 -b .fips-module From 4b1e516cd711a3875698b58056f5351570da199b Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 27 Oct 2021 11:52:10 +0200 Subject: [PATCH 43/88] Removed unused CAVS patch --- libgcrypt-1.7.3-fips-cavs.patch | 1311 ------------------------------- libgcrypt.spec | 3 - 2 files changed, 1314 deletions(-) delete mode 100644 libgcrypt-1.7.3-fips-cavs.patch diff --git a/libgcrypt-1.7.3-fips-cavs.patch b/libgcrypt-1.7.3-fips-cavs.patch deleted file mode 100644 index 42d028e..0000000 --- a/libgcrypt-1.7.3-fips-cavs.patch +++ /dev/null @@ -1,1311 +0,0 @@ -diff -up libgcrypt-1.7.3/tests/cavs_driver.pl.cavs libgcrypt-1.7.3/tests/cavs_driver.pl ---- libgcrypt-1.7.3/tests/cavs_driver.pl.cavs 2013-03-15 20:25:38.000000000 +0100 -+++ libgcrypt-1.7.3/tests/cavs_driver.pl 2016-11-22 17:29:06.067553077 +0100 -@@ -1,9 +1,11 @@ - #!/usr/bin/env perl - # --# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ -+# $Id: cavs_driver.pl 2124 2010-12-20 07:56:30Z smueller $ - # - # CAVS test driver (based on the OpenSSL driver) - # Written by: Stephan Müller -+# Werner Koch (libgcrypt interface) -+# Tomas Mraz (addition of DSA2) - # Copyright (c) atsec information security corporation - # - # Permission is hereby granted, free of charge, to any person obtaining a copy -@@ -85,13 +87,16 @@ - # T[CBC|CFB??|ECB|OFB]varkey - # T[CBC|CFB??|ECB|OFB]invperm - # T[CBC|CFB??|ECB|OFB]vartext -+# WARNING: TDES in CFB and OFB mode problems see below - # - # ANSI X9.31 RNG - # ANSI931_AES128MCT - # ANSI931_AES128VST - # --# DSA -+# DSA2 - # PQGGen -+# PQGVer -+# KeyPair - # SigGen - # SigVer - # -@@ -101,6 +106,36 @@ - # RC4PltBD - # RC4REGT - # -+# -+# TDES MCT for CFB and OFB: -+# ------------------------- -+# The inner loop cannot be handled by this script. If you want to have tests -+# for these cipher types, implement your own inner loop and add it to -+# crypto_mct. -+# -+# the value $next_source in crypto_mct is NOT set by the standard implementation -+# of this script. It would need to be set as follows for these two (code take -+# from fipsdrv.c from libgcrypt - the value input at the end will contain the -+# the value for $next_source: -+# -+# ... inner loop ... -+# ... -+# get_current_iv (hd, last_iv, blocklen); -+# ... encrypt / decrypt (input is the data to be en/decrypted and output is the -+# result of operation) ... -+# if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB)) -+# memcpy (input, last_iv, blocklen); -+# else if (cipher_mode == GCRY_CIPHER_MODE_OFB) -+# memcpy (input, last_iv, blocklen); -+# else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) -+# { -+# /* Reconstruct the output vector. */ -+# int i; -+# for (i=0; i < blocklen; i++) -+# input[i] ^= output[i]; -+# } -+# ... inner loop ends ... -+# ==> now, the value of input is to be put into $next_source - - use strict; - use warnings; -@@ -226,6 +261,8 @@ my $hmac; - # Generate the P, Q, G, Seed, counter, h (value used to generate g) values - # for DSA - # $1: modulus size -+# $2: q size -+# $3: seed (might be empty string) - # return: string with the calculated values in hex format, where each value - # is separated from the previous with a \n in the following order: - # P\n -@@ -236,6 +273,19 @@ my $hmac; - # h - my $dsa_pqggen; - -+# Generate the G value from P and Q -+# for DSA -+# $1: modulus size -+# $2: q size -+# $3: P in hex form -+# $4: Q in hex form -+# return: string with the calculated values in hex format, where each value -+# is separated from the previous with a \n in the following order: -+# P\n -+# Q\n -+# G\n -+my $dsa_ggen; -+ - # - # Generate an DSA public key from the provided parameters: - # $1: Name of file to create -@@ -255,16 +305,30 @@ my $dsa_verify; - - # generate a new DSA key with the following properties: - # PEM format --# $1 keyfile name --# return: file created, hash with keys of P, Q, G in hex format -+# $1: modulus size -+# $2: q size -+# $3 keyfile name -+# return: file created with key, string with values of P, Q, G in hex format - my $gen_dsakey; - -+# generate a new DSA private key XY parameters in domain: -+# PEM format -+# $1: P in hex form -+# $2: Q in hex form -+# $3: G in hex form -+# return: string with values of X, Y in hex format -+my $gen_dsakey_domain; -+ - # Sign a message with DSA - # $1: data to be signed in hex form - # $2: Key file in PEM format with the private key - # return: hash of digest information in hex format with Y, R, S as keys - my $dsa_sign; - -+my $rsa_keygen; -+ -+my $rsa_keygen_kat; -+ - ################################################################ - ##### OpenSSL interface functions - ################################################################ -@@ -404,6 +468,35 @@ sub libgcrypt_rsa_derive($$$$$$$$) { - } - - -+sub libgcrypt_rsa_keygen($) { -+ my $n = shift; -+ my $sexp; -+ -+ $n = sprintf ("%u", $n); -+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")))\n"; -+ -+ return pipe_through_program($sexp, "fipsdrv rsa-keygen"); -+} -+ -+ -+sub libgcrypt_rsa_keygen_kat($$$$) { -+ my $n = shift; -+ my $e = shift; -+ my $p = shift; -+ my $q = shift; -+ my $sexp; -+ -+ $n = sprintf ("%u", $n); -+ $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" -+ . "(test-parms" -+ . "(e #$e#)" -+ . "(p #$p#)" -+ . "(q #$q#))))\n"; -+ -+ return pipe_through_program($sexp, "fipsdrv rsa-keygen-kat"); -+} -+ -+ - sub libgcrypt_rsa_sign($$$) { - my $data = shift; - my $hashalgo = shift; -@@ -500,17 +593,32 @@ sub libgcrypt_hmac($$$$) { - return pipe_through_program($msg, $program); - } - --sub libgcrypt_dsa_pqggen($) { -+sub libgcrypt_dsa_pqggen($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $seed = shift; -+ -+ my $program = "fipsdrv --keysize $mod --qsize $qsize dsa-pqg-gen"; -+ return pipe_through_program($seed, $program); -+} -+ -+sub libgcrypt_dsa_ggen($$$$) { - my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $domain = "(domain (p #$p#)(q #$q#))"; - -- my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key \'$domain\' dsa-g-gen"; - return pipe_through_program("", $program); - } - --sub libgcrypt_gen_dsakey($) { -+sub libgcrypt_gen_dsakey($$$) { -+ my $mod = shift; -+ my $qsize = shift; - my $file = shift; - -- my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; -+ my $program = "fipsdrv --keysize $mod --qsize $qsize --key $file dsa-gen"; - my $tmp; - my %ret; - -@@ -519,10 +627,21 @@ sub libgcrypt_gen_dsakey($) { - $tmp = pipe_through_program("", $program); - die "dsa key gen failed: file $file not created" if (! -f $file); - -- @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); -+ @ret{'P', 'Q', 'G'} = split(/\n/, $tmp); - return %ret; - } - -+sub libgcrypt_gen_dsakey_domain($$$) { -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $domain = "(domain (p #$p#)(q #$q#)(g #$g#))"; -+ -+ my $program = "fipsdrv --key '$domain' dsa-gen-key"; -+ -+ return pipe_through_program("", $program); -+} -+ - sub libgcrypt_dsa_genpubkey($$$$$) { - my $filename = shift; - my $p = shift; -@@ -1139,7 +1258,7 @@ sub hmac_kat($$$$) { - $out .= "Tlen = $tlen\n"; - $out .= "Key = $key\n"; - $out .= "Msg = $msg\n"; -- $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; -+ $out .= "Mac = " . lc(&$hmac($key, $tlen, $msg, $hashtype{$tlen})) . "\n"; - - return $out; - } -@@ -1205,7 +1324,7 @@ sub crypto_mct($$$$$$$$) { - } - my ($CO, $CI); - my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); -- $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); -+ $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/ && defined($state_cipher_des)); - my $pid = open2($CO, $CI, $cipher_imp); - - my $calc_data = $iv; # CT[j] -@@ -1213,8 +1332,8 @@ sub crypto_mct($$$$$$$$) { - my $old_old_calc_data; # CT[j-2] - my $next_source; - -- # TDES inner loop implements logic within driver -- if ($cipher =~ /des/) { -+ # TDES inner loop implements logic within driver of libgcrypt -+ if ($cipher =~ /des/ && $opt{'I'} && $opt{'I'} eq 'libgcrypt' ) { - # Need to provide a dummy IV in case of ECB mode. - my $iv_arg = (defined($iv) && $iv ne "") - ? bin2hex($iv) -@@ -1238,6 +1357,10 @@ sub crypto_mct($$$$$$$$) { - $line = <$CO>; - } else { - for (my $j = 0; $j < $iloop; ++$j) { -+ if ($cipher =~ /des-ede3-ofb/ || -+ (!$enc && $cipher =~ /des-ede3-cfb/)) { -+ die "Implementation lacks support for TDES OFB and TDES CFB in encryption mode - the problem is that we would need to extract the IV of the last round of encryption which would be the input for the next round - see comments in this script for implementation requirements"; -+ } - $old_old_calc_data = $old_calc_data; - $old_calc_data = $calc_data; - -@@ -1429,7 +1552,7 @@ sub rsa_sigver($$$$$) { - # $7 xq2 - # $8 Xq - # return: string formatted as expected by CAVS --sub rsa_keygen($$$$$$$$) { -+sub rsa_keygen_x931($$$$$$$$) { - my $modulus = shift; - my $e = shift; - my $xp1 = shift; -@@ -1503,21 +1626,23 @@ sub rngx931($$$$) { - return $out; - } - --# DSA PQGGen test -+# DSA PQGen test - # $1 modulus size --# $2 number of rounds to perform the test -+# $2 q size -+# $3 number of rounds to perform the test - # return: string formatted as expected by CAVS --sub dsa_pqggen_driver($$) { -+sub dsa_pqgen_driver($$$) { - my $mod = shift; -+ my $qsize = shift; - my $rounds = shift; - - my $out = ""; - for(my $i=0; $i<$rounds; $i++) { -- my $ret = &$dsa_pqggen($mod); -+ my $ret = &$dsa_pqggen($mod, $qsize, ""); - my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); -- die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" -- if (!defined($P) || !defined($Q) || !defined($G) || -- !defined($Seed) || !defined($c) || !defined($H)); -+ die "Return value does not contain all expected values of P, Q, Seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || -+ !defined($Seed) || !defined($c)); - - # now change the counter to decimal as CAVS wants decimal - # counter value although all other is HEX -@@ -1525,15 +1650,166 @@ sub dsa_pqggen_driver($$) { - - $out .= "P = $P\n"; - $out .= "Q = $Q\n"; -- $out .= "G = $G\n"; -- $out .= "Seed = $Seed\n"; -- $out .= "c = $c\n"; -- $out .= "H = $H\n\n"; -+ $out .= "domain_parameter_seed = $Seed\n"; -+ $out .= "counter = $c\n\n"; - } - - return $out; - } - -+# DSA GGen test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# return: string formatted as expected by CAVS -+sub dsa_ggen_driver($$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_ggen($mod, $qsize, $p, $q); -+ my ($P, $Q, $G) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G for dsa_ggen" -+ if (!defined($P) || !defined($Q) || !defined($G)); -+ -+ $out .= "G = $G\n\n"; -+ -+ return $out; -+} -+ -+sub hexcomp($$) { -+ my $a = lc shift; -+ my $b = lc shift; -+ -+ if (length $a < length $b) { -+ my $c = $a; -+ $a = $b; -+ $b = $a; -+ } -+ -+ while (length $b < length $a) { -+ $b = "00$b"; -+ } -+ -+ return $a eq $b; -+} -+ -+# DSA PQVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 seed in hex form -+# $6 c decimal counter -+# return: string formatted as expected by CAVS -+sub dsa_pqver_driver($$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $seed = shift; -+ my $c = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2)); -+ -+ $c2 = hex($c2); -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($seed, $seed2) && $c == $c2) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ return $out; -+} -+ -+# DSA PQGVer test -+# $1 modulus size -+# $2 q size -+# $3 p in hex form -+# $4 q in hex form -+# $5 g in hex form -+# $6 seed in hex form -+# $7 c decimal counter -+# $8 h in hex form -+# return: string formatted as expected by CAVS -+sub dsa_pqgver_driver($$$$$$$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $p = shift; -+ my $q = shift; -+ my $g = shift; -+ my $seed = shift; -+ my $c = shift; -+ my $h = shift; -+ -+ my $out = ""; -+ my $ret = &$dsa_pqggen($mod, $qsize, $seed); -+ my ($P, $Q, $G, $seed2, $c2, $h2) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of P, Q, G, seed, c, H for dsa_pqggen" -+ if (!defined($P) || !defined($Q) || !defined($G) || -+ !defined($seed2) || !defined($c2) || !defined($h2)); -+ -+ -+ -+ $out .= "Seed = $seed\n"; -+ $out .= "c = $c\n"; -+ $out .= "H = $h\n"; -+ -+ $c2 = hex($c2); -+ -+ if (hexcomp($P, $p) && hexcomp($Q, $q) && hexcomp($G, $g) && hexcomp($seed, $seed2) && -+ $c == $c2 && hex($h) == hex($h2)) { -+ $out .= "Result = P\n\n"; -+ } -+ else { -+ $out .= "Result = F\n\n"; -+ } -+ -+ return $out; -+} -+ -+# DSA Keypair test -+# $1 modulus size -+# $2 q size -+# $3 number of rounds to perform the test -+# return: string formatted as expected by CAVS -+sub dsa_keypair_driver($$$) { -+ my $mod = shift; -+ my $qsize = shift; -+ my $rounds = shift; -+ -+ my $out = ""; -+ my $tmpkeyfile = "dsa_siggen.tmp.$$"; -+ my %pqg = &$gen_dsakey($mod, $qsize, $tmpkeyfile); -+ $out .= "P = " . $pqg{'P'} . "\n"; -+ $out .= "Q = " . $pqg{'Q'} . "\n"; -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ unlink($tmpkeyfile); -+ -+ for(my $i=0; $i<$rounds; $i++) { -+ my $ret = &$gen_dsakey_domain($pqg{'P'}, $pqg{'Q'}, $pqg{'G'}); -+ my ($X, $Y) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of X, Y for gen_dsakey_domain" -+ if (!defined($X) || !defined($Y)); -+ -+ $out .= "X = $X\n"; -+ $out .= "Y = $Y\n\n"; -+ } -+ -+ return $out; -+} - - # DSA SigGen test - # $1: Message to be signed in hex form -@@ -1598,6 +1874,53 @@ sub dsa_sigver($$$$$$$$) { - return $out; - } - -+# RSA Keygen RPP test -+# $1 modulus size -+# $2 number of rounds to perform the test -+# return: string formatted as expected by CAVS -+sub rsa_keygen_driver($$) { -+ my $mod = shift; -+ my $rounds = shift; -+ -+ my $out = ""; -+ -+ for(my $i=0; $i<$rounds; $i++) { -+ my $ret = &$rsa_keygen($mod); -+ my ($e, $p, $q, $n, $d) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of e, p, q, n, d for rsa_keygen" -+ if (!defined($e) || !defined($p) || !defined($q) || !defined($n) || !defined($d)); -+ -+ $out .= "e = $e\n"; -+ $out .= "p = $p\n"; -+ $out .= "q = $q\n"; -+ $out .= "n = $n\n"; -+ $out .= "d = $d\n\n"; -+ } -+ -+ return $out; -+} -+ -+# RSA RPP Keygen KAT test -+# $1 modulus size -+# $2 p in hex form -+# $3 q in hex form -+# return: string formatted as expected by CAVS -+sub rsa_keygen_kat_driver($$$) { -+ my $mod = shift; -+ my $p = shift; -+ my $q = shift; -+ -+ my $out = ""; -+ my $ret = &$rsa_keygen_kat($mod, $p, $q); -+ my ($Result) = split(/\n/, $ret); -+ die "Return value does not contain all expected values of Result for rsa_keygen_kat" -+ if (!defined($Result)); -+ -+ $out .= "Result = $Result\n\n"; -+ return $out; -+} -+ -+ - ############################################################## - # Parser of input file and generator of result file - # -@@ -1658,12 +1981,18 @@ sub parse($$) { - my $klen = ""; - my $tlen = ""; - my $modulus = ""; -+ my $qsize = ""; - my $capital_n = 0; -+ my $num = 0; - my $capital_p = ""; - my $capital_q = ""; - my $capital_g = ""; - my $capital_y = ""; - my $capital_r = ""; -+ my $capital_h = ""; -+ my $c = ""; -+ my $prandom = ""; -+ my $qrandom = ""; - my $xp1 = ""; - my $xp2 = ""; - my $Xp = ""; -@@ -1700,7 +2029,7 @@ sub parse($$) { - - ##### Extract cipher - # XXX there may be more - to be added -- if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { -+ if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA|KeyGen - Random Probably Prime|KeyPair|PQGVer)/) { - if ($tmpline =~ /CBC/) { $mode="cbc"; } - elsif ($tmpline =~ /ECB/) { $mode="ecb"; } - elsif ($tmpline =~ /OFB/) { $mode="ofb"; } -@@ -1749,7 +2078,23 @@ sub parse($$) { - - if ($tt == 0) { - ##### Identify the test type -- if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { -+ if ($tmpline =~ /KeyGen - Random Probably Prime Known Answer Test/) { -+ $tt = 19; -+ die "Interface function rsa_keygen_kat for RSA key generation KAT not defined for tested library" -+ if (!defined($rsa_keygen_kat)); -+ } elsif ($tmpline =~ /KeyGen - Random Probably Prime Test/) { -+ $tt = 18; -+ die "Interface function rsa_keygen for RSA key generation not defined for tested library" -+ if (!defined($rsa_keygen)); -+ } elsif ($tmpline =~ /PQGVer/) { -+ $tt = 16; -+ die "Interface function for DSA PQGVer testing not defined for tested library" -+ if (!defined($dsa_pqggen)); -+ } elsif ($tmpline =~ /KeyPair/) { -+ $tt = 14; -+ die "Interface function dsa_keygen for DSA key generation not defined for tested library" -+ if (!defined($gen_dsakey_domain)); -+ } elsif ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { - $tt = 13; - die "Interface function rsa_derive for RSA key generation not defined for tested library" - if (!defined($rsa_derive)); -@@ -1760,11 +2105,11 @@ sub parse($$) { - } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { - $tt = 11; - die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" -- if (!defined($dsa_sign) || !defined($gen_rsakey)); -+ if (!defined($dsa_sign) || !defined($gen_dsakey)); - } elsif ($tmpline =~ /PQGGen/) { - $tt = 10; - die "Interface function for DSA PQGGen testing not defined for tested library" -- if (!defined($dsa_pqggen)); -+ if (!defined($dsa_pqggen) || !defined($dsa_ggen)); - } elsif ($tmpline =~ /Hash sizes tested/) { - $tt = 9; - die "Interface function hmac for HMAC testing not defined for tested library" -@@ -1792,7 +2137,7 @@ sub parse($$) { - } elsif ($tmpline =~ /Monte|MCT|Carlo/) { - $tt = 2; - die "Interface function state_cipher for Stateful Cipher operation defined for tested library" -- if (!defined($state_cipher) || !defined($state_cipher_des)); -+ if (!defined($state_cipher) && !defined($state_cipher_des)); - } elsif ($cipher =~ /^sha/) { - $tt = 3; - die "Interface function hash for Hashing not defined for tested library" -@@ -1875,18 +2220,44 @@ sub parse($$) { - die "Msg/Seed seen twice - input file crap" if ($pt ne ""); - $pt=$2; - } -- elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ elsif ($line =~ /^\[A.2.1\s.*\]$/) { # found in DSA2 PQGGen request -+ $out .= $line . "\n"; # print it -+ if ($tt == 10) { -+ # now generate G from PQ -+ $tt = 15; -+ } -+ } -+ elsif ($line =~ /^\[A.2.2\s.*\]$/) { # found in DSA2 PQGVer request -+ $out .= $line . "\n"; # print it -+ if ($tt == 16) { -+ # now verify PQG -+ $tt = 17; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*L=([0-9]*),\s*N=([0-9]*).*\]$/) { # found in DSA2 requests - $modulus = $1; -+ $qsize = $2; - $out .= $line . "\n\n"; # print it -+ # clear eventual PQG -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; - # generate the private key with given bit length now - # as we have the required key length in bit - if ($tt == 11) { - $dsa_keyfile = "dsa_siggen.tmp.$$"; -- my %pqg = &$gen_dsakey($dsa_keyfile); -+ my %pqg = &$gen_dsakey($modulus, $qsize, $dsa_keyfile); - $out .= "P = " . $pqg{'P'} . "\n"; - $out .= "Q = " . $pqg{'Q'} . "\n"; -- $out .= "G = " . $pqg{'G'} . "\n"; -- } elsif ( $tt == 5 ) { -+ $out .= "G = " . $pqg{'G'} . "\n\n"; -+ } -+ } -+ elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests -+ $modulus = $1; -+ $out .= $line . "\n\n"; # print it -+ # generate the private key with given bit length now -+ # as we have the required key length in bit -+ if ( $tt == 5 ) { - # XXX maybe a secure temp file name is better here - # but since it is not run on a security sensitive - # system, I hope that this is fine -@@ -1907,6 +2278,9 @@ sub parse($$) { - } - elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests - $e=$1; -+ if ($tt == 19) { -+ $out .= $line . "\n"; # print it -+ } - } - elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests - die "S seen twice - input file crap" if ($signature ne ""); -@@ -1932,11 +2306,16 @@ sub parse($$) { - if ($tlen ne ""); - $tlen=$1; - } -- elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen -+ elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA KeyPair - die "N seen twice - check input file" - if ($capital_n); - $capital_n = $1; - } -+ elsif ($line =~ /^Num\s*=\s*(.*)/) { #DSA PQGGen -+ die "Num seen twice - check input file" -+ if ($num); -+ $num = $1; -+ } - elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer - die "P seen twice - check input file" - if ($capital_p); -@@ -1965,6 +2344,16 @@ sub parse($$) { - if ($capital_r); - $capital_r = $1; - } -+ elsif ($line =~ /^H\s*=\s*(.*)/) { #DSA PQGVer -+ die "H seen twice - check input file" -+ if ($capital_h); -+ $capital_h = $1; -+ } -+ elsif ($line =~ /^c\s*=\s*(.*)/) { #DSA PQGVer -+ die "c seen twice - check input file" -+ if ($c); -+ $c = $1; -+ } - elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen - die "xp1 seen twice - check input file" - if ($xp1); -@@ -1995,6 +2384,22 @@ sub parse($$) { - if ($Xq); - $Xq = $1; - } -+ elsif ($line =~ /^prandom\s*=\s*(.*)/) { #RSA key gen KAT -+ die "prandom seen twice - check input file" -+ if ($prandom); -+ $prandom = $1; -+ $out .= $line . "\n"; # print it -+ } -+ elsif ($line =~ /^qrandom\s*=\s*(.*)/) { #RSA key gen KAT -+ die "qrandom seen twice - check input file" -+ if ($qrandom); -+ $qrandom = $1; -+ $out .= $line . "\n"; # print it -+ } -+ elsif ($tt == 19 && $line =~ /^ / && $qrandom eq "") { #RSA key gen KAT -+ $qrandom = "00"; -+ $out .= $line . "\n"; # print it -+ } - else { - $out .= $line . "\n"; - } -@@ -2074,11 +2479,10 @@ sub parse($$) { - } - } - elsif ($tt == 10) { -- if ($modulus ne "" && $capital_n > 0) { -- $out .= dsa_pqggen_driver($modulus, $capital_n); -- #$mod is not resetted -- $capital_n = 0; -- } -+ if ($modulus ne "" && $qsize ne "" && $num > 0) { -+ $out .= dsa_pqgen_driver($modulus, $qsize, $num); -+ $num = 0; -+ } - } - elsif ($tt == 11) { - if ($pt ne "" && $dsa_keyfile ne "") { -@@ -2124,7 +2528,7 @@ sub parse($$) { - $xq1 ne "" && - $xq2 ne "" && - $Xq ne "") { -- $out .= rsa_keygen($modulus, -+ $out .= rsa_keygen_x931($modulus, - $e, - $xp1, - $xp2, -@@ -2141,6 +2545,96 @@ sub parse($$) { - $Xq = ""; - } - } -+ elsif ($tt == 14) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_n > 0) { -+ $out .= dsa_keypair_driver($modulus, -+ $qsize, -+ $capital_n); -+ $capital_n = 0; -+ } -+ } -+ elsif ($tt == 15) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "") { -+ $out .= dsa_ggen_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q); -+ $capital_p = ""; -+ $capital_q = ""; -+ $num--; -+ } -+ } -+ elsif ($tt == 16) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $pt ne "" && -+ $c ne "") { -+ $out .= dsa_pqver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $pt, -+ $c); -+ $capital_p = ""; -+ $capital_q = ""; -+ $pt = ""; -+ $c = ""; -+ } -+ } -+ elsif ($tt == 17) { -+ if ($modulus ne "" && -+ $qsize ne "" && -+ $capital_p ne "" && -+ $capital_q ne "" && -+ $capital_g ne "" && -+ $pt ne "" && -+ $c ne "" && -+ $capital_h ne "") { -+ $out .= dsa_pqgver_driver($modulus, -+ $qsize, -+ $capital_p, -+ $capital_q, -+ $capital_g, -+ $pt, -+ $c, -+ $capital_h); -+ $capital_p = ""; -+ $capital_q = ""; -+ $capital_g = ""; -+ $pt = ""; -+ $c = ""; -+ $capital_h = ""; -+ } -+ } -+ elsif ($tt == 18) { -+ if ($modulus ne "" && -+ $capital_n > 0) { -+ $out .= rsa_keygen_driver($modulus, -+ $capital_n); -+ $capital_n = 0; -+ } -+ } -+ elsif ($tt == 19) { -+ if ($modulus ne "" && -+ $e ne "" && -+ $prandom ne "" && -+ $qrandom ne "") { -+ $out .= rsa_keygen_kat_driver($modulus, -+ $e, -+ $prandom, -+ $qrandom); -+ $prandom = ""; -+ $qrandom = ""; -+ $e = ""; -+ } -+ } - elsif ($tt > 0) { - die "Test case $tt not defined"; - } -@@ -2199,10 +2693,14 @@ sub main() { - $state_rng = \&libgcrypt_state_rng; - $hmac = \&libgcrypt_hmac; - $dsa_pqggen = \&libgcrypt_dsa_pqggen; -+ $dsa_ggen = \&libgcrypt_dsa_ggen; - $gen_dsakey = \&libgcrypt_gen_dsakey; -+ $gen_dsakey_domain = \&libgcrypt_gen_dsakey_domain; - $dsa_sign = \&libgcrypt_dsa_sign; - $dsa_verify = \&libgcrypt_dsa_verify; - $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; -+ $rsa_keygen = \&libgcrypt_rsa_keygen; -+ $rsa_keygen_kat = \&libgcrypt_rsa_keygen_kat; - } else { - die "Invalid interface option given"; - } -diff -up libgcrypt-1.7.3/tests/cavs_tests.sh.cavs libgcrypt-1.7.3/tests/cavs_tests.sh ---- libgcrypt-1.7.3/tests/cavs_tests.sh.cavs 2013-03-15 20:25:38.000000000 +0100 -+++ libgcrypt-1.7.3/tests/cavs_tests.sh 2016-11-22 17:29:06.067553077 +0100 -@@ -55,7 +55,7 @@ function run_one_test () { - [ -d "$respdir" ] || mkdir "$respdir" - [ -f "$rspfile" ] && rm "$rspfile" - -- if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then -+ if echo "$reqfile" | grep '/DSA.\?/req/' >/dev/null 2>/dev/null; then - dflag="-D" - fi - -diff -up libgcrypt-1.7.3/tests/fipsdrv.c.cavs libgcrypt-1.7.3/tests/fipsdrv.c ---- libgcrypt-1.7.3/tests/fipsdrv.c.cavs 2016-07-14 11:19:17.000000000 +0200 -+++ libgcrypt-1.7.3/tests/fipsdrv.c 2016-11-22 17:33:15.468330859 +0100 -@@ -892,6 +892,9 @@ print_mpi_line (gcry_mpi_t a, int no_lz) - die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); - - p = buf; -+ while (*p) -+ *p++ = tolower(*p); -+ p = buf; - if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) - p += 2; - -@@ -1765,14 +1768,14 @@ run_rsa_verify (const void *data, size_t - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen (int keysize) -+dsa_gen (int keysize, int qsize) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; - - err = gcry_sexp_build (&keyspec, NULL, -- "(genkey (dsa (nbits %d)(use-fips186-2)))", -- keysize); -+ "(genkey (dsa (nbits %d)(qbits %d)(use-fips186)))", -+ keysize, qsize); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1790,7 +1793,7 @@ dsa_gen (int keysize) - /* Generate a DSA key of size KEYSIZE and return the complete - S-expression. */ - static gcry_sexp_t --dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) -+dsa_gen_with_seed (int keysize, int qsize, const void *seed, size_t seedlen) - { - gpg_error_t err; - gcry_sexp_t keyspec, key; -@@ -1799,10 +1802,11 @@ dsa_gen_with_seed (int keysize, const vo - "(genkey" - " (dsa" - " (nbits %d)" -- " (use-fips186-2)" -+ " (qbits %d)" -+ " (use-fips186)" - " (derive-parms" - " (seed %b))))", -- keysize, (int)seedlen, seed); -+ keysize, qsize, (int)seedlen, seed); - if (err) - die ("gcry_sexp_build failed for DSA key generation: %s\n", - gpg_strerror (err)); -@@ -1810,6 +1814,37 @@ dsa_gen_with_seed (int keysize, const vo - err = gcry_pk_genkey (&key, keyspec); - if (err) - die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); -+ -+ gcry_sexp_release (keyspec); -+ -+ return key; -+} -+ -+/* Generate a DSA key with specified domain parameters and return the complete -+ S-expression. */ -+static gcry_sexp_t -+dsa_gen_key (const char *domain) -+{ -+ gpg_error_t err; -+ gcry_sexp_t keyspec, key, domspec; -+ -+ err = gcry_sexp_new (&domspec, domain, strlen(domain), 0); -+ if (err) -+ die ("gcry_sexp_build failed for domain spec: %s\n", -+ gpg_strerror (err)); -+ -+ err = gcry_sexp_build (&keyspec, NULL, -+ "(genkey" -+ " (dsa" -+ " (use-fips186)" -+ " %S))", -+ domspec); -+ if (err) -+ die ("gcry_sexp_build failed for DSA key generation: %s\n", -+ gpg_strerror (err)); -+ err = gcry_pk_genkey (&key, keyspec); -+ if (err) -+ die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); - - gcry_sexp_release (keyspec); - -@@ -1849,7 +1884,7 @@ ecdsa_gen_key (const char *curve) - with one parameter per line in hex format using this order: p, q, - g, seed, counter, h. */ - static void --print_dsa_domain_parameters (gcry_sexp_t key) -+print_dsa_domain_parameters (gcry_sexp_t key, int print_misc) - { - gcry_sexp_t l1, l2; - gcry_mpi_t mpi; -@@ -1885,6 +1920,9 @@ print_dsa_domain_parameters (gcry_sexp_t - } - gcry_sexp_release (l1); - -+ if (!print_misc) -+ return; -+ - /* Extract the seed values. */ - l1 = gcry_sexp_find_token (key, "misc-key-info", 0); - if (!l1) -@@ -1976,38 +2014,106 @@ print_ecdsa_dq (gcry_sexp_t key) - } - - --/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+/* Print just the XY private key parameters. KEY -+ is the complete key as returned by dsa_gen. We print to stdout -+ with one parameter per line in hex format using this order: x, y. */ -+static void -+print_dsa_xy (gcry_sexp_t key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t mpi; -+ int idx; -+ -+ l1 = gcry_sexp_find_token (key, "private-key", 0); -+ if (!l1) -+ die ("private key not found in genkey result\n"); -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("returned private key not formed as expected\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ /* Extract the parameters from the S-expression and print them to stdout. */ -+ for (idx=0; "xy"[idx]; idx++) -+ { -+ l2 = gcry_sexp_find_token (l1, "xy"+idx, 1); -+ if (!l2) -+ die ("no %c parameter in returned public key\n", "xy"[idx]); -+ mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); -+ if (!mpi) -+ die ("no value for %c parameter in returned private key\n","xy"[idx]); -+ gcry_sexp_release (l2); -+ if (standalone_mode) -+ printf ("%c = ", "XY"[idx]); -+ print_mpi_line (mpi, 1); -+ gcry_mpi_release (mpi); -+ } -+ -+ gcry_sexp_release (l1); -+} -+ -+ -+/* Generate DSA pq domain parameters for a modulus size of KEYSIZE. The - result is printed to stdout with one parameter per line in hex -- format and in this order: p, q, g, seed, counter, h. If SEED is -+ format and in this order: p, q, seed, counter. If SEED is - not NULL this seed value will be used for the generation. */ - static void --run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) -+run_dsa_pqg_gen (int keysize, int qsize, const void *seed, size_t seedlen) - { - gcry_sexp_t key; - - if (seed) -- key = dsa_gen_with_seed (keysize, seed, seedlen); -+ key = dsa_gen_with_seed (keysize, qsize, seed, seedlen); - else -- key = dsa_gen (keysize); -- print_dsa_domain_parameters (key); -+ key = dsa_gen (keysize, qsize); -+ print_dsa_domain_parameters (key, 1); -+ gcry_sexp_release (key); -+} -+ -+ -+/* Generate DSA domain parameters for a modulus size of KEYSIZE. The -+ result is printed to stdout with one parameter per line in hex -+ format and in this order: p, q, g, seed, counter, h. If SEED is -+ not NULL this seed value will be used for the generation. */ -+static void -+run_dsa_g_gen (int keysize, int qsize, const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_domain_parameters (key, 0); -+ gcry_sexp_release (key); -+} -+ -+/* Generate a DSA key with specified domain parameters -+ and print the XY values. */ -+static void -+run_dsa_gen_key (const char *domain) -+{ -+ gcry_sexp_t key; -+ -+ key = dsa_gen_key (domain); -+ print_dsa_xy (key); -+ - gcry_sexp_release (key); - } - - - /* Generate a DSA key of size of KEYSIZE and write the private key to - FILENAME. Also write the parameters to stdout in the same way as -- run_dsa_pqg_gen. */ -+ run_dsa_g_gen. */ - static void --run_dsa_gen (int keysize, const char *filename) -+run_dsa_gen (int keysize, int qsize, const char *filename) - { - gcry_sexp_t key, private_key; - FILE *fp; - -- key = dsa_gen (keysize); -+ key = dsa_gen (keysize, qsize); - private_key = gcry_sexp_find_token (key, "private-key", 0); - if (!private_key) - die ("private key not found in genkey result\n"); -- print_dsa_domain_parameters (key); -+ print_dsa_domain_parameters (key, 1); - - fp = fopen (filename, "wb"); - if (!fp) -@@ -2020,6 +2126,53 @@ run_dsa_gen (int keysize, const char *fi - } - - -+static int -+dsa_hash_from_key(gcry_sexp_t s_key) -+{ -+ gcry_sexp_t l1, l2; -+ gcry_mpi_t q; -+ unsigned int qbits; -+ -+ l1 = gcry_sexp_find_token (s_key, "public-key", 0); -+ if (!l1) -+ { -+ l1 = gcry_sexp_find_token (s_key, "private-key", 0); -+ if (!l1) -+ die ("neither private nor public key found in the loaded key\n"); -+ } -+ -+ l2 = gcry_sexp_find_token (l1, "dsa", 0); -+ if (!l2) -+ die ("public key not formed as expected - no dsa\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ l2 = gcry_sexp_find_token (l1, "q", 0); -+ if (!l2) -+ die ("public key not formed as expected - no q\n"); -+ gcry_sexp_release (l1); -+ l1 = l2; -+ -+ q = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); -+ if (!q) -+ die ("public key not formed as expected - no mpi in q\n"); -+ qbits = gcry_mpi_get_nbits(q); -+ gcry_sexp_release(l1); -+ gcry_mpi_release(q); -+ switch(qbits) -+ { -+ case 160: -+ return GCRY_MD_SHA1; -+ case 224: -+ return GCRY_MD_SHA224; -+ case 256: -+ return GCRY_MD_SHA256; -+ default: -+ die("bad number bits (%d) of q in key\n", qbits); -+ } -+ return GCRY_MD_NONE; -+} -+ - - /* Sign DATA of length DATALEN using the key taken from the S-expression - encoded KEYFILE. */ -@@ -2029,11 +2182,16 @@ run_dsa_sign (const void *data, size_t d - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; -+ -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ gcry_md_hash_buffer (algo, hash, data, datalen); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -2044,8 +2202,6 @@ run_dsa_sign (const void *data, size_t d - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); -- - err = gcry_pk_sign (&s_sig, s_data, s_key); - if (err) - { -@@ -2121,13 +2277,18 @@ run_dsa_verify (const void *data, size_t - { - gpg_error_t err; - gcry_sexp_t s_data, s_key, s_sig; -- char hash[20]; -+ char hash[128]; - gcry_mpi_t tmpmpi; -+ int algo; - -- gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); -+ s_key = read_sexp_from_file (keyfile); -+ algo = dsa_hash_from_key(s_key); -+ -+ gcry_md_hash_buffer (algo, hash, data, datalen); - /* Note that we can't simply use %b with HASH to build the - S-expression, because that might yield a negative value. */ -- err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); -+ err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, -+ gcry_md_get_algo_dlen(algo), NULL); - if (!err) - { - err = gcry_sexp_build (&s_data, NULL, -@@ -2138,7 +2299,6 @@ run_dsa_verify (const void *data, size_t - die ("gcry_sexp_build failed for DSA data input: %s\n", - gpg_strerror (err)); - -- s_key = read_sexp_from_file (keyfile); - s_sig = read_sexp_from_file (sigfile); - - err = gcry_pk_verify (s_sig, s_data, s_key); -@@ -2304,7 +2464,7 @@ usage (int show_help) - "MODE:\n" - " encrypt, decrypt, digest, random, hmac-sha,\n" - " rsa-{derive,gen,sign,verify},\n" -- " dsa-{pqg-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" -+ " dsa-{pq-gen,g-gen,gen,sign,verify}, ecdsa-{gen-key,sign,verify}\n" - "OPTIONS:\n" - " --verbose Print additional information\n" - " --binary Input and output is in binary form\n" -@@ -2315,6 +2475,7 @@ usage (int show_help) - " --algo NAME Use algorithm NAME\n" - " --curve NAME Select ECC curve spec NAME\n" - " --keysize N Use a keysize of N bits\n" -+ " --qize N Use a DSA q parameter size of N bits\n" - " --signature NAME Take signature from file NAME\n" - " --chunk N Read in chunks of N bytes (implies --binary)\n" - " --pkcs1 Use PKCS#1 encoding\n" -@@ -2344,6 +2505,7 @@ main (int argc, char **argv) - const char *dt_string = NULL; - const char *algo_string = NULL; - const char *keysize_string = NULL; -+ const char *qsize_string = NULL; - const char *signature_string = NULL; - FILE *input; - void *data; -@@ -2437,6 +2599,14 @@ main (int argc, char **argv) - keysize_string = *argv; - argc--; argv++; - } -+ else if (!strcmp (*argv, "--qsize")) -+ { -+ argc--; argv++; -+ if (!argc) -+ usage (0); -+ qsize_string = *argv; -+ argc--; argv++; -+ } - else if (!strcmp (*argv, "--signature")) - { - argc--; argv++; -@@ -2792,23 +2962,49 @@ main (int argc, char **argv) - } - else if (!strcmp (mode_string, "dsa-pqg-gen")) - { -- int keysize; -+ int keysize, qsize; -+ -+ keysize = keysize_string? atoi (keysize_string) : 0; -+ if (keysize < 1024 || keysize > 3072) -+ die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ run_dsa_pqg_gen (keysize, qsize, datalen? data:NULL, datalen); -+ } -+ else if (!strcmp (mode_string, "dsa-g-gen")) -+ { -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -- run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); -+ if (!key_string) -+ die ("option --key containing pq domain parameters is required in this mode\n"); -+ run_dsa_g_gen (keysize, qsize, key_string); -+ } -+ else if (!strcmp (mode_string, "dsa-gen-key")) -+ { -+ if (!key_string) -+ die ("option --key containing pqg domain parameters is required in this mode\n"); -+ run_dsa_gen_key (key_string); - } - else if (!strcmp (mode_string, "dsa-gen")) - { -- int keysize; -+ int keysize, qsize; - - keysize = keysize_string? atoi (keysize_string) : 0; - if (keysize < 1024 || keysize > 3072) - die ("invalid keysize specified; needs to be 1024 .. 3072\n"); -+ qsize = qsize_string? atoi (qsize_string) : 0; -+ if (qsize < 160 || qsize > 256) -+ die ("invalid qsize specified; needs to be 160 .. 256\n"); - if (!key_string) - die ("option --key is required in this mode\n"); -- run_dsa_gen (keysize, key_string); -+ run_dsa_gen (keysize, qsize, key_string); - } - else if (!strcmp (mode_string, "dsa-sign")) - { diff --git a/libgcrypt.spec b/libgcrypt.spec index f09a85d..3dd4420 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -27,8 +27,6 @@ Patch2: libgcrypt-1.8.5-use-fipscheck.patch Patch5: libgcrypt-1.8.4-fips-keygen.patch # fix the tests to work correctly in the FIPS mode Patch6: libgcrypt-1.9.3-fips-tests.patch -# update the CAVS tests -Patch7: libgcrypt-1.7.3-fips-cavs.patch # use poll instead of select when gathering randomness Patch11: libgcrypt-1.8.4-use-poll.patch # slight optimalization of mpicoder.c to silence Valgrind (#968288) @@ -82,7 +80,6 @@ applications using libgcrypt. %patch2 -p1 -b .use-fipscheck %patch5 -p1 -b .fips-keygen %patch6 -p1 -b .tests-fipsmode -%patch7 -p1 -b .cavs %patch11 -p1 -b .use-poll %patch13 -p1 -b .gccopt %patch18 -p1 -b .fips-ctor From aff6b907cfe5498f9ca030f8db8621b59c76c9e8 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jan 2022 16:16:00 +0000 Subject: [PATCH 44/88] - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3dd4420..9880c7f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,6 +1,6 @@ Name: libgcrypt Version: 1.9.4 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: libgcrypt-%{version}-hobbled.tar.xz # The original libgcrypt sources now contain potentially patented ECC @@ -196,6 +196,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Thu Jan 20 2022 Fedora Release Engineering - 1.9.4-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild + * Mon Aug 23 2021 Jakub Jelen - 1.9.4-1 - New upstream release (#1996467) From 364af5a45153c9e9e07d7dbc0829a22aabef9320 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 2 Feb 2022 10:57:27 +0100 Subject: [PATCH 45/88] libgcrypt-1.10.0-1 --- .gitignore | 2 + curves.c | 271 ---- ecc-curves.c | 1483 ------------------ hobble-libgcrypt | 11 - keygrip.c | 341 ---- libgcrypt-1.10.0-disable-brainpool.patch | 239 +++ libgcrypt-1.6.1-mpicoder-gccopt.patch | 104 -- libgcrypt-1.8.3-fips-ctor.patch | 73 - libgcrypt-1.8.3-md-fips-enforce.patch | 37 - libgcrypt-1.8.4-fips-keygen.patch | 64 - libgcrypt-1.8.4-use-poll.patch | 77 - libgcrypt-1.8.5-fips-module.patch | 139 -- libgcrypt-1.8.5-getrandom.patch | 277 ---- libgcrypt-1.8.5-intel-cet.patch | 34 - libgcrypt-1.8.5-use-fipscheck.patch | 77 - libgcrypt-1.9.3-fips-tests.patch | 1804 ---------------------- libgcrypt.spec | 97 +- random.conf | 4 - sources | 3 +- 19 files changed, 277 insertions(+), 4860 deletions(-) delete mode 100644 curves.c delete mode 100644 ecc-curves.c delete mode 100755 hobble-libgcrypt delete mode 100644 keygrip.c create mode 100644 libgcrypt-1.10.0-disable-brainpool.patch delete mode 100644 libgcrypt-1.6.1-mpicoder-gccopt.patch delete mode 100644 libgcrypt-1.8.3-fips-ctor.patch delete mode 100644 libgcrypt-1.8.3-md-fips-enforce.patch delete mode 100644 libgcrypt-1.8.4-fips-keygen.patch delete mode 100644 libgcrypt-1.8.4-use-poll.patch delete mode 100644 libgcrypt-1.8.5-fips-module.patch delete mode 100644 libgcrypt-1.8.5-getrandom.patch delete mode 100644 libgcrypt-1.8.5-intel-cet.patch delete mode 100644 libgcrypt-1.8.5-use-fipscheck.patch delete mode 100644 libgcrypt-1.9.3-fips-tests.patch delete mode 100644 random.conf diff --git a/.gitignore b/.gitignore index 870812f..1bb23eb 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.9.2-hobbled.tar.xz /libgcrypt-1.9.3-hobbled.tar.xz /libgcrypt-1.9.4-hobbled.tar.xz +/libgcrypt-1.10.0.tar.bz2 +/libgcrypt-1.10.0.tar.bz2.sig diff --git a/curves.c b/curves.c deleted file mode 100644 index 1b190d1..0000000 --- a/curves.c +++ /dev/null @@ -1,271 +0,0 @@ -/* curves.c - ECC curves regression tests - * Copyright (C) 2011 Free Software Foundation, Inc. - * - * This file is part of Libgcrypt. - * - * Libgcrypt is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Libgcrypt is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif -#include -#include -#include -#include - -#include "../src/gcrypt-int.h" - - -#define PGM "curves" -#include "t-common.h" - -/* Number of curves defined in ../cipger/ecc-curves.c */ -#define N_CURVES 20 - -/* A real world sample public key. */ -static char const sample_key_1[] = -"(public-key\n" -" (ecdsa\n" -" (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)\n" -" (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)\n" -" (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)\n" -" (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296" - "4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)\n" -" (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)\n" -" (h #000000000000000000000000000000000000000000000000000000000000000001#)\n" -" (q #0442B927242237639A36CE9221B340DB1A9AB76DF2FE3E171277F6A4023DED146EE" - "86525E38CCECFF3FB8D152CC6334F70D23A525175C1BCBDDE6E023B2228770E#)\n" -" ))"; -static char const sample_key_1_curve[] = "NIST P-256"; -static unsigned int sample_key_1_nbits = 256; - -static void -list_curves (void) -{ - int idx; - const char *name; - unsigned int nbits; - - for (idx=0; (name = gcry_pk_get_curve (NULL, idx, &nbits)); idx++) - { - if (verbose) - printf ("%s - %u bits\n", name, nbits); - } - if (idx != N_CURVES) - fail ("expected %d curves but got %d\n", N_CURVES, idx); - if (gcry_pk_get_curve (NULL, -1, NULL)) - fail ("curve iteration failed\n"); -} - - -static void -check_matching (void) -{ - gpg_error_t err; - gcry_sexp_t key; - const char *name; - unsigned int nbits; - - err = gcry_sexp_new (&key, sample_key_1, 0, 1); - if (err) - die ("parsing s-expression string failed: %s\n", gpg_strerror (err)); - name = gcry_pk_get_curve (key, 0, &nbits); - if (!name) - fail ("curve name not found for sample_key_1\n"); - else if (strcmp (name, sample_key_1_curve)) - fail ("expected curve name %s but got %s for sample_key_1\n", - sample_key_1_curve, name); - else if (nbits != sample_key_1_nbits) - fail ("expected curve size %u but got %u for sample_key_1\n", - sample_key_1_nbits, nbits); - - gcry_sexp_release (key); -} - - -static void -check_get_params (void) -{ - static struct { - int algo; - const char *name; - int error_expected; - } tv[] = - { - { GCRY_PK_ECC, "Ed25519" }, - { GCRY_PK_ECC, "1.3.6.1.4.1.11591.15.1" }, - { GCRY_PK_ECC, "1.3.101.112" }, - - { GCRY_PK_ECC, "Curve25519" }, - { GCRY_PK_ECC, "1.3.6.1.4.1.3029.1.5.1" }, - { GCRY_PK_ECC, "1.3.101.110" }, - { GCRY_PK_ECC, "X25519" }, - - { GCRY_PK_ECC, "Ed448" }, - { GCRY_PK_ECC, "X448" }, - { GCRY_PK_ECC, "1.3.101.113" }, - { GCRY_PK_ECC, "1.3.101.111" }, - - { GCRY_PK_ECC, "NIST P-192" }, - { GCRY_PK_ECC, "1.2.840.10045.3.1.1" }, - { GCRY_PK_ECC, "prime192v1" }, - { GCRY_PK_ECC, "secp192r1" }, - { GCRY_PK_ECC, "nistp192" }, - - { GCRY_PK_ECC, "NIST P-224" }, - { GCRY_PK_ECC, "secp224r1" }, - { GCRY_PK_ECC, "1.3.132.0.33" }, - { GCRY_PK_ECC, "nistp224" }, - - { GCRY_PK_ECC, "NIST P-256" }, - { GCRY_PK_ECC, "1.2.840.10045.3.1.7" }, - { GCRY_PK_ECC, "prime256v1" }, - { GCRY_PK_ECC, "secp256r1" }, - { GCRY_PK_ECC, "nistp256" }, - - { GCRY_PK_ECC, "NIST P-384" }, - { GCRY_PK_ECC, "secp384r1" }, - { GCRY_PK_ECC, "1.3.132.0.34" }, - { GCRY_PK_ECC, "nistp384" }, - - { GCRY_PK_ECC, "NIST P-521" }, - { GCRY_PK_ECC, "secp521r1" }, - { GCRY_PK_ECC, "1.3.132.0.35" }, - { GCRY_PK_ECC, "nistp521" }, - - { GCRY_PK_ECC, "GOST2001-test" }, - { GCRY_PK_ECC, "1.2.643.2.2.35.0" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "1.2.643.2.2.35.1" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, - { GCRY_PK_ECC, "1.2.643.2.2.35.2" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "1.2.643.2.2.35.3" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-XchA" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-XchB" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "1.2.643.2.2.36.0" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "1.2.643.2.2.36.1" }, - - /* Noet that GOST2012-256-tc26-A" is only in the curve alias - * list but has no parameter entry. */ - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.2" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-A" }, - { GCRY_PK_ECC, "GOST2012-256-tc26-B" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.3" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-B" }, - { GCRY_PK_ECC, "GOST2012-256-tc26-C" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.1.4" }, - { GCRY_PK_ECC, "GOST2001-CryptoPro-C" }, - { GCRY_PK_ECC, "GOST2012-256-tc26-D" }, - - { GCRY_PK_ECC, "GOST2012-512-test" }, - { GCRY_PK_ECC, "GOST2012-test" }, - { GCRY_PK_ECC, "GOST2012-512-test" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.0" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-A" }, - { GCRY_PK_ECC, "GOST2012-tc26-A" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-B" }, - { GCRY_PK_ECC, "GOST2012-tc26-B" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-A" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.1" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-B" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.2" }, - { GCRY_PK_ECC, "GOST2012-512-tc26-C" }, - { GCRY_PK_ECC, "1.2.643.7.1.2.1.2.3" }, - - { GCRY_PK_ECC, "secp256k1" }, - { GCRY_PK_ECC, "1.3.132.0.10" }, - - { GCRY_PK_ECC, "sm2p256v1" }, - { GCRY_PK_ECC, "1.2.156.10197.1.301" }, - - /* Check also the ECC algo mapping. */ - { GCRY_PK_ECDSA, "Ed25519" }, - { GCRY_PK_EDDSA, "Ed25519" }, - { GCRY_PK_ECDH, "Ed25519" }, - { GCRY_PK_ECDSA, "Curve25519" }, - { GCRY_PK_EDDSA, "Curve25519" }, - { GCRY_PK_ECDH, "Curve25519" }, - { GCRY_PK_ECC, "NoSuchCurve", 1 }, - { GCRY_PK_RSA, "rsa", 1 }, - { GCRY_PK_ELG, "elg", 1 }, - { GCRY_PK_DSA, "dsa", 1 } - }; - int idx; - gcry_sexp_t param; - const char *name; - - param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_1_curve); - if (!param) - fail ("error gerring parameters for `%s'\n", sample_key_1_curve); - - name = gcry_pk_get_curve (param, 0, NULL); - if (!name) - fail ("get_param: curve name not found for sample_key_1\n"); - else if (strcmp (name, sample_key_1_curve)) - fail ("get_param: expected curve name %s but got %s for sample_key_1\n", - sample_key_1_curve, name); - - gcry_sexp_release (param); - - /* Some simple tests */ - for (idx=0; idx < DIM (tv); idx++) - { - param = gcry_pk_get_param (tv[idx].algo, tv[idx].name); - if (!param) - { - if (!tv[idx].error_expected) - fail ("get_param: test %d (%s) failed\n", idx, tv[idx].name); - } - else - { - if (tv[idx].error_expected) - fail ("get_param: test %d (%s) failed (error expected)\n", - idx, tv[idx].name); - } - gcry_sexp_release (param); - } -} - - -int -main (int argc, char **argv) -{ - if (argc > 1 && !strcmp (argv[1], "--verbose")) - verbose = 1; - else if (argc > 1 && !strcmp (argv[1], "--debug")) - verbose = debug = 1; - - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - - xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - list_curves (); - check_matching (); - check_get_params (); - - return error_count ? 1 : 0; -} diff --git a/ecc-curves.c b/ecc-curves.c deleted file mode 100644 index 5236b19..0000000 --- a/ecc-curves.c +++ /dev/null @@ -1,1483 +0,0 @@ -/* ecc-curves.c - Elliptic Curve parameter mangement - * Copyright (C) 2007, 2008, 2010, 2011 Free Software Foundation, Inc. - * Copyright (C) 2013 g10 Code GmbH - * - * This file is part of Libgcrypt. - * - * Libgcrypt is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Libgcrypt is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, see . - */ - -#include -#include -#include -#include -#include - -#include "g10lib.h" -#include "mpi.h" -#include "mpi-internal.h" -#include "cipher.h" -#include "context.h" -#include "ec-context.h" -#include "pubkey-internal.h" -#include "ecc-common.h" - - -static gpg_err_code_t -point_from_keyparam (gcry_mpi_point_t *r_a, - gcry_sexp_t keyparam, const char *name, mpi_ec_t ec); - -/* This tables defines aliases for curve names. */ -static const struct -{ - const char *name; /* Our name. */ - const char *other; /* Other name. */ -} curve_aliases[] = - { - { "Ed25519", "1.3.6.1.4.1.11591.15.1" }, /* OpenPGP */ - { "Ed25519", "1.3.101.112" }, /* rfc8410 */ - - { "Curve25519", "1.3.6.1.4.1.3029.1.5.1" }, /* OpenPGP */ - { "Curve25519", "1.3.101.110" }, /* rfc8410 */ - { "Curve25519", "X25519" }, /* rfc8410 */ - - { "Ed448", "1.3.101.113" }, /* rfc8410 */ - { "X448", "1.3.101.111" }, /* rfc8410 */ - - { "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */ - { "NIST P-192", "prime192v1" }, /* X9.62 name. */ - { "NIST P-192", "secp192r1" }, /* SECP name. */ - { "NIST P-192", "nistp192" }, /* rfc5656. */ - - { "NIST P-224", "secp224r1" }, - { "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */ - { "NIST P-224", "nistp224" }, /* rfc5656. */ - - { "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */ - { "NIST P-256", "prime256v1" }, - { "NIST P-256", "secp256r1" }, - { "NIST P-256", "nistp256" }, /* rfc5656. */ - - { "NIST P-384", "secp384r1" }, - { "NIST P-384", "1.3.132.0.34" }, - { "NIST P-384", "nistp384" }, /* rfc5656. */ - - { "NIST P-521", "secp521r1" }, - { "NIST P-521", "1.3.132.0.35" }, - { "NIST P-521", "nistp521" }, /* rfc5656. */ - - { "GOST2001-test", "1.2.643.2.2.35.0" }, - { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" }, - { "GOST2001-CryptoPro-B", "1.2.643.2.2.35.2" }, - { "GOST2001-CryptoPro-C", "1.2.643.2.2.35.3" }, - { "GOST2001-CryptoPro-A", "GOST2001-CryptoPro-XchA" }, - { "GOST2001-CryptoPro-C", "GOST2001-CryptoPro-XchB" }, - { "GOST2001-CryptoPro-A", "1.2.643.2.2.36.0" }, - { "GOST2001-CryptoPro-C", "1.2.643.2.2.36.1" }, - - { "GOST2012-256-tc26-A", "1.2.643.7.1.2.1.1.1" }, - { "GOST2001-CryptoPro-A", "1.2.643.7.1.2.1.1.2" }, - { "GOST2001-CryptoPro-A", "GOST2012-256-tc26-B" }, - { "GOST2001-CryptoPro-B", "1.2.643.7.1.2.1.1.3" }, - { "GOST2001-CryptoPro-B", "GOST2012-256-tc26-C" }, - { "GOST2001-CryptoPro-C", "1.2.643.7.1.2.1.1.4" }, - { "GOST2001-CryptoPro-C", "GOST2012-256-tc26-D" }, - - { "GOST2012-512-test", "GOST2012-test" }, - { "GOST2012-512-test", "1.2.643.7.1.2.1.2.0" }, - { "GOST2012-512-tc26-A", "GOST2012-tc26-A" }, - { "GOST2012-512-tc26-B", "GOST2012-tc26-B" }, - { "GOST2012-512-tc26-A", "1.2.643.7.1.2.1.2.1" }, - { "GOST2012-512-tc26-B", "1.2.643.7.1.2.1.2.2" }, - { "GOST2012-512-tc26-C", "1.2.643.7.1.2.1.2.3" }, - - { "secp256k1", "1.3.132.0.10" }, - - { "sm2p256v1", "1.2.156.10197.1.301" }, - - { NULL, NULL} - }; - - -typedef struct -{ - const char *desc; /* Description of the curve. */ - unsigned int nbits; /* Number of bits. */ - unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */ - - /* The model describing this curve. This is mainly used to select - the group equation. */ - enum gcry_mpi_ec_models model; - - /* The actual ECC dialect used. This is used for curve specific - optimizations and to select encodings etc. */ - enum ecc_dialects dialect; - - const char *p; /* The prime defining the field. */ - const char *a, *b; /* The coefficients. For Twisted Edwards - Curves b is used for d. For Montgomery - Curves (a,b) has ((A-2)/4,B^-1). */ - const char *n; /* The order of the base point. */ - const char *g_x, *g_y; /* Base point. */ - unsigned int h; /* Cofactor. */ -} ecc_domain_parms_t; - - -/* This static table defines all available curves. */ -static const ecc_domain_parms_t domain_parms[] = - { - { - /* (-x^2 + y^2 = 1 + dx^2y^2) */ - "Ed25519", 255, 0, - MPI_EC_EDWARDS, ECC_DIALECT_ED25519, - "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "-0x01", - "-0x2DFC9311D490018C7338BF8688861767FF8FF5B2BEBE27548A14B235ECA6874A", - "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", - "0x216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A", - "0x6666666666666666666666666666666666666666666666666666666666666658", - 8 - }, - { - /* (y^2 = x^3 + 486662*x^2 + x) */ - "Curve25519", 255, 0, - MPI_EC_MONTGOMERY, ECC_DIALECT_STANDARD, - "0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED", - "0x01DB41", - "0x01", - "0x1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED", - "0x0000000000000000000000000000000000000000000000000000000000000009", - "0x20AE19A1B8A086B4E01EDD2C7748D14C923D4D7E6D7C61B229E9C5A27ECED3D9", - 8 - /* Note: As per RFC-7748 errata eid4730 the g_y value should be - * "0x5F51E65E475F794B1FE122D388B72EB36DC2B28192839E4DD6163A5D81312C14" - * but that breaks the keygrip. The new value is recovered in - * the function _gcry_ecc_fill_in_curve. See bug #4712. - */ - }, - { - /* (x^2 + y^2 = 1 + dx^2y^2) */ - "Ed448", 448, 0, - MPI_EC_EDWARDS, ECC_DIALECT_SAFECURVE, - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "0x01", - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF6756", - "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3", - "0x4F1970C66BED0DED221D15A622BF36DA9E146570470F1767EA6DE324" - "A3D3A46412AE1AF72AB66511433B80E18B00938E2626A82BC70CC05E", - "0x693F46716EB6BC248876203756C9C7624BEA73736CA3984087789C1E" - "05A0C2D73AD3FF1CE67C39C4FDBD132C4ED7C8AD9808795BF230FA14", - 4, - }, - { - /* (y^2 = x^3 + 156326*x^2 + x) */ - "X448", 448, 0, - MPI_EC_MONTGOMERY, ECC_DIALECT_SAFECURVE, - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFE" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", - "0x98A9", - "0x01", - "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "7CCA23E9C44EDB49AED63690216CC2728DC58F552378C292AB5844F3", - "0x00000000000000000000000000000000000000000000000000000000" - "00000000000000000000000000000000000000000000000000000005", - "0x7D235D1295F5B1F66C98AB6E58326FCECBAE5D34F55545D060F75DC2" - "8DF3F6EDB8027E2346430D211312C4B150677AF76FD7223D457B5B1A", - 4, - }, -#if 0 /* No real specs yet found. */ - { - /* x^2 + y^2 = 1 + 3617x^2y^2 mod 2^414 - 17 */ - "Curve3617", - "0x3FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF" - "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEF", - MPI_EC_EDWARDS, 0, - "0x01", - "0x0e21", - "0x07FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEB3CC92414CF" - "706022B36F1C0338AD63CF181B0E71A5E106AF79", - "0x1A334905141443300218C0631C326E5FCD46369F44C03EC7F57FF35498A4AB4D" - "6D6BA111301A73FAA8537C64C4FD3812F3CBC595", - "0x22", - 8 - }, -#endif /*0*/ - { - "NIST P-192", 192, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffeffffffffffffffff", - "0xfffffffffffffffffffffffffffffffefffffffffffffffc", - "0x64210519e59c80e70fa7e9ab72243049feb8deecc146b9b1", - "0xffffffffffffffffffffffff99def836146bc9b1b4d22831", - - "0x188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012", - "0x07192b95ffc8da78631011ed6b24cdd573f977a11e794811", - 1 - }, - { - "NIST P-224", 224, 1, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xffffffffffffffffffffffffffffffff000000000000000000000001", - "0xfffffffffffffffffffffffffffffffefffffffffffffffffffffffe", - "0xb4050a850c04b3abf54132565044b0b7d7bfd8ba270b39432355ffb4", - "0xffffffffffffffffffffffffffff16a2e0b8f03e13dd29455c5c2a3d" , - - "0xb70e0cbd6bb4bf7f321390b94a03c1d356c21122343280d6115c1d21", - "0xbd376388b5f723fb4c22dfe6cd4375a05a07476444d5819985007e34", - 1 - }, - { - "NIST P-256", 256, 1, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xffffffff00000001000000000000000000000000ffffffffffffffffffffffff", - "0xffffffff00000001000000000000000000000000fffffffffffffffffffffffc", - "0x5ac635d8aa3a93e7b3ebbd55769886bc651d06b0cc53b0f63bce3c3e27d2604b", - "0xffffffff00000000ffffffffffffffffbce6faada7179e84f3b9cac2fc632551", - - "0x6b17d1f2e12c4247f8bce6e563a440f277037d812deb33a0f4a13945d898c296", - "0x4fe342e2fe1a7f9b8ee7eb4a7c0f9e162bce33576b315ececbb6406837bf51f5", - 1 - }, - { - "NIST P-384", 384, 1, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000ffffffff", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe" - "ffffffff0000000000000000fffffffc", - "0xb3312fa7e23ee7e4988e056be3f82d19181d9c6efe8141120314088f5013875a" - "c656398d8a2ed19d2a85c8edd3ec2aef", - "0xffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf" - "581a0db248b0a77aecec196accc52973", - - "0xaa87ca22be8b05378eb1c71ef320ad746e1d3b628ba79b9859f741e082542a38" - "5502f25dbf55296c3a545e3872760ab7", - "0x3617de4a96262c6f5d9e98bf9292dc29f8f41dbd289a147ce9da3113b5f0b8c0" - "0a60b1ce1d7e819d7a431d7c90ea0e5f", - 1 - }, - { - "NIST P-521", 521, 1, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc", - "0x051953eb9618e1c9a1f929a21a0b68540eea2da725b99b315f3b8b489918ef10" - "9e156193951ec7e937b1652c0bd3bb1bf073573df883d2c34f1ef451fd46b503f00", - "0x01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffa51868783bf2f966b7fcc0148f709a5d03bb5c9b8899c47aebb6fb71e91386409", - - "0x00c6858e06b70404e9cd9e3ecb662395b4429c648139053fb521f828af606b4d" - "3dbaa14b5e77efe75928fe1dc127a2ffa8de3348b3c1856a429bf97e7e31c2e5bd66", - "0x011839296a789a3bc0045c8a5fb42c7d1bd998f54449579b446817afbd17273e" - "662c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650", - 1 - }, - - { - "GOST2001-test", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x8000000000000000000000000000000000000000000000000000000000000431", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x5fbff498aa938ce739b8e022fbafef40563f6e6a3472fc2a514c0ce9dae23b7e", - "0x8000000000000000000000000000000150fe8a1892976154c59cfc193accf5b3", - - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x08e2a8a0e65147d4bd6316030e16d19c85c97f0a9ca267122b96abbcea7e8fc8", - 1 - }, - { - "GOST2001-CryptoPro-A", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97", - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd94", - "0x00000000000000000000000000000000000000000000000000000000000000a6", - "0xffffffffffffffffffffffffffffffff6c611070995ad10045841b09b761b893", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x8d91e471e0989cda27df505a453f2b7635294f2ddf23e3b122acc99c9e9f1e14", - 1 - }, - { - "GOST2001-CryptoPro-B", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x8000000000000000000000000000000000000000000000000000000000000c99", - "0x8000000000000000000000000000000000000000000000000000000000000c96", - "0x3e1af419a269a5f866a7d3c25c3df80ae979259373ff2b182f49d4ce7e1bbc8b", - "0x800000000000000000000000000000015f700cfff1a624e5e497161bcc8a198f", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x3fa8124359f96680b83d1c3eb2c070e5c545c9858d03ecfb744bf8d717717efc", - 1 - }, - { - "GOST2001-CryptoPro-C", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d759b", - "0x9b9f605f5a858107ab1ec85e6b41c8aacf846e86789051d37998f7b9022d7598", - "0x000000000000000000000000000000000000000000000000000000000000805a", - "0x9b9f605f5a858107ab1ec85e6b41c8aa582ca3511eddfb74f02f3a6598980bb9", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x41ece55743711a8c3cbf3783cd08c0ee4d4dc440d4641a8f366e550dfdb3bb67", - 1 - }, - { - "GOST2012-256-A", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffd97", - "0xc2173f1513981673af4892c23035a27ce25e2013bf95aa33b22c656f277e7335", - "0x295f9bae7428ed9ccc20e7c359a9d41a22fccd9108e17bf7ba9337a6f8ae9513", - "0x400000000000000000000000000000000fd8cddfc87b6635c115af556c360c67", - "0x91e38443a5e82c0d880923425712b2bb658b9196932e02c78b2582fe742daa28", - "0x32879423ab1a0375895786c4bb46e9565fde0b5344766740af268adb32322e5c", - 4 - }, - { - "GOST2012-512-test", 511, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" - "f1d852741af4704a0458047e80e4546d35b8336fac224dd81664bbf528be6373", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x1cff0806a31116da29d8cfa54e57eb748bc5f377e49400fdd788b649eca1ac4" - "361834013b2ad7322480a89ca58e0cf74bc9e540c2add6897fad0a3084f302adc", - "0x4531acd1fe0023c7550d267b6b2fee80922b14b2ffb90f04d4eb7c09b5d2d15d" - "a82f2d7ecb1dbac719905c5eecc423f1d86e25edbe23c595d644aaf187e6e6df", - - "0x24d19cc64572ee30f396bf6ebbfd7a6c5213b3b3d7057cc825f91093a68cd762" - "fd60611262cd838dc6b60aa7eee804e28bc849977fac33b4b530f1b120248a9a", - "0x2bb312a43bd2ce6e0d020613c857acddcfbf061e91e5f2c3f32447c259f39b2" - "c83ab156d77f1496bf7eb3351e1ee4e43dc1a18b91b24640b6dbb92cb1add371e", - 1 - }, - { - "GOST2012-512-tc26-A", 512, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7", - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc4", - "0xe8c2505dedfc86ddc1bd0b2b6667f1da34b82574761cb0e879bd081cfd0b6265" - "ee3cb090f30d27614cb4574010da90dd862ef9d4ebee4761503190785a71c760", - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "27e69532f48d89116ff22b8d4e0560609b4b38abfad2b85dcacdb1411f10b275", - "0x0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000003", - "0x7503cfe87a836ae3a61b8816e25450e6ce5e1c93acf1abc1778064fdcbefa921" - "df1626be4fd036e93d75e6a50e3a41e98028fe5fc235f5b889a589cb5215f2a4", - 1 - }, - { - "GOST2012-512-tc26-B", 512, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0x8000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000006f", - "0x8000000000000000000000000000000000000000000000000000000000000000" - "000000000000000000000000000000000000000000000000000000000000006c", - "0x687d1b459dc841457e3e06cf6f5e2517b97c7d614af138bcbf85dc806c4b289f" - "3e965d2db1416d217f8b276fad1ab69c50f78bee1fa3106efb8ccbc7c5140116", - "0x8000000000000000000000000000000000000000000000000000000000000001" - "49a1ec142565a545acfdb77bd9d40cfa8b996712101bea0ec6346c54374f25bd", - "0x0000000000000000000000000000000000000000000000000000000000000000" - "0000000000000000000000000000000000000000000000000000000000000002", - "0x1a8f7eda389b094c2c071e3647a8940f3c123b697578c213be6dd9e6c8ec7335" - "dcb228fd1edf4a39152cbcaaf8c0398828041055f94ceeec7e21340780fe41bd", - 1 - }, - { - "GOST2012-512-tc26-C", 512, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc7", - "0xdc9203e514a721875485a529d2c722fb187bc8980eb866644de41c68e1430645" - "46e861c0e2c9edd92ade71f46fcf50ff2ad97f951fda9f2a2eb6546f39689bd3", - "0xb4c4ee28cebc6c2c8ac12952cf37f16ac7efb6a9f69f4b57ffda2e4f0de5ade0" - "38cbc2fff719d2c18de0284b8bfef3b52b8cc7a5f5bf0a3c8d2319a5312557e1", - "0x3fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" - "c98cdba46506ab004c33a9ff5147502cc8eda9e7a769a12694623cef47f023ed", - "0xe2e31edfc23de7bdebe241ce593ef5de2295b7a9cbaef021d385f7074cea043a" - "a27272a7ae602bf2a7b9033db9ed3610c6fb85487eae97aac5bc7928c1950148", - "0xf5ce40d95b5eb899abbccff5911cb8577939804d6527378b8c108c3d2090ff9be" - "18e2d33e3021ed2ef32d85822423b6304f726aa854bae07d0396e9a9addc40f", - 4 - }, - - { - "secp256k1", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", - "0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", - "0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8", - 1 - }, - - { - "sm2p256v1", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xfffffffeffffffffffffffffffffffffffffffff00000000ffffffffffffffff", - "0xfffffffeffffffffffffffffffffffffffffffff00000000fffffffffffffffc", - "0x28e9fa9e9d9f5e344d5a9e4bcf6509a7f39789f515ab8f92ddbcbd414d940e93", - "0xfffffffeffffffffffffffffffffffff7203df6b21c6052b53bbf40939d54123", - "0x32c4ae2c1f1981195f9904466a39c9948fe30bbff2660be1715a4589334c74c7", - "0xbc3736a2f4f6779c59bdcee36b692153d0a9877cc62a474002df32e52139f0a0", - 1 - }, - - { NULL, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL } - }; - - - - -/* Return a copy of POINT. */ -static gcry_mpi_point_t -point_copy (gcry_mpi_point_t point) -{ - gcry_mpi_point_t newpoint; - - if (point) - { - newpoint = mpi_point_new (0); - point_set (newpoint, point); - } - else - newpoint = NULL; - return newpoint; -} - - -/* Helper to scan a hex string. */ -static gcry_mpi_t -scanval (const char *string) -{ - gpg_err_code_t rc; - gcry_mpi_t val; - - rc = _gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL); - if (rc) - log_fatal ("scanning ECC parameter failed: %s\n", gpg_strerror (rc)); - return val; -} - - -/* Return the index of the domain_parms table for a curve with NAME. - Return -1 if not found. */ -static int -find_domain_parms_idx (const char *name) -{ - int idx, aliasno; - - /* First check our native curves. */ - for (idx = 0; domain_parms[idx].desc; idx++) - if (!strcmp (name, domain_parms[idx].desc)) - return idx; - - /* If not found consult the alias table. */ - if (!domain_parms[idx].desc) - { - for (aliasno = 0; curve_aliases[aliasno].name; aliasno++) - if (!strcmp (name, curve_aliases[aliasno].other)) - break; - if (curve_aliases[aliasno].name) - { - for (idx = 0; domain_parms[idx].desc; idx++) - if (!strcmp (curve_aliases[aliasno].name, domain_parms[idx].desc)) - return idx; - } - } - - return -1; -} - - -/* Generate the crypto system setup. This function takes the NAME of - a curve or the desired number of bits and stores at R_CURVE the - parameters of the named curve or those of a suitable curve. If - R_NBITS is not NULL, the chosen number of bits is stored there. - NULL may be given for R_CURVE, if the value is not required and for - example only a quick test for availability is desired. Note that - the curve fields should be initialized to zero because fields which - are not NULL are skipped. */ -gpg_err_code_t -_gcry_ecc_fill_in_curve (unsigned int nbits, const char *name, - elliptic_curve_t *curve, unsigned int *r_nbits) -{ - int idx; - const char *resname = NULL; /* Set to a found curve name. */ - - if (name) - idx = find_domain_parms_idx (name); - else - { - for (idx = 0; domain_parms[idx].desc; idx++) - if (nbits == domain_parms[idx].nbits - && domain_parms[idx].model == MPI_EC_WEIERSTRASS) - break; - if (!domain_parms[idx].desc) - idx = -1; - } - if (idx < 0) - return GPG_ERR_UNKNOWN_CURVE; - - resname = domain_parms[idx].desc; - - /* In fips mode we only support NIST curves. Note that it is - possible to bypass this check by specifying the curve parameters - directly. */ - if (fips_mode () && !domain_parms[idx].fips ) - return GPG_ERR_NOT_SUPPORTED; - - switch (domain_parms[idx].model) - { - case MPI_EC_WEIERSTRASS: - case MPI_EC_EDWARDS: - case MPI_EC_MONTGOMERY: - break; - default: - return GPG_ERR_BUG; - } - - - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - - if (curve) - { - curve->model = domain_parms[idx].model; - curve->dialect = domain_parms[idx].dialect; - if (!curve->p) - curve->p = scanval (domain_parms[idx].p); - if (!curve->a) - { - curve->a = scanval (domain_parms[idx].a); - if (curve->a->sign) - { - mpi_resize (curve->a, curve->p->nlimbs); - _gcry_mpih_sub_n (curve->a->d, curve->p->d, - curve->a->d, curve->p->nlimbs); - curve->a->nlimbs = curve->p->nlimbs; - curve->a->sign = 0; - } - } - if (!curve->b) - { - curve->b = scanval (domain_parms[idx].b); - if (curve->b->sign) - { - mpi_resize (curve->b, curve->p->nlimbs); - _gcry_mpih_sub_n (curve->b->d, curve->p->d, - curve->b->d, curve->p->nlimbs); - curve->b->nlimbs = curve->p->nlimbs; - curve->b->sign = 0; - } - } - if (!curve->n) - curve->n = scanval (domain_parms[idx].n); - if (!curve->G.x) - curve->G.x = scanval (domain_parms[idx].g_x); - if (!curve->G.y) - curve->G.y = scanval (domain_parms[idx].g_y); - curve->h = domain_parms[idx].h; - - /* - * In the constants of domain_parms, we defined Curve25519 - * domain parameters as the ones in RFC-7748 before the errata - * (eid4730). To keep the computation having exact same values, - * we recover the new value of g_y, here. - */ - if (!strcmp (resname, "Curve25519")) - mpi_sub (curve->G.y, curve->p, curve->G.y); - - if (!curve->G.z) - curve->G.z = mpi_alloc_set_ui (1); - if (!curve->name) - curve->name = resname; - } - - return 0; -} - - -/* Give the name of the curve NAME, store the curve parameters into P, - A, B, G, and N if they point to NULL value. Note that G is - returned in standard uncompressed format. Also update MODEL and - DIALECT if they are not NULL. */ -gpg_err_code_t -_gcry_ecc_update_curve_param (const char *name, - enum gcry_mpi_ec_models *model, - enum ecc_dialects *dialect, - gcry_mpi_t *p, gcry_mpi_t *a, gcry_mpi_t *b, - gcry_mpi_t *g, gcry_mpi_t *n) -{ - int idx; - - idx = find_domain_parms_idx (name); - if (idx < 0) - return GPG_ERR_UNKNOWN_CURVE; - - if (g) - { - char *buf; - size_t len; - - len = 4; - len += strlen (domain_parms[idx].g_x+2); - len += strlen (domain_parms[idx].g_y+2); - len++; - buf = xtrymalloc (len); - if (!buf) - return gpg_err_code_from_syserror (); - strcpy (stpcpy (stpcpy (buf, "0x04"), domain_parms[idx].g_x+2), - domain_parms[idx].g_y+2); - _gcry_mpi_release (*g); - *g = scanval (buf); - xfree (buf); - } - if (model) - *model = domain_parms[idx].model; - if (dialect) - *dialect = domain_parms[idx].dialect; - if (p) - { - _gcry_mpi_release (*p); - *p = scanval (domain_parms[idx].p); - } - if (a) - { - _gcry_mpi_release (*a); - *a = scanval (domain_parms[idx].a); - } - if (b) - { - _gcry_mpi_release (*b); - *b = scanval (domain_parms[idx].b); - } - if (n) - { - _gcry_mpi_release (*n); - *n = scanval (domain_parms[idx].n); - } - return 0; -} - - -/* Return the name matching the parameters in PKEY. This works only - with curves described by the Weierstrass equation. */ -const char * -_gcry_ecc_get_curve (gcry_sexp_t keyparms, int iterator, unsigned int *r_nbits) -{ - gpg_err_code_t rc; - const char *result = NULL; - elliptic_curve_t E; - gcry_mpi_point_t G = NULL; - gcry_mpi_t tmp = NULL; - int idx; - - memset (&E, 0, sizeof E); - - if (r_nbits) - *r_nbits = 0; - - if (!keyparms) - { - idx = iterator; - if (idx >= 0 && idx < DIM (domain_parms)) - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - } - return result; - } - - - /* - * Extract the curve parameters.. - */ - rc = gpg_err_code (sexp_extract_param (keyparms, NULL, "pabn", - &E.p, &E.a, &E.b, &E.n, NULL)); - if (rc == GPG_ERR_NO_OBJ) - { - /* This might be the second use case of checking whether a - specific curve given by name is supported. */ - gcry_sexp_t l1; - char *name; - - l1 = sexp_find_token (keyparms, "curve", 5); - if (!l1) - goto leave; /* No curve name parameter. */ - - name = sexp_nth_string (l1, 1); - sexp_release (l1); - if (!name) - goto leave; /* Name missing or out of core. */ - - idx = find_domain_parms_idx (name); - xfree (name); - if (idx >= 0) /* Curve found. */ - { - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - } - return result; - } - - if (rc) - goto leave; - - rc = point_from_keyparam (&G, keyparms, "g", NULL); - if (rc) - goto leave; - - _gcry_mpi_point_init (&E.G); - _gcry_mpi_point_set (&E.G, G->x, G->y, G->z); - - for (idx = 0; domain_parms[idx].desc; idx++) - { - mpi_free (tmp); - tmp = scanval (domain_parms[idx].p); - if (mpi_cmp (tmp, E.p)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].a); - if (tmp->sign) - { - if (!mpi_cmpabs (tmp, E.a)) - /* For backward compatibility to <= libgcrypt 1.8, we - allow this match to support existing keys in SEXP. */ - ; - else - { - mpi_resize (tmp, E.p->nlimbs); - _gcry_mpih_sub_n (tmp->d, E.p->d, - tmp->d, E.p->nlimbs); - tmp->nlimbs = E.p->nlimbs; - tmp->sign = 0; - if (mpi_cmp (tmp, E.a)) - continue; - } - } - else if (mpi_cmp (tmp, E.a)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].b); - if (tmp->sign) - { - if (!mpi_cmpabs (tmp, E.b)) - /* Same for backward compatibility, see above. */ - ; - else - { - mpi_resize (tmp, E.p->nlimbs); - _gcry_mpih_sub_n (tmp->d, E.p->d, - tmp->d, E.p->nlimbs); - tmp->nlimbs = E.p->nlimbs; - tmp->sign = 0; - if (mpi_cmp (tmp, E.b)) - continue; - } - } - else if (mpi_cmp (tmp, E.b)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].n); - if (mpi_cmp (tmp, E.n)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_x); - if (mpi_cmp (tmp, E.G.x)) - continue; - - mpi_free (tmp); - tmp = scanval (domain_parms[idx].g_y); - if (mpi_cmp (tmp, E.G.y)) - continue; - - result = domain_parms[idx].desc; - if (r_nbits) - *r_nbits = domain_parms[idx].nbits; - break; - } - - leave: - _gcry_mpi_point_release (G); - _gcry_mpi_release (tmp); - _gcry_mpi_release (E.p); - _gcry_mpi_release (E.a); - _gcry_mpi_release (E.b); - _gcry_mpi_point_free_parts (&E.G); - _gcry_mpi_release (E.n); - return result; -} - - -/* Helper to extract an MPI from key parameters. */ -static gpg_err_code_t -mpi_from_keyparam (gcry_mpi_t *r_a, gcry_sexp_t keyparam, const char *name, - int opaque) -{ - gcry_err_code_t ec = 0; - gcry_sexp_t l1; - - l1 = sexp_find_token (keyparam, name, 0); - if (l1) - { - *r_a = sexp_nth_mpi (l1, 1, opaque? GCRYMPI_FMT_OPAQUE : GCRYMPI_FMT_USG); - sexp_release (l1); - if (!*r_a) - ec = GPG_ERR_INV_OBJ; - } - return ec; -} - -/* Helper to extract a point from key parameters. If no parameter - with NAME is found, the functions tries to find a non-encoded point - by appending ".x", ".y" and ".z" to NAME. ".z" is in this case - optional and defaults to 1. EC is the context which at this point - may not be fully initialized. */ -static gpg_err_code_t -point_from_keyparam (gcry_mpi_point_t *r_a, - gcry_sexp_t keyparam, const char *name, mpi_ec_t ec) -{ - gcry_err_code_t rc; - gcry_sexp_t l1; - gcry_mpi_point_t point; - - l1 = sexp_find_token (keyparam, name, 0); - if (l1) - { - gcry_mpi_t a; - - a = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE); - sexp_release (l1); - if (!a) - return GPG_ERR_INV_OBJ; - - point = mpi_point_new (0); - rc = _gcry_mpi_ec_decode_point (point, a, ec); - mpi_free (a); - if (rc) - { - mpi_point_release (point); - return rc; - } - } - else - { - char *tmpname; - gcry_mpi_t x = NULL; - gcry_mpi_t y = NULL; - gcry_mpi_t z = NULL; - - tmpname = xtrymalloc (strlen (name) + 2 + 1); - if (!tmpname) - return gpg_err_code_from_syserror (); - strcpy (stpcpy (tmpname, name), ".x"); - rc = mpi_from_keyparam (&x, keyparam, tmpname, 0); - if (rc) - { - xfree (tmpname); - return rc; - } - strcpy (stpcpy (tmpname, name), ".y"); - rc = mpi_from_keyparam (&y, keyparam, tmpname, 0); - if (rc) - { - mpi_free (x); - xfree (tmpname); - return rc; - } - strcpy (stpcpy (tmpname, name), ".z"); - rc = mpi_from_keyparam (&z, keyparam, tmpname, 0); - if (rc) - { - mpi_free (y); - mpi_free (x); - xfree (tmpname); - return rc; - } - if (!z) - z = mpi_set_ui (NULL, 1); - if (x && y) - point = mpi_point_snatch_set (NULL, x, y, z); - else - { - mpi_free (x); - mpi_free (y); - mpi_free (z); - point = NULL; - } - xfree (tmpname); - } - - if (point) - *r_a = point; - return 0; -} - - - -static gpg_err_code_t -mpi_ec_get_elliptic_curve (elliptic_curve_t *E, int *r_flags, - gcry_sexp_t keyparam, const char *curvename) -{ - gpg_err_code_t errc; - unsigned int nbits; - gcry_sexp_t l1; - - errc = _gcry_pk_util_get_nbits (keyparam, &nbits); - if (errc) - return errc; - - E->model = MPI_EC_WEIERSTRASS; - E->dialect = ECC_DIALECT_STANDARD; - E->h = 1; - - if (keyparam) - { - /* Parse an optional flags list. */ - l1 = sexp_find_token (keyparam, "flags", 0); - if (l1) - { - int flags = 0; - - errc = _gcry_pk_util_parse_flaglist (l1, &flags, NULL); - sexp_release (l1); - l1 = NULL; - if (errc) - goto leave; - - *r_flags |= flags; - } - - /* Parse the deprecated optional transient-key flag. */ - l1 = sexp_find_token (keyparam, "transient-key", 0); - if (l1) - { - *r_flags |= PUBKEY_FLAG_TRANSIENT_KEY; - sexp_release (l1); - } - - /* Check whether a curve name was given. */ - l1 = sexp_find_token (keyparam, "curve", 5); - - /* If we don't have a curve name or if override parameters have - explicitly been requested, parse them. */ - if (!l1 || (*r_flags & PUBKEY_FLAG_PARAM)) - { - gcry_mpi_point_t G = NULL; - gcry_mpi_t cofactor = NULL; - - errc = mpi_from_keyparam (&E->p, keyparam, "p", 0); - if (errc) - goto leave; - errc = mpi_from_keyparam (&E->a, keyparam, "a", 0); - if (errc) - goto leave; - errc = mpi_from_keyparam (&E->b, keyparam, "b", 0); - if (errc) - goto leave; - errc = point_from_keyparam (&G, keyparam, "g", NULL); - if (errc) - goto leave; - if (G) - { - _gcry_mpi_point_init (&E->G); - mpi_point_set (&E->G, G->x, G->y, G->z); - mpi_point_set (G, NULL, NULL, NULL); - mpi_point_release (G); - } - errc = mpi_from_keyparam (&E->n, keyparam, "n", 0); - if (errc) - goto leave; - errc = mpi_from_keyparam (&cofactor, keyparam, "h", 0); - if (errc) - goto leave; - if (cofactor) - { - mpi_get_ui (&E->h, cofactor); - mpi_free (cofactor); - } - } - } - else - l1 = NULL; /* No curvename. */ - - /* Check whether a curve parameter is available and use that to fill - in missing values. If no curve parameter is available try an - optional provided curvename. If only the curvename has been - given use that one. */ - if (l1 || curvename || nbits) - { - char *name; - - if (l1) - { - name = sexp_nth_string (l1, 1); - sexp_release (l1); - if (!name) - { - errc = GPG_ERR_INV_OBJ; /* Name missing or out of core. */ - goto leave; - } - } - else - name = NULL; - - errc = _gcry_ecc_fill_in_curve (nbits, name? name : curvename, E, NULL); - xfree (name); - if (errc) - goto leave; - } - - leave: - return errc; -} - -static gpg_err_code_t -mpi_ec_setup_elliptic_curve (mpi_ec_t ec, int flags, - elliptic_curve_t *E, gcry_sexp_t keyparam) -{ - gpg_err_code_t errc = 0; - - ec->G = mpi_point_snatch_set (NULL, E->G.x, E->G.y, E->G.z); - E->G.x = NULL; - E->G.y = NULL; - E->G.z = NULL; - ec->n = E->n; - E->n = NULL; - ec->h = E->h; - ec->name = E->name; - - /* Now that we know the curve name we can look for the public key - Q. point_from_keyparam needs to know the curve parameters so - that it is able to use the correct decompression. Parsing - the private key D could have been done earlier but it is less - surprising if we do it here as well. */ - if (keyparam) - { - int is_opaque_bytes = ((ec->dialect == ECC_DIALECT_ED25519 - && (flags & PUBKEY_FLAG_EDDSA)) - || (ec->dialect == ECC_DIALECT_SAFECURVE)); - - errc = point_from_keyparam (&ec->Q, keyparam, "q", ec); - if (errc) - return errc; - errc = mpi_from_keyparam (&ec->d, keyparam, "d", is_opaque_bytes); - - /* Size of opaque bytes should match size of P. */ - if (!errc && ec->d && is_opaque_bytes) - { - unsigned int n = mpi_get_nbits (ec->d); - unsigned int len; - - len = (ec->nbits+7)/8; - /* EdDSA requires additional bit for sign. */ - if ((ec->nbits%8) == 0 && ec->model == MPI_EC_EDWARDS) - len++; - - if ((n+7)/8 != len) - { - if (ec->dialect == ECC_DIALECT_ED25519) - { - /* - * GnuPG (<= 2.2) or OpenPGP implementations with no - * SOS support may remove zeros at the beginning. - * Recover those zeros. - */ - /* - * Also, GnuPG (<= 2.2) may add additional zero at - * the beginning, when private key is moved from - * OpenPGP to gpg-agent. Remove such a zero-prefix. - */ - const unsigned char *buf; - unsigned char *value; - - buf = mpi_get_opaque (ec->d, &n); - if (!buf) - return GPG_ERR_INV_OBJ; - - value = xtrymalloc_secure (len); - if (!value) - return gpg_err_code_from_syserror (); - - if ((n+7)/8 < len) - /* Recover zeros. */ - { - memset (value, 0, len - (n+7)/8); - memcpy (value + len - (n+7)/8, buf, (n+7)/8); - } - else if ((n+7)/8 == len + 1) - /* Remove a zero. */ - memcpy (value, buf+1, len); - else - { - xfree (value); - return GPG_ERR_INV_OBJ; - } - - mpi_set_opaque (ec->d, value, len*8); - } - else - { - if (DBG_CIPHER) - log_debug ("scalar size (%d) != prime size (%d)", - (n+7)/8, len); - - errc = GPG_ERR_INV_OBJ; - } - } - } - } - - return errc; -} - -gpg_err_code_t -_gcry_mpi_ec_internal_new (mpi_ec_t *r_ec, int *r_flags, const char *name_op, - gcry_sexp_t keyparam, const char *curvename) -{ - gpg_err_code_t errc; - elliptic_curve_t E; - mpi_ec_t ec; - - *r_ec = NULL; - - memset (&E, 0, sizeof E); - errc = mpi_ec_get_elliptic_curve (&E, r_flags, keyparam, curvename); - if (errc) - goto leave; - - ec = _gcry_mpi_ec_p_internal_new (E.model, E.dialect, *r_flags, - E.p, E.a, E.b); - if (!ec) - goto leave; - - errc = mpi_ec_setup_elliptic_curve (ec, *r_flags, &E, keyparam); - if (errc) - { - _gcry_mpi_ec_free (ec); - goto leave; - } - else - *r_ec = ec; - - if (!errc && DBG_CIPHER) - { - gcry_mpi_t mpi_q = NULL; - gcry_sexp_t l1; - char msg[80]; - - l1 = sexp_find_token (keyparam, "q", 0); - if (l1) - { - mpi_q = sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE); - sexp_release (l1); - } - - log_debug ("%s info: %s/%s%s\n", name_op, - _gcry_ecc_model2str (ec->model), - _gcry_ecc_dialect2str (ec->dialect), - (*r_flags & PUBKEY_FLAG_EDDSA)? "+EdDSA" : ""); - if (ec->name) - log_debug ("%s name: %s\n", name_op, ec->name); - snprintf (msg, sizeof msg, "%s p", name_op); - log_printmpi (msg, ec->p); - snprintf (msg, sizeof msg, "%s a", name_op); - log_printmpi (msg, ec->a); - snprintf (msg, sizeof msg, "%s b", name_op); - log_printmpi (msg, ec->b); - snprintf (msg, sizeof msg, "%s g", name_op); - log_printpnt (msg, ec->G, NULL); - snprintf (msg, sizeof msg, "%s n", name_op); - log_printmpi (msg, ec->n); - log_debug ("%s h:+%02x\n", name_op, ec->h); - if (mpi_q) - { - snprintf (msg, sizeof msg, "%s q", name_op); - log_printmpi (msg, mpi_q); - mpi_free (mpi_q); - } - if (!fips_mode () && ec->d) - { - snprintf (msg, sizeof msg, "%s d", name_op); - log_printmpi (msg, ec->d); - } - } - - leave: - _gcry_ecc_curve_free (&E); - return errc; -} - -/* This function creates a new context for elliptic curve operations. - Either KEYPARAM or CURVENAME must be given. If both are given and - KEYPARAM has no curve parameter, CURVENAME is used to add missing - parameters. On success 0 is returned and the new context stored at - R_CTX. On error NULL is stored at R_CTX and an error code is - returned. The context needs to be released using - gcry_ctx_release. */ -gpg_err_code_t -_gcry_mpi_ec_new (gcry_ctx_t *r_ctx, - gcry_sexp_t keyparam, const char *curvename) -{ - gpg_err_code_t errc; - elliptic_curve_t E; - gcry_ctx_t ctx = NULL; - int flags = 0; - mpi_ec_t ec; - - *r_ctx = NULL; - - memset (&E, 0, sizeof E); - errc = mpi_ec_get_elliptic_curve (&E, &flags, keyparam, curvename); - if (errc) - goto leave; - - errc = _gcry_mpi_ec_p_new (&ctx, E.model, E.dialect, flags, E.p, E.a, E.b); - if (errc) - goto leave; - - ec = _gcry_ctx_get_pointer (ctx, CONTEXT_TYPE_EC); - errc = mpi_ec_setup_elliptic_curve (ec, flags, &E, keyparam); - if (errc) - goto leave; - - *r_ctx = ctx; - ctx = NULL; - - leave: - _gcry_ecc_curve_free (&E); - _gcry_ctx_release (ctx); - return errc; -} - - -/* Return the parameters of the curve NAME as an S-expression. */ -gcry_sexp_t -_gcry_ecc_get_param_sexp (const char *name) -{ - elliptic_curve_t E; - gcry_mpi_t pkey[5]; - gcry_sexp_t result; - - memset (&E, 0, sizeof E); - if (_gcry_ecc_fill_in_curve (0, name, &E, NULL)) - return NULL; - - pkey[0] = E.p; - pkey[1] = E.a; - pkey[2] = E.b; - pkey[3] = _gcry_ecc_ec2os (E.G.x, E.G.y, E.p); - pkey[4] = E.n; - - if (sexp_build (&result, NULL, - "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)(h%u)))", - pkey[0], pkey[1], pkey[2], pkey[3], pkey[4], E.h)) - result = NULL; - - _gcry_ecc_curve_free (&E); - _gcry_mpi_release (pkey[3]); - - return result; -} - - -/* Return an MPI (or opaque MPI) described by NAME and the context EC. - If COPY is true a copy is returned, if not a const MPI may be - returned. In any case mpi_free must be used. */ -gcry_mpi_t -_gcry_ecc_get_mpi (const char *name, mpi_ec_t ec, int copy) -{ - if (!*name) - return NULL; - - if (!strcmp (name, "p") && ec->p) - return mpi_is_const (ec->p) && !copy? ec->p : mpi_copy (ec->p); - if (!strcmp (name, "a") && ec->a) - return mpi_is_const (ec->a) && !copy? ec->a : mpi_copy (ec->a); - if (!strcmp (name, "b") && ec->b) - return mpi_is_const (ec->b) && !copy? ec->b : mpi_copy (ec->b); - if (!strcmp (name, "n") && ec->n) - return mpi_is_const (ec->n) && !copy? ec->n : mpi_copy (ec->n); - if (!strcmp (name, "h")) - { - gcry_mpi_t h = _gcry_mpi_get_const (ec->h); - - return !copy? h : mpi_set (NULL, h); - } - if (!strcmp (name, "d") && ec->d) - return mpi_is_const (ec->d) && !copy? ec->d : mpi_copy (ec->d); - - /* Return a requested point coordinate. */ - if (!strcmp (name, "g.x") && ec->G && ec->G->x) - return mpi_is_const (ec->G->x) && !copy? ec->G->x : mpi_copy (ec->G->x); - if (!strcmp (name, "g.y") && ec->G && ec->G->y) - return mpi_is_const (ec->G->y) && !copy? ec->G->y : mpi_copy (ec->G->y); - if (!strcmp (name, "q.x") && ec->Q && ec->Q->x) - return mpi_is_const (ec->Q->x) && !copy? ec->Q->x : mpi_copy (ec->Q->x); - if (!strcmp (name, "q.y") && ec->Q && ec->Q->y) - return mpi_is_const (ec->Q->y) && !copy? ec->Q->y : mpi_copy (ec->Q->y); - - /* If the base point has been requested, return it in standard - encoding. */ - if (!strcmp (name, "g") && ec->G) - return _gcry_mpi_ec_ec2os (ec->G, ec); - - /* If the public key has been requested, return it by default in - standard uncompressed encoding or if requested in other - encodings. */ - if (*name == 'q' && (!name[1] || name[1] == '@')) - { - /* If only the private key is given, compute the public key. */ - if (!ec->Q) - ec->Q = _gcry_ecc_compute_public (NULL, ec); - - if (!ec->Q) - return NULL; - - if (name[1] != '@') - return _gcry_mpi_ec_ec2os (ec->Q, ec); - - if (!strcmp (name+2, "eddsa") && ec->model == MPI_EC_EDWARDS) - { - unsigned char *encpk; - unsigned int encpklen; - - if (!_gcry_ecc_eddsa_encodepoint (ec->Q, ec, NULL, NULL, 0, - &encpk, &encpklen)) - return mpi_set_opaque (NULL, encpk, encpklen*8); - } - } - - return NULL; -} - - -/* Return a point described by NAME and the context EC. */ -gcry_mpi_point_t -_gcry_ecc_get_point (const char *name, mpi_ec_t ec) -{ - if (!strcmp (name, "g") && ec->G) - return point_copy (ec->G); - if (!strcmp (name, "q")) - { - /* If only the private key is given, compute the public key. */ - if (!ec->Q) - ec->Q = _gcry_ecc_compute_public (NULL, ec); - - if (ec->Q) - return point_copy (ec->Q); - } - - return NULL; -} - - -/* Store the MPI NEWVALUE into the context EC under NAME. */ -gpg_err_code_t -_gcry_ecc_set_mpi (const char *name, gcry_mpi_t newvalue, mpi_ec_t ec) -{ - gpg_err_code_t rc = 0; - - if (!*name) - ; - else if (!strcmp (name, "p")) - { - mpi_free (ec->p); - ec->p = mpi_copy (newvalue); - _gcry_mpi_ec_get_reset (ec); - } - else if (!strcmp (name, "a")) - { - mpi_free (ec->a); - ec->a = mpi_copy (newvalue); - _gcry_mpi_ec_get_reset (ec); - } - else if (!strcmp (name, "b")) - { - mpi_free (ec->b); - ec->b = mpi_copy (newvalue); - } - else if (!strcmp (name, "n")) - { - mpi_free (ec->n); - ec->n = mpi_copy (newvalue); - } - else if (!strcmp (name, "h")) - { - mpi_get_ui (&ec->h, newvalue); - } - else if (*name == 'q' && (!name[1] || name[1] == '@')) - { - if (newvalue) - { - if (!ec->Q) - ec->Q = mpi_point_new (0); - rc = _gcry_mpi_ec_decode_point (ec->Q, newvalue, ec); - } - if (rc || !newvalue) - { - _gcry_mpi_point_release (ec->Q); - ec->Q = NULL; - } - /* Note: We assume that Q matches d and thus do not reset d. */ - } - else if (!strcmp (name, "d")) - { - mpi_free (ec->d); - ec->d = mpi_copy (newvalue); - if (ec->d) - { - /* We need to reset the public key because it may not - anymore match. */ - _gcry_mpi_point_release (ec->Q); - ec->Q = NULL; - } - } - else - rc = GPG_ERR_UNKNOWN_NAME; - - return rc; -} - - -/* Store the point NEWVALUE into the context EC under NAME. */ -gpg_err_code_t -_gcry_ecc_set_point (const char *name, gcry_mpi_point_t newvalue, mpi_ec_t ec) -{ - if (!strcmp (name, "g")) - { - _gcry_mpi_point_release (ec->G); - ec->G = point_copy (newvalue); - } - else if (!strcmp (name, "q")) - { - _gcry_mpi_point_release (ec->Q); - ec->Q = point_copy (newvalue); - } - else - return GPG_ERR_UNKNOWN_NAME; - - return 0; -} diff --git a/hobble-libgcrypt b/hobble-libgcrypt deleted file mode 100755 index 1aa88dc..0000000 --- a/hobble-libgcrypt +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh - -# Quit out if anything fails. -set -e -x - -# Clean out patent-or-otherwise-encumbered code. -# EC: ????????? ??/??/2015 - -rm -f cipher/ecc-curves.c -rm -f tests/curves.c -rm -f tests/keygrip.c diff --git a/keygrip.c b/keygrip.c deleted file mode 100644 index 56fbba8..0000000 --- a/keygrip.c +++ /dev/null @@ -1,341 +0,0 @@ -/* keygrip.c - verifies that keygrips are calculated as expected - * Copyright (C) 2005 Free Software Foundation, Inc. - * - * This file is part of Libgcrypt. - * - * Libgcrypt is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as - * published by the Free Software Foundation; either version 2.1 of - * the License, or (at your option) any later version. - * - * Libgcrypt is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - */ - -#ifdef HAVE_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include - -#define PGM "keygrip" -#include "t-common.h" - -static int repetitions; - - - -static void -print_hex (const char *text, const void *buf, size_t n) -{ - const unsigned char *p = buf; - - fputs (text, stdout); - for (; n; n--, p++) - printf ("%02X", *p); - putchar ('\n'); -} - - - - -static struct -{ - int algo; - const char *key; - const unsigned char grip[20]; -} key_grips[] = - { - { - GCRY_PK_RSA, - "(private-key" - " (rsa" - " (n #00B6B509596A9ECABC939212F891E656A626BA07DA8521A9CAD4C08E640C04052FBB87F424EF1A0275A48A9299AC9DB69ABE3D0124E6C756B1F7DFB9B842D6251AEA6EE85390495CADA73D671537FCE5850A932F32BAB60AB1AC1F852C1F83C625E7A7D70CDA9EF16D5C8E47739D77DF59261ABE8454807FF441E143FBD37F8545#)" - " (e #010001#)" - " (d #077AD3DE284245F4806A1B82B79E616FBDE821C82D691A65665E57B5FAD3F34E67F401E7BD2E28699E89D9C496CF821945AE83AC7A1231176A196BA6027E77D85789055D50404A7A2A95B1512F91F190BBAEF730ED550D227D512F89C0CDB31AC06FA9A19503DDF6B66D0B42B9691BFD6140EC1720FFC48AE00C34796DC899E5#)" - " (p #00D586C78E5F1B4BF2E7CD7A04CA091911706F19788B93E44EE20AAF462E8363E98A72253ED845CCBF2481BB351E8557C85BCFFF0DABDBFF8E26A79A0938096F27#)" - " (q #00DB0CDF60F26F2A296C88D6BF9F8E5BE45C0DDD713C96CC73EBCB48B061740943F21D2A93D6E42A7211E7F02A95DCED6C390A67AD21ECF739AE8A0CA46FF2EBB3#)" - " (u #33149195F16912DB20A48D020DBC3B9E3881B39D722BF79378F6340F43148A6E9FC5F53E2853B7387BA4443BA53A52FCA8173DE6E85B42F9783D4A7817D0680B#)))", - "\x32\xCF\xFA\x85\xB1\x79\x1F\xBB\x26\x14\xE9\x1A\xFD\xF3\xAF\xE3\x32\x08\x2E\x25" - }, - { - GCRY_PK_DSA, - " (public-key" - " (dsa" - " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" - " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" - " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" - " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)))", - "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" - - }, - { - GCRY_PK_DSA, - "(private-key" - " (dsa" - " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" - " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" - " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" - " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)" - " (x #0087F9E91BFBCC1163DE71ED86D557708E32F8ADDE#)))", - "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" - }, - { - GCRY_PK_ECDSA, - "(public-key" - " (ecdsa(flags param)" - " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" - " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)" - " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" - " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" - " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" - " (h #000000000000000000000000000000000000000000000000000000000000000001#)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { - GCRY_PK_ECDSA, - "(public-key" - " (ecdsa(flags param)" - " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" - " (curve \"NIST P-256\")" - " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" - " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" - " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" - " (h #000000000000000000000000000000000000000000000000000000000000000001#)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { - GCRY_PK_ECDSA, - "(public-key" - " (ecdsa" - " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" - " (curve \"NIST P-256\")" - " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" - " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" - " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" - " (h #000000000000000000000000000000000000000000000000000000000000000001#)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { - GCRY_PK_ECDSA, - "(public-key" - " (ecdsa" - " (curve secp256r1)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve secp256r1)" - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, - { /* Ed25519 standard */ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Ed25519)" - " (q #04" - " 1CC662926E7EFF4982B7FB8B928E61CD74CCDD85277CC57196C3AD20B611085F" - " 47BD24842905C049257673B3F5249524E0A41FAA17B25B818D0F97E625F1A1D0#)" - " ))", - "\x0C\xCA\xB2\xFD\x48\x9A\x33\x40\x2C\xE8" - "\xE0\x4A\x1F\xB2\x45\xEA\x80\x3D\x0A\xF1" - }, - { /* Ed25519+EdDSA */ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Ed25519)(flags eddsa)" - " (q #773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" - "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" - }, - { /* Ed25519+EdDSA (with compression prefix) */ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Ed25519)(flags eddsa)" - " (q #40" - " 773E72848C1FD5F9652B29E2E7AF79571A04990E96F2016BF4E0EC1890C2B7DB#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" - "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" - }, - { /* Ed25519+EdDSA (same but uncompressed)*/ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Ed25519)(flags eddsa)" - " (q #04" - " 629ad237d1ed04dcd4abe1711dd699a1cf51b1584c4de7a4ef8b8a640180b26f" - " 5bb7c29018ece0f46b01f2960e99041a5779afe7e2292b65f9d51f8c84723e77#)" - " ))", - "\x9D\xB6\xC6\x4A\x38\x83\x0F\x49\x60\x70" - "\x17\x89\x47\x55\x20\xBE\x8C\x82\x1F\x47" - }, - { /* Cv25519 */ - GCRY_PK_ECC, - "(public-key" - " (ecc" - " (curve Curve25519)(flags djb-tweak)" - " (q #40" - " 918C1733127F6BF2646FAE3D081A18AE77111C903B906310B077505EFFF12740#)" - " ))", - "\x0F\x89\xA5\x65\xD3\xEA\x18\x7C\xE8\x39" - "\x33\x23\x98\xF5\xD4\x80\x67\x7D\xF4\x9C" - }, - { /* Random key */ - GCRY_PK_RSA, - "(shadowed-private-key" - " (rsa" - " (n #00B493C79928398DA9D99AC0E949FE6EB62F683CB974FFFBFBC01066F5C9A89B" - " D3DC48EAD7C65F36EA943C2B2C865C26C4884FF9EDFDA8C99C855B737D77EEF6" - " B85DBC0CCEC0E900C1F89A6893A2A93E8B31028469B6927CEB2F08687E547C68" - " 6B0A2F7E50A194FF7AB7637E03DE0912EF7F6E5F1EC37625BD1620CCC2E7A564" - " 31E168CDAFBD1D9E61AE47A69A6FA03EF22F844528A710B2392F262B95A3078C" - " F321DC8325F92A5691EF69F34FD0DE0B22C79D29DC87723FCADE463829E8E5F7" - " D196D73D6C9C180F6A6A0DDBF7B9D8F7FA293C36163B12199EF6A1A95CAE4051" - " E3069C522CC6C4A7110F663A5DAD20F66C13A1674D050088208FAE4F33B3AB51" - " 03#)" - " (e #00010001#)" - " (shadowed t1-v1" - " (#D2760001240102000005000123350000# OPENPGP.1)" - ")))", - "\xE5\x6E\xE6\xEE\x5A\x2F\xDC\x3E\x98\x9D" - "\xFE\x49\xDA\xF5\x67\x43\xE3\x27\x28\x33" - } - }; - - -static void -check (void) -{ - unsigned char buf[20]; - unsigned char *ret; - gcry_error_t err; - gcry_sexp_t sexp; - unsigned int i; - int repn; - - for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++) - { - if (gcry_pk_test_algo (key_grips[i].algo)) - { - if (verbose) - fprintf (stderr, "algo %d not available; test skipped\n", - key_grips[i].algo); - continue; - } - err = gcry_sexp_sscan (&sexp, NULL, key_grips[i].key, - strlen (key_grips[i].key)); - if (err) - die ("scanning data %d failed: %s\n", i, gpg_strerror (err)); - - if (debug) - info ("check(%d): s-exp='%s'\n", i, key_grips[i].key); - - for (repn=0; repn < repetitions; repn++) - { - ret = gcry_pk_get_keygrip (sexp, buf); - if (!ret) - die ("gcry_pk_get_keygrip failed for %d\n", i); - - if ( memcmp (key_grips[i].grip, buf, sizeof (buf)) ) - { - print_hex ("keygrip: ", buf, sizeof buf); - die ("keygrip for %d does not match\n", i); - } - else if (debug && !repn) - print_hex ("keygrip: ", buf, sizeof buf); - } - - gcry_sexp_release (sexp); - } -} - - - -static void -progress_handler (void *cb_data, const char *what, int printchar, - int current, int total) -{ - (void)cb_data; - (void)what; - (void)current; - (void)total; - - putchar (printchar); -} - -int -main (int argc, char **argv) -{ - int last_argc = -1; - - if (argc) - { argc--; argv++; } - - while (argc && last_argc != argc ) - { - last_argc = argc; - if (!strcmp (*argv, "--")) - { - argc--; argv++; - break; - } - else if (!strcmp (*argv, "--verbose")) - { - verbose = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--debug")) - { - verbose = 1; - debug = 1; - argc--; argv++; - } - else if (!strcmp (*argv, "--repetitions")) - { - argc--; argv++; - if (argc) - { - repetitions = atoi(*argv); - argc--; argv++; - } - } - } - - if (repetitions < 1) - repetitions = 1; - - if (!gcry_check_version (GCRYPT_VERSION)) - die ("version mismatch\n"); - - gcry_set_progress_handler (progress_handler, NULL); - - xgcry_control ((GCRYCTL_DISABLE_SECMEM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - - check (); - - return 0; -} diff --git a/libgcrypt-1.10.0-disable-brainpool.patch b/libgcrypt-1.10.0-disable-brainpool.patch new file mode 100644 index 0000000..f0c5a72 --- /dev/null +++ b/libgcrypt-1.10.0-disable-brainpool.patch @@ -0,0 +1,239 @@ +From d651e25be0bc0c11f4d3d7c72be8cfbbe82b3874 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 10 Sep 2021 18:39:00 +0200 +Subject: [PATCH] Allow building libgcrypt without Brainpool curves + +* README: Document possibility to build without brainpool curves +* cipher/ecc-curves.c: Conditionalize brainpool curves definitions +* configure.ac: Implement possibility to build without brainpool curves +* tests/curves.c: Skip brainpool curves if they are not built-in +* tests/keygrip.c: Skip brainpool curves if they are not built-in + +-- + +Signed-off-by: Jakub Jelen +--- + README | 3 +++ + cipher/ecc-curves.c | 4 ++++ + configure.ac | 13 +++++++++++++ + tests/curves.c | 46 ++++++++++++++++++++++++++++++--------------- + tests/keygrip.c | 2 ++ + 5 files changed, 53 insertions(+), 15 deletions(-) + +diff --git a/README b/README +index 436b6cd4..1044109c 100644 +--- a/README ++++ b/README +@@ -127,6 +127,9 @@ + the list used with the current build the program + tests/version may be used. + ++ --disable-brainpool ++ Do not build in support for Brainpool curves. ++ + --disable-endian-check + Don't let configure test for the endianness but + try to use the OS provided macros at compile +diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c +index 7c86e12c..8fd95a9c 100644 +--- a/cipher/ecc-curves.c ++++ b/cipher/ecc-curves.c +@@ -77,6 +77,7 @@ static const struct + { "NIST P-521", "1.3.132.0.35" }, + { "NIST P-521", "nistp521" }, /* rfc5656. */ + ++#ifdef ENABLE_BRAINPOOL + { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" }, + { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" }, + { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" }, +@@ -84,6 +85,7 @@ static const struct + { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" }, + { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"}, + { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"}, ++#endif /* ENABLE_BRAINPOOL */ + + { "GOST2001-test", "1.2.643.2.2.35.0" }, + { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" }, +@@ -297,6 +299,7 @@ static const ecc_domain_parms_t domain_parms[] = + 1 + }, + ++#ifdef ENABLE_BRAINPOOL + { "brainpoolP160r1", 160, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, + "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f", +@@ -391,6 +394,7 @@ static const ecc_domain_parms_t domain_parms[] = + "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892", + 1 + }, ++#endif /* ENABLE_BRAINPOOL */ + { + "GOST2001-test", 256, 0, + MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, +diff --git a/configure.ac b/configure.ac +index 6efbf139..f4ac1887 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -614,6 +614,14 @@ AC_ARG_WITH(fips-module-version, + AC_DEFINE_UNQUOTED(FIPS_MODULE_VERSION, "$fips_module_version", + [Define FIPS module version for certification]) + ++# Implementation of the --disable-brainpool switch. ++AC_MSG_CHECKING([whether we want to disable the use of brainpool curves]) ++AC_ARG_ENABLE(brainpool, ++ AS_HELP_STRING([--disable-brainpool], ++ [Disable the brainpool curves]), ++ use_brainpool="$enableval",use_brainpool=yes) ++AC_MSG_RESULT($use_brainpool) ++ + # Implementation of the --disable-jent-support switch. + AC_MSG_CHECKING([whether jitter entropy support is requested]) + AC_ARG_ENABLE(jent-support, +@@ -2466,6 +2474,10 @@ if test x"$ppccryptosupport" = xyes ; then + AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1, + [Enable support for POWER 8 (PowerISA 2.07) crypto extension.]) + fi ++if test x"$use_brainpool" = xyes ; then ++ AC_DEFINE(ENABLE_BRAINPOOL, 1, ++ [Enable support for the brainpool curves.]) ++fi + if test x"$jentsupport" = xyes ; then + AC_DEFINE(ENABLE_JENT_SUPPORT, 1, + [Enable support for the jitter entropy collector.]) +@@ -3296,6 +3308,7 @@ GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) + GCRY_MSG_WRAP([Enabled kdf algorithms: ],[$enabled_kdfs]) + GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers]) + GCRY_MSG_SHOW([Random number generator: ],[$random]) ++GCRY_MSG_SHOW([Enabled Brainpool curves: ],[$use_brainpool]) + GCRY_MSG_SHOW([Try using jitter entropy: ],[$jentsupport]) + GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities]) + GCRY_MSG_SHOW([FIPS module version: ],[$fips_module_version]) +diff --git a/tests/curves.c b/tests/curves.c +index 3c738171..8eb79565 100644 +--- a/tests/curves.c ++++ b/tests/curves.c +@@ -33,7 +33,11 @@ + #include "t-common.h" + + /* Number of curves defined in ../cipher/ecc-curves.c */ +-#define N_CURVES 27 ++#ifdef ENABLE_BRAINPOOL ++# define N_CURVES 27 ++#else ++# define N_CURVES 20 ++#endif + + /* A real world sample public key. */ + static char const sample_key_1[] = +@@ -52,6 +56,7 @@ static char const sample_key_1[] = + static char const sample_key_1_curve[] = "NIST P-256"; + static unsigned int sample_key_1_nbits = 256; + ++#ifdef ENABLE_BRAINPOOL + /* A made up sample public key. */ + static char const sample_key_2[] = + "(public-key\n" +@@ -68,6 +73,7 @@ static char const sample_key_2[] = + " ))"; + static char const sample_key_2_curve[] = "brainpoolP160r1"; + static unsigned int sample_key_2_nbits = 160; ++#endif /* ENABLE_BRAINPOOL */ + + static int in_fips_mode; + +@@ -113,6 +119,7 @@ check_matching (void) + + gcry_sexp_release (key); + ++#ifdef ENABLE_BRAINPOOL + if (!in_fips_mode) + { + err = gcry_sexp_new (&key, sample_key_2, 0, 1); +@@ -130,6 +137,7 @@ check_matching (void) + + gcry_sexp_release (key); + } ++#endif /* ENABLE_BRAINPOOL */ + } + + #define TEST_ERROR_EXPECTED (1 << 0) +@@ -185,20 +193,26 @@ check_get_params (void) + { GCRY_PK_ECC, "1.3.132.0.35" }, + { GCRY_PK_ECC, "nistp521" }, + +- { GCRY_PK_ECC, "brainpoolP160r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP192r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP224r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP256r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP320r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP384r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11", TEST_NOFIPS }, +- { GCRY_PK_ECC, "brainpoolP512r1", TEST_NOFIPS }, +- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13", TEST_NOFIPS }, ++#ifdef ENABLE_BRAINPOOL ++# define BRAINPOOL_FLAGS TEST_NOFIPS ++#else ++# define BRAINPOOL_FLAGS TEST_ERROR_EXPECTED ++#endif /* ENABLE_BRAINPOOL */ ++ { GCRY_PK_ECC, "brainpoolP160r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP192r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP224r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP256r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP320r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP384r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "brainpoolP512r1", BRAINPOOL_FLAGS }, ++ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13", BRAINPOOL_FLAGS }, ++#undef BRAINPOOL_ERROR_EXPECTED + + { GCRY_PK_ECC, "GOST2001-test", TEST_NOFIPS }, + { GCRY_PK_ECC, "1.2.643.2.2.35.0", TEST_NOFIPS }, +@@ -282,6 +296,7 @@ check_get_params (void) + + gcry_sexp_release (param); + ++#ifdef ENABLE_BRAINPOOL + if (!in_fips_mode) + { + param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_2_curve); +@@ -297,6 +312,7 @@ check_get_params (void) + + gcry_sexp_release (param); + } ++#endif /* ENABLE_BRAINPOOL */ + + /* Some simple tests */ + for (idx=0; idx < DIM (tv); idx++) +diff --git a/tests/keygrip.c b/tests/keygrip.c +index 49bd71bc..fc4c17be 100644 +--- a/tests/keygrip.c ++++ b/tests/keygrip.c +@@ -149,6 +149,7 @@ static struct + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, ++#ifdef ENABLE_BRAINPOOL + { + GCRY_PK_ECC, + "(public-key" +@@ -197,6 +198,7 @@ static struct + "\xD6\xE1\xBF\x43\xAC\x9B\x9A\x12\xE7\x3F", + 1 + }, ++#endif /*ENABLE_BRAINPOOL */ + { /* Ed25519 standard */ + GCRY_PK_ECC, + "(public-key" +-- +2.34.1 + diff --git a/libgcrypt-1.6.1-mpicoder-gccopt.patch b/libgcrypt-1.6.1-mpicoder-gccopt.patch deleted file mode 100644 index 12555d3..0000000 --- a/libgcrypt-1.6.1-mpicoder-gccopt.patch +++ /dev/null @@ -1,104 +0,0 @@ -diff -up libgcrypt-1.6.1/mpi/mpicoder.c.gccopt libgcrypt-1.6.1/mpi/mpicoder.c ---- libgcrypt-1.6.1/mpi/mpicoder.c.gccopt 2014-02-28 15:37:53.983139821 +0100 -+++ libgcrypt-1.6.1/mpi/mpicoder.c 2014-02-28 15:47:35.312576387 +0100 -@@ -627,16 +627,16 @@ _gcry_mpi_print (enum gcry_mpi_format fo - extra = 1; - } - -- if (buffer && n > len) -- { -- /* The provided buffer is too short. */ -- xfree (tmp); -- return GPG_ERR_TOO_SHORT; -- } - if (buffer) - { - unsigned char *s = buffer; - -+ if (n > len) -+ { -+ /* The provided buffer is too short. */ -+ xfree (tmp); -+ return GPG_ERR_TOO_SHORT; -+ } - if (extra == 1) - *s++ = 0; - else if (extra) -@@ -654,13 +654,12 @@ _gcry_mpi_print (enum gcry_mpi_format fo - /* Note: We ignore the sign for this format. */ - /* FIXME: for performance reasons we should put this into - mpi_aprint because we can then use the buffer directly. */ -- -- if (buffer && n > len) -- return GPG_ERR_TOO_SHORT; - if (buffer) - { - unsigned char *tmp; - -+ if (n > len) -+ return GPG_ERR_TOO_SHORT; - tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL); - if (!tmp) - return gpg_err_code_from_syserror (); -@@ -678,14 +677,14 @@ _gcry_mpi_print (enum gcry_mpi_format fo - if (negative) - return GPG_ERR_INV_ARG; - -- if (buffer && n+2 > len) -- return GPG_ERR_TOO_SHORT; -- - if (buffer) - { - unsigned char *tmp; - unsigned char *s = buffer; - -+ if (n+2 > len) -+ return GPG_ERR_TOO_SHORT; -+ - s[0] = nbits >> 8; - s[1] = nbits; - -@@ -724,16 +723,16 @@ _gcry_mpi_print (enum gcry_mpi_format fo - extra=1; - } - -- if (buffer && n+4 > len) -- { -- xfree(tmp); -- return GPG_ERR_TOO_SHORT; -- } -- - if (buffer) - { - unsigned char *s = buffer; - -+ if (n+4 > len) -+ { -+ xfree(tmp); -+ return GPG_ERR_TOO_SHORT; -+ } -+ - *s++ = n >> 24; - *s++ = n >> 16; - *s++ = n >> 8; -@@ -761,15 +760,15 @@ _gcry_mpi_print (enum gcry_mpi_format fo - if (!n || (*tmp & 0x80)) - extra = 2; - -- if (buffer && 2*n + extra + negative + 1 > len) -- { -- xfree(tmp); -- return GPG_ERR_TOO_SHORT; -- } - if (buffer) - { - unsigned char *s = buffer; - -+ if (2*n + extra + negative + 1 > len) -+ { -+ xfree(tmp); -+ return GPG_ERR_TOO_SHORT; -+ } - if (negative) - *s++ = '-'; - if (extra) diff --git a/libgcrypt-1.8.3-fips-ctor.patch b/libgcrypt-1.8.3-fips-ctor.patch deleted file mode 100644 index a5d3467..0000000 --- a/libgcrypt-1.8.3-fips-ctor.patch +++ /dev/null @@ -1,73 +0,0 @@ -diff -up libgcrypt-1.8.3/src/global.c.fips-ctor libgcrypt-1.8.3/src/global.c ---- libgcrypt-1.8.3/src/global.c.fips-ctor 2017-11-23 19:25:58.000000000 +0100 -+++ libgcrypt-1.8.3/src/global.c 2020-04-17 16:29:59.258218015 +0200 -@@ -141,6 +141,34 @@ global_init (void) - } - - -+#ifndef FIPS_MODULE_PATH -+#define FIPS_MODULE_PATH "/etc/system-fips" -+#endif -+ -+void __attribute__ ((constructor)) _gcry_global_constructor (void) -+{ -+ int rv; -+ -+ rv = access (FIPS_MODULE_PATH, F_OK); -+ if (rv < 0 && errno != ENOENT) -+ rv = 0; -+ -+ if (!rv) -+ { -+ int no_secmem_save; -+ -+ /* it should be always 0 at this point but let's keep on the safe side */ -+ no_secmem_save = no_secure_memory; -+ no_secure_memory = 1; -+ /* force selftests */ -+ global_init(); -+ _gcry_fips_run_selftests (0); -+ if (!fips_mode()) -+ _gcry_random_close_fds (); -+ no_secure_memory = no_secmem_save; -+ } -+} -+ - /* This function is called by the macro fips_is_operational and makes - sure that the minimal initialization has been done. This is far - from a perfect solution and hides problems with an improper -@@ -671,8 +699,7 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - - case GCRYCTL_FIPS_MODE_P: - if (fips_mode () -- && !_gcry_is_fips_mode_inactive () -- && !no_secure_memory) -+ && !_gcry_is_fips_mode_inactive ()) - rc = GPG_ERR_GENERAL; /* Used as TRUE value */ - break; - -@@ -749,9 +776,9 @@ _gcry_vcontrol (enum gcry_ctl_cmds cmd, - break; - - case GCRYCTL_SET_ENFORCED_FIPS_FLAG: -- if (!_gcry_global_any_init_done) -+ if (fips_mode ()) - { -- /* Not yet initialized at all. Set the enforced fips mode flag */ -+ /* We are in FIPS mode, we can set the enforced fips mode flag. */ - _gcry_set_preferred_rng_type (0); - _gcry_set_enforced_fips_mode (); - } -diff --git a/tests/t-secmem.c b/tests/t-secmem.c -index 2b769134..1d33bbfd 100644 ---- a/tests/t-secmem.c -+++ b/tests/t-secmem.c -@@ -54,7 +54,7 @@ test_secmem (void) - - /* Allocating another 2k should fail for the default 16k pool. */ - b = gcry_malloc_secure (chunk_size*4); -- if (b) -+ if (b && !gcry_fips_mode_active ()) - fail ("allocation did not fail as expected\n"); - - for (i=0; i < DIM(a); i++) diff --git a/libgcrypt-1.8.3-md-fips-enforce.patch b/libgcrypt-1.8.3-md-fips-enforce.patch deleted file mode 100644 index 3b730a1..0000000 --- a/libgcrypt-1.8.3-md-fips-enforce.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -up libgcrypt-1.8.3/cipher/md.c.fips-enforce libgcrypt-1.8.3/cipher/md.c ---- libgcrypt-1.8.3/cipher/md.c.fips-enforce 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.3/cipher/md.c 2020-04-17 15:07:31.364945130 +0200 -@@ -409,13 +409,10 @@ md_enable (gcry_md_hd_t hd, int algorith - } - - -- if (!err && algorithm == GCRY_MD_MD5 && fips_mode ()) -+ if (!err && !spec->flags.fips && fips_mode ()) - { -- _gcry_inactivate_fips_mode ("MD5 used"); - if (_gcry_enforced_fips_mode () ) - { -- /* We should never get to here because we do not register -- MD5 in enforced fips mode. But better throw an error. */ - err = GPG_ERR_DIGEST_ALGO; - } - } -diff --git a/tests/t-kdf.c b/tests/t-kdf.c -index 7a48e98a..48309b9a 100644 ---- a/tests/t-kdf.c -+++ b/tests/t-kdf.c -@@ -1104,6 +1104,13 @@ check_pbkdf2 (void) - GCRY_KDF_PBKDF2, tv[tvidx].hashalgo, - tv[tvidx].salt, tv[tvidx].saltlen, - tv[tvidx].c, tv[tvidx].dklen, outbuf); -+ if (gcry_fips_mode_active() && tvidx > 6) -+ { -+ if (!err) -+ fail ("pbkdf2 test %d unexpectedly passed in FIPS mode: %s\n", -+ tvidx, gpg_strerror (err)); -+ continue; -+ } - if (err) - fail ("pbkdf2 test %d failed: %s\n", tvidx, gpg_strerror (err)); - else if (memcmp (outbuf, tv[tvidx].dk, tv[tvidx].dklen)) - diff --git a/libgcrypt-1.8.4-fips-keygen.patch b/libgcrypt-1.8.4-fips-keygen.patch deleted file mode 100644 index a3e241f..0000000 --- a/libgcrypt-1.8.4-fips-keygen.patch +++ /dev/null @@ -1,64 +0,0 @@ -diff -up libgcrypt-1.8.4/cipher/dsa.c.fips-keygen libgcrypt-1.8.4/cipher/dsa.c ---- libgcrypt-1.8.4/cipher/dsa.c.fips-keygen 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/cipher/dsa.c 2019-02-12 14:29:25.629513989 +0100 -@@ -457,13 +457,22 @@ generate_fips186 (DSA_secret_key *sk, un - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen); -- else -+ else if (!domain->p || !domain->q) - ec = _gcry_generate_fips186_3_prime (nbits, qbits, - initial_seed.seed, - initial_seed.seedlen, - &prime_q, &prime_p, - r_counter, - r_seed, r_seedlen, NULL); -+ else -+ { -+ /* Domain parameters p and q are given; use them. */ -+ prime_p = mpi_copy (domain->p); -+ prime_q = mpi_copy (domain->q); -+ gcry_assert (mpi_get_nbits (prime_p) == nbits); -+ gcry_assert (mpi_get_nbits (prime_q) == qbits); -+ ec = 0; -+ } - sexp_release (initial_seed.sexp); - if (ec) - goto leave; -@@ -855,13 +866,12 @@ dsa_generate (const gcry_sexp_t genparms - sexp_release (l1); - sexp_release (domainsexp); - -- /* Check that all domain parameters are available. */ -- if (!domain.p || !domain.q || !domain.g) -+ /* Check that p and q domain parameters are available. */ -+ if (!domain.p || !domain.q || (!domain.g && !(flags & PUBKEY_FLAG_USE_FIPS186))) - { - _gcry_mpi_release (domain.p); - _gcry_mpi_release (domain.q); - _gcry_mpi_release (domain.g); -- sexp_release (deriveparms); - return GPG_ERR_MISSING_VALUE; - } - -diff -up libgcrypt-1.8.4/cipher/rsa.c.fips-keygen libgcrypt-1.8.4/cipher/rsa.c ---- libgcrypt-1.8.4/cipher/rsa.c.fips-keygen 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.4/cipher/rsa.c 2019-02-12 14:29:25.630513971 +0100 -@@ -389,7 +389,7 @@ generate_fips (RSA_secret_key *sk, unsig - - if (nbits < 1024 || (nbits & 0x1FF)) - return GPG_ERR_INV_VALUE; -- if (_gcry_enforced_fips_mode() && nbits != 2048 && nbits != 3072) -+ if (fips_mode() && nbits < 2048) - return GPG_ERR_INV_VALUE; - - /* The random quality depends on the transient_key flag. */ -@@ -696,7 +696,7 @@ generate_x931 (RSA_secret_key *sk, unsig - - *swapped = 0; - -- if (e_value == 1) /* Alias for a secure value. */ -+ if (e_value == 1 || e_value == 0) /* Alias for a secure value. */ - e_value = 65537; - - /* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */ diff --git a/libgcrypt-1.8.4-use-poll.patch b/libgcrypt-1.8.4-use-poll.patch deleted file mode 100644 index 8032992..0000000 --- a/libgcrypt-1.8.4-use-poll.patch +++ /dev/null @@ -1,77 +0,0 @@ -diff -up libgcrypt-1.8.4/random/rndlinux.c.use-poll libgcrypt-1.8.4/random/rndlinux.c ---- libgcrypt-1.8.4/random/rndlinux.c.use-poll 2018-10-26 13:50:20.000000000 +0200 -+++ libgcrypt-1.8.4/random/rndlinux.c 2018-11-20 15:51:56.760669058 +0100 -@@ -32,6 +32,7 @@ - #include - #include - #include -+#include - #if defined(__APPLE__) && defined(__MACH__) - #include - #ifdef __MAC_10_11 -@@ -241,9 +242,8 @@ _gcry_rndlinux_gather_random (void (*add - return with something we will actually use 100ms. */ - while (length) - { -- fd_set rfds; -- struct timeval tv; - int rc; -+ struct pollfd pfd; - - /* If we have a modern operating system, we first try to use the new - * getentropy function. That call guarantees that the kernel's -@@ -300,36 +300,25 @@ _gcry_rndlinux_gather_random (void (*add - any_need_entropy = 1; - } - -- /* If the system has no limit on the number of file descriptors -- and we encounter an fd which is larger than the fd_set size, -- we don't use the select at all. The select code is only used -- to emit progress messages. A better solution would be to -- fall back to poll() if available. */ --#ifdef FD_SETSIZE -- if (fd < FD_SETSIZE) --#endif -+ pfd.fd = fd; -+ pfd.events = POLLIN; -+ -+ _gcry_pre_syscall (); -+ rc = poll(&pfd, 1, delay); -+ _gcry_post_syscall (); -+ if (!rc) - { -- FD_ZERO(&rfds); -- FD_SET(fd, &rfds); -- tv.tv_sec = delay; -- tv.tv_usec = delay? 0 : 100000; -- _gcry_pre_syscall (); -- rc = select (fd+1, &rfds, NULL, NULL, &tv); -- _gcry_post_syscall (); -- if (!rc) -- { -- any_need_entropy = 1; -- delay = 3; /* Use 3 seconds henceforth. */ -- continue; -- } -- else if( rc == -1 ) -- { -- log_error ("select() error: %s\n", strerror(errno)); -- if (!delay) -- delay = 1; /* Use 1 second if we encounter an error before -- we have ever blocked. */ -- continue; -- } -+ any_need_entropy = 1; -+ delay = 3000; /* Use 3 seconds henceforth. */ -+ continue; -+ } -+ else if( rc == -1 ) -+ { -+ log_error ("poll() error: %s\n", strerror(errno)); -+ if (!delay) -+ delay = 1000; /* Use 1 second if we encounter an error before -+ we have ever blocked. */ -+ continue; - } - - do diff --git a/libgcrypt-1.8.5-fips-module.patch b/libgcrypt-1.8.5-fips-module.patch deleted file mode 100644 index 8ffe465..0000000 --- a/libgcrypt-1.8.5-fips-module.patch +++ /dev/null @@ -1,139 +0,0 @@ -diff -up libgcrypt-1.8.5/src/fips.c.fips-module libgcrypt-1.8.5/src/fips.c ---- libgcrypt-1.8.5/src/fips.c.fips-module 2020-04-20 19:07:45.924919645 +0200 -+++ libgcrypt-1.8.5/src/fips.c 2020-04-20 19:10:33.690722470 +0200 -@@ -35,10 +35,6 @@ - #include "hmac256.h" - - --/* The name of the file used to force libgcrypt into fips mode. */ --#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" -- -- - /* The states of the finite state machine used in fips mode. */ - enum module_states - { -@@ -122,54 +118,6 @@ _gcry_initialize_fips_mode (int force) - goto leave; - } - -- /* For testing the system it is useful to override the system -- provided detection of the FIPS mode and force FIPS mode using a -- file. The filename is hardwired so that there won't be any -- confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is -- actually used. The file itself may be empty. */ -- if ( !access (FIPS_FORCE_FILE, F_OK) ) -- { -- gcry_assert (!_gcry_no_fips_mode_required); -- goto leave; -- } -- -- /* Checking based on /proc file properties. */ -- { -- static const char procfname[] = "/proc/sys/crypto/fips_enabled"; -- FILE *fp; -- int saved_errno; -- -- fp = fopen (procfname, "r"); -- if (fp) -- { -- char line[256]; -- -- if (fgets (line, sizeof line, fp) && atoi (line)) -- { -- /* System is in fips mode. */ -- fclose (fp); -- gcry_assert (!_gcry_no_fips_mode_required); -- goto leave; -- } -- fclose (fp); -- } -- else if ((saved_errno = errno) != ENOENT -- && saved_errno != EACCES -- && !access ("/proc/version", F_OK) ) -- { -- /* Problem reading the fips file despite that we have the proc -- file system. We better stop right away. */ -- log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", -- procfname, strerror (saved_errno)); --#ifdef HAVE_SYSLOG -- syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -- "reading `%s' failed: %s - abort", -- procfname, strerror (saved_errno)); --#endif /*HAVE_SYSLOG*/ -- abort (); -- } -- } -- - /* Fips not not requested, set flag. */ - _gcry_no_fips_mode_required = 1; - -diff -up libgcrypt-1.8.5/src/g10lib.h.fips-module libgcrypt-1.8.5/src/g10lib.h ---- libgcrypt-1.8.5/src/g10lib.h.fips-module 2020-04-20 19:07:45.918919759 +0200 -+++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 19:11:05.003125740 +0200 -@@ -422,6 +422,9 @@ gpg_err_code_t _gcry_sexp_vextract_param - - /*-- fips.c --*/ - -+/* The name of the file used to force libgcrypt into fips mode. */ -+#define FIPS_FORCE_FILE "/etc/gcrypt/fips_enabled" -+ - extern int _gcry_no_fips_mode_required; - - void _gcry_initialize_fips_mode (int force); -diff -up libgcrypt-1.8.5/src/global.c.fips-module libgcrypt-1.8.5/src/global.c ---- libgcrypt-1.8.5/src/global.c.fips-module 2020-04-20 19:07:45.919919741 +0200 -+++ libgcrypt-1.8.5/src/global.c 2020-04-20 19:07:45.950919149 +0200 -@@ -160,6 +160,53 @@ void __attribute__ ((constructor)) _gcry - rv = access (FIPS_MODULE_PATH, F_OK); - if (rv < 0 && errno != ENOENT) - rv = 0; -+ -+ /* For testing the system it is useful to override the system -+ provided detection of the FIPS mode and force FIPS mode using a -+ file. The filename is hardwired so that there won't be any -+ confusion on whether /etc/gcrypt/ or /usr/local/etc/gcrypt/ is -+ actually used. The file itself may be empty. */ -+ if ( !access (FIPS_FORCE_FILE, F_OK) ) -+ { -+ rv = 0; -+ force_fips_mode = 1; -+ } -+ -+ /* Checking based on /proc file properties. */ -+ { -+ static const char procfname[] = "/proc/sys/crypto/fips_enabled"; -+ FILE *fp; -+ int saved_errno; -+ -+ fp = fopen (procfname, "r"); -+ if (fp) -+ { -+ char line[256]; -+ -+ if (fgets (line, sizeof line, fp) && atoi (line)) -+ { -+ /* System is in fips mode. */ -+ rv = 0; -+ force_fips_mode = 1; -+ } -+ fclose (fp); -+ } -+ else if ((saved_errno = errno) != ENOENT -+ && saved_errno != EACCES -+ && !access ("/proc/version", F_OK) ) -+ { -+ /* Problem reading the fips file despite that we have the proc -+ file system. We better stop right away. */ -+ log_info ("FATAL: error reading `%s' in libgcrypt: %s\n", -+ procfname, strerror (saved_errno)); -+#ifdef HAVE_SYSLOG -+ syslog (LOG_USER|LOG_ERR, "Libgcrypt error: " -+ "reading `%s' failed: %s - abort", -+ procfname, strerror (saved_errno)); -+#endif /*HAVE_SYSLOG*/ -+ abort (); -+ } -+ } - - if (!rv) - { diff --git a/libgcrypt-1.8.5-getrandom.patch b/libgcrypt-1.8.5-getrandom.patch deleted file mode 100644 index 1779dc1..0000000 --- a/libgcrypt-1.8.5-getrandom.patch +++ /dev/null @@ -1,277 +0,0 @@ -diff -up libgcrypt-1.8.5/random/rand-internal.h.getrandom libgcrypt-1.8.5/random/rand-internal.h ---- libgcrypt-1.8.5/random/rand-internal.h.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/rand-internal.h 2020-04-20 14:55:34.875949624 +0200 -@@ -47,6 +47,7 @@ void _gcry_random_progress (const char * - - /*-- random-csprng.c --*/ - void _gcry_rngcsprng_initialize (int full); -+void _gcry_rngcsprng_deinit (void); - void _gcry_rngcsprng_close_fds (void); - void _gcry_rngcsprng_dump_stats (void); - void _gcry_rngcsprng_secure_alloc (void); -@@ -68,6 +69,7 @@ void _gcry_rngcsprng_fast_poll (void); - - /*-- random-drbg.c --*/ - void _gcry_rngdrbg_inititialize (int full); -+void _gcry_rngdrbg_deinit (void); - void _gcry_rngdrbg_close_fds (void); - void _gcry_rngdrbg_dump_stats (void); - int _gcry_rngdrbg_is_faked (void); -diff -up libgcrypt-1.8.5/random/random.c.getrandom libgcrypt-1.8.5/random/random.c ---- libgcrypt-1.8.5/random/random.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/random.c 2020-04-20 14:55:34.876949605 +0200 -@@ -110,8 +110,8 @@ _gcry_random_read_conf (void) - unsigned int result = 0; - - fp = fopen (fname, "r"); -- if (!fp) -- return result; -+ if (!fp) /* We make only_urandom the default. */ -+ return RANDOM_CONF_ONLY_URANDOM; - - for (;;) - { -@@ -228,6 +228,22 @@ _gcry_random_initialize (int full) - } - - -+/* Deinitialize this random subsystem. */ -+void -+_gcry_random_deinit (void) -+{ -+ if (fips_mode ()) -+ _gcry_rngdrbg_deinit (); -+ else if (rng_types.standard) -+ _gcry_rngcsprng_deinit (); -+ else if (rng_types.fips) -+ _gcry_rngdrbg_deinit (); -+ else -+ _gcry_rngcsprng_deinit (); -+ /* not needed for system */ -+} -+ -+ - /* If possible close file descriptors used by the RNG. */ - void - _gcry_random_close_fds (void) -diff -up libgcrypt-1.8.5/random/random-csprng.c.getrandom libgcrypt-1.8.5/random/random-csprng.c ---- libgcrypt-1.8.5/random/random-csprng.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/random-csprng.c 2020-04-20 15:04:27.182877975 +0200 -@@ -55,6 +55,10 @@ - #ifdef __MINGW32__ - #include - #endif -+#if defined(__linux__) && defined(HAVE_SYSCALL) -+# include -+# include -+#endif - #include "g10lib.h" - #include "random.h" - #include "rand-internal.h" -@@ -343,6 +347,21 @@ _gcry_rngcsprng_initialize (int full) - } - - -+void -+_gcry_rngcsprng_deinit (void) -+{ -+ lock_pool(); -+ pool_writepos = 0; -+ pool_readpos = 0; -+ pool_filled = 0; -+ pool_filled_counter = 0; -+ did_initial_extra_seeding = 0; -+ pool_balance = 0; -+ just_mixed = 0; -+ unlock_pool(); -+} -+ -+ - /* Try to close the FDs of the random gather module. This is - currently only implemented for rndlinux. */ - void -@@ -1116,6 +1135,22 @@ getfnc_gather_random (void))(void (*)(co - enum random_origins, size_t, int); - - #if USE_RNDLINUX -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ long ret; -+ char buffer[1]; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret != -1 || errno != ENOSYS) -+ { -+ fnc = _gcry_rndlinux_gather_random; -+ return fnc; -+ } -+ else -+ /* The syscall is not supported - fallback to /dev/urandom. */ -+#endif - if ( !access (NAME_OF_DEV_RANDOM, R_OK) - && !access (NAME_OF_DEV_URANDOM, R_OK)) - { -diff -up libgcrypt-1.8.5/random/random-drbg.c.getrandom libgcrypt-1.8.5/random/random-drbg.c ---- libgcrypt-1.8.5/random/random-drbg.c.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/random-drbg.c 2020-04-20 15:02:37.782947902 +0200 -@@ -1811,6 +1811,22 @@ _gcry_rngdrbg_inititialize (int full) - } - - /* -+ * Deinitialize the DRBG invoked by the libgcrypt API -+ * It will be automatically re-initialized on next call -+ */ -+void -+_gcry_rngdrbg_deinit (void) -+{ -+ drbg_lock (); -+ if (drbg_state) -+ { -+ drbg_uninstantiate (drbg_state); -+ drbg_state = NULL; -+ } -+ drbg_unlock (); -+} -+ -+/* - * Backend handler function for GCRYCTL_DRBG_REINIT - * - * Select a different DRBG type and initialize it. -diff -up libgcrypt-1.8.5/random/random.h.getrandom libgcrypt-1.8.5/random/random.h ---- libgcrypt-1.8.5/random/random.h.getrandom 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/random/random.h 2020-04-20 14:55:34.877949586 +0200 -@@ -29,6 +29,7 @@ void _gcry_register_random_progress (voi - - void _gcry_set_preferred_rng_type (int type); - void _gcry_random_initialize (int full); -+void _gcry_random_deinit (void); - void _gcry_random_close_fds (void); - int _gcry_get_rng_type (int ignore_fips_mode); - void _gcry_random_dump_stats(void); -diff -up libgcrypt-1.8.5/random/rndlinux.c.getrandom libgcrypt-1.8.5/random/rndlinux.c ---- libgcrypt-1.8.5/random/rndlinux.c.getrandom 2020-04-20 15:01:50.159848963 +0200 -+++ libgcrypt-1.8.5/random/rndlinux.c 2020-04-20 16:14:21.901610921 +0200 -@@ -35,6 +35,7 @@ - #if defined(__linux__) || !defined(HAVE_GETENTROPY) - #ifdef HAVE_SYSCALL - # include -+# include - # ifdef __NR_getrandom - # define getentropy(buf,buflen) syscall (__NR_getrandom, buf, buflen, 0) - # endif -@@ -147,12 +148,12 @@ _gcry_rndlinux_gather_random (void (*add - if (!add) - { - /* Special mode to close the descriptors. */ -- if (fd_random != -1) -+ if (fd_random >= 0) - { - close (fd_random); - fd_random = -1; - } -- if (fd_urandom != -1) -+ if (fd_urandom >= 0) - { - close (fd_urandom); - fd_urandom = -1; -@@ -166,12 +167,12 @@ _gcry_rndlinux_gather_random (void (*add - apid = getpid (); - if (my_pid != apid) - { -- if (fd_random != -1) -+ if (fd_random >= 0) - { - close (fd_random); - fd_random = -1; - } -- if (fd_urandom != -1) -+ if (fd_urandom >= 0) - { - close (fd_urandom); - fd_urandom = -1; -@@ -216,7 +217,23 @@ _gcry_rndlinux_gather_random (void (*add - that we always require the device to be existent but want a more - graceful behaviour if the rarely needed close operation has been - used and the device needs to be re-opened later. */ -- if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom) -+#if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom) -+ if (fd_urandom != -2 && !_gcry_in_constructor ()) -+ { -+ long ret; -+ -+ _gcry_pre_syscall (); -+ ret = syscall (__NR_getrandom, -+ (void*)buffer, (size_t)1, (unsigned int)GRND_NONBLOCK); -+ _gcry_post_syscall (); -+ if (ret > -1 || errno == EAGAIN || errno == EINTR) -+ { -+ fd_urandom = -2; -+ fd_random = -2; -+ } -+ } -+#endif -+ if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom && !_gcry_in_constructor ()) - { - if (fd_random == -1) - { -@@ -270,9 +288,7 @@ _gcry_rndlinux_gather_random (void (*add - _gcry_post_syscall (); - } - while (ret == -1 && errno == EINTR); -- if (ret == -1 && errno == ENOSYS) -- ; /* getentropy is not supported - fallback to pulling from fd. */ -- else -+ if (1) - { /* getentropy is supported. Some sanity checks. */ - if (ret == -1) - log_fatal ("unexpected error from getentropy: %s\n", -diff -up libgcrypt-1.8.5/src/g10lib.h.getrandom libgcrypt-1.8.5/src/g10lib.h ---- libgcrypt-1.8.5/src/g10lib.h.getrandom 2020-04-20 15:08:16.528538580 +0200 -+++ libgcrypt-1.8.5/src/g10lib.h 2020-04-20 15:08:28.641309399 +0200 -@@ -464,6 +464,6 @@ gpg_err_code_t _gcry_fips_run_selftests - void _gcry_fips_noreturn (void); - #define fips_noreturn() (_gcry_fips_noreturn ()) - -- -+int _gcry_in_constructor (void); - - #endif /* G10LIB_H */ -diff -up libgcrypt-1.8.5/src/global.c.getrandom libgcrypt-1.8.5/src/global.c ---- libgcrypt-1.8.5/src/global.c.getrandom 2020-04-20 15:06:21.891707597 +0200 -+++ libgcrypt-1.8.5/src/global.c 2020-04-20 15:07:29.018437509 +0200 -@@ -145,10 +145,18 @@ global_init (void) - #define FIPS_MODULE_PATH "/etc/system-fips" - #endif - -+static int in_constructor = 0; -+ -+int _gcry_in_constructor(void) -+{ -+ return in_constructor; -+} -+ - void __attribute__ ((constructor)) _gcry_global_constructor (void) - { - int rv; - -+ in_constructor = 1; - rv = access (FIPS_MODULE_PATH, F_OK); - if (rv < 0 && errno != ENOENT) - rv = 0; -@@ -163,10 +171,12 @@ void __attribute__ ((constructor)) _gcry - /* force selftests */ - global_init(); - _gcry_fips_run_selftests (0); -- if (!fips_mode()) -- _gcry_random_close_fds (); -+ _gcry_random_close_fds (); -+ _gcry_random_deinit (); - no_secure_memory = no_secmem_save; - } -+ -+ in_constructor = 0; - } - - /* This function is called by the macro fips_is_operational and makes diff --git a/libgcrypt-1.8.5-intel-cet.patch b/libgcrypt-1.8.5-intel-cet.patch deleted file mode 100644 index a19d2f1..0000000 --- a/libgcrypt-1.8.5-intel-cet.patch +++ /dev/null @@ -1,34 +0,0 @@ -From b04c0a86b19856071c29d2a6285f3240c606ee7a Mon Sep 17 00:00:00 2001 -From: "H.J. Lu" -Date: Tue, 27 Apr 2021 09:08:41 -0700 -Subject: [PATCH] Always include in cipher assembly codes - -* cipher/poly1305-s390x.S: Always include . - -When Intel CET is enabled, we need to include in assembly codes -to mark Intel CET support even if it is empty. We should always include - in cipher assembly codes so that they will be marked for -Intel CET support when compiling for x86-64 and i686. - -Signed-off-by: H.J. Lu ---- - cipher/poly1305-s390x.S | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cipher/poly1305-s390x.S b/cipher/poly1305-s390x.S -index 844245f6..28bed560 100644 ---- a/cipher/poly1305-s390x.S -+++ b/cipher/poly1305-s390x.S -@@ -18,8 +18,8 @@ - * License along with this program; if not, see . - */ - --#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9 - #include -+#if defined (__s390x__) && __GNUC__ >= 4 && __ARCH__ >= 9 - #if defined(HAVE_GCC_INLINE_ASM_S390X) - - #include "asm-poly1305-s390x.h" --- -GitLab - diff --git a/libgcrypt-1.8.5-use-fipscheck.patch b/libgcrypt-1.8.5-use-fipscheck.patch deleted file mode 100644 index 46145d8..0000000 --- a/libgcrypt-1.8.5-use-fipscheck.patch +++ /dev/null @@ -1,77 +0,0 @@ -diff -up libgcrypt-1.8.5/src/fips.c.use-fipscheck libgcrypt-1.8.5/src/fips.c ---- libgcrypt-1.8.5/src/fips.c.use-fipscheck 2017-11-23 19:16:58.000000000 +0100 -+++ libgcrypt-1.8.5/src/fips.c 2020-04-23 10:18:36.235764741 +0200 -@@ -581,23 +581,50 @@ run_random_selftests (void) - return !!err; - } - -+#ifdef ENABLE_HMAC_BINARY_CHECK -+static int -+get_library_path(const char *libname, const char *symbolname, char *path, size_t pathlen) -+{ -+ Dl_info info; -+ void *dl, *sym; -+ int rv = -1; -+ -+ dl = dlopen(libname, RTLD_LAZY); -+ if (dl == NULL) { -+ return -1; -+ } -+ -+ sym = dlsym(dl, symbolname); -+ -+ if (sym != NULL && dladdr(sym, &info)) { -+ strncpy(path, info.dli_fname, pathlen-1); -+ path[pathlen-1] = '\0'; -+ rv = 0; -+ } -+ -+ dlclose(dl); -+ -+ return rv; -+} -+#endif -+ - /* Run an integrity check on the binary. Returns 0 on success. */ - static int - check_binary_integrity (void) - { - #ifdef ENABLE_HMAC_BINARY_CHECK - gpg_error_t err; -- Dl_info info; -+ char libpath[4096]; - unsigned char digest[32]; - int dlen; - char *fname = NULL; -- const char key[] = "What am I, a doctor or a moonshuttle conductor?"; -- -- if (!dladdr ("gcry_check_version", &info)) -+ const char key[] = "orboDeJITITejsirpADONivirpUkvarP"; -+ -+ if (get_library_path ("libgcrypt.so.20", "gcry_check_version", libpath, sizeof(libpath))) - err = gpg_error_from_syserror (); - else - { -- dlen = _gcry_hmac256_file (digest, sizeof digest, info.dli_fname, -+ dlen = _gcry_hmac256_file (digest, sizeof digest, libpath, - key, strlen (key)); - if (dlen < 0) - err = gpg_error_from_syserror (); -@@ -605,7 +632,7 @@ check_binary_integrity (void) - err = gpg_error (GPG_ERR_INTERNAL); - else - { -- fname = xtrymalloc (strlen (info.dli_fname) + 1 + 5 + 1 ); -+ fname = xtrymalloc (strlen (libpath) + 1 + 5 + 1 ); - if (!fname) - err = gpg_error_from_syserror (); - else -@@ -614,7 +641,7 @@ check_binary_integrity (void) - char *p; - - /* Prefix the basename with a dot. */ -- strcpy (fname, info.dli_fname); -+ strcpy (fname, libpath); - p = strrchr (fname, '/'); - if (p) - p++; diff --git a/libgcrypt-1.9.3-fips-tests.patch b/libgcrypt-1.9.3-fips-tests.patch deleted file mode 100644 index 1ddc64f..0000000 --- a/libgcrypt-1.9.3-fips-tests.patch +++ /dev/null @@ -1,1804 +0,0 @@ -commit 57cf83834bc00a7431378aabda692bf700e4876c -Author: Jussi Kivilinna -Date: Sat Apr 17 17:06:40 2021 +0300 - - tests/bench-slope: add ECC benchmarking - - * tests/bench-slope.c (bench_print_result_nsec_per_iteration): New. - (bench_print_header_nsec_per_iteration): New. - (kdf_bench_one, kdf_bench): Use new print helper functions. - [USE_ECC]: New ECC benchmarks. - (ecc_bench): New. - (print_help): Add 'ecc' option. - (main): Add ECC benchmarks. - -- - - Signed-off-by: Jussi Kivilinna - -diff --git a/tests/bench-slope.c b/tests/bench-slope.c -index c8647b6b..9b4a139a 100644 ---- a/tests/bench-slope.c -+++ b/tests/bench-slope.c -@@ -783,6 +783,54 @@ bench_print_result (double nsecs_per_byte) - bench_print_result_std (nsecs_per_byte); - } - -+static void -+bench_print_result_nsec_per_iteration (double nsecs_per_iteration) -+{ -+ double cycles_per_iteration; -+ char nsecpiter_buf[16]; -+ char cpiter_buf[16]; -+ char mhz_buf[16]; -+ -+ strcpy(cpiter_buf, csv_mode ? "" : "-"); -+ strcpy(mhz_buf, csv_mode ? "" : "-"); -+ -+ double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); -+ -+ /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ -+ if (bench_ghz > 0.0) -+ { -+ cycles_per_iteration = nsecs_per_iteration * bench_ghz; -+ double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); -+ double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); -+ } -+ -+ if (csv_mode) -+ { -+ if (auto_ghz) -+ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", -+ current_section_name, -+ current_algo_name ? current_algo_name : "", -+ current_mode_name ? current_mode_name : "", -+ nsecpiter_buf, -+ cpiter_buf, -+ mhz_buf); -+ else -+ printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", -+ current_section_name, -+ current_algo_name ? current_algo_name : "", -+ current_mode_name ? current_mode_name : "", -+ nsecpiter_buf, -+ cpiter_buf); -+ } -+ else -+ { -+ if (auto_ghz) -+ printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); -+ else -+ printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); -+ } -+} -+ - static void - bench_print_section (const char *section_name, const char *print_name) - { -@@ -819,6 +867,28 @@ bench_print_header (int algo_width, const char *algo_name) - } - } - -+static void -+bench_print_header_nsec_per_iteration (int algo_width, const char *algo_name) -+{ -+ if (csv_mode) -+ { -+ gcry_free (current_algo_name); -+ current_algo_name = gcry_xstrdup (algo_name); -+ } -+ else -+ { -+ if (algo_width < 0) -+ printf (" %-*s | ", -algo_width, algo_name); -+ else -+ printf (" %-*s | ", algo_width, algo_name); -+ -+ if (auto_ghz) -+ printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); -+ else -+ printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); -+ } -+} -+ - static void - bench_print_algo (int algo_width, const char *algo_name) - { -@@ -1991,11 +2061,7 @@ kdf_bench_one (int algo, int subalgo) - struct bench_kdf_mode mode = { &kdf_ops }; - struct bench_obj obj = { 0 }; - double nsecs_per_iteration; -- double cycles_per_iteration; - char algo_name[32]; -- char nsecpiter_buf[16]; -- char cpiter_buf[16]; -- char mhz_buf[16]; - - mode.algo = algo; - mode.subalgo = subalgo; -@@ -2030,45 +2096,7 @@ kdf_bench_one (int algo, int subalgo) - obj.priv = &mode; - - nsecs_per_iteration = do_slope_benchmark (&obj); -- -- strcpy(cpiter_buf, csv_mode ? "" : "-"); -- strcpy(mhz_buf, csv_mode ? "" : "-"); -- -- double_to_str (nsecpiter_buf, sizeof (nsecpiter_buf), nsecs_per_iteration); -- -- /* If user didn't provide CPU speed, we cannot show cycles/iter results. */ -- if (bench_ghz > 0.0) -- { -- cycles_per_iteration = nsecs_per_iteration * bench_ghz; -- double_to_str (cpiter_buf, sizeof (cpiter_buf), cycles_per_iteration); -- double_to_str (mhz_buf, sizeof (mhz_buf), bench_ghz * 1000); -- } -- -- if (csv_mode) -- { -- if (auto_ghz) -- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter,%s,Mhz\n", -- current_section_name, -- current_algo_name ? current_algo_name : "", -- current_mode_name ? current_mode_name : "", -- nsecpiter_buf, -- cpiter_buf, -- mhz_buf); -- else -- printf ("%s,%s,%s,,,,,,,,,%s,ns/iter,%s,c/iter\n", -- current_section_name, -- current_algo_name ? current_algo_name : "", -- current_mode_name ? current_mode_name : "", -- nsecpiter_buf, -- cpiter_buf); -- } -- else -- { -- if (auto_ghz) -- printf ("%14s %13s %9s\n", nsecpiter_buf, cpiter_buf, mhz_buf); -- else -- printf ("%14s %13s\n", nsecpiter_buf, cpiter_buf); -- } -+ bench_print_result_nsec_per_iteration (nsecs_per_iteration); - } - - void -@@ -2079,14 +2107,7 @@ kdf_bench (char **argv, int argc) - - bench_print_section ("kdf", "KDF"); - -- if (!csv_mode) -- { -- printf (" %-*s | ", 24, ""); -- if (auto_ghz) -- printf ("%14s %13s %9s\n", "nanosecs/iter", "cycles/iter", "auto Mhz"); -- else -- printf ("%14s %13s\n", "nanosecs/iter", "cycles/iter"); -- } -+ bench_print_header_nsec_per_iteration (24, ""); - - if (argv && argc) - { -@@ -2116,13 +2137,571 @@ kdf_bench (char **argv, int argc) - } - - -+/************************************************************ ECC benchmarks. */ -+ -+#if USE_ECC -+enum bench_ecc_algo -+{ -+ ECC_ALGO_ED25519 = 0, -+ ECC_ALGO_ED448, -+ ECC_ALGO_NIST_P192, -+ ECC_ALGO_NIST_P224, -+ ECC_ALGO_NIST_P256, -+ ECC_ALGO_NIST_P384, -+ ECC_ALGO_NIST_P521, -+ ECC_ALGO_SECP256K1, -+ __MAX_ECC_ALGO -+}; -+ -+enum bench_ecc_operation -+{ -+ ECC_OPER_MULT = 0, -+ ECC_OPER_KEYGEN, -+ ECC_OPER_SIGN, -+ ECC_OPER_VERIFY, -+ __MAX_ECC_OPER -+}; -+ -+struct bench_ecc_oper -+{ -+ enum bench_ecc_operation oper; -+ const char *name; -+ struct bench_ops *ops; -+ -+ enum bench_ecc_algo algo; -+}; -+ -+struct bench_ecc_mult_hd -+{ -+ gcry_ctx_t ec; -+ gcry_mpi_t k, x, y; -+ gcry_mpi_point_t G, Q; -+}; -+ -+struct bench_ecc_hd -+{ -+ gcry_sexp_t key_spec; -+ gcry_sexp_t data; -+ gcry_sexp_t pub_key; -+ gcry_sexp_t sec_key; -+ gcry_sexp_t sig; -+}; -+ -+ -+static const char * -+ecc_algo_name (int algo) -+{ -+ switch (algo) -+ { -+ case ECC_ALGO_ED25519: -+ return "Ed25519"; -+ case ECC_ALGO_ED448: -+ return "Ed448"; -+ case ECC_ALGO_NIST_P192: -+ return "NIST-P192"; -+ case ECC_ALGO_NIST_P224: -+ return "NIST-P224"; -+ case ECC_ALGO_NIST_P256: -+ return "NIST-P256"; -+ case ECC_ALGO_NIST_P384: -+ return "NIST-P384"; -+ case ECC_ALGO_NIST_P521: -+ return "NIST-P521"; -+ case ECC_ALGO_SECP256K1: -+ return "secp256k1"; -+ default: -+ return NULL; -+ } -+} -+ -+static const char * -+ecc_algo_curve (int algo) -+{ -+ switch (algo) -+ { -+ case ECC_ALGO_ED25519: -+ return "Ed25519"; -+ case ECC_ALGO_ED448: -+ return "Ed448"; -+ case ECC_ALGO_NIST_P192: -+ return "NIST P-192"; -+ case ECC_ALGO_NIST_P224: -+ return "NIST P-224"; -+ case ECC_ALGO_NIST_P256: -+ return "NIST P-256"; -+ case ECC_ALGO_NIST_P384: -+ return "NIST P-384"; -+ case ECC_ALGO_NIST_P521: -+ return "NIST P-521"; -+ case ECC_ALGO_SECP256K1: -+ return "secp256k1"; -+ default: -+ return NULL; -+ } -+} -+ -+static int -+ecc_nbits (int algo) -+{ -+ switch (algo) -+ { -+ case ECC_ALGO_ED25519: -+ return 255; -+ case ECC_ALGO_ED448: -+ return 448; -+ case ECC_ALGO_NIST_P192: -+ return 192; -+ case ECC_ALGO_NIST_P224: -+ return 224; -+ case ECC_ALGO_NIST_P256: -+ return 256; -+ case ECC_ALGO_NIST_P384: -+ return 384; -+ case ECC_ALGO_NIST_P521: -+ return 521; -+ case ECC_ALGO_SECP256K1: -+ return 256; -+ default: -+ return 0; -+ } -+} -+ -+static int -+ecc_map_name (const char *name) -+{ -+ int i; -+ -+ for (i = 0; i < __MAX_ECC_ALGO; i++) -+ { -+ if (strcmp(ecc_algo_name(i), name) == 0) -+ { -+ return i; -+ } -+ } -+ -+ return -1; -+} -+ -+ -+static int -+bench_ecc_mult_init (struct bench_obj *obj) -+{ -+ struct bench_ecc_oper *oper = obj->priv; -+ struct bench_ecc_mult_hd *hd; -+ int p_size = ecc_nbits (oper->algo); -+ gpg_error_t err; -+ gcry_mpi_t p; -+ -+ obj->min_bufsize = 1; -+ obj->max_bufsize = 4; -+ obj->step_size = 1; -+ obj->num_measure_repetitions = -+ num_measurement_repetitions / obj->max_bufsize; -+ -+ while (obj->num_measure_repetitions == 0) -+ { -+ if (obj->max_bufsize == 2) -+ { -+ obj->num_measure_repetitions = 2; -+ } -+ else -+ { -+ obj->max_bufsize--; -+ obj->num_measure_repetitions = -+ num_measurement_repetitions / obj->max_bufsize; -+ } -+ } -+ -+ hd = calloc (1, sizeof(*hd)); -+ if (!hd) -+ return -1; -+ -+ err = gcry_mpi_ec_new (&hd->ec, NULL, ecc_algo_curve(oper->algo)); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_mpi_ec_new failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ hd->G = gcry_mpi_ec_get_point ("g", hd->ec, 1); -+ hd->Q = gcry_mpi_point_new (0); -+ hd->x = gcry_mpi_new (0); -+ hd->y = gcry_mpi_new (0); -+ hd->k = gcry_mpi_new (p_size); -+ gcry_mpi_randomize (hd->k, p_size, GCRY_WEAK_RANDOM); -+ p = gcry_mpi_ec_get_mpi ("p", hd->ec, 1); -+ gcry_mpi_mod (hd->k, hd->k, p); -+ gcry_mpi_release (p); -+ -+ obj->hd = hd; -+ return 0; -+} -+ -+static void -+bench_ecc_mult_free (struct bench_obj *obj) -+{ -+ struct bench_ecc_mult_hd *hd = obj->hd; -+ -+ gcry_mpi_release (hd->k); -+ gcry_mpi_release (hd->y); -+ gcry_mpi_release (hd->x); -+ gcry_mpi_point_release (hd->Q); -+ gcry_mpi_point_release (hd->G); -+ gcry_ctx_release (hd->ec); -+ free (hd); -+ obj->hd = NULL; -+} -+ -+static void -+bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) -+{ -+ struct bench_ecc_mult_hd *hd = obj->hd; -+ size_t i; -+ -+ (void)buf; -+ -+ for (i = 0; i < num_iter; i++) -+ { -+ gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec); -+ if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec)) -+ { -+ fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n"); -+ exit (1); -+ } -+ } -+} -+ -+ -+static int -+bench_ecc_init (struct bench_obj *obj) -+{ -+ struct bench_ecc_oper *oper = obj->priv; -+ struct bench_ecc_hd *hd; -+ int p_size = ecc_nbits (oper->algo); -+ gpg_error_t err; -+ gcry_mpi_t x; -+ -+ obj->min_bufsize = 1; -+ obj->max_bufsize = 4; -+ obj->step_size = 1; -+ obj->num_measure_repetitions = -+ num_measurement_repetitions / obj->max_bufsize; -+ -+ while (obj->num_measure_repetitions == 0) -+ { -+ if (obj->max_bufsize == 2) -+ { -+ obj->num_measure_repetitions = 2; -+ } -+ else -+ { -+ obj->max_bufsize--; -+ obj->num_measure_repetitions = -+ num_measurement_repetitions / obj->max_bufsize; -+ } -+ } -+ -+ hd = calloc (1, sizeof(*hd)); -+ if (!hd) -+ return -1; -+ -+ x = gcry_mpi_new (p_size); -+ gcry_mpi_randomize (x, p_size, GCRY_WEAK_RANDOM); -+ -+ switch (oper->algo) -+ { -+ default: -+ return -1; -+ -+ case ECC_ALGO_ED25519: -+ err = gcry_sexp_build (&hd->key_spec, NULL, -+ "(genkey (ecdsa (curve \"Ed25519\")" -+ "(flags eddsa)))"); -+ if (err) -+ break; -+ err = gcry_sexp_build (&hd->data, NULL, -+ "(data (flags eddsa)(hash-algo sha512)" -+ " (value %m))", x); -+ break; -+ -+ case ECC_ALGO_ED448: -+ err = gcry_sexp_build (&hd->key_spec, NULL, -+ "(genkey (ecdsa (curve \"Ed448\")" -+ "(flags eddsa)))"); -+ if (err) -+ break; -+ err = gcry_sexp_build (&hd->data, NULL, -+ "(data (flags eddsa)(hash-algo shake256)" -+ " (value %m))", x); -+ break; -+ -+ case ECC_ALGO_NIST_P192: -+ case ECC_ALGO_NIST_P224: -+ case ECC_ALGO_NIST_P256: -+ case ECC_ALGO_NIST_P384: -+ case ECC_ALGO_NIST_P521: -+ err = gcry_sexp_build (&hd->key_spec, NULL, -+ "(genkey (ECDSA (nbits %d)))", p_size); -+ if (err) -+ break; -+ err = gcry_sexp_build (&hd->data, NULL, -+ "(data (flags raw) (value %m))", x); -+ break; -+ } -+ -+ gcry_mpi_release (x); -+ -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_sexp_build failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ -+ obj->hd = hd; -+ return 0; -+} -+ -+static void -+bench_ecc_free (struct bench_obj *obj) -+{ -+ struct bench_ecc_hd *hd = obj->hd; -+ -+ gcry_sexp_release (hd->sig); -+ gcry_sexp_release (hd->pub_key); -+ gcry_sexp_release (hd->sec_key); -+ gcry_sexp_release (hd->data); -+ gcry_sexp_release (hd->key_spec); -+ free (hd); -+ obj->hd = NULL; -+} -+ -+static void -+bench_ecc_keygen (struct bench_ecc_hd *hd) -+{ -+ gcry_sexp_t key_pair; -+ gpg_error_t err; -+ -+ err = gcry_pk_genkey (&key_pair, hd->key_spec); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_pk_genkey failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ -+ hd->pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); -+ if (!hd->pub_key) -+ { -+ fprintf (stderr, PGM ": public part missing in key\n"); -+ exit (1); -+ } -+ hd->sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); -+ if (!hd->sec_key) -+ { -+ fprintf (stderr, PGM ": private part missing in key\n"); -+ exit (1); -+ } -+ -+ gcry_sexp_release (key_pair); -+} -+ -+static void -+bench_ecc_keygen_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) -+{ -+ struct bench_ecc_hd *hd = obj->hd; -+ size_t i; -+ -+ (void)buf; -+ -+ for (i = 0; i < num_iter; i++) -+ { -+ bench_ecc_keygen (hd); -+ gcry_sexp_release (hd->pub_key); -+ gcry_sexp_release (hd->sec_key); -+ } -+ -+ hd->pub_key = NULL; -+ hd->sec_key = NULL; -+} -+ -+static void -+bench_ecc_sign_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) -+{ -+ struct bench_ecc_hd *hd = obj->hd; -+ gpg_error_t err; -+ size_t i; -+ -+ (void)buf; -+ -+ bench_ecc_keygen (hd); -+ -+ for (i = 0; i < num_iter; i++) -+ { -+ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ gcry_sexp_release (hd->sig); -+ } -+ -+ gcry_sexp_release (hd->pub_key); -+ gcry_sexp_release (hd->sec_key); -+ hd->sig = NULL; -+ hd->pub_key = NULL; -+ hd->sec_key = NULL; -+} -+ -+static void -+bench_ecc_verify_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) -+{ -+ struct bench_ecc_hd *hd = obj->hd; -+ gpg_error_t err; -+ int i; -+ -+ (void)buf; -+ -+ bench_ecc_keygen (hd); -+ err = gcry_pk_sign (&hd->sig, hd->data, hd->sec_key); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_pk_sign failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ -+ for (i = 0; i < num_iter; i++) -+ { -+ err = gcry_pk_verify (hd->sig, hd->data, hd->pub_key); -+ if (err) -+ { -+ fprintf (stderr, PGM ": gcry_pk_verify failed: %s\n", -+ gpg_strerror (err)); -+ exit (1); -+ } -+ } -+ -+ gcry_sexp_release (hd->sig); -+ gcry_sexp_release (hd->pub_key); -+ gcry_sexp_release (hd->sec_key); -+ hd->sig = NULL; -+ hd->pub_key = NULL; -+ hd->sec_key = NULL; -+} -+ -+ -+static struct bench_ops ecc_mult_ops = { -+ &bench_ecc_mult_init, -+ &bench_ecc_mult_free, -+ &bench_ecc_mult_do_bench -+}; -+ -+static struct bench_ops ecc_keygen_ops = { -+ &bench_ecc_init, -+ &bench_ecc_free, -+ &bench_ecc_keygen_do_bench -+}; -+ -+static struct bench_ops ecc_sign_ops = { -+ &bench_ecc_init, -+ &bench_ecc_free, -+ &bench_ecc_sign_do_bench -+}; -+ -+static struct bench_ops ecc_verify_ops = { -+ &bench_ecc_init, -+ &bench_ecc_free, -+ &bench_ecc_verify_do_bench -+}; -+ -+ -+static struct bench_ecc_oper ecc_operations[] = { -+ { ECC_OPER_MULT, "mult", &ecc_mult_ops }, -+ { ECC_OPER_KEYGEN, "keygen", &ecc_keygen_ops }, -+ { ECC_OPER_SIGN, "sign", &ecc_sign_ops }, -+ { ECC_OPER_VERIFY, "verify", &ecc_verify_ops }, -+ { 0, NULL, NULL } -+}; -+ -+ -+static void -+cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper) -+{ -+ struct bench_ecc_oper oper = *poper; -+ struct bench_obj obj = { 0 }; -+ double result; -+ -+ if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT) -+ return; -+ -+ oper.algo = algo; -+ -+ bench_print_mode (14, oper.name); -+ -+ obj.ops = oper.ops; -+ obj.priv = &oper; -+ -+ result = do_slope_benchmark (&obj); -+ bench_print_result_nsec_per_iteration (result); -+} -+ -+ -+static void -+_ecc_bench (int algo) -+{ -+ const char *algo_name; -+ int i; -+ -+ algo_name = ecc_algo_name (algo); -+ -+ bench_print_header_nsec_per_iteration (14, algo_name); -+ -+ for (i = 0; ecc_operations[i].name; i++) -+ cipher_ecc_one (algo, &ecc_operations[i]); -+ -+ bench_print_footer (14); -+} -+#endif -+ -+ -+void -+ecc_bench (char **argv, int argc) -+{ -+#if USE_ECC -+ int i, algo; -+ -+ bench_print_section ("ecc", "ECC"); -+ -+ if (argv && argc) -+ { -+ for (i = 0; i < argc; i++) -+ { -+ algo = ecc_map_name (argv[i]); -+ if (algo >= 0) -+ _ecc_bench (algo); -+ } -+ } -+ else -+ { -+ for (i = 0; i < __MAX_ECC_ALGO; i++) -+ _ecc_bench (i); -+ } -+#else -+ (void)argv; -+ (void)argc; -+#endif -+} -+ - /************************************************************** Main program. */ - - void - print_help (void) - { - static const char *help_lines[] = { -- "usage: bench-slope [options] [hash|mac|cipher|kdf [algonames]]", -+ "usage: bench-slope [options] [hash|mac|cipher|kdf|ecc [algonames]]", - "", - " options:", - " --cpu-mhz Set CPU speed for calculating cycles", -@@ -2304,6 +2883,7 @@ main (int argc, char **argv) - mac_bench (NULL, 0); - cipher_bench (NULL, 0); - kdf_bench (NULL, 0); -+ ecc_bench (NULL, 0); - } - else if (!strcmp (*argv, "hash")) - { -@@ -2337,6 +2917,14 @@ main (int argc, char **argv) - warm_up_cpu (); - kdf_bench ((argc == 0) ? NULL : argv, argc); - } -+ else if (!strcmp (*argv, "ecc")) -+ { -+ argc--; -+ argv++; -+ -+ warm_up_cpu (); -+ ecc_bench ((argc == 0) ? NULL : argv, argc); -+ } - else - { - fprintf (stderr, PGM ": unknown argument: %s\n", *argv); - -commit 9911069388e762d2a85bc2a11ca6cfcc4c895e4f -Author: Jussi Kivilinna -Date: Wed Jun 16 20:27:01 2021 +0300 - - bench-slope: add X25519 and X448 scalar multiplication - - * tests/bench-slope.c (ECC_ALGO_X25519, ECC_ALGO_X448): New. - (ecc_algo_name, ecc_algo_curve, ecc_nbits): Add X25519 and X448. - (bench_ecc_mult_do_bench): Pass Y as NULL to ec_get_affine with - X25519 and X448. - (cipher_ecc_one): Run only multiplication bench for X25519 and X448. - -- - - Signed-off-by: Jussi Kivilinna - -diff --git a/tests/bench-slope.c b/tests/bench-slope.c -index 9b4a139a..35272094 100644 ---- a/tests/bench-slope.c -+++ b/tests/bench-slope.c -@@ -2144,6 +2144,8 @@ enum bench_ecc_algo - { - ECC_ALGO_ED25519 = 0, - ECC_ALGO_ED448, -+ ECC_ALGO_X25519, -+ ECC_ALGO_X448, - ECC_ALGO_NIST_P192, - ECC_ALGO_NIST_P224, - ECC_ALGO_NIST_P256, -@@ -2197,6 +2199,10 @@ ecc_algo_name (int algo) - return "Ed25519"; - case ECC_ALGO_ED448: - return "Ed448"; -+ case ECC_ALGO_X25519: -+ return "X25519"; -+ case ECC_ALGO_X448: -+ return "X448"; - case ECC_ALGO_NIST_P192: - return "NIST-P192"; - case ECC_ALGO_NIST_P224: -@@ -2223,6 +2229,10 @@ ecc_algo_curve (int algo) - return "Ed25519"; - case ECC_ALGO_ED448: - return "Ed448"; -+ case ECC_ALGO_X25519: -+ return "Curve25519"; -+ case ECC_ALGO_X448: -+ return "X448"; - case ECC_ALGO_NIST_P192: - return "NIST P-192"; - case ECC_ALGO_NIST_P224: -@@ -2249,6 +2259,10 @@ ecc_nbits (int algo) - return 255; - case ECC_ALGO_ED448: - return 448; -+ case ECC_ALGO_X25519: -+ return 255; -+ case ECC_ALGO_X448: -+ return 448; - case ECC_ALGO_NIST_P192: - return 192; - case ECC_ALGO_NIST_P224: -@@ -2355,15 +2369,26 @@ bench_ecc_mult_free (struct bench_obj *obj) - static void - bench_ecc_mult_do_bench (struct bench_obj *obj, void *buf, size_t num_iter) - { -+ struct bench_ecc_oper *oper = obj->priv; - struct bench_ecc_mult_hd *hd = obj->hd; -+ gcry_mpi_t y; - size_t i; - - (void)buf; - -+ if (oper->algo == ECC_ALGO_X25519 || oper->algo == ECC_ALGO_X448) -+ { -+ y = NULL; -+ } -+ else -+ { -+ y = hd->y; -+ } -+ - for (i = 0; i < num_iter; i++) - { - gcry_mpi_ec_mul (hd->Q, hd->k, hd->G, hd->ec); -- if (gcry_mpi_ec_get_affine (hd->x, hd->y, hd->Q, hd->ec)) -+ if (gcry_mpi_ec_get_affine (hd->x, y, hd->Q, hd->ec)) - { - fprintf (stderr, PGM ": gcry_mpi_ec_get_affine failed\n"); - exit (1); -@@ -2634,7 +2659,8 @@ cipher_ecc_one (enum bench_ecc_algo algo, struct bench_ecc_oper *poper) - struct bench_obj obj = { 0 }; - double result; - -- if (algo == ECC_ALGO_SECP256K1 && oper.oper != ECC_OPER_MULT) -+ if ((algo == ECC_ALGO_X25519 || algo == ECC_ALGO_X448 || -+ algo == ECC_ALGO_SECP256K1) && oper.oper != ECC_OPER_MULT) - return; - - oper.algo = algo; - - -From bd49a4fa915b8a078c341b35f5a51fcb2a004c35 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Mon, 12 Jul 2021 21:35:18 +0200 -Subject: [PATCH 1/8] mac: Disable AES GMAC in FIPS mode - -* cipher/mac-gmac.c (_gcry_mac_type_spec_gmac_aes): Remove FIPS flag --- -The GMAC does not work in FIPS mode until libgcrypt will have internal -IV generator. - -Signed-off-by: Jakub Jelen ---- - cipher/mac-gmac.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/cipher/mac-gmac.c b/cipher/mac-gmac.c -index e04c6d1e..1d59d085 100644 ---- a/cipher/mac-gmac.c -+++ b/cipher/mac-gmac.c -@@ -157,7 +157,7 @@ static gcry_mac_spec_ops_t gmac_ops = { - - #if USE_AES - gcry_mac_spec_t _gcry_mac_type_spec_gmac_aes = { -- GCRY_MAC_GMAC_AES, {0, 1}, "GMAC_AES", -+ GCRY_MAC_GMAC_AES, {0, 0}, "GMAC_AES", - &gmac_ops - }; - #endif --- -2.31.1 - - -From fd0e1c3e7f6062579869d345875d6ef823706e56 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Mon, 12 Jul 2021 21:36:34 +0200 -Subject: [PATCH 2/8] tests: Do not expect GCM work in FIPS - -* tests/basic.c (check_one_cipher_core): Expect GCM ciphers to fail in - FIPS mode - (check_cipher_modes): Skip GCM ciphers tests as they fail quite late - in gcry_cipher_gettag(). --- - -Signed-off-by: Jakub Jelen ---- - tests/basic.c | 14 +++++++++++++- - 1 file changed, 13 insertions(+), 1 deletion(-) - -diff --git a/tests/basic.c b/tests/basic.c -index 0572c46e..d7b7f496 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -9510,6 +9510,13 @@ check_one_cipher_core (int algo, int mode, int flags, - - clutter_vector_registers(); - err = gcry_cipher_encrypt (hd, out, nplain, plain, nplain); -+ if (in_fips_mode && mode == GCRY_CIPHER_MODE_GCM) -+ { -+ if (!err) -+ fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt is expected to " -+ "fail in FIPS mode: %s\n", pass, algo, mode, gpg_strerror (err)); -+ goto err_out_free; -+ } - if (err) - { - fail ("pass %d, algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", -@@ -10257,7 +10264,12 @@ check_cipher_modes(void) - check_cfb_cipher (); - check_ofb_cipher (); - check_ccm_cipher (); -- check_gcm_cipher (); -+ if (!in_fips_mode) -+ { -+ /* This will have to go through modifications as the GCM fails in fips -+ * as late as in gcry_cipher_gettag, but we want to allow it in the end */ -+ check_gcm_cipher (); -+ } - check_poly1305_cipher (); - check_ocb_cipher (); - check_xts_cipher (); --- -2.31.1 - - -From ccbb1694693080822858e2065cf88ab43ec03fbc Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 09:18:52 +0200 -Subject: [PATCH 3/8] tests: Skip unsupported mechanisms in FIPS mode - -* tests/bench-slope.c (cipher_bench_one): Skip GCM mode in FIPS mode - (ecc_algo_fips_allowed): New function - (_ecc_bench): Skip algorithms disabled in FIPS mode - (main): Check for FIPS mode -* tests/benchmark.c (cipher_bench): Skip GCM in FIPS mode --- -In FIPS mode, not all the curves are allowed. This is already checked in -other parts of the code base, but not in the benchmark test. - -Signed-off-by: Jakub Jelen ---- - tests/bench-slope.c | 33 +++++++++++++++++++++++++++++++-- - tests/benchmark.c | 4 ++++ - 2 files changed, 35 insertions(+), 2 deletions(-) - -diff --git a/tests/bench-slope.c b/tests/bench-slope.c -index 35272094..5bdb391e 100644 ---- a/tests/bench-slope.c -+++ b/tests/bench-slope.c -@@ -70,6 +70,7 @@ static double bench_ghz; - /* Current accuracy of auto-detected CPU Ghz. */ - static double bench_ghz_diff; - -+static int in_fips_mode = 0; - - /*************************************** Default parameters for measurements. */ - -@@ -1642,8 +1643,8 @@ cipher_bench_one (int algo, struct bench_cipher_mode *pmode) - if (mode.mode == GCRY_CIPHER_MODE_CCM && blklen != GCRY_CCM_BLOCK_LEN) - return; - -- /* GCM has restrictions for block-size */ -- if (mode.mode == GCRY_CIPHER_MODE_GCM && blklen != GCRY_GCM_BLOCK_LEN) -+ /* GCM has restrictions for block-size; not allowed in FIPS mode */ -+ if (mode.mode == GCRY_CIPHER_MODE_GCM && (in_fips_mode || blklen != GCRY_GCM_BLOCK_LEN)) - return; - - /* XTS has restrictions for block-size */ -@@ -2190,6 +2191,27 @@ struct bench_ecc_hd - }; - - -+static int -+ecc_algo_fips_allowed (int algo) -+{ -+ switch (algo) -+ { -+ case ECC_ALGO_NIST_P224: -+ case ECC_ALGO_NIST_P256: -+ case ECC_ALGO_NIST_P384: -+ case ECC_ALGO_NIST_P521: -+ return 1; -+ case ECC_ALGO_SECP256K1: -+ case ECC_ALGO_ED25519: -+ case ECC_ALGO_ED448: -+ case ECC_ALGO_X25519: -+ case ECC_ALGO_X448: -+ case ECC_ALGO_NIST_P192: -+ default: -+ return 0; -+ } -+} -+ - static const char * - ecc_algo_name (int algo) - { -@@ -2681,6 +2703,10 @@ _ecc_bench (int algo) - const char *algo_name; - int i; - -+ /* Skip not allowed mechanisms */ -+ if (!ecc_algo_fips_allowed(algo)) -+ return; -+ - algo_name = ecc_algo_name (algo); - - bench_print_header_nsec_per_iteration (14, algo_name); -@@ -2899,6 +2925,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - if (in_regression_test) - fputs ("Note: " PGM " running in quick regression test mode.\n", stdout); - -diff --git a/tests/benchmark.c b/tests/benchmark.c -index 605b50c6..24141371 100644 ---- a/tests/benchmark.c -+++ b/tests/benchmark.c -@@ -943,6 +943,10 @@ cipher_bench ( const char *algoname ) - && algo != GCRY_CIPHER_CHACHA20) - continue; - -+ /* GCM is not available in FIPS mode */ -+ if (in_fips_mode && modes[modeidx].mode == GCRY_CIPHER_MODE_GCM) -+ continue; -+ - if (modes[modeidx].req_blocksize > 0 - && blklen != modes[modeidx].req_blocksize) - { --- -2.31.1 - - -From 744baa85722da10d7374c6eca6b08b8197819ab6 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 09:20:18 +0200 -Subject: [PATCH 4/8] tests: Expect curves 25519/448 to fail in FIPS mode - -* tests/t-cv25519.c (test_cv_hl): Expect the operation to fail in FIPS - mode. - (test_cv_x25519, test_it): Ditto. - (main) Detect FIPS mode. -* tests/t-ed25519.c (one_test): Expect the operation to fail in FIPS - mode. - (main) Detect FIPS mode. -* tests/t-ed448.c (one_test): Expect the operation to fail in FIPS - mode. - (main) Detect FIPS mode. -* tests/t-x448.c (test_cv_hl): Expect the operation to fail in FIPS - mode. - (test_cv_x448, test_cv): Ditto. - (main) Detect FIPS mode. --- -The ed25519, ed448, cv25519 and cv448 curves are not available in FIPS -mode. Some of the tests already skipped these, but it is always better -to make sure thy are failing, rather than just skipping these. - -Signed-off-by: Jakub Jelen ---- - tests/t-cv25519.c | 37 +++++++++++++++++++++++++++++++++++-- - tests/t-ed25519.c | 18 ++++++++++++++---- - tests/t-ed448.c | 18 ++++++++++++++---- - tests/t-x448.c | 41 +++++++++++++++++++++++++++++++++++++---- - 4 files changed, 100 insertions(+), 14 deletions(-) - -diff --git a/tests/t-cv25519.c b/tests/t-cv25519.c -index 0de50a02..b4126f4c 100644 ---- a/tests/t-cv25519.c -+++ b/tests/t-cv25519.c -@@ -33,6 +33,7 @@ - #include "t-common.h" - #define N_TESTS 18 - -+static int in_fips_mode = 0; - - static void - print_mpi (const char *text, gcry_mpi_t a) -@@ -188,7 +189,17 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, - xfree (buffer); - buffer = NULL; - -- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) -+ err = gcry_pk_encrypt (&s_result, s_data, s_pk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_encrypt failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -281,7 +292,17 @@ test_cv_x25519 (int testno, const char *k_str, const char *u_str, - goto leave; - } - -- if ((err = gcry_ecc_mul_point (algo, result, scalar, point))) -+ err = gcry_ecc_mul_point (algo, result, scalar, point); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_ecc_mul_point failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -335,6 +356,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) - info ("Running test %d: iteration=%d\n", testno, iter); - - gcry_mpi_ec_new (&ctx, NULL, "Curve25519"); -+ if (in_fips_mode) -+ { -+ if (ctx) -+ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ return; -+ } - Q = gcry_mpi_point_new (0); - - if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 32) -@@ -640,6 +670,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - start_timer (); - check_cv25519 (); - stop_timer (); -diff --git a/tests/t-ed25519.c b/tests/t-ed25519.c -index a5271c25..567bc797 100644 ---- a/tests/t-ed25519.c -+++ b/tests/t-ed25519.c -@@ -36,6 +36,7 @@ - static int sign_with_pk; - static int no_verify; - static int custom_data_file; -+static int in_fips_mode = 0; - - - static void -@@ -271,7 +272,17 @@ one_test (int testno, const char *sk, const char *pk, - goto leave; - } - -- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) -+ err = gcry_pk_sign (&s_sig, s_msg, s_sk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); - if (debug) - show_sexp ("sig=", s_sig); -@@ -481,9 +492,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -- /* Ed25519 isn't supported in fips mode */ -- if (gcry_fips_mode_active()) -- return 77; -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - - start_timer (); - check_ed25519 (fname); -diff --git a/tests/t-ed448.c b/tests/t-ed448.c -index 1f445ffc..f38cd10c 100644 ---- a/tests/t-ed448.c -+++ b/tests/t-ed448.c -@@ -36,6 +36,7 @@ - static int sign_with_pk; - static int no_verify; - static int custom_data_file; -+static int in_fips_mode = 0; - - - static void -@@ -302,7 +303,17 @@ one_test (int testno, int ph, const char *sk, const char *pk, - } - } - -- if ((err = gcry_pk_sign (&s_sig, s_msg, s_sk))) -+ err = gcry_pk_sign (&s_sig, s_msg, s_sk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_sign is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_pk_sign failed for test %d: %s", testno, gpg_strerror (err)); - if (debug) - show_sexp ("sig=", s_sig); -@@ -521,9 +532,8 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -- /* Ed448 isn't supported in fips mode */ -- if (gcry_fips_mode_active()) -- return 77; -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - - start_timer (); - check_ed448 (fname); -diff --git a/tests/t-x448.c b/tests/t-x448.c -index 5c3cbeb9..cc4b10fc 100644 ---- a/tests/t-x448.c -+++ b/tests/t-x448.c -@@ -34,6 +34,7 @@ - #include "t-common.h" - #define N_TESTS 9 - -+static int in_fips_mode = 0; - - static void - print_mpi (const char *text, gcry_mpi_t a) -@@ -179,8 +180,18 @@ test_cv_hl (int testno, const char *k_str, const char *u_str, - xfree (buffer); - buffer = NULL; - -- if ((err = gcry_pk_encrypt (&s_result, s_data, s_pk))) -- fail ("gcry_pk_encrypt failed for test %d: %s", testno, -+ err = gcry_pk_encrypt (&s_result, s_data, s_pk); -+ if (in_fips_mode) -+ { -+ if (!err) -+ fail ("gcry_pk_encrypt is not expected to work in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) -+ fail ("gcry_pk_encrypt goto leavefailed for test %d: %s", testno, - gpg_strerror (err)); - - s_tmp = gcry_sexp_find_token (s_result, "s", 0); -@@ -257,7 +268,17 @@ test_cv_x448 (int testno, const char *k_str, const char *u_str, - goto leave; - } - -- if ((err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point))) -+ err = gcry_ecc_mul_point (GCRY_ECC_CURVE448, result, scalar, point); -+ if (in_fips_mode) -+ { -+ if (err != GPG_ERR_NOT_SUPPORTED) -+ fail ("gcry_ecc_mul_point is not expected to work in FIPS mode for test %d: %s", -+ testno, gpg_strerror (err)); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ goto leave; -+ } -+ if (err) - fail ("gcry_ecc_mul_point failed for test %d: %s", testno, - gpg_strerror (err)); - -@@ -296,7 +317,7 @@ test_cv (int testno, const char *k_str, const char *u_str, - static void - test_it (int testno, const char *k_str, int iter, const char *result_str) - { -- gcry_ctx_t ctx; -+ gcry_ctx_t ctx = NULL; - gpg_error_t err; - void *buffer = NULL; - size_t buflen; -@@ -311,6 +332,15 @@ test_it (int testno, const char *k_str, int iter, const char *result_str) - info ("Running test %d: iteration=%d\n", testno, iter); - - gcry_mpi_ec_new (&ctx, NULL, "X448"); -+ if (in_fips_mode) -+ { -+ if (ctx) -+ fail ("gcry_mpi_ec_new should fail in FIPS mode for test %d", -+ testno); -+ if (verbose > 1) -+ info ("not executed in FIPS mode\n"); -+ return; -+ } - Q = gcry_mpi_point_new (0); - - if (!(buffer = hex2buffer (k_str, &buflen)) || buflen != 56) -@@ -583,6 +613,9 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - start_timer (); - check_x448 (); - stop_timer (); --- -2.31.1 - - -From d3a603cd4a0ff2a8df35f5bb39efd64c52b2b2c5 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 10:11:42 +0200 -Subject: [PATCH 5/8] tests: Expect the 192b ECDSA tests to fail in fips mode - -* tests/dsa-rfc6979.c (check_dsa_rfc6979): Expect ECDSA 192b keys to - fail in FIPS mode. - (main): Detect FIPS mode. --- -The 192b ECDSA curve is not FIPS approved so it does not work. This adds -a flag to the list of the keys to mark if it is expected to work in FIPS -mode. - -Signed-off-by: Jakub Jelen ---- - tests/dsa-rfc6979.c | 24 +++++++++++++++++------- - 1 file changed, 17 insertions(+), 7 deletions(-) - -diff --git a/tests/dsa-rfc6979.c b/tests/dsa-rfc6979.c -index 7d3d2080..0f124575 100644 ---- a/tests/dsa-rfc6979.c -+++ b/tests/dsa-rfc6979.c -@@ -33,6 +33,7 @@ - #define PGM "dsa-rfc6979" - #include "t-common.h" - -+static int in_fips_mode = 0; - - static void - show_sexp (const char *prefix, gcry_sexp_t a) -@@ -111,6 +112,7 @@ check_dsa_rfc6979 (void) - static struct { - const char *name; - const char *key; -+ int fips; - } keys[] = { - { - "DSA, 1024 bits", -@@ -130,7 +132,7 @@ check_dsa_rfc6979 (void) - " 92195A38B90523E2542EE61871C0440CB87C322FC4B4D2EC5E1E7EC766E1BE8D" - " 4CE935437DC11C3C8FD426338933EBFE739CB3465F4D3668C5E473508253B1E6" - " 82F65CBDC4FAE93C2EA212390E54905A86E2223170B44EAA7DA5DD9FFCFB7F3B#)" -- " ))" -+ " ))", 1 - }, - { - "DSA, 2048 bits", -@@ -162,7 +164,7 @@ check_dsa_rfc6979 (void) - " 687972A2D382599C9BAC4E0ED7998193078913032558134976410B89D2C171D1" - " 23AC35FD977219597AA7D15C1A9A428E59194F75C721EBCBCFAE44696A499AFA" - " 74E04299F132026601638CB87AB79190D4A0986315DA8EEC6561C938996BEADF#)" -- " ))" -+ " ))", 1 - }, - { - "ECDSA, 192 bits (prime field)", -@@ -172,7 +174,7 @@ check_dsa_rfc6979 (void) - " (q #04AC2C77F529F91689FEA0EA5EFEC7F210D8EEA0B9E047ED56" - " 3BC723E57670BD4887EBC732C523063D0A7C957BC97C1C43#)" - " (d #6FAB034934E4C0FC9AE67F5B5659A9D7D1FEFD187EE09FD4#)" -- " ))" -+ " ))", 0 - }, - { - "ECDSA, 224 bits (prime field)", -@@ -183,7 +185,7 @@ check_dsa_rfc6979 (void) - " 00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C" - " EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A#)" - " (d #F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1#)" -- " ))" -+ " ))", 1 - }, - { - "ECDSA, 256 bits (prime field)", -@@ -194,7 +196,7 @@ check_dsa_rfc6979 (void) - " 60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6" - " 7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299#)" - " (d #C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721#)" -- " ))" -+ " ))", 1 - }, - { - "ECDSA, 384 bits (prime field)", -@@ -208,7 +210,7 @@ check_dsa_rfc6979 (void) - " 288B231C3AE0D4FE7344FD2533264720#)" - " (d #6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D8" - " 96D5724E4C70A825F872C9EA60D2EDF5#)" -- " ))" -+ " ))", 1 - }, - { - "ECDSA, 521 bits (prime field)", -@@ -225,7 +227,7 @@ check_dsa_rfc6979 (void) - " (d #FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75" - " CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B8" - " 3538#)" -- " ))" -+ " ))", 1 - }, - { NULL } - }; -@@ -937,6 +939,12 @@ check_dsa_rfc6979 (void) - die ("building data sexp failed: %s\n", gpg_strerror (err)); - - err = gcry_pk_sign (&sig, data, seckey); -+ if (in_fips_mode && !keys[i].fips) -+ { -+ if (!err) -+ fail ("signing should not work in FIPS mode: %s\n", gpg_strerror (err)); -+ continue; -+ } - if (err) - fail ("signing failed: %s\n", gpg_strerror (err)); - -@@ -972,6 +980,8 @@ main (int argc, char **argv) - die ("version mismatch; pgm=%s, library=%s\n", - GCRYPT_VERSION,gcry_check_version (NULL)); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - if (debug) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u, 0)); - /* No valuable keys are create, so we can speed up our RNG. */ --- -2.31.1 - - -From d4a52861e7d0d1871f4c1d32bc0815f0824eb9ab Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 10:32:33 +0200 -Subject: [PATCH 6/8] tests: Skip secmem overflow test in FIPS mode - -* tests/t-secmem.c (main): Skip overflow tests in FIPS mode because they - are fatal and there is no way to override the outofcore handler. --- - -Signed-off-by: Jakub Jelen ---- - tests/t-secmem.c | 7 ++++++- - 1 file changed, 6 insertions(+), 1 deletion(-) - -diff --git a/tests/t-secmem.c b/tests/t-secmem.c -index 2b769134..692c0f1a 100644 ---- a/tests/t-secmem.c -+++ b/tests/t-secmem.c -@@ -37,6 +37,7 @@ - #define MINIMUM_POOL_SIZE 16384 - static size_t pool_size; - static size_t chunk_size; -+static int in_fips_mode = 0; - - static void - test_secmem (void) -@@ -182,8 +183,11 @@ main (int argc, char **argv) - xgcry_control ((GCRYCTL_SET_DEBUG_FLAGS, 1u , 0)); - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - xgcry_control ((GCRYCTL_INIT_SECMEM, pool_size, 0)); -+ /* This is ignored in FIPS Mode */ - gcry_set_outofcore_handler (outofcore_handler, NULL); - xgcry_control ((GCRYCTL_INITIALIZATION_FINISHED, 0)); -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; - - /* Libgcrypt prints a warning when the first overflow is allocated; - * we do not want to see that. */ -@@ -192,7 +196,8 @@ main (int argc, char **argv) - - - test_secmem (); -- test_secmem_overflow (); -+ if (!in_fips_mode) -+ test_secmem_overflow (); - /* FIXME: We need to improve the tests, for example by registering - * our own log handler and comparing the output of - * PRIV_CTL_DUMP_SECMEM_STATS to expected pattern. */ --- -2.31.1 - - -From fc6de9c7b48ab45deb8ea84d1c768e4f056edb08 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 10:52:00 +0200 -Subject: [PATCH 7/8] tests: Transient DSA keys work in FIPS mode - -* tests/pubkey.c (check_run): Enable tests with DSA transient keys which - work in FIPS. --- - -Signed-off-by: Jakub Jelen ---- - tests/pubkey.c | 15 ++++++--------- - 1 file changed, 6 insertions(+), 9 deletions(-) - -diff --git a/tests/pubkey.c b/tests/pubkey.c -index 754952ee..cd51e0a2 100644 ---- a/tests/pubkey.c -+++ b/tests/pubkey.c -@@ -680,15 +680,12 @@ check_run (void) - gcry_sexp_release (pkey); - gcry_sexp_release (skey); - -- if (!gcry_fips_mode_active ()) -- { -- if (verbose) -- fprintf (stderr, "Generating transient DSA key.\n"); -- get_dsa_key_new (&pkey, &skey, 1); -- /* Fixme: Add a check function for DSA keys. */ -- gcry_sexp_release (pkey); -- gcry_sexp_release (skey); -- } -+ if (verbose) -+ fprintf (stderr, "Generating transient DSA key.\n"); -+ get_dsa_key_new (&pkey, &skey, 1); -+ /* Fixme: Add a check function for DSA keys. */ -+ gcry_sexp_release (pkey); -+ gcry_sexp_release (skey); - - if (verbose) - fprintf (stderr, "Generating DSA key (FIPS 186).\n"); --- -2.31.1 - - -From e68b538008063938b9b054f18e56e9f27bb3a720 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Tue, 13 Jul 2021 10:53:13 +0200 -Subject: [PATCH 8/8] tests: Generating DSA from domain should fail in FIPS - mode - -* tests/pubkey.c (get_dsa_key_with_domain_new): Expect failure in FIPS - mode - (check_x931_derived_key): Simplify testing for FIPS mode. - (main): Check for fips mode. --- - -Signed-off-by: Jakub Jelen ---- - tests/pubkey.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/tests/pubkey.c b/tests/pubkey.c -index cd51e0a2..7209f44e 100644 ---- a/tests/pubkey.c -+++ b/tests/pubkey.c -@@ -29,6 +29,7 @@ - #define PGM "pubkey" - #include "t-common.h" - -+static int in_fips_mode; - - /* Sample RSA keys, taken from basic.c. */ - -@@ -518,6 +519,14 @@ get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) - die ("error creating S-expression: %s\n", gcry_strerror (rc)); - rc = gcry_pk_genkey (&key, key_spec); - gcry_sexp_release (key_spec); -+ if (in_fips_mode) -+ { -+ if (!rc) -+ die ("generating DSA key should fail in FIPS mode: %s\n", gcry_strerror (rc)); -+ *pkey = NULL; -+ *skey = NULL; -+ return; -+ } - if (rc) - die ("error generating DSA key: %s\n", gcry_strerror (rc)); - -@@ -899,7 +908,7 @@ check_x931_derived_key (int what) - err = _gcry_pk_util_get_nbits(key_spec, &nbits); - if (err) - die ("nbits not found\n"); -- if (gcry_fips_mode_active() && nbits < 2048) -+ if (in_fips_mode && nbits < 2048) - { - info("RSA key test with %d bits skipped in fips mode\n", nbits); - goto leave; -@@ -1186,6 +1195,9 @@ main (int argc, char **argv) - /* No valuable keys are create, so we can speed up our RNG. */ - xgcry_control ((GCRYCTL_ENABLE_QUICK_RANDOM, 0)); - -+ if (gcry_fips_mode_active ()) -+ in_fips_mode = 1; -+ - for (i=0; i < 2; i++) - check_run (); - -@@ -1193,7 +1205,7 @@ main (int argc, char **argv) - check_x931_derived_key (i); - - check_ecc_sample_key (); -- if (!gcry_fips_mode_active ()) -+ if (!in_fips_mode) - check_ed25519ecdsa_sample_key (); - - return !!error_count; --- -2.31.1 - -commit 61c87070abc4baeb9d847db015e6a3031f349483 -Author: NIIBE Yutaka -Date: Wed Jul 7 15:52:06 2021 +0900 - - tests: Skip unavailable ciphers in FIPS mode. - - * tests/basic.c (_check_poly1305_cipher): - (check_ocb_cipher_largebuf_split): Skip unavailable ciphers when - IN_FIPS_MODE. - (check_ocb_cipher_checksum, check_gost28147_cipher_basic): Likewise. - - -- - - GnuPG-bug-id: 5520 - Signed-off-by: NIIBE Yutaka - -diff --git a/tests/basic.c b/tests/basic.c -index 0a1e8293..43ef122e 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -5026,6 +5026,14 @@ _check_poly1305_cipher (unsigned int step) - - for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) - { -+ if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ tv[i].algo); -+ continue; -+ } -+ - if (verbose) - fprintf (stderr, " checking POLY1305 mode for %s [%i]\n", - gcry_cipher_algo_name (tv[i].algo), -@@ -6643,6 +6651,14 @@ check_ocb_cipher_largebuf_split (int algo, int keylen, const char *tagexpect, - memcpy(inbuf + i, hash, 16); - } - -+ if (gcry_cipher_test_algo (algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ algo); -+ goto out_free; -+ } -+ - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hdd, algo, GCRY_CIPHER_MODE_OCB, 0); -@@ -6841,6 +6857,14 @@ check_ocb_cipher_checksum (int algo, int keylen) - blk[byteidx] |= 1 << bitpos; - } - -+ if (gcry_cipher_test_algo (algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ algo); -+ goto out_free; -+ } -+ - err = gcry_cipher_open (&hde, algo, GCRY_CIPHER_MODE_OCB, 0); - if (!err) - err = gcry_cipher_open (&hde2, algo, GCRY_CIPHER_MODE_OCB, 0); -@@ -7651,6 +7675,15 @@ check_gost28147_cipher_basic (enum gcry_cipher_algos algo) - - if (verbose) - fprintf (stderr, " Starting GOST28147 cipher checks.\n"); -+ -+ if (gcry_cipher_test_algo (algo) && in_fips_mode) -+ { -+ if (verbose) -+ fprintf (stderr, " algorithm %d not available in fips mode\n", -+ algo); -+ return; -+ } -+ - keylen = gcry_cipher_get_algo_keylen(algo); - if (!keylen) - { -commit b98ca3f798abd17696f52163665204c4e83d9092 -Author: Jussi Kivilinna -Date: Wed Jul 7 18:21:27 2021 +0300 - - tests/basic: use SHA256 instead of RMD160 for SHAKE extract testing - - * tests/basic.c (check_one_md): Use GCRY_MD_SHA256 as 'crcalgo' for - SHAKE128/SHAKE256 testing. - -- - - RMD160 was used to calculate output checksum from two SHAKE extract - streams, which are run with different extract buffer size but for - same total length and with same input. Patch switches to use SHA256 - for checksumming for FIPS support. - - GnuPG-bug-id: 5520 - Signed-off-by: Jussi Kivilinna - -diff --git a/tests/basic.c b/tests/basic.c -index bc34bb99..eb6d1514 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -10395,7 +10395,7 @@ check_one_md (int algo, const char *data, int len, const char *expect, int elen, - - if (*data == '!' && !data[1]) - { -- int crcalgo = GCRY_MD_RMD160; -+ int crcalgo = GCRY_MD_SHA256; - gcry_md_hd_t crc1, crc2; - size_t startlen; - size_t piecelen; -commit ccb076e8aabb9c49e7026258b3a36a8422f6bbe4 -Author: NIIBE Yutaka -Date: Wed Jul 7 16:29:48 2021 +0900 - - tests: Fix tests/basic.c for FIPS mode. - - * tests/basic.c (main): Use bare gcry_control for - GCRYCTL_FORCE_FIPS_MODE. - - -- - - GnuPG-bug-id: 5520 - Signed-off-by: NIIBE Yutaka - -diff --git a/tests/basic.c b/tests/basic.c -index 43ef122e..bc34bb99 100644 ---- a/tests/basic.c -+++ b/tests/basic.c -@@ -14610,7 +14610,7 @@ main (int argc, char **argv) - gcry_md_hd_t md; - - /* First trigger a self-test. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); -+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("not in operational state after self-test\n"); - -@@ -14639,7 +14639,7 @@ main (int argc, char **argv) - { - /* Now run a self-test and to get back into - operational state. */ -- xgcry_control ((GCRYCTL_FORCE_FIPS_MODE, 0)); -+ gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); - if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) - fail ("did not reach operational after error " - "and self-test\n"); diff --git a/libgcrypt.spec b/libgcrypt.spec index 9880c7f..d657930 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,46 +1,11 @@ Name: libgcrypt -Version: 1.9.4 -Release: 2%{?dist} +Version: 1.10.0 +Release: 1%{?dist} URL: https://www.gnupg.org/ -Source0: libgcrypt-%{version}-hobbled.tar.xz -# The original libgcrypt sources now contain potentially patented ECC -# cipher support. We have to remove it in the tarball we ship with -# the hobble-libgcrypt script. -# (We replace it with RH approved ECC in Source4-5) -# rm -rf libgcrypt-x.y.z # make sure there are no leftover files -# tar -xf libgcrypt-x.y.z.tar.bz2 -# pushd libgcrypt-x.y.z && ../hobble-libgcrypt && popd -# tar -cvJf libgcrypt-x.y.z-hobbled.tar.xz libgcrypt-x.y.z -#Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2 -#Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-{version}.tar.bz2.sig +Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 +Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com -Source3: hobble-libgcrypt -# Approved ECC support -Source4: ecc-curves.c -Source5: curves.c -Source7: random.conf -Source8: keygrip.c -# make FIPS hmac compatible with fipscheck - non upstreamable -# update on soname bump -Patch2: libgcrypt-1.8.5-use-fipscheck.patch -# modify FIPS RSA and DSA keygen to comply with requirements -Patch5: libgcrypt-1.8.4-fips-keygen.patch -# fix the tests to work correctly in the FIPS mode -Patch6: libgcrypt-1.9.3-fips-tests.patch -# use poll instead of select when gathering randomness -Patch11: libgcrypt-1.8.4-use-poll.patch -# slight optimalization of mpicoder.c to silence Valgrind (#968288) -Patch13: libgcrypt-1.6.1-mpicoder-gccopt.patch -# Run the FIPS mode initialization in the shared library constructor -Patch18: libgcrypt-1.8.3-fips-ctor.patch -# Do not try to open /dev/urandom if getrandom() works -Patch24: libgcrypt-1.8.5-getrandom.patch -# Disable non-approved FIPS hashes in the enforced FIPS mode -Patch27: libgcrypt-1.8.3-md-fips-enforce.patch -# Missing Intel CET support in the library (#1954049) -Patch28: libgcrypt-1.8.5-intel-cet.patch -# FIPS module is redefined a little bit (implicit by kernel FIPS mode) -Patch30: libgcrypt-1.8.5-fips-module.patch +Patch1: libgcrypt-1.10.0-disable-brainpool.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -76,20 +41,7 @@ applications using libgcrypt. %prep %setup -q -%{SOURCE3} -%patch2 -p1 -b .use-fipscheck -%patch5 -p1 -b .fips-keygen -%patch6 -p1 -b .tests-fipsmode -%patch11 -p1 -b .use-poll -%patch13 -p1 -b .gccopt -%patch18 -p1 -b .fips-ctor -%patch24 -p1 -b .getrandom -%patch27 -p1 -b .fips-enforce -%patch28 -p1 -b .intel-cet -%patch30 -p1 -b .fips-module - -cp %{SOURCE4} cipher/ -cp %{SOURCE5} %{SOURCE8} tests/ +%patch1 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -101,29 +53,48 @@ cp %{SOURCE5} %{SOURCE8} tests/ # F34, so we use it here explicitly %define _lto_cflags -flto=auto -ffat-lto-objects +grep "Red Hat" /etc/system-release && \ +export FIPS_SWITCH="--with-fips-module-version=RHEL%{?rhel}-%{name}-%{version}-$(date +%Y%m%d)" +grep "Fedora" /etc/system-release && \ +export FIPS_SWITCH="--with-fips-module-version=Fedora%{?fedora}-%{name}-%{version}-$(date +%Y%m%d)" +grep "CentOS" /etc/system-release && \ +export FIPS_SWITCH="--with-fips-module-version=CentOS%{?centos}-%{name}-%{version}-$(date +%Y%m%d)" + +# should be all algorithms except SM3 and SM4 +export DIGESTS='crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2' +export CIPHERS='arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20' + autoreconf -f %configure --disable-static \ %ifarch sparc64 --disable-asm \ %endif --enable-noexecstack \ - --enable-hmac-binary-check \ - --enable-pubkey-ciphers='dsa elgamal rsa ecc' \ - --disable-O-flag-munging + --enable-hmac-binary-check=%{hmackey} \ + --disable-brainpool \ + --enable-digests="$DIGESTS" \ + --enable-ciphers="$CIPHERS" \ + $FIPS_SWITCH sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool %make_build %check -src/hmac256 %{hmackey} src/.libs/%{gcrysoname} | cut -f1 -d ' ' >src/.libs/.%{gcrysoname}.hmac - make check +# try in faked FIPS mode too +LIBGCRYPT_FORCE_FIPS_MODE=1 make check # Add generation of HMAC checksums of the final stripped binaries +%define libpath $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname}.?.? %define __spec_install_post \ %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ %{__os_install_post} \ - src/hmac256 %{hmackey} $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname} | cut -f1 -d ' ' >$RPM_BUILD_ROOT%{gcrylibdir}/.%{gcrysoname}.hmac \ + dd if=/dev/zero of=%{libpath}.hmac bs=32 count=1 \ + objcopy --update-section .rodata1=%{libpath}.hmac %{libpath} %{libpath}.empty \ + src/hmac256 --binary %{hmackey} %{libpath}.empty > %{libpath}.hmac \ + objcopy --update-section .rodata1=%{libpath}.hmac %{libpath}.empty %{libpath}.new \ + mv -f %{libpath}.new %{libpath} \ + rm -f %{libpath}.hmac %{libpath}.empty %{nil} %install @@ -168,16 +139,13 @@ popd # Create /etc/gcrypt (hardwired, not dependent on the configure invocation) so # that _someone_ owns it. mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt -install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %ldconfig_scriptlets %files %dir /etc/gcrypt -%config(noreplace) /etc/gcrypt/random.conf %{gcrylibdir}/libgcrypt.so.*.* %{gcrylibdir}/%{gcrysoname} -%{gcrylibdir}/.%{gcrysoname}.hmac %license COPYING.LIB %doc AUTHORS NEWS THANKS @@ -196,6 +164,9 @@ install -m644 %{SOURCE7} $RPM_BUILD_ROOT/etc/gcrypt/random.conf %license COPYING %changelog +* Wed Feb 02 2022 Jakub Jelen - 1.10.0-1 +- New upstream release (#2049322) + * Thu Jan 20 2022 Fedora Release Engineering - 1.9.4-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_36_Mass_Rebuild diff --git a/random.conf b/random.conf deleted file mode 100644 index 6041bcd..0000000 --- a/random.conf +++ /dev/null @@ -1,4 +0,0 @@ -# use only /dev/urandom - see https://www.2uo.de/myths-about-urandom/ -only-urandom -# Keep jitter entropy generator enabled (should do no harm) -#disable-jent diff --git a/sources b/sources index 8d0f1cb..745f52b 100644 --- a/sources +++ b/sources @@ -1 +1,2 @@ -SHA512 (libgcrypt-1.9.4-hobbled.tar.xz) = 80b1b2159ec3c7795450037d76d81b737f2734f1cff72c8aa6ac8c1a5654ece4fce0aabfbed0cce99d123747831db135df0d040f67081052cb2363bf52f5d4e6 +SHA512 (libgcrypt-1.10.0.tar.bz2) = 785c2e14272308956bb6adcea9567c4097edf103122e18cd3907fb42a110a48a5d59c0057f05a438acd7f221c70c7f7ff87e176bd6d7ed99d16e847f9d7be087 +SHA512 (libgcrypt-1.10.0.tar.bz2.sig) = 75201612225b206faaae284297e92d1b25dcaf0665bcf1f4c5cc9a3a750a803063d0f7bd0af556dbe419f1276c953ce047554fd18a144a90085a42a7ec885168 From 559b903aa2608fd74b66a1e9bc994b725d0e0400 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 2 Feb 2022 13:13:00 +0100 Subject: [PATCH 46/88] Update test to work again --- tests/smoke-test/Makefile | 10 +++- tests/smoke-test/runtest.sh | 106 +++++++++++++++++++++++++++++++----- 2 files changed, 100 insertions(+), 16 deletions(-) diff --git a/tests/smoke-test/Makefile b/tests/smoke-test/Makefile index 0e0dda3..0682152 100644 --- a/tests/smoke-test/Makefile +++ b/tests/smoke-test/Makefile @@ -57,10 +57,14 @@ $(METADATA): Makefile @echo "Requires: libgcrypt" >> $(METADATA) @echo "Requires: nfs-utils" >> $(METADATA) @echo "Requires: rpm-build" >> $(METADATA) + @echo "Requires: autoconf automake libtool" >> $(METADATA) @echo "Requires: gawk" >> $(METADATA) - @echo "Requires: gcc-c++ fipscheck" >> $(METADATA) - @echo "Requires: libgpg-error-devel wget" >> $(METADATA) - @echo "Requires: pkgconfig texinfo libselinux-utils" >> $(METADATA) + @echo "Requires: gcc-c++" >> $(METADATA) + @echo "Requires: libgpg-error-devel" >> $(METADATA) + @echo "Requires: pkgconfig texinfo fipscheck libkcapi-fipscheck" >> $(METADATA) + @echo "Requires: crypto-policies-scripts" >> $(METADATA) + @echo "Requires: bc" >> $(METADATA) + @echo "RhtsRequires: library(distribution/fips)" >> $(METADATA) @echo "Releases: -RHEL3 -RHEL4" >> $(METADATA) @echo "Priority: Normal" >> $(METADATA) @echo "Architectures: i386 x86_64 s390x ia64" >> $(METADATA) diff --git a/tests/smoke-test/runtest.sh b/tests/smoke-test/runtest.sh index dd1803d..ddd0182 100755 --- a/tests/smoke-test/runtest.sh +++ b/tests/smoke-test/runtest.sh @@ -26,8 +26,6 @@ # # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -# Include rhts environment -#. /usr/bin/rhts-environment.sh . /usr/share/beakerlib/beakerlib.sh PACKAGE="libgcrypt" @@ -35,36 +33,118 @@ PACKAGE="libgcrypt" rlJournalStart rlPhaseStartSetup + rlImport distribution/fips || rlFail "FIPS library needed for some phases" TmpDir=`mktemp -d` rlAssertRpm $PACKAGE - rlFileBackup --clean "/etc/gcrypt/fips_enabled" + rlRun "rlFileBackup --clean /etc/gcrypt/fips_enabled" + if [[ -r /etc/gcrypt/hwf.deny ]]; then + rlRun "rlFileBackup /etc/gcrypt/hwf.deny" + rlRun "rm -f /etc/gcrypt/hwf.deny" + fi rlRun "pushd $TmpDir" 0 - rlFetchSrcForInstalled $PACKAGE + rlRun "rlFetchSrcForInstalled $PACKAGE" rlRun "rpm -ihv `ls *.rpm`" 0 if grep '1' /proc/sys/crypto/fips_enabled; then rlRun "echo '1' > /etc/gcrypt/fips_enabled" 0 fi rlPhaseEnd - rlPhaseStartTest + rlPhaseStartTest "Package build" TOPDIR=`rpm --eval %_topdir` rlRun "pushd $TOPDIR" 0 rlRun "rm -rf BUILD/libgcrypt-*" 0-255 rlRun "rpmbuild -vv -bc SPECS/libgcrypt.spec" 0 rlRun "pushd BUILD/libgcrypt-*" 0 rlRun "fipshmac src/.libs/libgcrypt.so.??" 0 - rlRun "make check > $TmpDir/make_check.out" 0 - rlRun "popd" 0 - rlRun "popd" 0 - rlRun "grep \"All [0-9]\+ tests passed\" $TmpDir/make_check.out" 0 \ - "All tests passed" - rlRun "cat $TmpDir/make_check.out" 0 + rlRun "popd" + rlRun "popd" rlPhaseEnd + rlPhaseStartTest "Upstream testsuite" + rlRun "pushd $TOPDIR/BUILD/libgcrypt-*" 0 + exp_fails=() + if [[ $fipsMode = 'enabled' ]]; then + if rlIsFedora 33; then + exp_fails+=("basic") + exp_fails+=("basic-disable-all-hwf") + exp_fails+=("t-kdf") + exp_fails+=("t-secmem") + elif rlIsFedora 34; then + exp_fails+=("basic") + exp_fails+=("basic-disable-all-hwf") + exp_fails+=("t-kdf") + exp_fails+=("t-secmem") + exp_fails+=("t-x448") + elif rlIsFedora 35; then # Fedora-35 + exp_fails+=("curves") + fi + fi + rlRun "echo 'Expecting ${#exp_fails[@]} fails'" + exp_exitcode=0 + if [[ ${#exp_fails[@]} -gt 0 ]]; then exp_exitcode=2; fi + rlRun "make check &> $TmpDir/make_check.out" $exp_exitcode + rlRun "grep ^FAIL: $TmpDir/make_check.out" 0,1 "Print fails" + if [[ ${#exp_fails[@]} -gt 0 ]]; then + for f in "${exp_fails[@]}"; do + rlAssertGrep "^FAIL: $f\$" $TmpDir/make_check.out + done + [[ $(grep -c '^FAIL:' $TmpDir/make_check.out) -eq ${#exp_fails[@]} ]] || rlFail "Unexpected fails present" + else + rlRun "grep \"All [0-9]\+ tests passed\" $TmpDir/make_check.out" 0 \ + "All tests passed" + fi + rlRun "cat $TmpDir/make_check.out" + rlRun "popd" + rlPhaseEnd + + if ! (rlIsRHEL '<=8.4' || ([[ $fipsMode = "enabled" ]] && rlIsFedora '<37')); then + # (we are ~expecting to fix HW optimization problem around Fedora-37) + rlPhaseStartTest "Performance with HW optimizations disabled - bz1990059" + # we are gathering more samples, so that this test is robust in shared environments + N_SAMPLES=5 + N_MEDIAN=$(echo "$N_SAMPLES/2+1" |bc) + HWF_DENY_FILE="/etc/gcrypt/hwf.deny" + # Disabling via cmdline arguments would need either handpicking + # all the algorithms (variant with ":"), or making "all" work. + # "--disable-hwf all" does not work: https://dev.gnupg.org/T5636 + #dis_arg="--disable-hwf all" + dis_arg="" + + for x in "cipher:aes256:CBC enc" "hash:sha256:SHA256" "mac:hmac_sha256:HMAC_SHA256"; do + alg_type=$(echo $x |cut -d: -f1) + algorithm=$(echo $x |cut -d: -f2) + alg_line=$(echo $x |cut -d: -f3) + rlRun "rm -f $algorithm.ena $algorithm.dis" + rlLogInfo "Performance measurements started ..." + for i in `seq 1 $N_SAMPLES`; do + # run with HW optimizations ENAbled + rm -f $HWF_DENY_FILE + $TOPDIR/BUILD/libgcrypt-*/tests/bench-slope $alg_type $algorithm |grep "$alg_line" >>$algorithm.ena + + # run with HW optimizations DISabled + # this looks idiotic, but I wasn't able to make --disable-hwf work + echo "all" >$HWF_DENY_FILE + $TOPDIR/BUILD/libgcrypt-*/tests/bench-slope $dis_arg $alg_type $algorithm |grep "$alg_line" >>$algorithm.dis + done + rlLogInfo "Performance measurements finished" + rlRun "cat $algorithm.ena" + rlRun "cat $algorithm.dis" + dis=$(cat $algorithm.dis |cut -d'|' -f2 |awk '{ print $1 }' |sort -n |sed -n "$N_MEDIAN p") + ena=$(cat $algorithm.ena |cut -d'|' -f2 |awk '{ print $1 }' |sort -n |sed -n "$N_MEDIAN p") + rlRun "echo '$algorithm Time: disabled $dis enabled $ena'" + if (( $(echo "$dis > $ena" |bc -l) )); then + rlPass "HW optimizations work for $algorithm" + else + rlFail "HW optimizations DO NOT work for $algorithm" + fi + done + rlPhaseEnd + fi + rlPhaseStartCleanup - rlRun "popd" 0 + rlRun "popd" rlRun "rm -r $TmpDir" 0 - rlFileRestore + rlRun "rlFileRestore" rlPhaseEnd rlJournalPrintText From 0b1d9d2b6db97065449fd6f7fcf94703127ba813 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Mar 2022 11:18:05 +0200 Subject: [PATCH 47/88] libgcrypt-1.10.1-1 --- .gitignore | 2 + libgcrypt-1.10.0-disable-brainpool.patch | 91 +++++++++++++++++++++--- libgcrypt.spec | 9 ++- sources | 4 +- 4 files changed, 93 insertions(+), 13 deletions(-) diff --git a/.gitignore b/.gitignore index 1bb23eb..5380134 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.9.4-hobbled.tar.xz /libgcrypt-1.10.0.tar.bz2 /libgcrypt-1.10.0.tar.bz2.sig +/libgcrypt-1.10.1.tar.bz2 +/libgcrypt-1.10.1.tar.bz2.sig diff --git a/libgcrypt-1.10.0-disable-brainpool.patch b/libgcrypt-1.10.0-disable-brainpool.patch index f0c5a72..f341efc 100644 --- a/libgcrypt-1.10.0-disable-brainpool.patch +++ b/libgcrypt-1.10.0-disable-brainpool.patch @@ -1,4 +1,4 @@ -From d651e25be0bc0c11f4d3d7c72be8cfbbe82b3874 Mon Sep 17 00:00:00 2001 +From f778433dd29fe07aa1791a0137f6f14febcce607 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 10 Sep 2021 18:39:00 +0200 Subject: [PATCH] Allow building libgcrypt without Brainpool curves @@ -8,6 +8,7 @@ Subject: [PATCH] Allow building libgcrypt without Brainpool curves * configure.ac: Implement possibility to build without brainpool curves * tests/curves.c: Skip brainpool curves if they are not built-in * tests/keygrip.c: Skip brainpool curves if they are not built-in +* tests/bench-slope.c: Skip brainpoll curves in they are not built-in -- @@ -16,15 +17,16 @@ Signed-off-by: Jakub Jelen README | 3 +++ cipher/ecc-curves.c | 4 ++++ configure.ac | 13 +++++++++++++ + tests/bench-slope.c | 12 ++++++++++++ tests/curves.c | 46 ++++++++++++++++++++++++++++++--------------- tests/keygrip.c | 2 ++ - 5 files changed, 53 insertions(+), 15 deletions(-) + 6 files changed, 65 insertions(+), 15 deletions(-) diff --git a/README b/README -index 436b6cd4..1044109c 100644 +index 4d7697dd..b290d01e 100644 --- a/README +++ b/README -@@ -127,6 +127,9 @@ +@@ -121,6 +121,9 @@ the list used with the current build the program tests/version may be used. @@ -71,10 +73,10 @@ index 7c86e12c..8fd95a9c 100644 "GOST2001-test", 256, 0, MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, diff --git a/configure.ac b/configure.ac -index 6efbf139..f4ac1887 100644 +index 0e67baf9..a63f7360 100644 --- a/configure.ac +++ b/configure.ac -@@ -614,6 +614,14 @@ AC_ARG_WITH(fips-module-version, +@@ -595,6 +595,14 @@ AC_ARG_WITH(fips-module-version, AC_DEFINE_UNQUOTED(FIPS_MODULE_VERSION, "$fips_module_version", [Define FIPS module version for certification]) @@ -89,7 +91,7 @@ index 6efbf139..f4ac1887 100644 # Implementation of the --disable-jent-support switch. AC_MSG_CHECKING([whether jitter entropy support is requested]) AC_ARG_ENABLE(jent-support, -@@ -2466,6 +2474,10 @@ if test x"$ppccryptosupport" = xyes ; then +@@ -2459,6 +2467,10 @@ if test x"$ppccryptosupport" = xyes ; then AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1, [Enable support for POWER 8 (PowerISA 2.07) crypto extension.]) fi @@ -100,7 +102,7 @@ index 6efbf139..f4ac1887 100644 if test x"$jentsupport" = xyes ; then AC_DEFINE(ENABLE_JENT_SUPPORT, 1, [Enable support for the jitter entropy collector.]) -@@ -3296,6 +3308,7 @@ GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) +@@ -3294,6 +3306,7 @@ GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) GCRY_MSG_WRAP([Enabled kdf algorithms: ],[$enabled_kdfs]) GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers]) GCRY_MSG_SHOW([Random number generator: ],[$random]) @@ -108,6 +110,79 @@ index 6efbf139..f4ac1887 100644 GCRY_MSG_SHOW([Try using jitter entropy: ],[$jentsupport]) GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities]) GCRY_MSG_SHOW([FIPS module version: ],[$fips_module_version]) +diff --git a/tests/bench-slope.c b/tests/bench-slope.c +index 5c49ac25..1b5941af 100644 +--- a/tests/bench-slope.c ++++ b/tests/bench-slope.c +@@ -2316,7 +2316,9 @@ enum bench_ecc_algo + ECC_ALGO_NIST_P384, + ECC_ALGO_NIST_P521, + ECC_ALGO_SECP256K1, ++#ifdef ENABLE_BRAINPOOL + ECC_ALGO_BRAINP256R1, ++#endif /* ENABLE_BRAINPOOL */ + __MAX_ECC_ALGO + }; + +@@ -2366,7 +2368,9 @@ ecc_algo_fips_allowed (int algo) + case ECC_ALGO_NIST_P521: + return 1; + case ECC_ALGO_SECP256K1: ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: ++#endif /* ENABLE_BRAINPOOL */ + case ECC_ALGO_ED25519: + case ECC_ALGO_ED448: + case ECC_ALGO_X25519: +@@ -2402,8 +2406,10 @@ ecc_algo_name (int algo) + return "NIST-P521"; + case ECC_ALGO_SECP256K1: + return "secp256k1"; ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: + return "brainpoolP256r1"; ++#endif /* ENABLE_BRAINPOOL */ + default: + return NULL; + } +@@ -2434,8 +2440,10 @@ ecc_algo_curve (int algo) + return "NIST P-521"; + case ECC_ALGO_SECP256K1: + return "secp256k1"; ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: + return "brainpoolP256r1"; ++#endif /* ENABLE_BRAINPOOL */ + default: + return NULL; + } +@@ -2466,8 +2474,10 @@ ecc_nbits (int algo) + return 521; + case ECC_ALGO_SECP256K1: + return 256; ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: + return 256; ++#endif /* ENABLE_BRAINPOOL */ + default: + return 0; + } +@@ -2665,6 +2675,7 @@ bench_ecc_init (struct bench_obj *obj) + err = gcry_sexp_build (&hd->data, NULL, + "(data (flags raw) (value %m))", x); + break; ++#ifdef ENABLE_BRAINPOOL + case ECC_ALGO_BRAINP256R1: + err = gcry_sexp_build (&hd->key_spec, NULL, + "(genkey (ECDSA (curve brainpoolP256r1)))"); +@@ -2673,6 +2684,7 @@ bench_ecc_init (struct bench_obj *obj) + err = gcry_sexp_build (&hd->data, NULL, + "(data (flags raw) (value %m))", x); + break; ++#endif /* ENABLE_BRAINPOOL */ + } + + gcry_mpi_release (x); diff --git a/tests/curves.c b/tests/curves.c index 3c738171..8eb79565 100644 --- a/tests/curves.c diff --git a/libgcrypt.spec b/libgcrypt.spec index d657930..f330028 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,5 +1,5 @@ Name: libgcrypt -Version: 1.10.0 +Version: 1.10.1 Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 @@ -90,9 +90,9 @@ LIBGCRYPT_FORCE_FIPS_MODE=1 make check %{__arch_install_post} \ %{__os_install_post} \ dd if=/dev/zero of=%{libpath}.hmac bs=32 count=1 \ - objcopy --update-section .rodata1=%{libpath}.hmac %{libpath} %{libpath}.empty \ + objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} %{libpath}.empty \ src/hmac256 --binary %{hmackey} %{libpath}.empty > %{libpath}.hmac \ - objcopy --update-section .rodata1=%{libpath}.hmac %{libpath}.empty %{libpath}.new \ + objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath}.empty %{libpath}.new \ mv -f %{libpath}.new %{libpath} \ rm -f %{libpath}.hmac %{libpath}.empty %{nil} @@ -164,6 +164,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Mar 29 2022 Jakub Jelen - 1.10.1-1 +- Final release (#2069263) + * Wed Feb 02 2022 Jakub Jelen - 1.10.0-1 - New upstream release (#2049322) diff --git a/sources b/sources index 745f52b..0021e06 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.10.0.tar.bz2) = 785c2e14272308956bb6adcea9567c4097edf103122e18cd3907fb42a110a48a5d59c0057f05a438acd7f221c70c7f7ff87e176bd6d7ed99d16e847f9d7be087 -SHA512 (libgcrypt-1.10.0.tar.bz2.sig) = 75201612225b206faaae284297e92d1b25dcaf0665bcf1f4c5cc9a3a750a803063d0f7bd0af556dbe419f1276c953ce047554fd18a144a90085a42a7ec885168 +SHA512 (libgcrypt-1.10.1.tar.bz2) = e5ca7966624fff16c3013795836a2c4377f0193dbb4ac5ad2b79654b1fa8992e17d83816569a402212dc8367a7980d4141f5d6ac282bae6b9f02186365b61f13 +SHA512 (libgcrypt-1.10.1.tar.bz2.sig) = b156ae05079776698bc95ba5a9e48e95de8f716aa1760ef4b2e7cb8518ccec660337fc7823f865bde870461800d472fd8e458d03a7095b6bb614f6dd96f796d8 From 7b71c161ddbc2b6bd4962b1fd79c9912e8240a1e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 1 Apr 2022 11:25:41 +0200 Subject: [PATCH 48/88] Sync the FIPS module name version with RHEL --- libgcrypt.spec | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index f330028..6b686a6 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -1,3 +1,19 @@ +# This is taken from gnutls.spec +%define srpmhash() %{lua: +local files = rpm.expand("%_specdir/libgcrypt.spec") +for i, p in ipairs(patches) do + files = files.." "..p +end +for i, p in ipairs(sources) do + files = files.." "..p +end +local sha256sum = assert(io.popen("cat "..files.."| sha256sum")) +local hash = sha256sum:read("*a") +sha256sum:close() +print(string.sub(hash, 0, 16)) +} + + Name: libgcrypt Version: 1.10.1 Release: 1%{?dist} @@ -53,17 +69,13 @@ applications using libgcrypt. # F34, so we use it here explicitly %define _lto_cflags -flto=auto -ffat-lto-objects -grep "Red Hat" /etc/system-release && \ -export FIPS_SWITCH="--with-fips-module-version=RHEL%{?rhel}-%{name}-%{version}-$(date +%Y%m%d)" -grep "Fedora" /etc/system-release && \ -export FIPS_SWITCH="--with-fips-module-version=Fedora%{?fedora}-%{name}-%{version}-$(date +%Y%m%d)" -grep "CentOS" /etc/system-release && \ -export FIPS_SWITCH="--with-fips-module-version=CentOS%{?centos}-%{name}-%{version}-$(date +%Y%m%d)" - # should be all algorithms except SM3 and SM4 export DIGESTS='crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2' export CIPHERS='arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20' +eval $(sed -n 's/^\(\(NAME\|VERSION_ID\)=.*\)/OS_\1/p' /etc/os-release) +export FIPS_MODULE_NAME="$OS_NAME ${OS_VERSION_ID%%.*} %name" + autoreconf -f %configure --disable-static \ %ifarch sparc64 @@ -74,7 +86,7 @@ autoreconf -f --disable-brainpool \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ - $FIPS_SWITCH + --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool %make_build From e7354685a27c2ed4481a4f632eea14fa47163662 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 8 Apr 2022 17:10:51 +0200 Subject: [PATCH 49/88] Adjust integrity check creation to match upstream (#2073018) --- libgcrypt.spec | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 6b686a6..758808f 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -101,12 +101,12 @@ LIBGCRYPT_FORCE_FIPS_MODE=1 make check %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ %{__os_install_post} \ - dd if=/dev/zero of=%{libpath}.hmac bs=32 count=1 \ - objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} %{libpath}.empty \ - src/hmac256 --binary %{hmackey} %{libpath}.empty > %{libpath}.hmac \ - objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath}.empty %{libpath}.new \ - mv -f %{libpath}.new %{libpath} \ - rm -f %{libpath}.hmac %{libpath}.empty + pushd src \ + sed -i -e 's|FILE=.*|FILE=\\\$1|' gen-note-integrity.sh \ + READELF=readelf AWK=awk ECHO_N="-n" bash gen-note-integrity.sh %{libpath} > %{libpath}.hmac \ + objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} new \ + mv -f new %{libpath} \ + rm -f %{libpath}.hmac \ %{nil} %install From 040bc4d9b98ea02e647982e915763b580253ced6 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 8 Apr 2022 17:13:08 +0200 Subject: [PATCH 50/88] 1.10.1-2 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 758808f..b129fcf 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -16,7 +16,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -176,6 +176,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Fri Apr 08 2022 Jakub Jelen - 1.10.1-2 +- Adjust integrity check creation to match upstream (#2073018) + * Tue Mar 29 2022 Jakub Jelen - 1.10.1-1 - Final release (#2069263) From 9140219786a877c450d50a9d13e2de44f7bc0927 Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Sun, 29 May 2022 17:08:50 -0400 Subject: [PATCH 51/88] improve --disable-brainpool configure output The configure output from the --disable-brainpool option is confusing: checking whether we want to disable the use of brainpool curves... no Reword the message to make it clearer and match the nearby configure checks for other `--disable-*` options: checking whether brainpool curves support is requested... no --- libgcrypt-1.10.0-disable-brainpool.patch | 2 +- libgcrypt.spec | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/libgcrypt-1.10.0-disable-brainpool.patch b/libgcrypt-1.10.0-disable-brainpool.patch index f341efc..8a9d980 100644 --- a/libgcrypt-1.10.0-disable-brainpool.patch +++ b/libgcrypt-1.10.0-disable-brainpool.patch @@ -81,7 +81,7 @@ index 0e67baf9..a63f7360 100644 [Define FIPS module version for certification]) +# Implementation of the --disable-brainpool switch. -+AC_MSG_CHECKING([whether we want to disable the use of brainpool curves]) ++AC_MSG_CHECKING([whether brainpool curves support is requested]) +AC_ARG_ENABLE(brainpool, + AS_HELP_STRING([--disable-brainpool], + [Disable the brainpool curves]), diff --git a/libgcrypt.spec b/libgcrypt.spec index b129fcf..f766487 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -16,7 +16,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -176,6 +176,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Sun May 29 2022 Todd Zullinger - 1.10.1-3 +- improve --disable-brainpool configure output + * Fri Apr 08 2022 Jakub Jelen - 1.10.1-2 - Adjust integrity check creation to match upstream (#2073018) From 6571417ff46056d7d6256bceb8e0066abe1fe961 Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Sun, 29 May 2022 15:41:22 -0400 Subject: [PATCH 52/88] use %bcond_with to disable brainpool curves The `%bcond_with` macro allows others to rebuild the package with the brainpool curves enabled by passing `--with brainpool` to `rpmbuild`. --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index f766487..5ed4f4c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -13,6 +13,8 @@ sha256sum:close() print(string.sub(hash, 0, 16)) } +# disable brainpool curves by default +%bcond_with brainpool Name: libgcrypt Version: 1.10.1 @@ -83,7 +85,7 @@ autoreconf -f %endif --enable-noexecstack \ --enable-hmac-binary-check=%{hmackey} \ - --disable-brainpool \ + %{!?with_brainpool:--disable-brainpool} \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" @@ -178,6 +180,7 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %changelog * Sun May 29 2022 Todd Zullinger - 1.10.1-3 - improve --disable-brainpool configure output +- use %%bcond_with to disable brainpool curves * Fri Apr 08 2022 Jakub Jelen - 1.10.1-2 - Adjust integrity check creation to match upstream (#2073018) From 491a0e733e7d8fe5f393c1846b247c214c8101e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Jun 2022 17:03:49 +0200 Subject: [PATCH 53/88] Fix annobin flags (#2016349) --- libgcrypt-1.10.1-annobin.patch | 22 ++++++++++++++++++++++ libgcrypt.spec | 4 ++++ 2 files changed, 26 insertions(+) create mode 100644 libgcrypt-1.10.1-annobin.patch diff --git a/libgcrypt-1.10.1-annobin.patch b/libgcrypt-1.10.1-annobin.patch new file mode 100644 index 0000000..c333c4e --- /dev/null +++ b/libgcrypt-1.10.1-annobin.patch @@ -0,0 +1,22 @@ +diff -rup libgcrypt.orig/src/Makefile.am libgcrypt-1.8.3/src/Makefile.am +--- libgcrypt.orig/src/Makefile.am 2021-10-18 16:36:20.914025497 +0100 ++++ libgcrypt-1.8.3/src/Makefile.am 2021-10-19 12:23:08.652960618 +0100 +@@ -108,6 +108,7 @@ endif !HAVE_W32_SYSTEM + + + libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \ ++ -Wc,-fplugin=annobin \ + $(libgcrypt_version_script_cmd) -version-info \ + @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@ + libgcrypt_la_DEPENDENCIES = \ +Only in libgcrypt-1.8.3/src: Makefile.am.annobin +diff -rup libgcrypt.orig/src/Makefile.in libgcrypt-1.8.3/src/Makefile.in +--- libgcrypt.orig/src/Makefile.in 2021-10-18 16:36:20.914025497 +0100 ++++ libgcrypt-1.8.3/src/Makefile.in 2021-10-19 12:23:37.791875325 +0100 +@@ -483,6 +483,7 @@ gcrypt_hwf_modules = @GCRYPT_HWF_MODULES + @HAVE_W32_SYSTEM_TRUE@gcrypt_deps = $(gcrypt_res) libgcrypt.def + @HAVE_W32_SYSTEM_FALSE@gcrypt_res_ldflag = + libgcrypt_la_LDFLAGS = $(no_undefined) $(export_symbols) $(extra_ltoptions) \ ++ -Wc,-fplugin=annobin \ + $(libgcrypt_version_script_cmd) -version-info \ + @LIBGCRYPT_LT_CURRENT@:@LIBGCRYPT_LT_REVISION@:@LIBGCRYPT_LT_AGE@ diff --git a/libgcrypt.spec b/libgcrypt.spec index 5ed4f4c..cd321d7 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -23,7 +23,10 @@ URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com +# brainpool curves are still not allowed to be shipped in Fedora Patch1: libgcrypt-1.10.0-disable-brainpool.patch +# Pass the annobin flags to the libgcrypt.so (#2016349) +Patch2: libgcrypt-1.10.1-annobin.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -60,6 +63,7 @@ applications using libgcrypt. %prep %setup -q %patch1 -p1 +%patch2 -p1 %build # This package has a configure test which uses ASMs, but does not link the From 2fe61ab47d8dbac25c3144e4790e9dd82daf2d17 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 21 Jul 2022 17:51:35 +0000 Subject: [PATCH 54/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index cd321d7..73d6e64 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -18,7 +18,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 3%{?dist} +Release: 4%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -182,6 +182,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 21 2022 Fedora Release Engineering - 1.10.1-4 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild + * Sun May 29 2022 Todd Zullinger - 1.10.1-3 - improve --disable-brainpool configure output - use %%bcond_with to disable brainpool curves From 9e608ad3fa1de990e0e874131c817aae1a86c0ba Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Sun, 6 Nov 2022 19:05:40 -0500 Subject: [PATCH 55/88] enable brainpool curves by default Thanks to the Fedora Legal team, we are now able to include Brainpool ECC in Fedora. Matthew Miller notified the Fedora Legal list. References: https://bugzilla.redhat.com/1413618 https://lists.fedoraproject.org/archives/list/legal@lists.fedoraproject.org/message/752Z34MTHB6B4XRUW2TTAPEIUUK4O2LA/ --- libgcrypt-1.10.0-disable-brainpool.patch | 314 ----------------------- libgcrypt.spec | 14 +- 2 files changed, 5 insertions(+), 323 deletions(-) delete mode 100644 libgcrypt-1.10.0-disable-brainpool.patch diff --git a/libgcrypt-1.10.0-disable-brainpool.patch b/libgcrypt-1.10.0-disable-brainpool.patch deleted file mode 100644 index 8a9d980..0000000 --- a/libgcrypt-1.10.0-disable-brainpool.patch +++ /dev/null @@ -1,314 +0,0 @@ -From f778433dd29fe07aa1791a0137f6f14febcce607 Mon Sep 17 00:00:00 2001 -From: Jakub Jelen -Date: Fri, 10 Sep 2021 18:39:00 +0200 -Subject: [PATCH] Allow building libgcrypt without Brainpool curves - -* README: Document possibility to build without brainpool curves -* cipher/ecc-curves.c: Conditionalize brainpool curves definitions -* configure.ac: Implement possibility to build without brainpool curves -* tests/curves.c: Skip brainpool curves if they are not built-in -* tests/keygrip.c: Skip brainpool curves if they are not built-in -* tests/bench-slope.c: Skip brainpoll curves in they are not built-in - --- - -Signed-off-by: Jakub Jelen ---- - README | 3 +++ - cipher/ecc-curves.c | 4 ++++ - configure.ac | 13 +++++++++++++ - tests/bench-slope.c | 12 ++++++++++++ - tests/curves.c | 46 ++++++++++++++++++++++++++++++--------------- - tests/keygrip.c | 2 ++ - 6 files changed, 65 insertions(+), 15 deletions(-) - -diff --git a/README b/README -index 4d7697dd..b290d01e 100644 ---- a/README -+++ b/README -@@ -121,6 +121,9 @@ - the list used with the current build the program - tests/version may be used. - -+ --disable-brainpool -+ Do not build in support for Brainpool curves. -+ - --disable-endian-check - Don't let configure test for the endianness but - try to use the OS provided macros at compile -diff --git a/cipher/ecc-curves.c b/cipher/ecc-curves.c -index 7c86e12c..8fd95a9c 100644 ---- a/cipher/ecc-curves.c -+++ b/cipher/ecc-curves.c -@@ -77,6 +77,7 @@ static const struct - { "NIST P-521", "1.3.132.0.35" }, - { "NIST P-521", "nistp521" }, /* rfc5656. */ - -+#ifdef ENABLE_BRAINPOOL - { "brainpoolP160r1", "1.3.36.3.3.2.8.1.1.1" }, - { "brainpoolP192r1", "1.3.36.3.3.2.8.1.1.3" }, - { "brainpoolP224r1", "1.3.36.3.3.2.8.1.1.5" }, -@@ -84,6 +85,7 @@ static const struct - { "brainpoolP320r1", "1.3.36.3.3.2.8.1.1.9" }, - { "brainpoolP384r1", "1.3.36.3.3.2.8.1.1.11"}, - { "brainpoolP512r1", "1.3.36.3.3.2.8.1.1.13"}, -+#endif /* ENABLE_BRAINPOOL */ - - { "GOST2001-test", "1.2.643.2.2.35.0" }, - { "GOST2001-CryptoPro-A", "1.2.643.2.2.35.1" }, -@@ -297,6 +299,7 @@ static const ecc_domain_parms_t domain_parms[] = - 1 - }, - -+#ifdef ENABLE_BRAINPOOL - { "brainpoolP160r1", 160, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, - "0xe95e4a5f737059dc60dfc7ad95b3d8139515620f", -@@ -391,6 +394,7 @@ static const ecc_domain_parms_t domain_parms[] = - "b2dcde494a5f485e5bca4bd88a2763aed1ca2b2fa8f0540678cd1e0f3ad80892", - 1 - }, -+#endif /* ENABLE_BRAINPOOL */ - { - "GOST2001-test", 256, 0, - MPI_EC_WEIERSTRASS, ECC_DIALECT_STANDARD, -diff --git a/configure.ac b/configure.ac -index 0e67baf9..a63f7360 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -595,6 +595,14 @@ AC_ARG_WITH(fips-module-version, - AC_DEFINE_UNQUOTED(FIPS_MODULE_VERSION, "$fips_module_version", - [Define FIPS module version for certification]) - -+# Implementation of the --disable-brainpool switch. -+AC_MSG_CHECKING([whether brainpool curves support is requested]) -+AC_ARG_ENABLE(brainpool, -+ AS_HELP_STRING([--disable-brainpool], -+ [Disable the brainpool curves]), -+ use_brainpool="$enableval",use_brainpool=yes) -+AC_MSG_RESULT($use_brainpool) -+ - # Implementation of the --disable-jent-support switch. - AC_MSG_CHECKING([whether jitter entropy support is requested]) - AC_ARG_ENABLE(jent-support, -@@ -2459,6 +2467,10 @@ if test x"$ppccryptosupport" = xyes ; then - AC_DEFINE(ENABLE_PPC_CRYPTO_SUPPORT,1, - [Enable support for POWER 8 (PowerISA 2.07) crypto extension.]) - fi -+if test x"$use_brainpool" = xyes ; then -+ AC_DEFINE(ENABLE_BRAINPOOL, 1, -+ [Enable support for the brainpool curves.]) -+fi - if test x"$jentsupport" = xyes ; then - AC_DEFINE(ENABLE_JENT_SUPPORT, 1, - [Enable support for the jitter entropy collector.]) -@@ -3294,6 +3306,7 @@ GCRY_MSG_WRAP([Enabled digest algorithms:],[$enabled_digests]) - GCRY_MSG_WRAP([Enabled kdf algorithms: ],[$enabled_kdfs]) - GCRY_MSG_WRAP([Enabled pubkey algorithms:],[$enabled_pubkey_ciphers]) - GCRY_MSG_SHOW([Random number generator: ],[$random]) -+GCRY_MSG_SHOW([Enabled Brainpool curves: ],[$use_brainpool]) - GCRY_MSG_SHOW([Try using jitter entropy: ],[$jentsupport]) - GCRY_MSG_SHOW([Using linux capabilities: ],[$use_capabilities]) - GCRY_MSG_SHOW([FIPS module version: ],[$fips_module_version]) -diff --git a/tests/bench-slope.c b/tests/bench-slope.c -index 5c49ac25..1b5941af 100644 ---- a/tests/bench-slope.c -+++ b/tests/bench-slope.c -@@ -2316,7 +2316,9 @@ enum bench_ecc_algo - ECC_ALGO_NIST_P384, - ECC_ALGO_NIST_P521, - ECC_ALGO_SECP256K1, -+#ifdef ENABLE_BRAINPOOL - ECC_ALGO_BRAINP256R1, -+#endif /* ENABLE_BRAINPOOL */ - __MAX_ECC_ALGO - }; - -@@ -2366,7 +2368,9 @@ ecc_algo_fips_allowed (int algo) - case ECC_ALGO_NIST_P521: - return 1; - case ECC_ALGO_SECP256K1: -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: -+#endif /* ENABLE_BRAINPOOL */ - case ECC_ALGO_ED25519: - case ECC_ALGO_ED448: - case ECC_ALGO_X25519: -@@ -2402,8 +2406,10 @@ ecc_algo_name (int algo) - return "NIST-P521"; - case ECC_ALGO_SECP256K1: - return "secp256k1"; -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: - return "brainpoolP256r1"; -+#endif /* ENABLE_BRAINPOOL */ - default: - return NULL; - } -@@ -2434,8 +2440,10 @@ ecc_algo_curve (int algo) - return "NIST P-521"; - case ECC_ALGO_SECP256K1: - return "secp256k1"; -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: - return "brainpoolP256r1"; -+#endif /* ENABLE_BRAINPOOL */ - default: - return NULL; - } -@@ -2466,8 +2474,10 @@ ecc_nbits (int algo) - return 521; - case ECC_ALGO_SECP256K1: - return 256; -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: - return 256; -+#endif /* ENABLE_BRAINPOOL */ - default: - return 0; - } -@@ -2665,6 +2675,7 @@ bench_ecc_init (struct bench_obj *obj) - err = gcry_sexp_build (&hd->data, NULL, - "(data (flags raw) (value %m))", x); - break; -+#ifdef ENABLE_BRAINPOOL - case ECC_ALGO_BRAINP256R1: - err = gcry_sexp_build (&hd->key_spec, NULL, - "(genkey (ECDSA (curve brainpoolP256r1)))"); -@@ -2673,6 +2684,7 @@ bench_ecc_init (struct bench_obj *obj) - err = gcry_sexp_build (&hd->data, NULL, - "(data (flags raw) (value %m))", x); - break; -+#endif /* ENABLE_BRAINPOOL */ - } - - gcry_mpi_release (x); -diff --git a/tests/curves.c b/tests/curves.c -index 3c738171..8eb79565 100644 ---- a/tests/curves.c -+++ b/tests/curves.c -@@ -33,7 +33,11 @@ - #include "t-common.h" - - /* Number of curves defined in ../cipher/ecc-curves.c */ --#define N_CURVES 27 -+#ifdef ENABLE_BRAINPOOL -+# define N_CURVES 27 -+#else -+# define N_CURVES 20 -+#endif - - /* A real world sample public key. */ - static char const sample_key_1[] = -@@ -52,6 +56,7 @@ static char const sample_key_1[] = - static char const sample_key_1_curve[] = "NIST P-256"; - static unsigned int sample_key_1_nbits = 256; - -+#ifdef ENABLE_BRAINPOOL - /* A made up sample public key. */ - static char const sample_key_2[] = - "(public-key\n" -@@ -68,6 +73,7 @@ static char const sample_key_2[] = - " ))"; - static char const sample_key_2_curve[] = "brainpoolP160r1"; - static unsigned int sample_key_2_nbits = 160; -+#endif /* ENABLE_BRAINPOOL */ - - static int in_fips_mode; - -@@ -113,6 +119,7 @@ check_matching (void) - - gcry_sexp_release (key); - -+#ifdef ENABLE_BRAINPOOL - if (!in_fips_mode) - { - err = gcry_sexp_new (&key, sample_key_2, 0, 1); -@@ -130,6 +137,7 @@ check_matching (void) - - gcry_sexp_release (key); - } -+#endif /* ENABLE_BRAINPOOL */ - } - - #define TEST_ERROR_EXPECTED (1 << 0) -@@ -185,20 +193,26 @@ check_get_params (void) - { GCRY_PK_ECC, "1.3.132.0.35" }, - { GCRY_PK_ECC, "nistp521" }, - -- { GCRY_PK_ECC, "brainpoolP160r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP192r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP224r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP256r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP320r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP384r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11", TEST_NOFIPS }, -- { GCRY_PK_ECC, "brainpoolP512r1", TEST_NOFIPS }, -- { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13", TEST_NOFIPS }, -+#ifdef ENABLE_BRAINPOOL -+# define BRAINPOOL_FLAGS TEST_NOFIPS -+#else -+# define BRAINPOOL_FLAGS TEST_ERROR_EXPECTED -+#endif /* ENABLE_BRAINPOOL */ -+ { GCRY_PK_ECC, "brainpoolP160r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP192r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.3", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP224r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.5", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP256r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.7", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP320r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.9", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP384r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.11", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "brainpoolP512r1", BRAINPOOL_FLAGS }, -+ { GCRY_PK_ECC, "1.3.36.3.3.2.8.1.1.13", BRAINPOOL_FLAGS }, -+#undef BRAINPOOL_ERROR_EXPECTED - - { GCRY_PK_ECC, "GOST2001-test", TEST_NOFIPS }, - { GCRY_PK_ECC, "1.2.643.2.2.35.0", TEST_NOFIPS }, -@@ -282,6 +296,7 @@ check_get_params (void) - - gcry_sexp_release (param); - -+#ifdef ENABLE_BRAINPOOL - if (!in_fips_mode) - { - param = gcry_pk_get_param (GCRY_PK_ECDSA, sample_key_2_curve); -@@ -297,6 +312,7 @@ check_get_params (void) - - gcry_sexp_release (param); - } -+#endif /* ENABLE_BRAINPOOL */ - - /* Some simple tests */ - for (idx=0; idx < DIM (tv); idx++) -diff --git a/tests/keygrip.c b/tests/keygrip.c -index 49bd71bc..fc4c17be 100644 ---- a/tests/keygrip.c -+++ b/tests/keygrip.c -@@ -149,6 +149,7 @@ static struct - " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", - "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" - }, -+#ifdef ENABLE_BRAINPOOL - { - GCRY_PK_ECC, - "(public-key" -@@ -197,6 +198,7 @@ static struct - "\xD6\xE1\xBF\x43\xAC\x9B\x9A\x12\xE7\x3F", - 1 - }, -+#endif /*ENABLE_BRAINPOOL */ - { /* Ed25519 standard */ - GCRY_PK_ECC, - "(public-key" --- -2.34.1 - diff --git a/libgcrypt.spec b/libgcrypt.spec index 73d6e64..f458aab 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -13,20 +13,15 @@ sha256sum:close() print(string.sub(hash, 0, 16)) } -# disable brainpool curves by default -%bcond_with brainpool - Name: libgcrypt Version: 1.10.1 -Release: 4%{?dist} +Release: 5%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com -# brainpool curves are still not allowed to be shipped in Fedora -Patch1: libgcrypt-1.10.0-disable-brainpool.patch # Pass the annobin flags to the libgcrypt.so (#2016349) -Patch2: libgcrypt-1.10.1-annobin.patch +Patch1: libgcrypt-1.10.1-annobin.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -63,7 +58,6 @@ applications using libgcrypt. %prep %setup -q %patch1 -p1 -%patch2 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -89,7 +83,6 @@ autoreconf -f %endif --enable-noexecstack \ --enable-hmac-binary-check=%{hmackey} \ - %{!?with_brainpool:--disable-brainpool} \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" @@ -182,6 +175,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Nov 08 2022 Todd Zullinger - 1.10.1-5 +- enable brainpool by default (#1413618) + * Thu Jul 21 2022 Fedora Release Engineering - 1.10.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From 96a092be6b72c9b160392320a380ebddc0dd0c4b Mon Sep 17 00:00:00 2001 From: Todd Zullinger Date: Wed, 9 Nov 2022 17:53:31 -0500 Subject: [PATCH 56/88] fix sporadic failures generating RSA keys in FIPS mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The test suite occasionally fails with "error generating RSA key: Number is not prime" in FIPS mode¹. Apply the upstream fix, cd30ed3c (cipher: Change the bounds for RSA key generation round., 2022-04-20). ¹ https://dev.gnupg.org/T5919 --- ...e-bounds-for-RSA-key-generation-roun.patch | 55 +++++++++++++++++++ libgcrypt.spec | 6 ++ 2 files changed, 61 insertions(+) create mode 100644 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch diff --git a/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch b/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch new file mode 100644 index 0000000..3ec87e6 --- /dev/null +++ b/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch @@ -0,0 +1,55 @@ +From cd30ed3c0d715aa0c58a32a29cfb1476163a5b94 Mon Sep 17 00:00:00 2001 +From: NIIBE Yutaka +Date: Wed, 20 Apr 2022 15:09:41 +0900 +Subject: [PATCH] cipher: Change the bounds for RSA key generation round. + +* cipher/rsa.c (generate_fips): Use 10 for p, 20 for q. + +-- + +Constants from FIPS 186-5-draft. + +GnuPG-bug-id: 5919 +Signed-off-by: NIIBE Yutaka +--- + cipher/rsa.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/cipher/rsa.c b/cipher/rsa.c +index 486a34f0..771413b3 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -476,7 +476,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, + + retry: + /* generate p and q */ +- for (i = 0; i < 5 * pbits; i++) ++ for (i = 0; i < 10 * pbits; i++) + { + ploop: + if (!testparms) +@@ -506,10 +506,10 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, + else if (testparms) + goto err; + } +- if (i >= 5 * pbits) ++ if (i >= 10 * pbits) + goto err; + +- for (i = 0; i < 5 * pbits; i++) ++ for (i = 0; i < 20 * pbits; i++) + { + qloop: + if (!testparms) +@@ -555,7 +555,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, + else if (testparms) + goto err; + } +- if (i >= 5 * pbits) ++ if (i >= 20 * pbits) + goto err; + + if (testparms) +-- +2.38.1 + diff --git a/libgcrypt.spec b/libgcrypt.spec index f458aab..89c1036 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -22,6 +22,10 @@ Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch +# https://dev.gnupg.org/T5919 +# tests occasionally fail with "error generating RSA key: Number is not prime" +# https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=cd30ed3c0 +Patch2: 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -58,6 +62,7 @@ applications using libgcrypt. %prep %setup -q %patch1 -p1 +%patch2 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -177,6 +182,7 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %changelog * Tue Nov 08 2022 Todd Zullinger - 1.10.1-5 - enable brainpool by default (#1413618) +- fix sporadic failures generating RSA keys in FIPS mode * Thu Jul 21 2022 Fedora Release Engineering - 1.10.1-4 - Rebuilt for https://fedoraproject.org/wiki/Fedora_37_Mass_Rebuild From 1a44ed4636073d3286676072091b274d04c5ff8e Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Sat, 3 Dec 2022 12:17:30 +0100 Subject: [PATCH 57/88] Port configure script to C99 Related to: --- libgcrypt-configure-c99.patch | 139 ++++++++++++++++++++++++++++++++++ libgcrypt.spec | 8 +- 2 files changed, 146 insertions(+), 1 deletion(-) create mode 100644 libgcrypt-configure-c99.patch diff --git a/libgcrypt-configure-c99.patch b/libgcrypt-configure-c99.patch new file mode 100644 index 0000000..321743a --- /dev/null +++ b/libgcrypt-configure-c99.patch @@ -0,0 +1,139 @@ +Add missing prototypes to test functions. Future compilers will not +support implicit function declarations by default, causing spurious +test failures. + +The patch has been submitted to the gcrypt-devel list, but has yet to +appear in the list archives. + +diff --git a/configure.ac b/configure.ac +index 6ea38f53b8548ee8..2baf25bc7d9481e6 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1211,7 +1211,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARM assembly implementat + /* Test if '.type' and '.size' are supported. */ + ".size asmfunc,.-asmfunc;\n\t" + ".type asmfunc,%function;\n\t" +- );]], [ asmfunc(); ] )], ++ ); ++ void asmfunc(void);]], [ asmfunc(); ] )], + [gcry_cv_gcc_arm_platform_as_ok=yes]) + fi]) + if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then +@@ -1238,7 +1239,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARMv8/Aarch64 assembly i + "eor x0, x0, x30, ror #12;\n\t" + "add x0, x0, x30, asr #12;\n\t" + "eor v0.16b, v0.16b, v31.16b;\n\t" +- );]], [ asmfunc(); ] )], ++ ); ++ void asmfunc(void);]], [ asmfunc(); ] )], + [gcry_cv_gcc_aarch64_platform_as_ok=yes]) + fi]) + if test "$gcry_cv_gcc_aarch64_platform_as_ok" = "yes" ; then +@@ -1267,7 +1269,8 @@ AC_CACHE_CHECK([whether GCC assembler supports for CFI directives], + ".cfi_restore_state\n\t" + ".long 0\n\t" + ".cfi_endproc\n\t" +- );]])], ++ ); ++ void asmfunc(void)]])], + [gcry_cv_gcc_asm_cfi_directives=yes])]) + if test "$gcry_cv_gcc_asm_cfi_directives" = "yes" ; then + AC_DEFINE(HAVE_GCC_ASM_CFI_DIRECTIVES,1, +@@ -1666,7 +1669,8 @@ if test $amd64_as_feature_detection = yes; then + [gcry_cv_gcc_as_const_division_ok], + [gcry_cv_gcc_as_const_division_ok=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( +- [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]], ++ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t"); ++ void fn(void);]], + [fn();])], + [gcry_cv_gcc_as_const_division_ok=yes])]) + if test "$gcry_cv_gcc_as_const_division_ok" = "no" ; then +@@ -1679,7 +1683,8 @@ if test $amd64_as_feature_detection = yes; then + [gcry_cv_gcc_as_const_division_with_wadivide_ok], + [gcry_cv_gcc_as_const_division_with_wadivide_ok=no + AC_LINK_IFELSE([AC_LANG_PROGRAM( +- [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]], ++ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t"); ++ void fn(void);]], + [fn();])], + [gcry_cv_gcc_as_const_division_with_wadivide_ok=yes])]) + if test "$gcry_cv_gcc_as_const_division_with_wadivide_ok" = "no" ; then +@@ -1715,7 +1720,8 @@ if test $amd64_as_feature_detection = yes; then + * and "-Wa,--divide" workaround failed, this causes assembly + * to be disable on this machine. */ + "xorl \$(123456789/12345678), %ebp;\n\t" +- );]], [ asmfunc(); ])], ++ ); ++ void asmfunc(void);]], [ asmfunc(); ])], + [gcry_cv_gcc_amd64_platform_as_ok=yes]) + fi]) + if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then +@@ -1734,7 +1740,8 @@ if test $amd64_as_feature_detection = yes; then + ".globl asmfunc\n\t" + "asmfunc:\n\t" + "xorq \$(1234), %rbp;\n\t" +- );]], [ asmfunc(); ])], ++ ); ++ void asmfunc(void);]], [ asmfunc(); ])], + [gcry_cv_gcc_win64_platform_as_ok=yes])]) + if test "$gcry_cv_gcc_win64_platform_as_ok" = "yes" ; then + AC_DEFINE(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS,1, +@@ -1767,7 +1774,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for Intel syntax assembly im + "sub eax, [esp + 4];\n\t" + "add dword ptr [esp + eax], 0b10101;\n\t" + ".att_syntax prefix\n\t" +- );]], [ actest(); ])], ++ ); ++ void actest(void);]], [ actest(); ])], + [gcry_cv_gcc_platform_as_ok_for_intel_syntax=yes]) + fi]) + if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then +@@ -1832,6 +1840,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports NEON instructions], + "vadd.u64 %q0, %q1;\n\t" + "vadd.s64 %d3, %d2, %d3;\n\t" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_neon=yes]) + fi]) +@@ -1879,6 +1888,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch32 Crypto Extension i + + "vmull.p64 q0, d0, d0;\n\t" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_aarch32_crypto=yes]) + fi]) +@@ -1907,6 +1917,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 NEON instructions] + "dup v0.8b, w0;\n\t" + "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_aarch64_neon=yes]) + fi]) +@@ -1955,6 +1966,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 Crypto Extension i + "pmull v0.1q, v0.1d, v31.1d;\n\t" + "pmull2 v0.1q, v0.2d, v31.2d;\n\t" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_aarch64_crypto=yes]) + fi]) +@@ -2050,6 +2062,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto + "vshasigmad %v0, %v1, 0, 15;\n" + "vpmsumd %v11, %v11, %v11;\n" + ); ++ void testfn(void); + ]], [ testfn(); ] )], + [gcry_cv_gcc_inline_asm_ppc_altivec=yes]) + fi]) +@@ -2075,6 +2088,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports PowerISA 3.00 instructions + "testfn:\n" + "stxvb16x %r1,%v12,%v30;\n" + ); ++ void testfn(void); + ]], [ testfn(); ])], + [gcry_cv_gcc_inline_asm_ppc_arch_3_00=yes]) + fi]) diff --git a/libgcrypt.spec b/libgcrypt.spec index 89c1036..7392318 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 5%{?dist} +Release: 6%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -27,6 +27,8 @@ Patch1: libgcrypt-1.10.1-annobin.patch # https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=cd30ed3c0 Patch2: 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch +Patch3: libgcrypt-configure-c99.patch + %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 %global hmackey orboDeJITITejsirpADONivirpUkvarP @@ -63,6 +65,7 @@ applications using libgcrypt. %setup -q %patch1 -p1 %patch2 -p1 +%patch3 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -180,6 +183,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Sat Dec 3 2022 Florian Weimer - 1.10.1-6 +- Port configure script to C99 + * Tue Nov 08 2022 Todd Zullinger - 1.10.1-5 - enable brainpool by default (#1413618) - fix sporadic failures generating RSA keys in FIPS mode From 31745f126fcd5bdaa8b28354d552e7f8c926d955 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Mon, 5 Dec 2022 13:47:38 +0100 Subject: [PATCH 58/88] libgcrypt-configure-c99.patch: Add upstream patch submission URL --- libgcrypt-configure-c99.patch | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libgcrypt-configure-c99.patch b/libgcrypt-configure-c99.patch index 321743a..8238ed4 100644 --- a/libgcrypt-configure-c99.patch +++ b/libgcrypt-configure-c99.patch @@ -2,8 +2,9 @@ Add missing prototypes to test functions. Future compilers will not support implicit function declarations by default, causing spurious test failures. -The patch has been submitted to the gcrypt-devel list, but has yet to -appear in the list archives. +Submitted upstream: + + diff --git a/configure.ac b/configure.ac index 6ea38f53b8548ee8..2baf25bc7d9481e6 100644 From 01380c605d1e634ff62231b57c8c7008558ccdde Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 19 Jan 2023 16:23:04 +0000 Subject: [PATCH 59/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 7392318..3679c3b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.1 -Release: 6%{?dist} +Release: 7%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -183,6 +183,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jan 19 2023 Fedora Release Engineering - 1.10.1-7 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild + * Sat Dec 3 2022 Florian Weimer - 1.10.1-6 - Port configure script to C99 From a17db7fa5890b2266da7fb6347aa1367be7840bd Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Apr 2023 14:20:12 +0200 Subject: [PATCH 60/88] Simplify HMAC checksum calculation and avoid using CWD --- libgcrypt.spec | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 3679c3b..aae97fc 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -108,12 +108,12 @@ LIBGCRYPT_FORCE_FIPS_MODE=1 make check %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ %{__os_install_post} \ - pushd src \ + cd src \ sed -i -e 's|FILE=.*|FILE=\\\$1|' gen-note-integrity.sh \ READELF=readelf AWK=awk ECHO_N="-n" bash gen-note-integrity.sh %{libpath} > %{libpath}.hmac \ - objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} new \ - mv -f new %{libpath} \ - rm -f %{libpath}.hmac \ + objcopy --update-section .note.fdo.integrity=%{libpath}.hmac %{libpath} %{libpath}.new \ + mv -f %{libpath}.new %{libpath} \ + rm -f %{libpath}.hmac %{nil} %install From 021f499feb26e7b9cc90ee2c91eb48f723391b24 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 11 Apr 2023 14:35:51 +0200 Subject: [PATCH 61/88] libgcrypt-1.10.2-1 * Remove already-applied patches * Avoid using deprecated %patchN --- .gitignore | 2 + ...e-bounds-for-RSA-key-generation-roun.patch | 55 ------- libgcrypt-configure-c99.patch | 140 ------------------ libgcrypt.spec | 17 +-- sources | 4 +- 5 files changed, 10 insertions(+), 208 deletions(-) delete mode 100644 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch delete mode 100644 libgcrypt-configure-c99.patch diff --git a/.gitignore b/.gitignore index 5380134..b60502b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.10.0.tar.bz2.sig /libgcrypt-1.10.1.tar.bz2 /libgcrypt-1.10.1.tar.bz2.sig +/libgcrypt-1.10.2.tar.bz2 +/libgcrypt-1.10.2.tar.bz2.sig diff --git a/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch b/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch deleted file mode 100644 index 3ec87e6..0000000 --- a/0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch +++ /dev/null @@ -1,55 +0,0 @@ -From cd30ed3c0d715aa0c58a32a29cfb1476163a5b94 Mon Sep 17 00:00:00 2001 -From: NIIBE Yutaka -Date: Wed, 20 Apr 2022 15:09:41 +0900 -Subject: [PATCH] cipher: Change the bounds for RSA key generation round. - -* cipher/rsa.c (generate_fips): Use 10 for p, 20 for q. - --- - -Constants from FIPS 186-5-draft. - -GnuPG-bug-id: 5919 -Signed-off-by: NIIBE Yutaka ---- - cipher/rsa.c | 8 ++++---- - 1 file changed, 4 insertions(+), 4 deletions(-) - -diff --git a/cipher/rsa.c b/cipher/rsa.c -index 486a34f0..771413b3 100644 ---- a/cipher/rsa.c -+++ b/cipher/rsa.c -@@ -476,7 +476,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, - - retry: - /* generate p and q */ -- for (i = 0; i < 5 * pbits; i++) -+ for (i = 0; i < 10 * pbits; i++) - { - ploop: - if (!testparms) -@@ -506,10 +506,10 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, - else if (testparms) - goto err; - } -- if (i >= 5 * pbits) -+ if (i >= 10 * pbits) - goto err; - -- for (i = 0; i < 5 * pbits; i++) -+ for (i = 0; i < 20 * pbits; i++) - { - qloop: - if (!testparms) -@@ -555,7 +555,7 @@ generate_fips (RSA_secret_key *sk, unsigned int nbits, unsigned long use_e, - else if (testparms) - goto err; - } -- if (i >= 5 * pbits) -+ if (i >= 20 * pbits) - goto err; - - if (testparms) --- -2.38.1 - diff --git a/libgcrypt-configure-c99.patch b/libgcrypt-configure-c99.patch deleted file mode 100644 index 8238ed4..0000000 --- a/libgcrypt-configure-c99.patch +++ /dev/null @@ -1,140 +0,0 @@ -Add missing prototypes to test functions. Future compilers will not -support implicit function declarations by default, causing spurious -test failures. - -Submitted upstream: - - - -diff --git a/configure.ac b/configure.ac -index 6ea38f53b8548ee8..2baf25bc7d9481e6 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -1211,7 +1211,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARM assembly implementat - /* Test if '.type' and '.size' are supported. */ - ".size asmfunc,.-asmfunc;\n\t" - ".type asmfunc,%function;\n\t" -- );]], [ asmfunc(); ] )], -+ ); -+ void asmfunc(void);]], [ asmfunc(); ] )], - [gcry_cv_gcc_arm_platform_as_ok=yes]) - fi]) - if test "$gcry_cv_gcc_arm_platform_as_ok" = "yes" ; then -@@ -1238,7 +1239,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for ARMv8/Aarch64 assembly i - "eor x0, x0, x30, ror #12;\n\t" - "add x0, x0, x30, asr #12;\n\t" - "eor v0.16b, v0.16b, v31.16b;\n\t" -- );]], [ asmfunc(); ] )], -+ ); -+ void asmfunc(void);]], [ asmfunc(); ] )], - [gcry_cv_gcc_aarch64_platform_as_ok=yes]) - fi]) - if test "$gcry_cv_gcc_aarch64_platform_as_ok" = "yes" ; then -@@ -1267,7 +1269,8 @@ AC_CACHE_CHECK([whether GCC assembler supports for CFI directives], - ".cfi_restore_state\n\t" - ".long 0\n\t" - ".cfi_endproc\n\t" -- );]])], -+ ); -+ void asmfunc(void)]])], - [gcry_cv_gcc_asm_cfi_directives=yes])]) - if test "$gcry_cv_gcc_asm_cfi_directives" = "yes" ; then - AC_DEFINE(HAVE_GCC_ASM_CFI_DIRECTIVES,1, -@@ -1666,7 +1669,8 @@ if test $amd64_as_feature_detection = yes; then - [gcry_cv_gcc_as_const_division_ok], - [gcry_cv_gcc_as_const_division_ok=no - AC_LINK_IFELSE([AC_LANG_PROGRAM( -- [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]], -+ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t"); -+ void fn(void);]], - [fn();])], - [gcry_cv_gcc_as_const_division_ok=yes])]) - if test "$gcry_cv_gcc_as_const_division_ok" = "no" ; then -@@ -1679,7 +1683,8 @@ if test $amd64_as_feature_detection = yes; then - [gcry_cv_gcc_as_const_division_with_wadivide_ok], - [gcry_cv_gcc_as_const_division_with_wadivide_ok=no - AC_LINK_IFELSE([AC_LANG_PROGRAM( -- [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t");]], -+ [[__asm__(".text\n\tfn:\n\t xorl \$(123456789/12345678), %ebp;\n\t"); -+ void fn(void);]], - [fn();])], - [gcry_cv_gcc_as_const_division_with_wadivide_ok=yes])]) - if test "$gcry_cv_gcc_as_const_division_with_wadivide_ok" = "no" ; then -@@ -1715,7 +1720,8 @@ if test $amd64_as_feature_detection = yes; then - * and "-Wa,--divide" workaround failed, this causes assembly - * to be disable on this machine. */ - "xorl \$(123456789/12345678), %ebp;\n\t" -- );]], [ asmfunc(); ])], -+ ); -+ void asmfunc(void);]], [ asmfunc(); ])], - [gcry_cv_gcc_amd64_platform_as_ok=yes]) - fi]) - if test "$gcry_cv_gcc_amd64_platform_as_ok" = "yes" ; then -@@ -1734,7 +1740,8 @@ if test $amd64_as_feature_detection = yes; then - ".globl asmfunc\n\t" - "asmfunc:\n\t" - "xorq \$(1234), %rbp;\n\t" -- );]], [ asmfunc(); ])], -+ ); -+ void asmfunc(void);]], [ asmfunc(); ])], - [gcry_cv_gcc_win64_platform_as_ok=yes])]) - if test "$gcry_cv_gcc_win64_platform_as_ok" = "yes" ; then - AC_DEFINE(HAVE_COMPATIBLE_GCC_WIN64_PLATFORM_AS,1, -@@ -1767,7 +1774,8 @@ AC_CACHE_CHECK([whether GCC assembler is compatible for Intel syntax assembly im - "sub eax, [esp + 4];\n\t" - "add dword ptr [esp + eax], 0b10101;\n\t" - ".att_syntax prefix\n\t" -- );]], [ actest(); ])], -+ ); -+ void actest(void);]], [ actest(); ])], - [gcry_cv_gcc_platform_as_ok_for_intel_syntax=yes]) - fi]) - if test "$gcry_cv_gcc_platform_as_ok_for_intel_syntax" = "yes" ; then -@@ -1832,6 +1840,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports NEON instructions], - "vadd.u64 %q0, %q1;\n\t" - "vadd.s64 %d3, %d2, %d3;\n\t" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_neon=yes]) - fi]) -@@ -1879,6 +1888,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch32 Crypto Extension i - - "vmull.p64 q0, d0, d0;\n\t" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_aarch32_crypto=yes]) - fi]) -@@ -1907,6 +1917,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 NEON instructions] - "dup v0.8b, w0;\n\t" - "ld4 {v0.8b,v1.8b,v2.8b,v3.8b},[x0],\#32;\n\t" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_aarch64_neon=yes]) - fi]) -@@ -1955,6 +1966,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports AArch64 Crypto Extension i - "pmull v0.1q, v0.1d, v31.1d;\n\t" - "pmull2 v0.1q, v0.2d, v31.2d;\n\t" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_aarch64_crypto=yes]) - fi]) -@@ -2050,6 +2062,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports PowerPC AltiVec/VSX/crypto - "vshasigmad %v0, %v1, 0, 15;\n" - "vpmsumd %v11, %v11, %v11;\n" - ); -+ void testfn(void); - ]], [ testfn(); ] )], - [gcry_cv_gcc_inline_asm_ppc_altivec=yes]) - fi]) -@@ -2075,6 +2088,7 @@ AC_CACHE_CHECK([whether GCC inline assembler supports PowerISA 3.00 instructions - "testfn:\n" - "stxvb16x %r1,%v12,%v30;\n" - ); -+ void testfn(void); - ]], [ testfn(); ])], - [gcry_cv_gcc_inline_asm_ppc_arch_3_00=yes]) - fi]) diff --git a/libgcrypt.spec b/libgcrypt.spec index aae97fc..899e3f9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,20 +14,14 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.10.1 -Release: 7%{?dist} +Version: 1.10.2 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch -# https://dev.gnupg.org/T5919 -# tests occasionally fail with "error generating RSA key: Number is not prime" -# https://git.gnupg.org/cgi-bin/gitweb.cgi?p=libgcrypt.git;a=patch;h=cd30ed3c0 -Patch2: 0001-cipher-Change-the-bounds-for-RSA-key-generation-roun.patch - -Patch3: libgcrypt-configure-c99.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -63,9 +57,7 @@ applications using libgcrypt. %prep %setup -q -%patch1 -p1 -%patch2 -p1 -%patch3 -p1 +%patch 1 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -183,6 +175,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Apr 11 2023 Jakub Jelen - 1.10.2-1 +- New upstream release (#2185084) + * Thu Jan 19 2023 Fedora Release Engineering - 1.10.1-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_38_Mass_Rebuild diff --git a/sources b/sources index 0021e06..d17dc31 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.10.1.tar.bz2) = e5ca7966624fff16c3013795836a2c4377f0193dbb4ac5ad2b79654b1fa8992e17d83816569a402212dc8367a7980d4141f5d6ac282bae6b9f02186365b61f13 -SHA512 (libgcrypt-1.10.1.tar.bz2.sig) = b156ae05079776698bc95ba5a9e48e95de8f716aa1760ef4b2e7cb8518ccec660337fc7823f865bde870461800d472fd8e458d03a7095b6bb614f6dd96f796d8 +SHA512 (libgcrypt-1.10.2.tar.bz2) = 3a850baddfe8ffe8b3e96dc54af3fbb9e1dab204db1f06b9b90b8fbbfb7fb7276260cd1e61ba4dde5a662a2385385007478834e62e95f785d2e3d32652adb29e +SHA512 (libgcrypt-1.10.2.tar.bz2.sig) = 9350444a0bcfa49217815a831f2286ccea470311673257bd809eb5dedbe97d2a5543b0bc7fb752312df69adeb7ac5f064e433f2545a8bf3e494027986cd8020c From 595da4e6ed75903702935ea05ca109dc89d31828 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Jun 2023 10:42:49 +0200 Subject: [PATCH 62/88] Disable jitter entropy generator to follow RHEL changes --- libgcrypt.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index 899e3f9..e2fdf1b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -83,6 +83,7 @@ autoreconf -f %endif --enable-noexecstack \ --enable-hmac-binary-check=%{hmackey} \ + --disable-jent-support \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" From f968cc8fb23b50db5cd8c6ee8df1520f6c8492e9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 12 Jun 2023 11:14:17 +0200 Subject: [PATCH 63/88] Add SPDX license identifiers --- libgcrypt.spec | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index e2fdf1b..20c106b 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -27,10 +27,7 @@ Patch1: libgcrypt-1.10.1-annobin.patch %global gcrysoname libgcrypt.so.20 %global hmackey orboDeJITITejsirpADONivirpUkvarP -# Technically LGPLv2.1+, but Fedora's table doesn't draw a distinction. -# Documentation and some utilities are GPLv2+ licensed. These files -# are in the devel subpackage. -License: LGPLv2+ +License: BSD-3-Clause AND (BSD-3-Clause OR GPL-2.0-only) AND GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-2.0-or-later AND MIT-Modern-Variant Summary: A general-purpose cryptography library BuildRequires: gcc BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig @@ -41,7 +38,6 @@ BuildRequires: make %package devel Summary: Development files for the %{name} package -License: LGPLv2+ and GPLv2+ Requires: libgpg-error-devel Requires: %{name}%{?_isa} = %{version}-%{release} Requires: pkgconfig From bc207853a3e62b643b5568efe5d652c41a4165aa Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 20 Jul 2023 10:54:57 +0000 Subject: [PATCH 64/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild Signed-off-by: Fedora Release Engineering --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 20c106b..2fc8354 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.2 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -172,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 20 2023 Fedora Release Engineering - 1.10.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild + * Tue Apr 11 2023 Jakub Jelen - 1.10.2-1 - New upstream release (#2185084) From b03e7936f6484f7640eb06a9f1c42384f634290e Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Nov 2023 18:38:23 +0100 Subject: [PATCH 65/88] update comment about algorithms --- libgcrypt.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 2fc8354..466e2b4 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -65,7 +65,7 @@ applications using libgcrypt. # F34, so we use it here explicitly %define _lto_cflags -flto=auto -ffat-lto-objects -# should be all algorithms except SM3 and SM4 +# should be all algorithms except SM3 and SM4, aria export DIGESTS='crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2' export CIPHERS='arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20' From f099f466e069df587753638f94f82c2c2c1e8dbc Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 14 Nov 2023 18:47:06 +0100 Subject: [PATCH 66/88] libgcrypt-1.10.3-1 --- .gitignore | 2 ++ libgcrypt.spec | 7 +++++-- sources | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index b60502b..3359399 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.10.1.tar.bz2.sig /libgcrypt-1.10.2.tar.bz2 /libgcrypt-1.10.2.tar.bz2.sig +/libgcrypt-1.10.3.tar.bz2 +/libgcrypt-1.10.3.tar.bz2.sig diff --git a/libgcrypt.spec b/libgcrypt.spec index 466e2b4..ca9eb5d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,8 +14,8 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.10.2 -Release: 2%{?dist} +Version: 1.10.3 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -172,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Nov 14 2023 Jakub Jelen - 1.10.3-1 +- New upstream release (#2249639) + * Thu Jul 20 2023 Fedora Release Engineering - 1.10.2-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_39_Mass_Rebuild diff --git a/sources b/sources index d17dc31..09e5e42 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.10.2.tar.bz2) = 3a850baddfe8ffe8b3e96dc54af3fbb9e1dab204db1f06b9b90b8fbbfb7fb7276260cd1e61ba4dde5a662a2385385007478834e62e95f785d2e3d32652adb29e -SHA512 (libgcrypt-1.10.2.tar.bz2.sig) = 9350444a0bcfa49217815a831f2286ccea470311673257bd809eb5dedbe97d2a5543b0bc7fb752312df69adeb7ac5f064e433f2545a8bf3e494027986cd8020c +SHA512 (libgcrypt-1.10.3.tar.bz2) = 8a8d4c61a6622d8481ceb9edc88ec43f58da32e316f79f8d4775325a48f8936aaa9eb355923b39e2c267b784e9c390600daeb62e0c94f00e30bbadb0d8c0865d +SHA512 (libgcrypt-1.10.3.tar.bz2.sig) = 7b240b40992bbfd117ba6453377c3c8734aa70a43bc4e7d24b412b5f2446b85cd41e70950d2e973cc7e2da1f7669e267e276fd5f603e991b9a04919cb9bedab2 From 9caa9d782460e30d89a01f488166881d45dde212 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Sun, 21 Jan 2024 04:08:26 +0000 Subject: [PATCH 67/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index ca9eb5d..237a21a 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.3 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -172,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Sun Jan 21 2024 Fedora Release Engineering - 1.10.3-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Tue Nov 14 2023 Jakub Jelen - 1.10.3-1 - New upstream release (#2249639) From e851663be31ea6d9f01f5a15119df5bd9ab2a853 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 25 Jan 2024 02:13:24 +0000 Subject: [PATCH 68/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 237a21a..e42fa25 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.3 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -172,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jan 25 2024 Fedora Release Engineering - 1.10.3-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild + * Sun Jan 21 2024 Fedora Release Engineering - 1.10.3-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From fb3474ec1bced0045f855cef844aa31f746dd9b9 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 26 Mar 2024 09:11:49 +0100 Subject: [PATCH 69/88] Replace deprecated fgrep (#2271503) --- libgcrypt-1.10.3-fgrep.patch | 24 ++++++++++++++++++++++++ libgcrypt.spec | 3 +++ 2 files changed, 27 insertions(+) create mode 100644 libgcrypt-1.10.3-fgrep.patch diff --git a/libgcrypt-1.10.3-fgrep.patch b/libgcrypt-1.10.3-fgrep.patch new file mode 100644 index 0000000..26bf036 --- /dev/null +++ b/libgcrypt-1.10.3-fgrep.patch @@ -0,0 +1,24 @@ +diff --git a/src/libgcrypt-config.in b/src/libgcrypt-config.in +--- a/src/libgcrypt-config.in ++++ b/src/libgcrypt-config.in +@@ -154,7 +154,7 @@ if test "$echo_cflags" = "yes"; then + + tmp="" + for i in $includes $cflags_final; do +- if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then ++ if echo "$tmp" | grep -F -v -- "$i" >/dev/null; then + tmp="$tmp $i" + fi + done +@@ -175,7 +175,7 @@ if test "$echo_libs" = "yes"; then + + tmp="" + for i in $libdirs $libs_final; do +- if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then ++ if echo "$tmp" | grep -F -v -- "$i" >/dev/null; then + tmp="$tmp $i" + fi + done +-- +2.44.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index e42fa25..b670241 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -22,6 +22,8 @@ Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch +# based on 128121e74b66793fabd24e478df6ea2ab568e24a but hardcoded the "grep -F" to avoid need to autoreconf +Patch2: libgcrypt-1.10.3-fgrep.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -54,6 +56,7 @@ applications using libgcrypt. %prep %setup -q %patch 1 -p1 +%patch 2 -p1 %build # This package has a configure test which uses ASMs, but does not link the From c4f54248a0551c4b538f895d4c3a56d9d1f5ef44 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 26 Mar 2024 09:12:42 +0100 Subject: [PATCH 70/88] 1.10.3-4 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index b670241..00904d7 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.10.3 -Release: 3%{?dist} +Release: 4%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -175,6 +175,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Mar 26 2024 Jakub Jelen - 1.10.3-4 +- Replace deprecated fgrep (#2271503) + * Thu Jan 25 2024 Fedora Release Engineering - 1.10.3-3 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild From acfb1a25d81ce0763611401bc60ea7945a57018c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 19 Jun 2024 14:08:35 +0200 Subject: [PATCH 71/88] 1.11.0-1 --- .gitignore | 2 ++ libgcrypt-1.10.3-fgrep.patch | 24 ------------------------ libgcrypt.spec | 10 +++++----- sources | 4 ++-- 4 files changed, 9 insertions(+), 31 deletions(-) delete mode 100644 libgcrypt-1.10.3-fgrep.patch diff --git a/.gitignore b/.gitignore index 3359399..069ccb4 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.10.2.tar.bz2.sig /libgcrypt-1.10.3.tar.bz2 /libgcrypt-1.10.3.tar.bz2.sig +/libgcrypt-1.11.0.tar.bz2 +/libgcrypt-1.11.0.tar.bz2.sig diff --git a/libgcrypt-1.10.3-fgrep.patch b/libgcrypt-1.10.3-fgrep.patch deleted file mode 100644 index 26bf036..0000000 --- a/libgcrypt-1.10.3-fgrep.patch +++ /dev/null @@ -1,24 +0,0 @@ -diff --git a/src/libgcrypt-config.in b/src/libgcrypt-config.in ---- a/src/libgcrypt-config.in -+++ b/src/libgcrypt-config.in -@@ -154,7 +154,7 @@ if test "$echo_cflags" = "yes"; then - - tmp="" - for i in $includes $cflags_final; do -- if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then -+ if echo "$tmp" | grep -F -v -- "$i" >/dev/null; then - tmp="$tmp $i" - fi - done -@@ -175,7 +175,7 @@ if test "$echo_libs" = "yes"; then - - tmp="" - for i in $libdirs $libs_final; do -- if echo "$tmp" | fgrep -v -- "$i" >/dev/null; then -+ if echo "$tmp" | grep -F -v -- "$i" >/dev/null; then - tmp="$tmp $i" - fi - done --- -2.44.0 - diff --git a/libgcrypt.spec b/libgcrypt.spec index 00904d7..c240c9d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,16 +14,14 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.10.3 -Release: 4%{?dist} +Version: 1.11.0 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch -# based on 128121e74b66793fabd24e478df6ea2ab568e24a but hardcoded the "grep -F" to avoid need to autoreconf -Patch2: libgcrypt-1.10.3-fgrep.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -56,7 +54,6 @@ applications using libgcrypt. %prep %setup -q %patch 1 -p1 -%patch 2 -p1 %build # This package has a configure test which uses ASMs, but does not link the @@ -175,6 +172,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Wed Jun 19 2024 Jakub Jelen - 1.11.0-1 +- New upstream release (#2293064) + * Tue Mar 26 2024 Jakub Jelen - 1.10.3-4 - Replace deprecated fgrep (#2271503) diff --git a/sources b/sources index 09e5e42..4ef369d 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.10.3.tar.bz2) = 8a8d4c61a6622d8481ceb9edc88ec43f58da32e316f79f8d4775325a48f8936aaa9eb355923b39e2c267b784e9c390600daeb62e0c94f00e30bbadb0d8c0865d -SHA512 (libgcrypt-1.10.3.tar.bz2.sig) = 7b240b40992bbfd117ba6453377c3c8734aa70a43bc4e7d24b412b5f2446b85cd41e70950d2e973cc7e2da1f7669e267e276fd5f603e991b9a04919cb9bedab2 +SHA512 (libgcrypt-1.11.0.tar.bz2) = 8e093e69e3c45d30838625ca008e995556f0d5b272de1c003d44ef94633bcc0d0ef5d95e8725eb531bfafb4490ac273488633e0c801200d4666194f86c3e270e +SHA512 (libgcrypt-1.11.0.tar.bz2.sig) = 8c5ceb50d70ccdedcc1ff4b31a65a07198567b85f582e3e67699cc3e5d012bebf7b1d4903652d11905a9cd845976ad7d3642474804777d0bdc46c6847d92fe38 From 186e09a1905735564fb294c64c24ab7883b218a4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Fri, 21 Jun 2024 11:34:59 +0200 Subject: [PATCH 72/88] Unbreak s390x build --- ...e-SHA3-s390x-acceleration-for-CSHAKE.patch | 63 +++++++++++++++++++ libgcrypt.spec | 3 + 2 files changed, 66 insertions(+) create mode 100644 libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch diff --git a/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch b/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch new file mode 100644 index 0000000..0267ea0 --- /dev/null +++ b/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch @@ -0,0 +1,63 @@ +From 2486d9b5ae015c1786cb84466a751da4bc0d7122 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Thu, 20 Jun 2024 20:10:09 +0300 +Subject: [PATCH] Disable SHA3 s390x acceleration for CSHAKE + +* cipher/keccak.c (keccak_final_s390x): Add assert check for +expected SHAKE suffix. +(_gcry_cshake_customize, cshake_hash_buffers): Disable s390x +acceleration when selecting CSHAKE suffix. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/keccak.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +diff --git a/cipher/keccak.c b/cipher/keccak.c +index aaf83a62..44cc9f71 100644 +--- a/cipher/keccak.c ++++ b/cipher/keccak.c +@@ -745,6 +745,8 @@ keccak_final_s390x (void *context) + } + else + { ++ gcry_assert(ctx->suffix == SHAKE_DELIMITED_SUFFIX); ++ + klmd_shake_execute (ctx->kimd_func, &ctx->state, NULL, 0, ctx->buf, + ctx->count); + ctx->count = 0; +@@ -1497,9 +1499,14 @@ _gcry_cshake_customize (void *context, struct gcry_cshake_customization *p) + /* No customization */ + return 0; + ++ ctx->suffix = CSHAKE_DELIMITED_SUFFIX; ++#ifdef USE_S390X_CRYPTO ++ /* CSHAKE suffix is not supported by s390x/kimd. */ ++ ctx->kimd_func = 0; ++#endif ++ + len_written = cshake_input_n (ctx, p->n, p->n_len); + cshake_input_s (ctx, p->s, p->s_len, len_written); +- ctx->suffix = CSHAKE_DELIMITED_SUFFIX; + return 0; + } + +@@ -1536,9 +1543,14 @@ cshake_hash_buffers (const gcry_md_spec_t *spec, void *outbuf, size_t nbytes, + size_t s_len = iov[1].len; + size_t len; + ++ ctx.suffix = CSHAKE_DELIMITED_SUFFIX; ++#ifdef USE_S390X_CRYPTO ++ /* CSHAKE suffix is not supported by s390x/kimd. */ ++ ctx.kimd_func = 0; ++#endif ++ + len = cshake_input_n (&ctx, n, n_len); + cshake_input_s (&ctx, s, s_len, len); +- ctx.suffix = CSHAKE_DELIMITED_SUFFIX; + } + iovcnt -= 2; + iov += 2; +-- +2.43.0 diff --git a/libgcrypt.spec b/libgcrypt.spec index c240c9d..9931ad9 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -22,6 +22,8 @@ Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source2: wk@g10code.com # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch +# https://dev.gnupg.org/T7167 +Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -54,6 +56,7 @@ applications using libgcrypt. %prep %setup -q %patch 1 -p1 +%patch 2 -p1 %build # This package has a configure test which uses ASMs, but does not link the From 4949b993a1e7bfcf65cf8978da9011cc2d1b8771 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 3 Jul 2024 17:57:05 +0200 Subject: [PATCH 73/88] Verify tarball signatures --- libgcrypt.spec | 4 +- signature_key.asc | 86 ++ wk@g10code.com | 2007 --------------------------------------------- 3 files changed, 89 insertions(+), 2008 deletions(-) create mode 100644 signature_key.asc delete mode 100644 wk@g10code.com diff --git a/libgcrypt.spec b/libgcrypt.spec index 9931ad9..17fd93c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -19,7 +19,7 @@ Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig -Source2: wk@g10code.com +Source2: https://gnupg.org/signature_key.asc # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch # https://dev.gnupg.org/T7167 @@ -37,6 +37,7 @@ BuildRequires: gawk, libgpg-error-devel >= 1.11, pkgconfig BuildRequires: texinfo BuildRequires: autoconf, automake, libtool BuildRequires: make +BuildRequires: gnupg2 %package devel Summary: Development files for the %{name} package @@ -54,6 +55,7 @@ in GNU Privacy Guard. This package contains files needed to develop applications using libgcrypt. %prep +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' %setup -q %patch 1 -p1 %patch 2 -p1 diff --git a/signature_key.asc b/signature_key.asc new file mode 100644 index 0000000..151e8fa --- /dev/null +++ b/signature_key.asc @@ -0,0 +1,86 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +eiInsGZ/+h5XYrpXTgA= +=4+Sn +-----END PGP PUBLIC KEY BLOCK----- diff --git a/wk@g10code.com b/wk@g10code.com deleted file mode 100644 index 5e193e3..0000000 --- a/wk@g10code.com +++ /dev/null @@ -1,2007 +0,0 @@ -Login: wk Name: Werner Koch -No project. -No plan. -Public key: - pub 1024D/5B0358A2 1999-03-15 [expires: 2011-07-11] - uid Werner Koch - uid Werner Koch - uid Werner Koch - uid Werner Koch - sub 1024D/010A57ED 2004-03-21 [expires: 2007-12-31] - sub 2048R/C3680A6E 2006-01-01 [expires: 2007-12-31] - - pub 1024R/1CE0C630 2006-01-01 [expires: 2008-12-31] - uid Werner Koch (dist sig) - - pub 1024R/37D92FFB 2003-11-17 [expires: 2009-12-31] - uid g10 Code (code signing key 1) - - pub 1024D/57548DCD 1998-07-07 [expired: 2005-12-31] - uid Werner Koch (gnupg sig) - - -5B0358A2 is my main key. -1CE0C630 is used to sign software distributions. -37D92FFB is used to sign certain source files. -57548DCD was used to sign GNU crypto software; - it has been superseded by 1CE0C630. - -Please note that I use a subkey for signing messages; some old OpenPGP -implementations may not be able to check such a signature. The primary -key is stored at a more or less secure place and only used on a spare -laptop which is not connected to any network. If you find a key -certified by this one, you can be sure that I personally met this -person and checked the name part of the user ID against an official -looking passport or another suitable photo id. My signature does not -say anything about the email address (I merely check that the address -looks plausible). - - ------BEGIN PGP PUBLIC KEY BLOCK----- -Version: GnuPG v1.4.7 (GNU/Linux) - -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 -Ooh6BBMRAgA6BQJEXmVkMxpodHRwOi8vd3d3LnNjLWRlbHBoaW4tZXNjaHdlaWxl -ci5kZS9wZ3AvaW5kZXguaHRtbAAKCRC0deIHurWCKcwdAJ4hvG79xMFKtYL0GGP8 -WuvvxnMnzQCfZUjHFhMNMGgrCPthD6oeNaw2FxCIRgQTEQIABgUCRFz9JwAKCRCK -o2Kv6XIyzVjaAJ9MSW3iP1fUZqr7xdbj/PLkHLzJeACfZNe6IgDrJk9E3a/8IKZi -E4iYtqWIRgQTEQIABgUCRFz9LwAKCRCn31hycNRMI+EXAKDRHf6ZRUGa6T7Uosgx -huo5I3sK6gCfRxthF9FN1SXK11O+tjRS1mwN0JaIYwQTEQIAGwUCNxrPkAUJDMl8 -gAMLCgMDFQMCAxYCAQIXgAASCRBd4kmWWwNYogdlR1BHAAEBXcIAnjv7ON5AiwzC -LBwm9h9ywufXJQuVAJ9RMq6lpPqnDly6UCKz+kGt0EplyIhmBBMRAgAeAwsKAwMV -AwIDFgIBAheAAhkBBQJAXdnoBQkTa4v/ABIHZUdQRwABAQkQXeJJllsDWKLs0gCg -y5RdOqhFvwUFYWj+dHb4LGt7xi0AoKduFxGMuM/loPShQnjvk/VVFesAiF4EExEC -AB4DCwoDAxUDAgMWAgECF4ACGQEFAkBd2egFCRNri/8ACgkQXeJJllsDCRDs0gCg -y5RdOqhFvwUFYWj+dHb4LGt7xi0AoKduFxGMuM/loPShQnjvk/VVFesAiQEVAwUQ -O0HCUNImKUTOasbBAQFLZwgAkgMC/ximskOjL/CxghgdkSWkDFdpEr3XYhzUdLes -WgN4AM28mGZZKA9la7dXXRrKYkxhX8mpL4C3Q9LnrafP+Zn1c8mTuNIxX86j7iZA -IksoZ4D2csN8NSMYT9pKK6jZP1IOckCFBBI0W/yMGUGulDitWj4TwIArf2xQkV73 -//////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////// -/////////////////////////////////////////////4hGBBMRAgAGBQJDRBuk -AAoJEOrUtZD2iZvAafoAoKReCbMFRrpwzb2tS7M6iHDbN9E+AJoDy8nLf8A4f/EV -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 -wZyP4MwTIOb4NIhGBBARAgAGBQJEKFdaAAoJEBH0xB6z+64zBhUAoJ6kWu5gDqHB -Z8Wan0YynEZi6tKyAJsHBacxx6UNYPENlVXlb0xl+kssa4h6BBMRAgA6BQJEXmVA -MxpodHRwOi8vd3d3LnNjLWRlbHBoaW4tZXNjaHdlaWxlci5kZS9wZ3AvaW5kZXgu -aHRtbAAKCRCUj9ag4Q9QLulZAJ992LLlu7wU5sJddqnffDzPoKh69QCgoX8QzBEi -SZjLKSrALwLCTYI/akSIegQTEQIAOgUCRF5lZDMaaHR0cDovL3d3dy5zYy1kZWxw -aGluLWVzY2h3ZWlsZXIuZGUvcGdwL2luZGV4Lmh0bWwACgkQtHXiB7q1gikU0QCf -ZM81Hr4p7ZPwxMZW+TVcRdaSIjoAoMq7mN4xSLtRsB/lGlFLhc1O4soLiEYEExEC -AAYFAkRc/SoACgkQiqNir+lyMs3HBACfb7fa3KzNGB9Oma3KDWeC42feCzAAoIfF -w3OXxtigxx8+AowiXGsZmqI+iEYEExECAAYFAkRc/TEACgkQp99YcnDUTCOrZQCg -gV7PoPMl1d+gvPTiuUAZm8UG/dYAn3PlOcTP4vxayC7OGSkoDA8Dut+KiEYEExEC -AAYFAkNEG6QACgkQ6tS1kPaJm8DI0ACfRfci8SHm+sQpjzKqr0zxfJT5yF0AnA37 -mn7nQyY28SJ2sddCo/f1JhvAiEYEEBECAAYFAkQFglgACgkQb11ZaBzVLeiG9wCf -aX6+h8bpMOraCn/sH1yQb6aI34EAoLzx4H6lGdyqnQTYiLXSrBTrto/niEYEEBEC -AAYFAkQGCjQACgkQmsnSLGNcY0vZ4wCgvBjcB5ABcNYRMEFSWsClxhaRAqUAmwUv -MA9NWdLk0pcUndbE3w70B5hUiEwEEhECAAwFAkQGKycFgwZSqcEACgkQ3+ZXkjKV -xc2qMwCfdew+RX+7ultYmO0Y8gRoLJzjBfgAn1UkZILe3+NKZBJTd1ZowJQiljHI -iEwEEhECAAwFAkQGK2cFgwZSqYEACgkQoOUVvzmICVQuFwCgqbjde48qPvUqLEip -he/zFq6pqgAAn1dXi6z+1s+bHavwCQK/q+3K5gdHiJwEEwECAAYFAkQNdesACgkQ -/dJ0ek5GOmrWRgQAoFF9IdTs5vX5OIDKIHW+d4aJfPg6w91SKkfpElDxNqZuk3rA -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 -nj+zW9f9Z2M0K2r+gldEC2Ew2yTl -=I1gH ------END PGP PUBLIC KEY BLOCK----- From b73849fad4e17c992e9e948dd9e6efe4cc46f757 Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 18 Jul 2024 13:54:55 +0000 Subject: [PATCH 74/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 17fd93c..eebb9aa 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.0 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -177,6 +177,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 18 2024 Fedora Release Engineering - 1.11.0-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild + * Wed Jun 19 2024 Jakub Jelen - 1.11.0-1 - New upstream release (#2293064) From 493faf840cc5bc3258bbcff7e4276951ed8082b0 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 Jul 2024 13:38:35 +0200 Subject: [PATCH 75/88] Remove _lto_cflags override as it should be default --- libgcrypt.spec | 9 --------- 1 file changed, 9 deletions(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index eebb9aa..44f5232 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -61,15 +61,6 @@ applications using libgcrypt. %patch 2 -p1 %build -# This package has a configure test which uses ASMs, but does not link the -# resultant .o files. As such the ASM test is always successful, even on -# architectures were the ASM is not valid when compiling with LTO. -# -# -ffat-lto-objects is sufficient to address this issue. It is the default -# for F33, but is expected to only be enabled for packages that need it in -# F34, so we use it here explicitly -%define _lto_cflags -flto=auto -ffat-lto-objects - # should be all algorithms except SM3 and SM4, aria export DIGESTS='crc gostr3411-94 md4 md5 rmd160 sha1 sha256 sha512 sha3 tiger whirlpool stribog blake2' export CIPHERS='arcfour blowfish cast5 des aes twofish serpent rfc2268 seed camellia idea salsa20 gost28147 chacha20' From 0b1eb3742d4d3bc7f9a37cb7a5d27e94d26fdf09 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 Jul 2024 13:40:29 +0200 Subject: [PATCH 76/88] disable -O flag mnging as the jent support is disabled anyway --- libgcrypt.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index 44f5232..b7d86b3 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -76,6 +76,7 @@ autoreconf -f --enable-noexecstack \ --enable-hmac-binary-check=%{hmackey} \ --disable-jent-support \ + --disable-O-flag-munging \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" From 98af486ed06636cfc6609db7766f83ed50267962 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Thu, 25 Jul 2024 14:00:08 +0200 Subject: [PATCH 77/88] 1.11.0-3 --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index b7d86b3..0090ec5 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.0 -Release: 2%{?dist} +Release: 3%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -169,6 +169,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 25 2024 Jakub Jelen - 1.11.0-3 +- Disable -O flag munging and remove needles modification of LTO flags. + * Thu Jul 18 2024 Fedora Release Engineering - 1.11.0-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild From ebd8acdd2ef16401e716e7ec83cdb4e083f753aa Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Sat, 27 Jul 2024 12:31:49 +0200 Subject: [PATCH 78/88] Unbreak CF protection on the library --- libgcrypt-1.11.0-cf-protection.patch | 191 +++++++++++++++++++++++++++ libgcrypt.spec | 3 + 2 files changed, 194 insertions(+) create mode 100644 libgcrypt-1.11.0-cf-protection.patch diff --git a/libgcrypt-1.11.0-cf-protection.patch b/libgcrypt-1.11.0-cf-protection.patch new file mode 100644 index 0000000..e7ead95 --- /dev/null +++ b/libgcrypt-1.11.0-cf-protection.patch @@ -0,0 +1,191 @@ +From de3a04203b33c2248400392b535d2ab133bcd752 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Sat, 27 Jul 2024 08:16:56 +0300 +Subject: [PATCH] Do not build rijndael-vaes-avx2-i386 on x86-64 + +* configure.ac: Enable building i386 "rijndael-vaes" only +on i?86 host instead of x86 MPI arch ("i?86 + x86-64"). +-- + +Signed-off-by: Jussi Kivilinna +--- + configure.ac | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index d3dffb4b..1e182552 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3025,6 +3025,11 @@ if test "$found" = "1" ; then + AC_DEFINE(USE_AES, 1, [Defined if this module should be included]) + + case "${host}" in ++ i?86-*-*) ++ # Build with the VAES/AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-i386.lo" ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-avx2-i386.lo" ++ ;; + x86_64-*-*) + # Build with the assembly implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-amd64.lo" +@@ -3089,10 +3094,6 @@ if test "$found" = "1" ; then + + # Build with the Padlock implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-padlock.lo" +- +- # Build with the VAES/AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-i386.lo" +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-avx2-i386.lo" + ;; + esac + fi +-- +2.43.0 + + +From 9178af96038acd295d02a4c405c19435dce92ad8 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Fri, 26 Jul 2024 10:59:12 +0300 +Subject: [PATCH 1/2] Add CET support for x86-64 assembly + +* cipher/asm-common-amd64.h (ENDBRANCH): New. +(CFI_STARTPROC): Add ENDBRANCH. +[__CET__] (note.gnu.property): Add CET property section. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/asm-common-amd64.h | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h +index 3fa065e8..465ef62b 100644 +--- a/cipher/asm-common-amd64.h ++++ b/cipher/asm-common-amd64.h +@@ -76,9 +76,15 @@ + # endif + #endif + ++#ifdef __CET__ ++#define ENDBRANCH endbr64 ++#else ++#define ENDBRANCH /*_*/ ++#endif ++ + #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES + /* CFI directives to emit DWARF stack unwinding information. */ +-# define CFI_STARTPROC() .cfi_startproc ++# define CFI_STARTPROC() .cfi_startproc; ENDBRANCH + # define CFI_ENDPROC() .cfi_endproc + # define CFI_REMEMBER_STATE() .cfi_remember_state + # define CFI_RESTORE_STATE() .cfi_restore_state +@@ -146,7 +152,7 @@ + DW_SLEB128_28BIT(rsp_offs) + + #else +-# define CFI_STARTPROC() ++# define CFI_STARTPROC() ENDBRANCH + # define CFI_ENDPROC() + # define CFI_REMEMBER_STATE() + # define CFI_RESTORE_STATE() +@@ -214,4 +220,24 @@ + vpopcntb xmm16, xmm16; /* Supported only by newer AVX512 CPUs. */ \ + vpxord ymm16, ymm16, ymm16; + ++#ifdef __CET__ ++/* Generate CET property for all assembly files including this header. */ ++ELF(.section .note.gnu.property,"a") ++ELF(.align 8) ++ELF(.long 1f - 0f) ++ELF(.long 4f - 1f) ++ELF(.long 5) ++ELF(0:) ++ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ ++ELF(1:) ++ELF(.align 8) ++ELF(.long 0xc0000002) ++ELF(.long 3f - 2f) ++ELF(2:) ++ELF(.long 0x3) ++ELF(3:) ++ELF(.align 8) ++ELF(4:) ++#endif ++ + #endif /* GCRY_ASM_COMMON_AMD64_H */ +-- +2.43.0 + +From e7c81e64b1a81455ce72c54607ce6ab35c24f407 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Fri, 26 Jul 2024 11:09:37 +0300 +Subject: [PATCH 2/2] Add CET support for i386 assembly + +* cipher/asm-common-i386.h (ENDBRANCH): New. +(CFI_STARTPROC): Add ENDBRANCH. +[__CET__] (note.gnu.property): Add CET property section. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/asm-common-i386.h | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 deletions(-) + +diff --git a/cipher/asm-common-i386.h b/cipher/asm-common-i386.h +index d746ebc4..346a8ff2 100644 +--- a/cipher/asm-common-i386.h ++++ b/cipher/asm-common-i386.h +@@ -59,9 +59,15 @@ + movl name##@GOT(%reg), %reg; + #endif + ++#ifdef __CET__ ++#define ENDBRANCH endbr32 ++#else ++#define ENDBRANCH /*_*/ ++#endif ++ + #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES + /* CFI directives to emit DWARF stack unwinding information. */ +-# define CFI_STARTPROC() .cfi_startproc ++# define CFI_STARTPROC() .cfi_startproc; ENDBRANCH + # define CFI_ENDPROC() .cfi_endproc + # define CFI_REMEMBER_STATE() .cfi_remember_state + # define CFI_RESTORE_STATE() .cfi_restore_state +@@ -121,7 +127,7 @@ + DW_SLEB128_28BIT(esp_offs) + + #else +-# define CFI_STARTPROC() ++# define CFI_STARTPROC() ENDBRANCH + # define CFI_ENDPROC() + # define CFI_REMEMBER_STATE() + # define CFI_RESTORE_STATE() +@@ -158,4 +164,24 @@ + vpopcntb xmm7, xmm7; /* Supported only by newer AVX512 CPUs. */ \ + vpxord ymm7, ymm7, ymm7; + ++#ifdef __CET__ ++/* Generate CET property for all assembly files including this header. */ ++ELF(.section .note.gnu.property,"a") ++ELF(.align 4) ++ELF(.long 1f - 0f) ++ELF(.long 4f - 1f) ++ELF(.long 5) ++ELF(0:) ++ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ ++ELF(1:) ++ELF(.align 4) ++ELF(.long 0xc0000002) ++ELF(.long 3f - 2f) ++ELF(2:) ++ELF(.long 0x3) ++ELF(3:) ++ELF(.align 4) ++ELF(4:) ++#endif ++ + #endif /* GCRY_ASM_COMMON_AMD64_H */ +-- +2.43.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index 0090ec5..74d3528 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -24,6 +24,8 @@ Source2: https://gnupg.org/signature_key.asc Patch1: libgcrypt-1.10.1-annobin.patch # https://dev.gnupg.org/T7167 Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch +# https://dev.gnupg.org/T7220 +Patch3: libgcrypt-1.11.0-cf-protection.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -59,6 +61,7 @@ applications using libgcrypt. %setup -q %patch 1 -p1 %patch 2 -p1 +%patch 3 -p1 %build # should be all algorithms except SM3 and SM4, aria From efefee810753ddc19174e6532952fd156dedba83 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Aug 2024 09:03:18 +0200 Subject: [PATCH 79/88] Use upstream commits for CF protection --- libgcrypt-1.11.0-cf-protection.patch | 155 +++++++++++++++++++++++++-- 1 file changed, 146 insertions(+), 9 deletions(-) diff --git a/libgcrypt-1.11.0-cf-protection.patch b/libgcrypt-1.11.0-cf-protection.patch index e7ead95..ece660e 100644 --- a/libgcrypt-1.11.0-cf-protection.patch +++ b/libgcrypt-1.11.0-cf-protection.patch @@ -1,12 +1,55 @@ -From de3a04203b33c2248400392b535d2ab133bcd752 Mon Sep 17 00:00:00 2001 +From 7ee2e73495d051ca09dd57c90132a7a9cc53bc62 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Fri, 26 Jul 2024 11:00:30 +0300 +Subject: [PATCH] asm-common-amd64: add missing CFI directives for large memory + model code + +* cipher/asm-common-amd64.h [__code_model_large__] +(GET_EXTERN_POINTER): Add CFI_PUSH/CFI_POP directives. +-- + +Signed-off-by: Jussi Kivilinna +--- + cipher/asm-common-amd64.h | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h +index 870fef9a..3fa065e8 100644 +--- a/cipher/asm-common-amd64.h ++++ b/cipher/asm-common-amd64.h +@@ -59,14 +59,18 @@ + # ifdef __code_model_large__ + # define GET_EXTERN_POINTER(name, reg) \ + pushq %r15; \ ++ CFI_PUSH(%r15); \ + pushq %r14; \ ++ CFI_PUSH(%r14); \ + 1: leaq 1b(%rip), reg; \ + movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \ + movabsq $name@GOT, %r15; \ + addq %r14, reg; \ + popq %r14; \ ++ CFI_POP(%r14); \ + movq (reg, %r15), reg; \ +- popq %r15; ++ popq %r15; \ ++ CFI_POP(%r15); + # else + # define GET_EXTERN_POINTER(name, reg) movq name@GOTPCREL(%rip), reg + # endif +-- +2.45.2 + +From dd42a4e03e066c49a6d83e0d3a07e4261d77121a Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Sat, 27 Jul 2024 08:16:56 +0300 -Subject: [PATCH] Do not build rijndael-vaes-avx2-i386 on x86-64 +Subject: [PATCH] Do not build i386 assembly on x86-64 * configure.ac: Enable building i386 "rijndael-vaes" only on i?86 host instead of x86 MPI arch ("i?86 + x86-64"). -- +GnuPG-bug-id: 7220 Signed-off-by: Jussi Kivilinna --- configure.ac | 9 +++++---- @@ -40,19 +83,112 @@ index d3dffb4b..1e182552 100644 esac fi -- -2.43.0 +2.45.2 +From 5797d75e3b916caf504bed73a8629c6c168be58d Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Sat, 27 Jul 2024 08:50:57 +0300 +Subject: [PATCH] Do not build amd64 assembly on i386 -From 9178af96038acd295d02a4c405c19435dce92ad8 Mon Sep 17 00:00:00 2001 +* configure.ac: Build "serpent-avx2-amd64" and +"camellia-*-amd64" only on x86-64. +-- + +GnuPG-bug-id: 7220 +Signed-off-by: Jussi Kivilinna +--- + configure.ac | 50 +++++++++++++++++++++++++++----------------------- + 1 file changed, 27 insertions(+), 23 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 1e182552..191aa38d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3133,14 +3133,14 @@ if test "$found" = "1" ; then + x86_64-*-*) + # Build with the SSE2 implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-sse2-amd64.lo" ++ ++ if test x"$avx2support" = xyes ; then ++ # Build with the AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" ++ fi + ;; + esac + +- if test x"$avx2support" = xyes ; then +- # Build with the AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" +- fi +- + if test x"$avx512support" = xyes ; then + # Build with the AVX512 implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx512-x86.lo" +@@ -3186,28 +3186,32 @@ if test "$found" = "1" ; then + ;; + esac + +- if test x"$avxsupport" = xyes ; then +- if test x"$aesnisupport" = xyes ; then +- # Build with the AES-NI/AVX implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx-amd64.lo" +- fi +- fi ++ case "${host}" in ++ x86_64-*-*) ++ if test x"$avxsupport" = xyes ; then ++ if test x"$aesnisupport" = xyes ; then ++ # Build with the AES-NI/AVX implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx-amd64.lo" ++ fi ++ fi + +- if test x"$avx2support" = xyes ; then +- if test x"$aesnisupport" = xyes ; then +- # Build with the AES-NI/AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx2-amd64.lo" ++ if test x"$avx2support" = xyes ; then ++ if test x"$aesnisupport" = xyes ; then ++ # Build with the AES-NI/AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx2-amd64.lo" + +- # Build with the VAES/AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-vaes-avx2-amd64.lo" ++ # Build with the VAES/AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-vaes-avx2-amd64.lo" + +- # Build with the GFNI/AVX2 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx2-amd64.lo" ++ # Build with the GFNI/AVX2 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx2-amd64.lo" + +- # Build with the GFNI/AVX512 implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx512-amd64.lo" +- fi +- fi ++ # Build with the GFNI/AVX512 implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx512-amd64.lo" ++ fi ++ fi ++ ;; ++ esac + fi + + LIST_MEMBER(idea, $enabled_ciphers) +-- +2.45.2 + +From d69e6a29b986cf1cb21e09d337a0de2564ef34f2 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Fri, 26 Jul 2024 10:59:12 +0300 -Subject: [PATCH 1/2] Add CET support for x86-64 assembly +Subject: [PATCH] Add CET support for x86-64 assembly * cipher/asm-common-amd64.h (ENDBRANCH): New. (CFI_STARTPROC): Add ENDBRANCH. [__CET__] (note.gnu.property): Add CET property section. -- +GnuPG-bug-id: 7220 Signed-off-by: Jussi Kivilinna --- cipher/asm-common-amd64.h | 30 ++++++++++++++++++++++++++++-- @@ -114,18 +250,19 @@ index 3fa065e8..465ef62b 100644 + #endif /* GCRY_ASM_COMMON_AMD64_H */ -- -2.43.0 +2.45.2 -From e7c81e64b1a81455ce72c54607ce6ab35c24f407 Mon Sep 17 00:00:00 2001 +From 64ec13d11b08fbe31cc6f83e9464e7e251d41019 Mon Sep 17 00:00:00 2001 From: Jussi Kivilinna Date: Fri, 26 Jul 2024 11:09:37 +0300 -Subject: [PATCH 2/2] Add CET support for i386 assembly +Subject: [PATCH] Add CET support for i386 assembly * cipher/asm-common-i386.h (ENDBRANCH): New. (CFI_STARTPROC): Add ENDBRANCH. [__CET__] (note.gnu.property): Add CET property section. -- +GnuPG-bug-id: 7220 Signed-off-by: Jussi Kivilinna --- cipher/asm-common-i386.h | 30 ++++++++++++++++++++++++++++-- @@ -187,5 +324,5 @@ index d746ebc4..346a8ff2 100644 + #endif /* GCRY_ASM_COMMON_AMD64_H */ -- -2.43.0 +2.45.2 From 6582e15a918a6279b1ffaa1f163d5e724e8f3d7f Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Aug 2024 09:04:08 +0200 Subject: [PATCH 80/88] Fix PAC/BTI protection on Aarch64 --- libgcrypt-1.11.0-pac-bti-protection.patch | 229 ++++++++++++++++++++++ libgcrypt.spec | 2 + 2 files changed, 231 insertions(+) create mode 100644 libgcrypt-1.11.0-pac-bti-protection.patch diff --git a/libgcrypt-1.11.0-pac-bti-protection.patch b/libgcrypt-1.11.0-pac-bti-protection.patch new file mode 100644 index 0000000..3c713ab --- /dev/null +++ b/libgcrypt-1.11.0-pac-bti-protection.patch @@ -0,0 +1,229 @@ +From afdd68b162103820edb72ad170f8ee26f206b396 Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Sun, 4 Aug 2024 18:51:34 +0300 +Subject: [PATCH] Add PAC/BTI support for AArch64 assembly + +* cipher/asm-common-aarch64.h (AARCH64_BTI_PROPERTY_FLAG) +(AARCH64_HINT_BTI_C, AARCH64_PAC_PROPERTY_FLAG) +(note.gnu.property): New. +(CFI_STARTPROC): Add AARCH64_HINT_BTI_C. +-- + +GnuPG-bug-id: 7220 +Signed-off-by: Jussi Kivilinna +--- + cipher/asm-common-aarch64.h | 50 +++++++++++++++++++++++++++++++++++-- + 1 file changed, 48 insertions(+), 2 deletions(-) + +diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h +index 3a72d7c4..ff65ea6a 100644 +--- a/cipher/asm-common-aarch64.h ++++ b/cipher/asm-common-aarch64.h +@@ -45,9 +45,25 @@ + add reg, reg, #:lo12:name ; + #endif + ++#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 ++# define AARCH64_BTI_PROPERTY_FLAG (1 << 0) ++# define AARCH64_HINT_BTI_C \ ++ hint #34 ++#else ++# define AARCH64_BTI_PROPERTY_FLAG 0 /* No BTI */ ++# define AARCH64_HINT_BTI_C /*_*/ ++#endif ++ ++#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 3) != 0 ++/* PAC enabled, signed with either A or B key. */ ++# define AARCH64_PAC_PROPERTY_FLAG (1 << 1) ++#else ++# define AARCH64_PAC_PROPERTY_FLAG 0 /* No PAC */ ++#endif ++ + #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES + /* CFI directives to emit DWARF stack unwinding information. */ +-# define CFI_STARTPROC() .cfi_startproc ++# define CFI_STARTPROC() .cfi_startproc; AARCH64_HINT_BTI_C + # define CFI_ENDPROC() .cfi_endproc + # define CFI_REMEMBER_STATE() .cfi_remember_state + # define CFI_RESTORE_STATE() .cfi_restore_state +@@ -89,7 +105,7 @@ + DW_SLEB128_28BIT(rsp_offs) + + #else +-# define CFI_STARTPROC() ++# define CFI_STARTPROC() AARCH64_HINT_BTI_C + # define CFI_ENDPROC() + # define CFI_REMEMBER_STATE() + # define CFI_RESTORE_STATE() +@@ -129,4 +145,34 @@ + ldp d8, d9, [sp], #16; \ + CFI_ADJUST_CFA_OFFSET(-16); + ++#if (AARCH64_BTI_PROPERTY_FLAG | AARCH64_PAC_PROPERTY_FLAG) ++/* Generate PAC/BTI property for all assembly files including this header. ++ * ++ * libgcrypt support these extensions: ++ * - Armv8.3-A Pointer Authentication (PAC): ++ * As currently all AArch64 assembly functions are leaf functions and do ++ * not store/load link register LR, we just mark PAC as supported. ++ * ++ * - Armv8.5-A Branch Target Identification (BTI): ++ * All AArch64 assembly functions get branch target instruction through ++ * CFI_STARTPROC macro. ++ */ ++ELF(.section .note.gnu.property,"a") ++ELF(.balign 8) ++ELF(.long 1f - 0f) ++ELF(.long 4f - 1f) ++ELF(.long 5) ++ELF(0:) ++ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ ++ELF(1:) ++ELF(.balign 8) ++ELF(.long 0xc0000000) ++ELF(.long 3f - 2f) ++ELF(2:) ++ELF(.long (AARCH64_BTI_PROPERTY_FLAG | AARCH64_PAC_PROPERTY_FLAG)) ++ELF(3:) ++ELF(.balign 8) ++ELF(4:) ++#endif ++ + #endif /* GCRY_ASM_COMMON_AARCH64_H */ +-- +2.43.0 + +From 07706d69f238f6a3bfc3f74145686a02decbee9c Mon Sep 17 00:00:00 2001 +From: Jussi Kivilinna +Date: Mon, 5 Aug 2024 20:18:05 +0300 +Subject: [PATCH] Do not build 32-bit ARM assembly on Aarch64 + +* configure.ac: Build "serpent-armv7-neon", "salsa20-armv7-neon", +"chacha20-armv7-neon", "sha512-armv7-neon" and "keccak-armv7-neon" +only on 32-bit ARM. +-- + +GnuPG-bug-id: 7220 +Signed-off-by: Jussi Kivilinna +--- + configure.ac | 54 ++++++++++++++++++++++++++++------------------------ + 1 file changed, 29 insertions(+), 25 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 191aa38d..2b6ddb7b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3139,17 +3139,18 @@ if test "$found" = "1" ; then + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" + fi + ;; ++ arm*-*-*) ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-armv7-neon.lo" ++ fi ++ ;; + esac + + if test x"$avx512support" = xyes ; then + # Build with the AVX512 implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx512-x86.lo" + fi +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(rfc2268, $enabled_ciphers) +@@ -3230,12 +3231,13 @@ if test "$found" = "1" ; then + # Build with the assembly implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-amd64.lo" + ;; ++ arm*-*-*) ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-armv7-neon.lo" ++ fi ++ ;; + esac +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(gost28147, $enabled_ciphers) +@@ -3256,6 +3258,12 @@ if test "$found" = "1" ; then + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-amd64-avx2.lo" + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-amd64-avx512.lo" + ;; ++ arm*-*-*) ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-armv7-neon.lo" ++ fi ++ ;; + aarch64-*-*) + # Build with the assembly implementation + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-aarch64.lo" +@@ -3282,11 +3290,6 @@ if test "$found" = "1" ; then + GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-s390x.lo" + ;; + esac +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(sm4, $enabled_ciphers) +@@ -3491,6 +3494,11 @@ if test "$found" = "1" ; then + arm*-*-*) + # Build with the assembly implementation + GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-arm.lo" ++ ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-armv7-neon.lo" ++ fi + ;; + aarch64-*-*) + # Build with the assembly implementation +@@ -3510,11 +3518,6 @@ if test "$found" = "1" ; then + # Build with the crypto extension implementation + GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-ppc.lo" + esac +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(sha3, $enabled_digests) +@@ -3527,12 +3530,13 @@ if test "$found" = "1" ; then + # Build with the assembly implementation + GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-amd64-avx512.lo" + ;; ++ arm*-*-*) ++ if test x"$neonsupport" = xyes ; then ++ # Build with the NEON implementation ++ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-armv7-neon.lo" ++ fi ++ ;; + esac +- +- if test x"$neonsupport" = xyes ; then +- # Build with the NEON implementation +- GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-armv7-neon.lo" +- fi + fi + + LIST_MEMBER(tiger, $enabled_digests) +-- +2.43.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index 74d3528..e4ab400 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -26,6 +26,7 @@ Patch1: libgcrypt-1.10.1-annobin.patch Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch # https://dev.gnupg.org/T7220 Patch3: libgcrypt-1.11.0-cf-protection.patch +Patch4: libgcrypt-1.11.0-pac-bti-protection.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -62,6 +63,7 @@ applications using libgcrypt. %patch 1 -p1 %patch 2 -p1 %patch 3 -p1 +%patch 4 -p1 %build # should be all algorithms except SM3 and SM4, aria From 65c9f9c6a764fd46f2f1f12aa94b6c100358c89c Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Aug 2024 09:04:41 +0200 Subject: [PATCH 81/88] Run annocheck as part of build to catch issues early --- libgcrypt.spec | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libgcrypt.spec b/libgcrypt.spec index e4ab400..2c08d1c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -41,6 +41,7 @@ BuildRequires: texinfo BuildRequires: autoconf, automake, libtool BuildRequires: make BuildRequires: gnupg2 +BuildRequires: annobin-annocheck binutils %package devel Summary: Development files for the %{name} package @@ -93,6 +94,8 @@ make check # try in faked FIPS mode too LIBGCRYPT_FORCE_FIPS_MODE=1 make check +PROFILE=%{?dist} annocheck --ignore-unknown --verbose --profile=${PROFILE:1} $RPM_BUILD_ROOT%{gcrylibdir}/libgcrypt.so.20.5.0 + # Add generation of HMAC checksums of the final stripped binaries %define libpath $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname}.?.? %define __spec_install_post \ From 9c274d3bde2a67a4defaad5504803fb30ca8c8e4 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Oct 2024 17:39:29 +0100 Subject: [PATCH 82/88] Fix CVE-2024-2236 --- libgcrypt-1.11.0-marvin.patch | 2123 +++++++++++++++++++++++++++++++++ libgcrypt.spec | 4 + 2 files changed, 2127 insertions(+) create mode 100644 libgcrypt-1.11.0-marvin.patch diff --git a/libgcrypt-1.11.0-marvin.patch b/libgcrypt-1.11.0-marvin.patch new file mode 100644 index 0000000..d2998f0 --- /dev/null +++ b/libgcrypt-1.11.0-marvin.patch @@ -0,0 +1,2123 @@ +From 984e245fd21ff6e0058403f620f760013a744a3a Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 7 Jun 2024 14:42:33 +0200 +Subject: [PATCH 1/7] rsa: Do not accept invalid PKCS#1.5 padding when + deciphering + +The current code can accept 0-length padding when deciphering +PKCS#1.5 ciphertext. This is against the specification and hopefully +nobody depends on this. + +-- +* cipher/rsa-common.c (_gcry_rsa_pkcs1_decode_for_enc): Fail for too + short padding. +* src/const-time.h (ct_lt_s): New. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa-common.c | 2 ++ + src/const-time.h | 6 ++++++ + 2 files changed, 8 insertions(+) + +diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c +index 1920eedd..e45cb30d 100644 +--- a/cipher/rsa-common.c ++++ b/cipher/rsa-common.c +@@ -247,6 +247,8 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + + failed |= not_found; + n0 += ct_is_zero (not_found); /* Skip the zero byte. */ ++ /* the valid padding is at least 8 bytes -- the plaintext needs to start at index 11 or later */ ++ failed |= ct_lt_s (n0, 11); + + /* To avoid an extra allocation we reuse the frame buffer. The only + caller of this function will anyway free the result soon. */ +diff --git a/src/const-time.h b/src/const-time.h +index 46eb187d..245967eb 100644 +--- a/src/const-time.h ++++ b/src/const-time.h +@@ -34,6 +34,12 @@ extern volatile unsigned int _gcry_ct_vone; + #endif + + ++static inline size_t ++ct_lt_s (size_t a, size_t b) ++{ ++ return ((a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(size_t) * 8 - 1)); ++} ++ + /* + * Return 0 if A is 0 and return 1 otherwise. + */ +-- +2.46.0 + + +From aca5bd25e819b2596754fdc6ecb1844462a5b4f0 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Wed, 10 Apr 2024 15:18:39 +0200 +Subject: [PATCH 2/7] rsa: Constant time blinding removal + +* cipher/rsa.c (secret_blinded): Use constant time mulm implementation +* configure.ac: New configure option --enable-marvin-workaround +* mpi/Makefile.am: Build constant time multiplication +* mpi/mpi-internal.h: Add constant time function prototypes +* mpi/mpi-mul-cs.c: New file with constant time multiplication and + modulo. +* mpi/mpi-mul.c (_gcry_mpi_mul_sec): New function. + (_gcry_mpi_mod_sec): New function. + (_gcry_mpi_mod_sec): New function. + (_gcry_mpi_reverse_sec): New function. + (_gcry_mpi_mulm_sec): New function. +* src/gcrypt-int.h: Add new functions. + +-- + +The current MPI code is not constant time, potentially leaking plaintext +when the attacker can observe enough decipher operations using RSA +PKCS#1.5. This is described as a Marvin Attack: + +https://eprint.iacr.org/2023/1442 + +Note, that this code is tested to be constant time only with the -O3 +optimization level. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa.c | 4 + + configure.ac | 16 +++ + mpi/Makefile.am | 4 + + mpi/mpi-internal.h | 6 ++ + mpi/mpi-mul-cs.c | 263 +++++++++++++++++++++++++++++++++++++++++++++ + mpi/mpi-mul.c | 169 +++++++++++++++++++++++++++++ + src/gcrypt-int.h | 6 ++ + 7 files changed, 468 insertions(+) + create mode 100644 mpi/mpi-mul-cs.c + +diff --git a/cipher/rsa.c b/cipher/rsa.c +index c7a809f4..2f735f9c 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -1197,7 +1197,11 @@ secret_blinded (gcry_mpi_t output, gcry_mpi_t input, + /* Undo blinding. Here we calculate: y = (x * r^-1) mod n, where x + * is the blinded decrypted data, ri is the modular multiplicative + * inverse of r and n is the RSA modulus. */ ++#ifdef WITH_MARVIN_WORKAROUND ++ mpi_mulm_sec (output, output, ri, sk->n); ++#else + mpi_mulm (output, output, ri, sk->n); ++#endif /* WITH_MARVIN_WORKAROUND */ + + _gcry_mpi_release (r); + _gcry_mpi_release (ri); +diff --git a/configure.ac b/configure.ac +index 4c45de22..3f63b88e 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -603,6 +603,22 @@ AC_ARG_ENABLE(jent-support, + jentsupport=$enableval,jentsupport=yes) + AC_MSG_RESULT($jentsupport) + ++AC_MSG_CHECKING([whether a Marvin workaround is requested]) ++AC_ARG_ENABLE(marvin-workaround, ++ AS_HELP_STRING([--enable-marvin-workaround], ++ [Enable Marvin workaround for constant time PKCS1.5 depadding]), ++ [with_marvin_workaround="$enableval"], ++ [with_marvin_workaround=no]) ++AC_MSG_RESULT($with_marvin_workaround) ++if test "$with_marvin_workaround" = no ; then ++ WITH_MARVIN_WORKAROUND='' ++else ++ AC_DEFINE(WITH_MARVIN_WORKAROUND,1, ++ [Define to provide constant time PKCS1.5 depadding]) ++fi ++AM_CONDITIONAL(WITH_MARVIN_WORKAROUND, test "x$with_marvin_workaround" != xno) ++AC_SUBST(WITH_MARVIN_WORKAROUND) ++ + # Implementation of the --disable-padlock-support switch. + AC_MSG_CHECKING([whether padlock support is requested]) + AC_ARG_ENABLE(padlock-support, +diff --git a/mpi/Makefile.am b/mpi/Makefile.am +index 6fe63fce..85679e08 100644 +--- a/mpi/Makefile.am ++++ b/mpi/Makefile.am +@@ -181,3 +181,7 @@ EXTRA_libmpi_la_SOURCES = \ + asm-common-aarch64.h \ + asm-common-amd64.h \ + asm-common-i386.h ++ ++if WITH_MARVIN_WORKAROUND ++libmpi_la_SOURCES += mpi-mul-cs.c ++endif +diff --git a/mpi/mpi-internal.h b/mpi/mpi-internal.h +index 935bf3e1..39de5161 100644 +--- a/mpi/mpi-internal.h ++++ b/mpi/mpi-internal.h +@@ -239,6 +239,12 @@ void _gcry_mpih_mul_karatsuba_case( mpi_ptr_t prodp, + mpi_ptr_t vp, mpi_size_t vsize, + struct karatsuba_ctx *ctx ); + ++#ifdef WITH_MARVIN_WORKAROUND ++/*-- mpih-mul-cs.c --*/ ++void mul_cs(mpi_limb_t *ret, mpi_limb_t *a, mpi_limb_t *b, size_t n, mpi_limb_t *tmp); ++void mod_cs(mpi_limb_t *ret, mpi_limb_t *a, size_t anum, mpi_limb_t *mod, size_t modnum, mpi_limb_t *tmp); ++size_t mod_limb_numb(size_t anum, size_t modnum); ++#endif /* WITH_MARVIN_WORKAROUND */ + + /*-- mpih-mul_1.c (or xxx/cpu/ *.S) --*/ + mpi_limb_t _gcry_mpih_mul_1( mpi_ptr_t res_ptr, mpi_ptr_t s1_ptr, +diff --git a/mpi/mpi-mul-cs.c b/mpi/mpi-mul-cs.c +new file mode 100644 +index 00000000..3f77ac94 +--- /dev/null ++++ b/mpi/mpi-mul-cs.c +@@ -0,0 +1,263 @@ ++/* Copyright (c) 2024, Hubert Kario, Red Hat ++ * Released under BSD 2-Clause License, see LICENSE for details ++ */ ++#include ++#include ++#include ++#include ++#include ++#include "mpi-internal.h" ++#include "longlong.h" ++ ++/* For multiplication we're using schoolbook multiplication, ++ * so if we have two numbers, each with 6 "digits" (words) ++ * the multiplication is calculated as follows: ++ * A B C D E F ++ * x I J K L M N ++ * -------------- ++ * N*F ++ * N*E ++ * N*D ++ * N*C ++ * N*B ++ * N*A ++ * M*F ++ * M*E ++ * M*D ++ * M*C ++ * M*B ++ * M*A ++ * L*F ++ * L*E ++ * L*D ++ * L*C ++ * L*B ++ * L*A ++ * K*F ++ * K*E ++ * K*D ++ * K*C ++ * K*B ++ * K*A ++ * J*F ++ * J*E ++ * J*D ++ * J*C ++ * J*B ++ * J*A ++ * I*F ++ * I*E ++ * I*D ++ * I*C ++ * I*B ++ * + I*A ++ * ========================== ++ * N*B N*D N*F ++ * + N*A N*C N*E ++ * + M*B M*D M*F ++ * + M*A M*C M*E ++ * + L*B L*D L*F ++ * + L*A L*C L*E ++ * + K*B K*D K*F ++ * + K*A K*C K*E ++ * + J*B J*D J*F ++ * + J*A J*C J*E ++ * + I*B I*D I*F ++ * + I*A I*C I*E ++ * ++ * 1+1 1+3 1+5 ++ * 1+0 1+2 1+4 ++ * 0+1 0+3 0+5 ++ * 0+0 0+2 0+4 ++ * ++ * 0 1 2 3 4 5 6 ++ * which requires n^2 multiplications and 2n full length additions ++ * as we can keep every other result of limb multiplication in two separate ++ * limbs ++ */ ++ ++typedef mpi_limb_t limb_t; ++#if BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG_LONG ++#define LIMB_BIT_SIZE 64 ++#define LIMB_BYTE_SIZE 8 ++#elif BYTES_PER_MPI_LIMB == SIZEOF_UNSIGNED_LONG ++#define LIMB_BIT_SIZE 32 ++#define LIMB_BYTE_SIZE 4 ++/* if we're on a 32 bit platform */ ++#else ++#define LIMB_BIT_SIZE 16 ++#define LIMB_BYTE_SIZE 2 ++/* ++ * if the compiler doesn't have either a 128bit data type nor a "return ++ * high 64 bits of multiplication" ++ */ ++#endif ++ ++/* add two limbs with carry in, return carry out */ ++static limb_t ++_add_limb (limb_t *ret, limb_t a, limb_t b, limb_t carry) ++{ ++ limb_t carry1, carry2, t; ++ add_ssaaaa (carry1, t, 0, a, 0, carry); ++ add_ssaaaa (carry2, t, 0, b, 0, t); ++ *ret = t; ++ return carry1 + carry2; ++} ++ ++/* add two numbers of the same size, return overflow ++ * ++ * add a to b, place result in ret; all arrays need to be n limbs long ++ * return overflow from addition (0 or 1) ++ */ ++static limb_t ++add (limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ limb_t c = 0; ++ for (ssize_t i = n - 1; i > -1; i--) ++ { ++ c = _add_limb (&ret[i], a[i], b[i], c); ++ } ++ return c; ++} ++ ++/* multiply two numbers of the same size ++ * ++ * multiply a by b, place result in ret; a and b need to be n limbs long ++ * ret needs to be 2*n limbs long, tmp needs to be 2 * n 2 limbs ++ * long ++ */ ++void ++mul_cs (limb_t *ret, limb_t *a, limb_t *b, size_t n, limb_t *tmp) ++{ ++ limb_t *r_odd, *r_even; ++ r_odd = tmp; ++ r_even = &tmp[2 * n]; ++ ++ for (size_t i = 0; i < 2 * n; i++) ++ { ++ ret[i] = 0; ++ } ++ ++ for (size_t i=0; i> 1); ++ shift_in = shift_out; ++ } ++} ++ ++/* copy from either a or b to ret based on flag ++ * when flag == 0, then copies from b ++ * when flag == 1, then copies from a ++ */ ++static void ++cselect (limb_t flag, limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ /* would be more efficient with non volatile mask, but then gcc ++ * generates code with jumps */ ++ limb_t mask1 = ct_limb_gen_mask (flag); ++ limb_t mask2 = ct_limb_gen_inv_mask (flag); ++ for (size_t i = 0; i < n; i++) ++ { ++ ret[i] = (mask1 & a[i]) | (mask2 & b[i]); ++ } ++} ++ ++static limb_t ++_sub_limb (limb_t *ret, limb_t a, limb_t b, limb_t borrow) ++{ ++ limb_t borrow1, borrow2, t; ++ sub_ddmmss (borrow1, t, 0, a, 0, borrow); ++ sub_ddmmss (borrow2, t, 0, t, 0, b); ++ *ret = t; ++ return -(borrow1 + borrow2); ++} ++ ++/* place the result of a - b into ret, return the borrow bit. ++ * All arrays need to be n limbs long ++ */ ++static limb_t ++sub (limb_t *ret, limb_t *a, limb_t *b, size_t n) ++{ ++ limb_t borrow = 0; ++ for (ssize_t i=n-1; i>-1; i--) ++ { ++ borrow = _sub_limb (&ret[i], a[i], b[i], borrow); ++ } ++ return borrow; ++} ++ ++/* return the number of limbs necessary to allocate for the mod() tmp operand */ ++size_t ++mod_limb_numb (size_t anum, size_t modnum) ++{ ++ return (anum + modnum) * 3; ++} ++ ++/* calculate a % mod, place the result in ret ++ * size of a is defined by anum, size of ret and mod is modnum, ++ * size of tmp is returned by mod_limb_numb() ++ */ ++void ++mod_cs (limb_t *ret, limb_t *a, size_t anum, limb_t *mod, size_t modnum, limb_t *tmp) ++{ ++ limb_t *atmp, *modtmp, *rettmp; ++ limb_t res; ++ ++ memset (tmp, 0, mod_limb_numb(anum, modnum) * LIMB_BYTE_SIZE); ++ ++ atmp = tmp; ++ modtmp = &tmp[anum+modnum]; ++ rettmp = &tmp[(anum+modnum)*2]; ++ ++ for (size_t i=modnum; inlimbs < v->nlimbs) ++ { /* Swap U and V. */ ++ usize = v->nlimbs; ++ usign = v->sign; ++ usecure = mpi_is_secure (v); ++ up = v->d; ++ vsize = u->nlimbs; ++ vsign = u->sign; ++ vsecure = mpi_is_secure (u); ++ vp = u->d; ++ } ++ else ++ { ++ usize = u->nlimbs; ++ usign = u->sign; ++ usecure = mpi_is_secure (u); ++ up = u->d; ++ vsize = v->nlimbs; ++ vsign = v->sign; ++ vsecure = mpi_is_secure (v); ++ vp = v->d; ++ } ++ sign_product = usign ^ vsign; ++ wp = w->d; ++ ++ /* make sure u and v have the same length by extending the limbs to the larger one, now u */ ++ if (usize != vsize) ++ { ++ mpi_limb_t *tmp_vp = mpi_alloc_limb_space (usize, vsecure); ++ clean_vp = 1; ++ MPN_ZERO (tmp_vp, (usize - vsize)); ++ MPN_COPY (tmp_vp + (usize - vsize), vp, vsize); ++ vsize = usize; ++ vp = tmp_vp; ++ } ++ ++ /* w == u */ ++ /* Ensure W has space enough to store the result. */ ++ wsize = usize + vsize; ++ if (!mpi_is_secure (w) && (mpi_is_secure (u) || mpi_is_secure (v))) ++ { ++ /* w is not allocated in secure space but u or v is. To make sure ++ * that no temporary results are stored in w, we temporary use ++ * a newly allocated limb space for w */ ++ wp = mpi_alloc_limb_space( wsize, 1 ); ++ assign_wp = 2; /* mark it as 2 so that we can later copy it back to ++ * normal memory */ ++ } ++ else if (w->alloced < wsize ) ++ { ++ if (wp == up || wp == vp) ++ { ++ wp = mpi_alloc_limb_space (wsize, mpi_is_secure (w)); ++ assign_wp = 1; ++ } ++ else ++ { ++ mpi_resize(w, wsize ); ++ wp = w->d; ++ } ++ } ++ else ++ { /* Make U and V not overlap with W. */ ++ if (wp == up) ++ { ++ /* W and U are identical. Allocate temporary space for U. */ ++ tmp_limb_nlimbs = usize; ++ up = tmp_limb = mpi_alloc_limb_space (usize, usecure); ++ /* Is V identical too? Keep it identical with U. */ ++ if (wp == vp) ++ vp = up; ++ /* Copy to the temporary space. */ ++ MPN_COPY (up, wp, usize); ++ } ++ else if (wp == vp) ++ { ++ /* W and V are identical. Allocate temporary space for V. */ ++ tmp_limb_nlimbs = vsize; ++ vp = tmp_limb = mpi_alloc_limb_space (vsize, vsecure); ++ /* Copy to the temporary space. */ ++ MPN_COPY (vp, wp, vsize); ++ } ++ } ++ ++ if (!vsize) ++ wsize = 0; ++ else ++ { ++ mpi_limb_t *tmp = mpi_alloc_limb_space (wsize * 2, mpi_is_secure (w)); ++ mul_cs (wp, up, vp, vsize, tmp); ++ _gcry_mpi_free_limb_space (tmp, wsize * 2); ++ } ++ ++ if (clean_vp) ++ { ++ _gcry_mpi_free_limb_space (vp, vsize); ++ } ++ if (assign_wp) ++ { ++ if (assign_wp == 2) ++ { ++ /* copy the temp wp from secure memory back to normal memory */ ++ mpi_ptr_t tmp_wp = mpi_alloc_limb_space (wsize, 0); ++ MPN_COPY (tmp_wp, wp, wsize); ++ _gcry_mpi_free_limb_space (wp, 0); ++ wp = tmp_wp; ++ } ++ _gcry_mpi_assign_limb_space (w, wp, wsize); ++ } ++ w->nlimbs = wsize; ++ w->sign = sign_product; ++ if (tmp_limb) ++ _gcry_mpi_free_limb_space (tmp_limb, tmp_limb_nlimbs); ++} ++#endif /* WITH_MARVIN_WORKAROUND */ + + void + _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) +@@ -221,3 +348,45 @@ _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) + if (temp_m) + mpi_free(temp_m); + } ++ ++#ifdef WITH_MARVIN_WORKAROUND ++static void ++_gcry_mpi_mod_sec (gcry_mpi_t ret, gcry_mpi_t a, gcry_mpi_t mod) ++{ ++ size_t asize = a->nlimbs; ++ size_t modsize = mod->nlimbs; ++ size_t tmp_size = mod_limb_numb (asize, modsize); ++ mpi_limb_t *tmp_limb = mpi_alloc_limb_space (tmp_size, mpi_is_secure(a)); ++ mod_cs (ret->d, a->d, asize, mod->d, modsize, tmp_limb); ++ /* cut the length to the mod size */ ++ ret->nlimbs = mod->nlimbs; ++ _gcry_mpi_free_limb_space (tmp_limb, tmp_size); ++} ++ ++/* The constant time code uses different order of the limbs ... */ ++static void ++_gcry_mpi_reverse_sec (gcry_mpi_t w) ++{ ++ for (size_t i = 0; i < w->nlimbs/2; i++) ++ { ++ mpi_limb_t t = w->d[i]; ++ w->d[i] = w->d[w->nlimbs - i - 1]; ++ w->d[w->nlimbs - i - 1] = t; ++ } ++} ++ ++void ++_gcry_mpi_mulm_sec (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m) ++{ ++ /* w == u */ ++ _gcry_mpi_reverse_sec (u); ++ _gcry_mpi_reverse_sec (v); ++ _gcry_mpi_reverse_sec (m); ++ _gcry_mpi_mul_sec (w, u, v); ++ _gcry_mpi_mod_sec (w, w, m); ++ ++ /* get them back to the order the rest of the code expects */ ++ _gcry_mpi_reverse_sec (w); /* -- this is the result */ ++ _gcry_mpi_reverse_sec (m); /* -- this might be still used by the calling function */ ++} ++#endif /* WITH_MARVIN_WORKAROUND */ +diff --git a/src/gcrypt-int.h b/src/gcrypt-int.h +index 1b449281..7e9e9894 100644 +--- a/src/gcrypt-int.h ++++ b/src/gcrypt-int.h +@@ -453,6 +453,9 @@ void _gcry_mpi_subm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); + void _gcry_mpi_mul (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v); + void _gcry_mpi_mul_ui (gcry_mpi_t w, gcry_mpi_t u, unsigned long v ); + void _gcry_mpi_mulm (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++#ifdef WITH_MARVIN_WORKAROUND ++void _gcry_mpi_mulm_sec (gcry_mpi_t w, gcry_mpi_t u, gcry_mpi_t v, gcry_mpi_t m); ++#endif /* WITH_MARVIN_WORKAROUND */ + void _gcry_mpi_mul_2exp (gcry_mpi_t w, gcry_mpi_t u, unsigned long cnt); + void _gcry_mpi_div (gcry_mpi_t q, gcry_mpi_t r, + gcry_mpi_t dividend, gcry_mpi_t divisor, int round); +@@ -548,6 +551,9 @@ int _gcry_mpi_get_flag (gcry_mpi_t a, enum gcry_mpi_flag flag); + #define mpi_mul_2exp(w,u,v) _gcry_mpi_mul_2exp ((w),(u),(v)) + #define mpi_mul(w,u,v) _gcry_mpi_mul ((w),(u),(v)) + #define mpi_mulm(w,u,v,m) _gcry_mpi_mulm ((w),(u),(v),(m)) ++#ifdef WITH_MARVIN_WORKAROUND ++#define mpi_mulm_sec(w,u,v,m) _gcry_mpi_mulm_sec ((w),(u),(v),(m)) ++#endif /* WITH_MARVIN_WORKAROUND */ + #define mpi_powm(w,b,e,m) _gcry_mpi_powm ( (w), (b), (e), (m) ) + #define mpi_tdiv(q,r,a,m) _gcry_mpi_div ( (q), (r), (a), (m), 0) + #define mpi_fdiv(q,r,a,m) _gcry_mpi_div ( (q), (r), (a), (m), -1) +-- +2.46.0 + + +From 1b7b995c5f4cd48a3b98915826431efb41a927ce Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 26 Apr 2024 16:39:18 +0200 +Subject: [PATCH 3/7] Constant time conversion of the message to the SEXP + +* cipher/rsa.c (rsa_decrypt): Use constant time conversion to SEXP after + decryption. +* src/const-time.c (_gcry_ct_memcpy): Constant time memcpy. New. +* src/const-time.h (ct_lt): New. + (ct_char_gen{,_inv}_mask): New. +* src/sexp.c (do_vsexp_sscan): Introduce constant time version of %b +-- + +The current conversion of the message back to the SEXP buffer leaks the +length of the decrypted message. This introduces a constant-time variant +that should run for the same time for any input length. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa.c | 4 ++++ + src/const-time.c | 28 ++++++++++++++++++++++++++-- + src/const-time.h | 12 ++++++++++++ + src/sexp.c | 39 +++++++++++++++++++++++++++++++++------ + 4 files changed, 75 insertions(+), 8 deletions(-) + +diff --git a/cipher/rsa.c b/cipher/rsa.c +index 2f735f9c..52f2aa89 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -1519,7 +1519,11 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, nbits, plain); + mpi_free (plain); + plain = NULL; ++#ifdef WITH_MARVIN_WORKAROUND ++ rc_sexp = sexp_build (&result, NULL, "(value %c)", (int)unpadlen, unpad, (nbits + 7) / 8); ++#else + rc_sexp = sexp_build (&result, NULL, "(value %b)", (int)unpadlen, unpad); ++#endif /* WITH_MARVIN_WORKAROUND */ + *r_plain = sexp_null_cond (result, ct_is_not_zero (rc)); + dummy = sexp_null_cond (result, ct_is_zero (rc)); + sexp_release (dummy); +diff --git a/src/const-time.c b/src/const-time.c +index 0fb53a07..cecb1937 100644 +--- a/src/const-time.c ++++ b/src/const-time.c +@@ -77,8 +77,8 @@ _gcry_ct_memmov_cond (void *dst, const void *src, size_t len, + unsigned long op_enable) + { + /* Note: dual mask with AND/OR used for EM leakage mitigation */ +- unsigned char mask1 = ct_ulong_gen_mask(op_enable); +- unsigned char mask2 = ct_ulong_gen_inv_mask(op_enable); ++ volatile unsigned char mask1 = ct_ulong_gen_mask(op_enable); ++ volatile unsigned char mask2 = ct_ulong_gen_inv_mask(op_enable); + unsigned char *b_dst = dst; + const unsigned char *b_src = src; + size_t i; +@@ -86,3 +86,27 @@ _gcry_ct_memmov_cond (void *dst, const void *src, size_t len, + for (i = 0; i < len; i++) + b_dst[i] = (b_dst[i] & mask2) | (b_src[i] & mask1); + } ++ ++/* ++ * Copy LEN bytes from memory area SRC to memory area DST. The ++ * bytes are read up to the BUFFER_LEN size to keep the operation ++ * not dependent on the message length (both SRC and DST buffers ++ * need to have this size!). ++ */ ++void ++_gcry_ct_memcpy (void *dst, const void *src, size_t len, size_t buffer_len) ++{ ++ unsigned char mask_a, mask_b; ++ unsigned char *b_dst = dst; ++ const unsigned char *b_src = src; ++ unsigned int writing; ++ size_t i; ++ ++ for (i = 0; i < buffer_len; i++) ++ { ++ writing = ct_lt (i, len); ++ mask_b = ct_uchar_gen_inv_mask (writing); ++ mask_a = ct_uchar_gen_mask (writing); ++ b_dst[i] = (b_src[i] & mask_a) | (b_dst[i] & mask_b); ++ } ++} +diff --git a/src/const-time.h b/src/const-time.h +index 245967eb..74055a4b 100644 +--- a/src/const-time.h ++++ b/src/const-time.h +@@ -26,6 +26,7 @@ + #define ct_not_memequal _gcry_ct_not_memequal + #define ct_memequal _gcry_ct_memequal + #define ct_memmov_cond _gcry_ct_memmov_cond ++#define ct_memcpy _gcry_ct_memcpy + + + #ifndef HAVE_GCC_ASM_VOLATILE_MEMORY +@@ -33,6 +34,14 @@ extern volatile unsigned int _gcry_ct_vzero; + extern volatile unsigned int _gcry_ct_vone; + #endif + ++/* ++ * Return 1 if A < B and return 0 otherwise. ++ */ ++static inline int ++ct_lt (unsigned int a, unsigned int b) ++{ ++ return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(unsigned int)*8 - 1); ++} + + static inline size_t + ct_lt_s (size_t a, size_t b) +@@ -112,6 +121,7 @@ unsigned int _gcry_ct_memequal (const void *b1, const void *b2, size_t len); + #endif + DEFINE_CT_TYPE_GEN_MASK(uintptr, uintptr_t) + DEFINE_CT_TYPE_GEN_MASK(ulong, unsigned long) ++DEFINE_CT_TYPE_GEN_MASK(uchar, unsigned char) + + /* + * Return all bits set if A is 0 and return 1 otherwise. +@@ -137,6 +147,7 @@ DEFINE_CT_TYPE_GEN_MASK(int16, int16_t) + #endif + DEFINE_CT_TYPE_GEN_INV_MASK(uintptr, uintptr_t) + DEFINE_CT_TYPE_GEN_INV_MASK(ulong, unsigned long) ++DEFINE_CT_TYPE_GEN_INV_MASK(uchar, unsigned char) + + /* + * Return A when OP_ENABLED=1 +@@ -172,5 +183,6 @@ sexp_null_cond (gcry_sexp_t w, unsigned long op_enable) + */ + void _gcry_ct_memmov_cond (void *dst, const void *src, size_t len, + unsigned long op_enable); ++void _gcry_ct_memcpy (void *dst, const void *src, size_t len, size_t buffer_len); + + #endif /*GCRY_CONST_TIME_H*/ +diff --git a/src/sexp.c b/src/sexp.c +index c77d0212..8e6c847f 100644 +--- a/src/sexp.c ++++ b/src/sexp.c +@@ -31,6 +31,7 @@ + + #define GCRYPT_NO_MPI_MACROS 1 + #include "g10lib.h" ++#include "const-time.h" + + + /* Notes on the internal memory layout. +@@ -1079,6 +1080,10 @@ unquote_string (const char *string, size_t length, unsigned char *buf) + * %d - integer stored as string (no autoswitch to secure allocation) + * %b - memory buffer; this takes _two_ arguments: an integer with the + * length of the buffer and a pointer to the buffer. ++ * %c - memory buffer same as %b, but written in constant time; this ++ * takes _three_ arguments: an integer with the length of the buffer, ++ * a pointer to the buffer and the maximum length of the buffer ++ * to avoid potential side channel leaking the buffer length. + * %S - Copy an gcry_sexp_t here. The S-expression needs to be a + * regular one, starting with a parenthesis. + * (no autoswitch to secure allocation) +@@ -1204,7 +1209,7 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + { + switch (*p) + { +- case 'b': case 't': case 'v': case 'n': case 'f': ++ case 'b': case 'c': case 't': case 'v': case 'n': case 'f': + case 'r': case '"': case '\'': case '\\': + quoted_esc = 0; + break; +@@ -1538,14 +1543,27 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + memcpy (c.pos, astr, alen); + c.pos += alen; + } +- else if (*p == 'b') ++ else if (*p == 'b' || *p == 'c') + { + /* Insert a memory buffer. */ + const char *astr; +- int alen; ++ int alen, buflen = 0, reallen = 0; + + ARG_NEXT (alen, int); + ARG_NEXT (astr, const char *); ++ if (*p == 'c') ++ { ++ ARG_NEXT (buflen, int); ++ if (buflen < alen) ++ { ++ *erroff = p - buffer; ++ err = GPG_ERR_INV_ARG; ++ goto leave; ++ } ++ /* Do all the calculations with the buflen */ ++ reallen = alen; ++ alen = buflen; ++ } + + if (alen < 0) + { +@@ -1578,9 +1596,18 @@ do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff, + } + + *c.pos++ = ST_DATA; +- STORE_LEN (c.pos, alen); +- memcpy (c.pos, astr, alen); +- c.pos += alen; ++ if (*p == 'c') ++ { ++ STORE_LEN (c.pos, reallen); ++ ct_memcpy (c.pos, astr, reallen, buflen); ++ c.pos += reallen; ++ } ++ else ++ { ++ STORE_LEN (c.pos, alen); ++ memcpy (c.pos, astr, alen); ++ c.pos += alen; ++ } + } + else if (*p == 'd') + { +-- +2.46.0 + + +From 14008d6f9f3985461ea50a6760391086c9bbe72b Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Thu, 30 May 2024 17:50:36 +0200 +Subject: [PATCH 5/7] rsa: Implement constant-time conversion of MPI to string + +-- +* cipher/rsa-common.c (_gcry_rsa_pkcs1_decode_for_enc): Replace + _gcry_mpi_print() with constant time operation. + +The _gcry_mpi_print() does a lot of housekeeping on the provided MPI +including skipping all the leading zeroes. If the ciphertext decrypted +to many leading zeroes, the output from this function is much shorter +(could be even all zeroes), which would immediately fail. + +This implements the dummy conversion of the MPI with the knowledge that +the encrypted data will always have the fixed length, providing constant +time operation. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa-common.c | 35 ++++++++++++++++++++++++++++++++++- + 1 file changed, 34 insertions(+), 1 deletion(-) + +diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c +index e45cb30d..a61d82e3 100644 +--- a/cipher/rsa-common.c ++++ b/cipher/rsa-common.c +@@ -28,6 +28,7 @@ + #include "cipher.h" + #include "pubkey-internal.h" + #include "const-time.h" ++#include "bufhelp.h" + + + /* Turn VALUE into an octet string and store it in an allocated buffer +@@ -199,7 +200,6 @@ gpg_err_code_t + _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + unsigned int nbits, gcry_mpi_t value) + { +- gcry_error_t err; + unsigned char *frame = NULL; + size_t nframe = (nbits+7) / 8; + size_t n, n0; +@@ -208,6 +208,36 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + + *r_result = NULL; + ++ { ++#ifdef WITH_MARVIN_WORKAROUND ++ /* Allocate more to fit the whole MPI and allow moving it later to the right place */ ++ size_t alloc_len = value->nlimbs * BYTES_PER_MPI_LIMB; ++ if ( !(frame = xtrymalloc_secure (alloc_len))) ++ return gpg_err_code_from_syserror (); ++ ++ /* shovel the MPI content to the buffer as it is */ ++ unsigned char *p = frame; ++ for (int i = value->nlimbs - 1; i >= 0; i--) ++ { ++ mpi_limb_t *alimb = &value->d[i]; ++#if BYTES_PER_MPI_LIMB == 4 ++ buf_put_be32 (p, *alimb); ++ p += 4; ++#elif BYTES_PER_MPI_LIMB == 8 ++ buf_put_be64 (p, *alimb); ++ p += 8; ++#else ++# error please implement for this limb size. ++#endif ++ } ++ /* Remove leading zeroes, but not all! Keep the buffer to the nframe length! ++ * -- valid PKCS#1.5 padding will never have different lengths, than modulus */ ++ memmov_independently (frame, frame + (alloc_len - nframe), nframe, alloc_len); ++ n = 0; ++ failed |= ct_not_equal_byte (frame[n++], 0x00); ++#else ++ gcry_error_t err; ++ + if ( !(frame = xtrymalloc_secure (nframe))) + return gpg_err_code_from_syserror (); + +@@ -235,6 +265,9 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + n = 0; + if (!frame[0]) + n++; ++#endif ++ } ++ + failed |= ct_not_equal_byte (frame[n++], 0x02); + + /* Find the terminating zero byte. */ +-- +2.46.0 + + +From 5c0b1707e48d21fa4d860b0bafdeaeb438885707 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Fri, 31 May 2024 15:03:29 +0200 +Subject: [PATCH 6/7] cipher: Use the constant time conversion also for OAEP + +-- +* cipher/rsa-common.c (mpi_to_string): New function + (_gcry_rsa_pkcs1_decode_for_enc): Use new function for MPI to string + conversion. + (_gcry_rsa_oaep_decode): Use the new function for MPI to string + conversion. +* cipher/rsa.c (rsa_decrypt): Use constant time conversion to S-exp for + OAEP padding. + +Signed-off-by: Jakub Jelen +--- + cipher/rsa-common.c | 75 +++++++++++++++++++++++++++++++-------------- + cipher/rsa.c | 4 +++ + 2 files changed, 56 insertions(+), 23 deletions(-) + +diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c +index a61d82e3..82a9e083 100644 +--- a/cipher/rsa-common.c ++++ b/cipher/rsa-common.c +@@ -192,31 +192,26 @@ memmov_independently (void *dst, const void *src, size_t len, size_t buflen) + } + + +-/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding. +- NBITS is the size of the secret key. On success the result is +- stored as a newly allocated buffer at R_RESULT and its valid length at +- R_RESULTLEN. On error NULL is stored at R_RESULT. */ +-gpg_err_code_t +-_gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, +- unsigned int nbits, gcry_mpi_t value) ++static unsigned char * ++mpi_to_string(gcry_mpi_t value, size_t nframe) + { + unsigned char *frame = NULL; +- size_t nframe = (nbits+7) / 8; +- size_t n, n0; +- unsigned int failed = 0; +- unsigned int not_found = 1; ++ unsigned char *p; ++ size_t noff; ++ /* Allocate memory to fit the whole MPI limbs and allow moving it later to the right place */ ++ size_t alloc_len = value->nlimbs * BYTES_PER_MPI_LIMB; + +- *r_result = NULL; ++ /* for too short input, we need to allocate at least modulus length (which might still be valid in case of OAEP) */ ++ noff = (alloc_len < nframe) ? nframe - alloc_len : 0; ++ alloc_len = alloc_len + noff; + +- { +-#ifdef WITH_MARVIN_WORKAROUND +- /* Allocate more to fit the whole MPI and allow moving it later to the right place */ +- size_t alloc_len = value->nlimbs * BYTES_PER_MPI_LIMB; + if ( !(frame = xtrymalloc_secure (alloc_len))) +- return gpg_err_code_from_syserror (); ++ return NULL; + ++ if (noff) ++ memset (frame, 0, noff); ++ p = frame + noff; + /* shovel the MPI content to the buffer as it is */ +- unsigned char *p = frame; + for (int i = value->nlimbs - 1; i >= 0; i--) + { + mpi_limb_t *alimb = &value->d[i]; +@@ -230,9 +225,34 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + # error please implement for this limb size. + #endif + } +- /* Remove leading zeroes, but not all! Keep the buffer to the nframe length! +- * -- valid PKCS#1.5 padding will never have different lengths, than modulus */ ++ /* Move the MPI to the right place -- with the least significant bytes aligned to the modulus length ++ * -- this might keep some leading zeroes at the beginning of the buffer, but this might be valid for OAEP */ + memmov_independently (frame, frame + (alloc_len - nframe), nframe, alloc_len); ++ return frame; ++} ++ ++/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding. ++ NBITS is the size of the secret key. On success the result is ++ stored as a newly allocated buffer at R_RESULT and its valid length at ++ R_RESULTLEN. On error NULL is stored at R_RESULT. */ ++gpg_err_code_t ++_gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, ++ unsigned int nbits, gcry_mpi_t value) ++{ ++ unsigned char *frame = NULL; ++ size_t nframe = (nbits+7) / 8; ++ size_t n, n0; ++ unsigned int failed = 0; ++ unsigned int not_found = 1; ++ ++ *r_result = NULL; ++ ++ { ++#ifdef WITH_MARVIN_WORKAROUND ++ frame = mpi_to_string(value, nframe); ++ if (frame == NULL) ++ return gpg_err_code_from_syserror (); ++ + n = 0; + failed |= ct_not_equal_byte (frame[n++], 0x00); + #else +@@ -265,7 +285,7 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + n = 0; + if (!frame[0]) + n++; +-#endif ++#endif /* WITH_MARVIN_WORKAROUND */ + } + + failed |= ct_not_equal_byte (frame[n++], 0x02); +@@ -709,14 +729,23 @@ _gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen, + happen due to the leading zero in OAEP frames and due to the + following random octets (seed^mask) which may have leading zero + bytes. This all is needed to cope with our leading zeroes +- suppressing MPI implementation. The code implictly implements ++ suppressing MPI implementation. The code implicitly implements + Step 1b (bail out if NFRAME != N). */ ++#ifdef WITH_MARVIN_WORKAROUND ++ frame = mpi_to_string(value, nkey); ++ if (frame == NULL) ++ { ++ xfree (lhash); ++ return gpg_err_code_from_syserror (); ++ } ++#else + rc = octet_string_from_mpi (&frame, NULL, value, nkey); + if (rc) + { + xfree (lhash); + return GPG_ERR_ENCODING_PROBLEM; + } ++#endif /* WITH_MARVIN_WORKAROUND */ + nframe = nkey; + + /* Step 1c: Check that the key is long enough. */ +@@ -731,7 +760,7 @@ _gcry_rsa_oaep_decode (unsigned char **r_result, size_t *r_resultlen, + gcry_mpi_aprint above. */ + + /* Allocate space for SEED and DB. */ +- seed = xtrymalloc_secure (nframe - 1); ++ seed = xtrymalloc_secure (nframe); + if (!seed) + { + rc = gpg_err_code_from_syserror (); +diff --git a/cipher/rsa.c b/cipher/rsa.c +index 52f2aa89..c196724c 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -1537,7 +1537,11 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + plain, ctx.label, ctx.labellen); + mpi_free (plain); + plain = NULL; ++#ifdef WITH_MARVIN_WORKAROUND ++ rc_sexp = sexp_build (&result, NULL, "(value %c)", (int)unpadlen, unpad, (nbits + 7) / 8); ++#else + rc_sexp = sexp_build (&result, NULL, "(value %b)", (int)unpadlen, unpad); ++#endif /* WITH_MARVIN_WORKAROUND */ + *r_plain = sexp_null_cond (result, ct_is_not_zero (rc)); + dummy = sexp_null_cond (result, ct_is_zero (rc)); + sexp_release (dummy); +-- +2.46.0 + + +From 4dffeaeadf792931aee61e6f51f59cf911c0c1f5 Mon Sep 17 00:00:00 2001 +From: Jakub Jelen +Date: Mon, 29 Apr 2024 19:06:17 +0200 +Subject: [PATCH 7/7] Implement implicit rejection for PKCS#1.5 decipher + +-- +* cipher/pubkey-internal.h + (_gcry_rsa_pkcs1_decode_for_enc_implicit_rejection): New. +* pubkey-util.c (_gcry_pk_util_parse_flaglist): Parse the new flag + no-implicit-rejection. +* cipher/rsa-common.c (rsa_prf): New function. + (_gcry_rsa_pkcs1_decode_for_enc_implicit_rejection): New function. +* cipher/rsa.c (rsa_decrypt): Handle implicit rejection. +* src/cipher.h (pk_encoding): New flag. +* tests/pkcs1v2.c (extract_cmp_data): Allow quiet test. + (check_v15crypt): Add support for implicit rejection. +* tests/pkcs1v2-v15c.h: Add test vectors for implicit rejection. + +Signed-off-by: Jakub Jelen +--- + cipher/pubkey-internal.h | 8 ++ + cipher/pubkey-util.c | 9 ++ + cipher/rsa-common.c | 181 +++++++++++++++++++++++ + cipher/rsa.c | 81 +++++++++++ + src/cipher.h | 37 ++--- + src/const-time.c | 2 +- + src/const-time.h | 3 +- + tests/pkcs1v2-v15c.h | 304 +++++++++++++++++++++++++++++++++++++++ + tests/pkcs1v2.c | 124 +++++++++++----- + 9 files changed, 692 insertions(+), 57 deletions(-) + +diff --git a/cipher/pubkey-internal.h b/cipher/pubkey-internal.h +index acf45105..f66574fa 100644 +--- a/cipher/pubkey-internal.h ++++ b/cipher/pubkey-internal.h +@@ -55,6 +55,14 @@ _gcry_rsa_pkcs1_encode_for_enc (gcry_mpi_t *r_result, unsigned int nbits, + gpg_err_code_t + _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + unsigned int nbits, gcry_mpi_t value); ++#ifdef WITH_MARVIN_WORKAROUND ++gpg_err_code_t ++_gcry_rsa_pkcs1_decode_for_enc_implicit_rejection (unsigned char **r_result, ++ size_t *r_resultlen, ++ unsigned int nbits, ++ gcry_mpi_t value, ++ unsigned char *kdk); ++#endif /* WITH_MARVIN_WORKAROUND */ + gpg_err_code_t + _gcry_rsa_pkcs1_encode_raw_for_sig (gcry_mpi_t *r_result, unsigned int nbits, + const unsigned char *value, size_t valuelen); +diff --git a/cipher/pubkey-util.c b/cipher/pubkey-util.c +index 68defea6..e760dd4c 100644 +--- a/cipher/pubkey-util.c ++++ b/cipher/pubkey-util.c +@@ -193,6 +193,15 @@ _gcry_pk_util_parse_flaglist (gcry_sexp_t list, + rc = GPG_ERR_INV_FLAG; + break; + ++#ifdef WITH_MARVIN_WORKAROUND ++ case 21: ++ if (!memcmp (s, "no-implicit-rejection", 21)) ++ flags |= PUBKEY_FLAG_NO_IMPLICIT_REJECTION; ++ else if (!igninvflag) ++ rc = GPG_ERR_INV_FLAG; ++ break; ++#endif /* WITH_MARVIN_WORKAROUND */ ++ + default: + if (!igninvflag) + rc = GPG_ERR_INV_FLAG; +diff --git a/cipher/rsa-common.c b/cipher/rsa-common.c +index 82a9e083..e776a309 100644 +--- a/cipher/rsa-common.c ++++ b/cipher/rsa-common.c +@@ -318,6 +318,187 @@ _gcry_rsa_pkcs1_decode_for_enc (unsigned char **r_result, size_t *r_resultlen, + } + + ++#ifdef WITH_MARVIN_WORKAROUND ++#define SHA256_LEN 32 ++static gcry_err_code_t ++rsa_prf(unsigned char *out, size_t out_len, const char *label, size_t label_len, unsigned char *kdk, size_t nbits) ++{ ++ gcry_err_code_t rc = GPG_ERR_NO_ERROR; ++ size_t pos; ++ uint16_t iter = 0; ++ unsigned char be_iter[2]; ++ unsigned char be_bitlen[2]; ++ gcry_md_hd_t hd; ++ gcry_error_t err; ++ ++ be_bitlen[0] = (nbits >> 8) & 0xff; ++ be_bitlen[1] = nbits & 0xff; ++ ++ err = _gcry_md_open (&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); ++ if (err) ++ { ++ return GPG_ERR_INTERNAL; ++ } ++ err = _gcry_md_setkey (hd, kdk, SHA256_LEN); ++ if (err) ++ { ++ _gcry_md_close (hd); ++ return GPG_ERR_INTERNAL; ++ } ++ for (pos = 0; pos < out_len; pos += SHA256_LEN, iter++) ++ { ++ unsigned char *tmp; ++ ++ _gcry_md_reset(hd); ++ ++ be_iter[0] = (iter >> 8) & 0xff; ++ be_iter[1] = iter & 0xff; ++ _gcry_md_write (hd, be_iter, sizeof (be_iter)); ++ _gcry_md_write (hd, label, label_len); ++ _gcry_md_write (hd, be_bitlen, sizeof (be_bitlen)); ++ ++ tmp = _gcry_md_read(hd, 0); ++ if (pos + SHA256_LEN > out_len) ++ { ++ memcpy(out + pos, tmp, out_len - pos); ++ } ++ else ++ { ++ memcpy(out + pos, tmp, SHA256_LEN); ++ } ++ } ++ _gcry_md_close (hd); ++ return rc; ++} ++ ++ ++/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding. ++ NBITS is the size of the secret key. On success the result is ++ stored as a newly allocated buffer at R_RESULT and its valid length at ++ R_RESULTLEN. On error R_RESULT contains bogus value of random length. ++ For more information, see description of Implicit Rejection in Marvin paper ++ https://people.redhat.com/~hkario/marvin/marvin-attack-paper.pdf */ ++#define MAX_LEN_GEN_TRIES 128 ++gpg_err_code_t ++_gcry_rsa_pkcs1_decode_for_enc_implicit_rejection (unsigned char **r_result, ++ size_t *r_resultlen, ++ unsigned int nbits, ++ gcry_mpi_t value, ++ unsigned char *kdk) ++{ ++ unsigned char *frame = NULL; ++ size_t nframe = (nbits+7) / 8; ++ size_t n, n0; ++ unsigned int failed = 0; ++ unsigned int not_found = 1; ++ int i, j; ++ uint16_t len_mask; ++ uint16_t max_sep_offset; ++ unsigned char *synthetic = NULL; ++ unsigned long synthethic_length; ++ uint16_t len_candidate; ++ unsigned char candidate_lengths[MAX_LEN_GEN_TRIES * sizeof(len_candidate)]; ++ int synth_msg_index = 0, msg_index; ++ ++ *r_result = NULL; ++ ++ synthetic = xtrymalloc(nframe); ++ if (synthetic == NULL) ++ { ++ free (synthetic); ++ return gpg_err_code_from_syserror (); ++ } ++ ++ if (rsa_prf(synthetic, nframe, "message", 7, kdk, nframe * 8) < 0) ++ { ++ xfree (synthetic); ++ return GPG_ERR_INTERNAL; ++ } ++ ++ /* decide how long the random message should be */ ++ if (rsa_prf(candidate_lengths, sizeof(candidate_lengths), ++ "length", 6, kdk, MAX_LEN_GEN_TRIES * sizeof(len_candidate) * 8) < 0) ++ { ++ xfree (synthetic); ++ return GPG_ERR_INTERNAL; ++ } ++ ++ len_mask = max_sep_offset = nframe - 2 - 8; ++ len_mask |= len_mask >> 1; ++ len_mask |= len_mask >> 2; ++ len_mask |= len_mask >> 4; ++ len_mask |= len_mask >> 8; ++ ++ synthethic_length = 0; ++ for (i = 0; i < MAX_LEN_GEN_TRIES * (int)sizeof(len_candidate); ++ i += sizeof(len_candidate)) ++ { ++ len_candidate = (candidate_lengths[i] << 8) | candidate_lengths[i + 1]; ++ len_candidate &= len_mask; ++ ++ synthethic_length = ct_ulong_select( ++ len_candidate, synthethic_length, ++ ct_lt(len_candidate, max_sep_offset)); ++ } ++ ++ synth_msg_index = nframe - synthethic_length; ++ ++ /* we have alternative message ready, check the real one */ ++ /* mostly copy from _gcry_rsa_pkcs1_decode_for_enc */ ++ frame = mpi_to_string(value, nframe); ++ if (frame == NULL) ++ { ++ xfree (synthetic); ++ return gpg_err_code_from_syserror (); ++ } ++ ++ /* FRAME = 0x00 || 0x02 || PS || 0x00 || M */ ++ n = 0; ++ failed |= ct_not_equal_byte (frame[n++], 0x00); ++ failed |= ct_not_equal_byte (frame[n++], 0x02); ++ ++ /* Find the terminating zero byte. */ ++ n0 = n; ++ for (; n < nframe; n++) ++ { ++ not_found &= ct_not_equal_byte (frame[n], 0x00); ++ n0 += not_found; ++ } ++ ++ failed |= not_found; ++ n0 += ct_is_zero (not_found); /* Skip the zero byte. */ ++ /* the valid padding is at least 8 bytes -- the plaintext needs to start at index 11 or later */ ++ failed |= ct_lt_s (n0, 11); ++ ++ msg_index = ct_ulong_select (synth_msg_index, n0, failed); ++ ++ /* To avoid the need memmove (O(N*log(N))), we use separate buffer where we move either ++ * of the messages. We can now also use the msg_index safely as its timing is not ++ * possible to distinguish valid and invalid padding */ ++ for (i = msg_index, j = 0; i < nframe && j < nframe; i++, j++) ++ { ++ frame[j] = ct_uchar_select (synthetic[i], frame[i], failed); ++ } ++ ++ *r_resultlen = j; ++ *r_result = frame; ++ ++ if (DBG_CIPHER) ++ { ++ if (!failed) ++ log_printhex ("value extracted from PKCS#1 block type 2 encoded data", ++ frame, nframe - n0); ++ else ++ log_printhex ("Synthetic value from implicit rejection", ++ synthetic, synthethic_length); ++ } ++ ++ xfree (synthetic); ++ return 0; ++} ++#endif /* WITH_MARVIN_WORKAROUND */ ++ ++ + /* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorithm ALGO + using the pkcs#1 block type 1 padding. On success the result is + stored as a new MPI at R_RESULT. On error the value at R_RESULT is +diff --git a/cipher/rsa.c b/cipher/rsa.c +index c196724c..9c1ef1f7 100644 +--- a/cipher/rsa.c ++++ b/cipher/rsa.c +@@ -1436,6 +1436,7 @@ rsa_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t keyparms) + } + + ++#define SHA256_LEN 32 + static gcry_err_code_t + rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + +@@ -1451,6 +1452,9 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + unsigned int nbits = rsa_get_nbits (keyparms); + gcry_sexp_t result = NULL; + gcry_sexp_t dummy = NULL; ++#ifdef WITH_MARVIN_WORKAROUND ++ unsigned char kdk[SHA256_LEN]; ++#endif /* WITH_MARVIN_WORKAROUND */ + + rc = rsa_check_keysize (nbits); + if (rc) +@@ -1498,6 +1502,71 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + mpi_normalize (data); + mpi_fdiv_r (data, data, sk.n); + ++#ifdef WITH_MARVIN_WORKAROUND ++ /* Implicit rejection: Derive KDK */ ++ if (ctx.encoding == PUBKEY_ENC_PKCS1) ++ { ++ unsigned char *buf, *tmp; ++ unsigned int nbytes = (mpi_get_nbits (sk.n)+7)/8; ++ unsigned char key[SHA256_LEN]; ++ gcry_md_hd_t hd; ++ ++ /* (a) Convert `d` to big endian representation, left padded to the length of `n` */ ++ rc = _gcry_mpi_to_octet_string (&buf, NULL, sk.d, nbytes); ++ if (rc) ++ { ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ ++ /* (b) Hash it using SHA-256 */ ++ rc = _gcry_md_open (&hd, GCRY_MD_SHA256, 0); ++ if (rc) ++ { ++ xfree (buf); ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ _gcry_md_write (hd, buf, nbytes); ++ /* keep the buffer around -- it will be needed for the ciphertext */ ++ tmp = _gcry_md_read (hd, GCRY_MD_SHA256); ++ memcpy(key, tmp, SHA256_LEN); ++ _gcry_md_close (hd); ++ ++ /* (c) Use the hash as a SHA-256 HMAC key and ciphertext as a message */ ++ rc = _gcry_md_open (&hd, GCRY_MD_SHA256, GCRY_MD_FLAG_HMAC); ++ if (rc) ++ { ++ xfree (buf); ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ rc = _gcry_md_setkey (hd, key, sizeof (key)); ++ if (rc) ++ { ++ xfree (buf); ++ _gcry_md_close (hd); ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ ++ /* We need to convert the ciphertext to string, padded to the length of modulus */ ++ rc = _gcry_mpi_to_octet_string (NULL, buf, data, nbytes); ++ if (rc) ++ { ++ xfree (buf); ++ _gcry_md_close (hd); ++ rc = GPG_ERR_INTERNAL; ++ goto leave; ++ } ++ _gcry_md_write (hd, buf, nbytes); ++ xfree (buf); ++ buf = _gcry_md_read (hd, 0); ++ memcpy(kdk, buf, SHA256_LEN); ++ _gcry_md_close (hd); ++ } ++#endif /* WITH_MARVIN_WORKAROUND */ ++ + /* Allocate MPI for the plaintext. */ + plain = mpi_snew (nbits); + +@@ -1516,6 +1585,18 @@ rsa_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t keyparms) + switch (ctx.encoding) + { + case PUBKEY_ENC_PKCS1: ++#ifdef WITH_MARVIN_WORKAROUND ++ if (!(ctx.flags & PUBKEY_FLAG_NO_IMPLICIT_REJECTION)) ++ { ++ rc = _gcry_rsa_pkcs1_decode_for_enc_implicit_rejection (&unpad, &unpadlen, nbits, plain, kdk); ++ mpi_free (plain); ++ plain = NULL; ++ rc_sexp = sexp_build (&result, NULL, "(value %c)", (int)unpadlen, unpad, (nbits + 7) / 8); ++ *r_plain = result; ++ rc = ct_ulong_select (rc_sexp, rc, ct_is_zero (rc) & ct_is_not_zero (rc_sexp)); ++ break; ++ } ++#endif /* WITH_MARVIN_WORKAROUND */ + rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen, nbits, plain); + mpi_free (plain); + plain = NULL; +diff --git a/src/cipher.h b/src/cipher.h +index 0a2551fe..e522f39b 100644 +--- a/src/cipher.h ++++ b/src/cipher.h +@@ -26,24 +26,25 @@ + + #include "../random/random.h" + +-#define PUBKEY_FLAG_NO_BLINDING (1 << 0) +-#define PUBKEY_FLAG_RFC6979 (1 << 1) +-#define PUBKEY_FLAG_FIXEDLEN (1 << 2) +-#define PUBKEY_FLAG_LEGACYRESULT (1 << 3) +-#define PUBKEY_FLAG_RAW_FLAG (1 << 4) +-#define PUBKEY_FLAG_TRANSIENT_KEY (1 << 5) +-#define PUBKEY_FLAG_USE_X931 (1 << 6) +-#define PUBKEY_FLAG_USE_FIPS186 (1 << 7) +-#define PUBKEY_FLAG_USE_FIPS186_2 (1 << 8) +-#define PUBKEY_FLAG_PARAM (1 << 9) +-#define PUBKEY_FLAG_COMP (1 << 10) +-#define PUBKEY_FLAG_NOCOMP (1 << 11) +-#define PUBKEY_FLAG_EDDSA (1 << 12) +-#define PUBKEY_FLAG_GOST (1 << 13) +-#define PUBKEY_FLAG_NO_KEYTEST (1 << 14) +-#define PUBKEY_FLAG_DJB_TWEAK (1 << 15) +-#define PUBKEY_FLAG_SM2 (1 << 16) +-#define PUBKEY_FLAG_PREHASH (1 << 17) ++#define PUBKEY_FLAG_NO_BLINDING (1 << 0) ++#define PUBKEY_FLAG_RFC6979 (1 << 1) ++#define PUBKEY_FLAG_FIXEDLEN (1 << 2) ++#define PUBKEY_FLAG_LEGACYRESULT (1 << 3) ++#define PUBKEY_FLAG_RAW_FLAG (1 << 4) ++#define PUBKEY_FLAG_TRANSIENT_KEY (1 << 5) ++#define PUBKEY_FLAG_USE_X931 (1 << 6) ++#define PUBKEY_FLAG_USE_FIPS186 (1 << 7) ++#define PUBKEY_FLAG_USE_FIPS186_2 (1 << 8) ++#define PUBKEY_FLAG_PARAM (1 << 9) ++#define PUBKEY_FLAG_COMP (1 << 10) ++#define PUBKEY_FLAG_NOCOMP (1 << 11) ++#define PUBKEY_FLAG_EDDSA (1 << 12) ++#define PUBKEY_FLAG_GOST (1 << 13) ++#define PUBKEY_FLAG_NO_KEYTEST (1 << 14) ++#define PUBKEY_FLAG_DJB_TWEAK (1 << 15) ++#define PUBKEY_FLAG_SM2 (1 << 16) ++#define PUBKEY_FLAG_PREHASH (1 << 17) ++#define PUBKEY_FLAG_NO_IMPLICIT_REJECTION (1 << 18) + + + enum pk_operation +diff --git a/src/const-time.c b/src/const-time.c +index cecb1937..2b6a4b4e 100644 +--- a/src/const-time.c ++++ b/src/const-time.c +@@ -96,7 +96,7 @@ _gcry_ct_memmov_cond (void *dst, const void *src, size_t len, + void + _gcry_ct_memcpy (void *dst, const void *src, size_t len, size_t buffer_len) + { +- unsigned char mask_a, mask_b; ++ volatile unsigned char mask_a, mask_b; + unsigned char *b_dst = dst; + const unsigned char *b_src = src; + unsigned int writing; +diff --git a/src/const-time.h b/src/const-time.h +index 74055a4b..5e656e15 100644 +--- a/src/const-time.h ++++ b/src/const-time.h +@@ -40,7 +40,7 @@ extern volatile unsigned int _gcry_ct_vone; + static inline int + ct_lt (unsigned int a, unsigned int b) + { +- return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(unsigned int)*8 - 1); ++ return (a ^ ((a ^ b) | ((a - b) ^ b))) >> (sizeof(unsigned int) * 8 - 1); + } + + static inline size_t +@@ -164,6 +164,7 @@ DEFINE_CT_TYPE_GEN_INV_MASK(uchar, unsigned char) + } + DEFINE_CT_TYPE_SELECT_FUNC(uintptr, uintptr_t) + DEFINE_CT_TYPE_SELECT_FUNC(ulong, unsigned long) ++DEFINE_CT_TYPE_SELECT_FUNC(uchar, unsigned char) + + /* + * Return NULL when OP_ENABLED=1 +diff --git a/tests/pkcs1v2-v15c.h b/tests/pkcs1v2-v15c.h +index 26c7b238..cb750d4f 100644 +--- a/tests/pkcs1v2-v15c.h ++++ b/tests/pkcs1v2-v15c.h +@@ -21,6 +21,7 @@ + const char *mesg; + const char *seed; + const char *encr; ++ const char *synt; + } m[20]; + } tbl[] = + { +@@ -3915,5 +3916,308 @@ + "25db1dd892b71bb74a5cf68263d8fd58f1a48e6c2fcb8c0b71a251cfc1a20157" + } + } ++ }, ++ { ++ "A 2048-bit RSA Test vectors for the Bleichenbacher workaround", ++ "c8cc839714098da56caa23640f93dc8997c16372968fc1b0c6df5113c1c94e8b21e48ad2297e65419011b4e6d8f5e73b1b78b257400321d1ef6b602d4ec8ce8d141c94905eb4ad306639a49206534b6e7f2607423e97dffd133c88d721399defbc7e96ccdcbd7f3aae1fe892712bfb4929817d511666440a1facb7a208f5ea165910add8a3f2d497202360ccb632024f0d07169c1918f316f794b143aef54ec87522a4c02978f9689980bffbf649c307e81819bff88409638d48bd94be152b59ff649fa0bd629d0ffa1813c3abf4b56bd3c2ea5465dffa14589292a9d8a24ad26be7ee0510741b6382d43c83d5bfa40a46613d062be445517dbcaf0cb4e1a769", ++ "010001", ++ "1455010e0f2d587663a666a6ff1ccdbbf0edd8100646d02a023922908992c4ad39e5565929726ef6508c3a71158ef0b6ff751d39d07580bb2d2f063210442d0603ff50dbbd7b35fe2c9bb19a47a1af85a4c24901e02ca8b58b7919b20edf32aacfbf51adb4bc4b61b9b7e968caa4d570f70ef18d8063228893e47d439efca793259bcf2cd108a3d8688cdf078e7ac799969f2339d2c1f522b969684629a933baaec2681625eab84f4e56f4447e9d88fb9a199cf71023e0e257b14441b33c84d3bc67ca8031d2612618103a7a0a40844262f75d8890cd616e51f9035488fd6e099de8ff6d65a4ff118254807c9f58d2fbba8ba151dc8c68be349c977a204e04c1", ++ { ++ { ++ "1. a random positive test case", ++ NULL, ++ "", ++ "8bfe264e85d3bdeaa6b8851b8e3b956ee3d226fd3f69063a86880173a273d9f283b2eebdd1ed35f7e02d91c571981b6737d5320bd8396b0f3ad5b019daec1b0aab3cbbc026395f4fd14f13673f2dfc81f9b660ec26ac381e6db3299b4e460b43fab9955df2b3cfaa20e900e19c856238fd371899c2bf2ce8c868b76754e5db3b036533fd603746be13c10d4e3e6022ebc905d20c2a7f32b215a4cd53b3f44ca1c327d2c2b651145821c08396c89071f665349c25e44d2733cd9305985ceef6430c3cf57af5fa224089221218fa34737c79c446d28a94c41c96e4e92ac53fbcf384dea8419ea089f8784445a492c812eb0d409467f75afd7d4d1078886205a066", ++ "6c6f72656d20697073756d20646f6c6f722073697420616d6574" ++ },{ ++ "2. a random negative test case decrypting to empty", ++ NULL, ++ "", ++ "20aaa8adbbc593a924ba1c5c7990b5c2242ae4b99d0fe636a19a4cf754edbcee774e472fe028160ed42634f8864900cb514006da642cae6ae8c7d087caebcfa6dad1551301e130344989a1d462d4164505f6393933450c67bc6d39d8f5160907cabc251b737925a1cf21e5c6aa5781b7769f6a2a583d97cce008c0f8b6add5f0b2bd80bee60237aa39bb20719fe75749f4bc4e42466ef5a861ae3a92395c7d858d430bfe38040f445ea93fa2958b503539800ffa5ce5f8cf51fa8171a91f36cb4f4575e8de6b4d3f096ee140b938fd2f50ee13f0d050222e2a72b0a3069ff3a6738e82c87090caa5aed4fcbe882c49646aa250b98f12f83c8d528113614a29e7", ++ "" ++ },{ ++ "3. invalid decrypting to max length message", ++ NULL, ++ "", ++ "48cceab10f39a4db32f60074feea473cbcdb7accf92e150417f76b44756b190e843e79ec12aa85083a21f5437e7bad0a60482e601198f9d86923239c8786ee728285afd0937f7dde12717f28389843d7375912b07b991f4fdb0190fced8ba665314367e8c5f9d2981d0f5128feeb46cb50fc237e64438a86df198dd0209364ae3a842d77532b66b7ef263b83b1541ed671b120dfd660462e2107a4ee7b964e734a7bd68d90dda61770658a3c242948532da32648687e0318286473f675b412d6468f013f14d760a358dfcad3cda2afeec5e268a37d250c37f722f468a70dfd92d7294c3c1ee1e7f8843b7d16f9f37ef35748c3ae93aa155cdcdfeb4e78567303", ++ "22d850137b9eebe092b24f602dc5bb7918c16bd89ddbf20467b119d205f9c2e4bd7d2592cf1e532106e0f33557565923c73a02d4f09c0c22bea89148183e60317f7028b3aa1f261f91c979393101d7e15f4067e63979b32751658ef769610fe97cf9cef3278b3117d384051c3b1d82c251c2305418c8f6840530e631aad63e70e20e025bcd8efb54c92ec6d3b106a2f8e64eeff7d38495b0fc50c97138af4b1c0a67a1c4e27b077b8439332edfa8608dfeae653cd6a628ac550395f7e74390e42c11682234870925eeaa1fa71b76cf1f2ee3bda69f6717033ff8b7c95c9799e7a3bea5e7e4a1c359772fb6b1c6e6c516661dfe30c3" ++ },{ ++ "4. invalid decrypting to message with length specified by second to last value from PRF", ++ NULL, ++ "", ++ "1439e08c3f84c1a7fec74ce07614b20e01f6fa4e8c2a6cffdc3520d8889e5d9a950c6425798f85d4be38d300ea5695f13ecd4cb389d1ff5b82484b494d6280ab7fa78e645933981cb934cce8bfcd114cc0e6811eefa47aae20af638a1cd163d2d3366186d0a07df0c81f6c9f3171cf3561472e98a6006bf75ddb457bed036dcce199369de7d94ef2c68e8467ee0604eea2b3009479162a7891ba5c40cab17f49e1c438cb6eaea4f76ce23cce0e483ff0e96fa790ea15be67671814342d0a23f4a20262b6182e72f3a67cd289711503c85516a9ed225422f98b116f1ab080a80abd6f0216df88d8cfd67c139243be8dd78502a7aaf6bc99d7da71bcdf627e7354", ++ "0f9b" ++ },{ ++ "5. invalid decrypting to message with length specified by third to last value from PRF", ++ NULL, ++ "", ++ "1690ebcceece2ce024f382e467cf8510e74514120937978576caf684d4a02ad569e8d76cbe365a060e00779de2f0865ccf0d923de3b4783a4e2c74f422e2f326086c390b658ba47f31ab013aa80f468c71256e5fa5679b24e83cd82c3d1e05e398208155de2212993cd2b8bab6987cf4cc1293f19909219439d74127545e9ed8a706961b8ee2119f6bfacafbef91b75a789ba65b8b833bc6149cf49b5c4d2c6359f62808659ba6541e1cd24bf7f7410486b5103f6c0ea29334ea6f4975b17387474fe920710ea61568d7b7c0a7916acf21665ad5a31c4eabcde44f8fb6120d8457afa1f3c85d517cda364af620113ae5a3c52a048821731922737307f77a1081", ++ "4f02" ++ },{ ++ "6. positive test with 11 byte long value", ++ NULL, ++ "", ++ "6213634593332c485cef783ea2846e3d6e8b0e005cd8293eaebbaa5079712fd681579bdfbbda138ae4d9d952917a03c92398ec0cb2bb0c6b5a8d55061fed0d0d8d72473563152648cfe640b335dc95331c21cb133a91790fa93ae44497c128708970d2beeb77e8721b061b1c44034143734a77be8220877415a6dba073c3871605380542a9f25252a4babe8331cdd53cf828423f3cc70b560624d0581fb126b2ed4f4ed358f0eb8065cf176399ac1a846a31055f9ae8c9c24a1ba050bc20842125bc1753158f8065f3adb9cc16bfdf83816bdf38b624f12022c5a6fbfe29bc91542be8c0208a770bcd677dc597f5557dc2ce28a11bf3e3857f158717a33f6592", ++ "6c6f72656d20697073756d" ++ },{ ++ "7. positive test with 11 byte long value and zero padded ciphertext", ++ NULL, ++ "", ++ "00a2e8f114ea8d05d12dc843e3cc3b2edc8229ff2a028bda29ba9d55e3cd02911902fef1f42a075bf05e8016e8567213d6f260fa49e360779dd81aeea3e04c2cb567e0d72b98bf754014561b7511e083d20e0bfb9cd23f8a0d3c88900c49d2fcd5843ff0765607b2026f28202a87aa94678aed22a0c20724541394cd8f44e373eba1d2bae98f516c1e2ba3d86852d064f856b1daf24795e767a2b90396e50743e3150664afab131fe40ea405dcf572dd1079af1d3f0392ccadcca0a12740dbb213b925ca2a06b1bc1383e83a658c82ba2e7427342379084d5f66b544579f07664cb26edd4f10fd913fdbc0de05ef887d4d1ec1ac95652397ea7fd4e4759fda8b", ++ "6c6f72656d20697073756d" ++ },{ ++ "8. positive test with 11 byte long value and zero truncated ciphertext", ++ NULL, ++ "", ++ "a2e8f114ea8d05d12dc843e3cc3b2edc8229ff2a028bda29ba9d55e3cd02911902fef1f42a075bf05e8016e8567213d6f260fa49e360779dd81aeea3e04c2cb567e0d72b98bf754014561b7511e083d20e0bfb9cd23f8a0d3c88900c49d2fcd5843ff0765607b2026f28202a87aa94678aed22a0c20724541394cd8f44e373eba1d2bae98f516c1e2ba3d86852d064f856b1daf24795e767a2b90396e50743e3150664afab131fe40ea405dcf572dd1079af1d3f0392ccadcca0a12740dbb213b925ca2a06b1bc1383e83a658c82ba2e7427342379084d5f66b544579f07664cb26edd4f10fd913fdbc0de05ef887d4d1ec1ac95652397ea7fd4e4759fda8b", ++ "6c6f72656d20697073756d" ++ },{ ++ "9. positive test with 11 byte long value and double zero padded ciphertext", ++ NULL, ++ "", ++ "00001f71879b426127f7dead621f7380a7098cf7d22173aa27991b143c46d53383c209bd0c9c00d84078037e715f6b98c65005a77120070522ede51d472c87ef94b94ead4c5428ee108a345561658301911ec5a8f7dd43ed4a3957fd29fb02a3529bf63f8040d3953490939bd8f78b2a3404b6fb5ff70a4bfdaac5c541d6bcce49c9778cc390be24cbef1d1eca7e870457241d3ff72ca44f9f56bdf31a890fa5eb3a9107b603ccc9d06a5dd911a664c82b6abd4fe036f8db8d5a070c2d86386ae18d97adc1847640c211d91ff5c3387574a26f8ef27ca7f48d2dd1f0c7f14b81cc9d33ee6853031d3ecf10a914ffd90947909c8011fd30249219348ebff76bfc", ++ "6c6f72656d20697073756d" ++ },{ ++ "10. a random negative test that generates an 11 byte long message", ++ NULL, ++ "", ++ "5f02f4b1f46935c742ebe62b6f05aa0a3286aab91a49b34780adde6410ab46f7386e05748331864ac98e1da63686e4babe3a19ed40a7f5ceefb89179596aab07ab1015e03b8f825084dab028b6731288f2e511a4b314b6ea3997d2e8fe2825cef8897cbbdfb6c939d441d6e04948414bb69e682927ef8576c9a7090d4aad0e74c520d6d5ce63a154720f00b76de8cc550b1aa14f016d63a7b6d6eaa1f7dbe9e50200d3159b3d099c900116bf4eba3b94204f18b1317b07529751abf64a26b0a0bf1c8ce757333b3d673211b67cc0653f2fe2620d57c8b6ee574a0323a167eab1106d9bc7fd90d415be5f1e9891a0e6c709f4fc0404e8226f8477b4e939b36eb2", ++ "af9ac70191c92413cb9f2d" ++ },{ ++ "11. an otherwise correct plaintext, but with wrong first byte (0x01 instead of 0x00), generates a random 11 byte long plaintext", ++ NULL, ++ "", ++ "9b2ec9c0c917c98f1ad3d0119aec6be51ae3106e9af1914d48600ab6a2c0c0c8ae02a2dc3039906ff3aac904af32ec798fd65f3ad1afa2e69400e7c1de81f5728f3b3291f38263bc7a90a0563e43ce7a0d4ee9c0d8a716621ca5d3d081188769ce1b131af7d35b13dea99153579c86db31fe07d5a2c14d621b77854e48a8df41b5798563af489a291e417b6a334c63222627376118c02c53b6e86310f728734ffc86ef9d7c8bf56c0c841b24b82b59f51aee4526ba1c4268506d301e4ebc498c6aebb6fd5258c876bf900bac8ca4d309dd522f6a6343599a8bc3760f422c10c72d0ad527ce4af1874124ace3d99bb74db8d69d2528db22c3a37644640f95c05f", ++ "a1f8c9255c35cfba403ccc" ++ },{ ++ "12. an otherwise correct plaintext, but with wrong second byte (0x01 instead of 0x02), generates a random 11 byte long plaintext", ++ NULL, ++ "", ++ "782c2b59a21a511243820acedd567c136f6d3090c115232a82a5efb0b178285f55b5ec2d2bac96bf00d6592ea7cdc3341610c8fb07e527e5e2d20cfaf2c7f23e375431f45e998929a02f25fd95354c33838090bca838502259e92d86d568bc2cdb132fab2a399593ca60a015dc2bb1afcd64fef8a3834e17e5358d822980dc446e845b3ab4702b1ee41fe5db716d92348d5091c15d35a110555a35deb4650a5a1d2c98025d42d4544f8b32aa6a5e02dc02deaed9a7313b73b49b0d4772a3768b0ea0db5846ace6569cae677bf67fb0acf3c255dc01ec8400c963b6e49b1067728b4e563d7e1e1515664347b92ee64db7efb5452357a02fff7fcb7437abc2e579", ++ "e6d700309ca0ed62452254" ++ },{ ++ "13. an invalid ciphertext, with a zero byte in first byte of ciphertext, decrypts to a random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "0096136621faf36d5290b16bd26295de27f895d1faa51c800dafce73d001d60796cd4e2ac3fa2162131d859cd9da5a0c8a42281d9a63e5f353971b72e36b5722e4ac444d77f892a5443deb3dca49fa732fe855727196e23c26eeac55eeced8267a209ebc0f92f4656d64a6c13f7f7ce544ebeb0f668fe3a6c0f189e4bcd5ea12b73cf63e0c8350ee130dd62f01e5c97a1e13f52fde96a9a1bc9936ce734fdd61f27b18216f1d6de87f49cf4f2ea821fb8efd1f92cdad529baf7e31aff9bff4074f2cad2b4243dd15a711adcf7de900851fbd6bcb53dac399d7c880531d06f25f7002e1aaf1722765865d2c2b902c7736acd27bc6cbd3e38b560e2eecf7d4b576", ++ "ba27b1842e7c21c0e7ef6a" ++ },{ ++ "14. an invalid ciphertext, with a zero byte removed from first byte of ciphertext, decrypts to a random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "96136621faf36d5290b16bd26295de27f895d1faa51c800dafce73d001d60796cd4e2ac3fa2162131d859cd9da5a0c8a42281d9a63e5f353971b72e36b5722e4ac444d77f892a5443deb3dca49fa732fe855727196e23c26eeac55eeced8267a209ebc0f92f4656d64a6c13f7f7ce544ebeb0f668fe3a6c0f189e4bcd5ea12b73cf63e0c8350ee130dd62f01e5c97a1e13f52fde96a9a1bc9936ce734fdd61f27b18216f1d6de87f49cf4f2ea821fb8efd1f92cdad529baf7e31aff9bff4074f2cad2b4243dd15a711adcf7de900851fbd6bcb53dac399d7c880531d06f25f7002e1aaf1722765865d2c2b902c7736acd27bc6cbd3e38b560e2eecf7d4b576", ++ "ba27b1842e7c21c0e7ef6a" ++ },{ ++ "15. an invalid ciphertext, with two zero bytes in first bytes of ciphertext, decrypts to a random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "0000587cccc6b264bdfe0dc2149a988047fa921801f3502ea64624c510c6033d2f427e3f136c26e88ea9f6519e86a542cec96aad1e5e9013c3cc203b6de15a69183050813af5c9ad79703136d4b92f50ce171eefc6aa7988ecf02f319ffc5eafd6ee7a137f8fce64b255bb1b8dd19cfe767d64fdb468b9b2e9e7a0c24dae03239c8c714d3f40b7ee9c4e59ac15b17e4d328f1100756bce17133e8e7493b54e5006c3cbcdacd134130c5132a1edebdbd01a0c41452d16ed7a0788003c34730d0808e7e14c797a21f2b45a8aa1644357fd5e988f99b017d9df37563a354c788dc0e2f9466045622fa3f3e17db63414d27761f57392623a2bef6467501c63e8d645", ++ "d5cf555b1d6151029a429a" ++ },{ ++ "16. an invalid ciphertext, with two zero bytes removed from first bytes of ciphertext, decrypts to a random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "587cccc6b264bdfe0dc2149a988047fa921801f3502ea64624c510c6033d2f427e3f136c26e88ea9f6519e86a542cec96aad1e5e9013c3cc203b6de15a69183050813af5c9ad79703136d4b92f50ce171eefc6aa7988ecf02f319ffc5eafd6ee7a137f8fce64b255bb1b8dd19cfe767d64fdb468b9b2e9e7a0c24dae03239c8c714d3f40b7ee9c4e59ac15b17e4d328f1100756bce17133e8e7493b54e5006c3cbcdacd134130c5132a1edebdbd01a0c41452d16ed7a0788003c34730d0808e7e14c797a21f2b45a8aa1644357fd5e988f99b017d9df37563a354c788dc0e2f9466045622fa3f3e17db63414d27761f57392623a2bef6467501c63e8d645", ++ "d5cf555b1d6151029a429a" ++ },{ ++ "17. and invalid ciphertext, otherwise valid but starting with 000002, decrypts to random 11 byte long synthethic plaintext", ++ NULL, ++ "", ++ "1786550ce8d8433052e01ecba8b76d3019f1355b212ac9d0f5191b023325a7e7714b7802f8e9a17c4cb3cd3a84041891471b10ca1fcfb5d041d34c82e6d0011cf4dc76b90e9c2e0743590579d55bcd7857057152c4a8040361343d1d22ba677d62b011407c652e234b1d663af25e2386251d7409190f19fc8ec3f9374fdf1254633874ce2ec2bff40ad0cb473f9761ec7b68da45a4bd5e33f5d7dac9b9a20821df9406b653f78a95a6c0ea0a4d57f867e4db22c17bf9a12c150f809a7b72b6db86c22a8732241ebf3c6a4f2cf82671d917aba8bc61052b40ccddd743a94ea9b538175106201971cca9d136d25081739aaf6cd18b2aecf9ad320ea3f89502f955", ++ "3d4a054d9358209e9cbbb9" ++ },{ ++ "18. negative test with otherwise valid padding but a zero byte in first byte of padding", ++ NULL, ++ "", ++ "179598823812d2c58a7eb50521150a48bcca8b4eb53414018b6bca19f4801456c5e36a940037ac516b0d6412ba44ec6b4f268a55ef1c5ffbf18a2f4e3522bb7b6ed89774b79bffa22f7d3102165565642de0d43a955e96a1f2e80e5430671d7266eb4f905dc8ff5e106dc5588e5b0289e49a4913940e392a97062616d2bda38155471b7d360cfb94681c702f60ed2d4de614ea72bf1c53160e63179f6c5b897b59492bee219108309f0b7b8cb2b136c346a5e98b8b4b8415fb1d713bae067911e3057f1c335b4b7e39101eafd5d28f0189037e4334f4fdb9038427b1d119a6702aa8233319cc97d496cc289ae8c956ddc84042659a2d43d6aa22f12b81ab884e", ++ "1f037dd717b07d3e7f7359" ++ },{ ++ "19. negative test with otherwise valid padding but a zero byte at the eigth byte of padding", ++ NULL, ++ "", ++ "a7a340675a82c30e22219a55bc07cdf36d47d01834c1834f917f18b517419ce9de2a96460e745024436470ed85e94297b283537d52189c406a3f533cb405cc6a9dba46b482ce98b6e3dd52d8fce2237425617e38c11fbc46b61897ef200d01e4f25f5f6c4c5b38cd0de38ba11908b86595a8036a08a42a3d05b79600a97ac18ba368a08d6cf6ccb624f6e8002afc75599fba4de3d4f3ba7d208391ebe8d21f8282b18e2c10869eb2702e68f9176b42b0ddc9d763f0c86ba0ff92c957aaeab76d9ab8da52ea297ec11d92d770146faa1b300e0f91ef969b53e7d2907ffc984e9a9c9d11fb7d6cba91972059b46506b035efec6575c46d7114a6b935864858445f", ++ "63cb0bf65fc8255dd29e17" ++ },{ ++ "20. negative test with an otherwise valid plaintext but with missing separator byte", ++ NULL, ++ "", ++ "3d1b97e7aa34eaf1f4fc171ceb11dcfffd9a46a5b6961205b10b302818c1fcc9f4ec78bf18ea0cee7e9fa5b16fb4c611463b368b3312ac11cf9c06b7cf72b54e284848a508d3f02328c62c2999d0fb60929f81783c7a256891bc2ff4d91df2af96a24fc5701a1823af939ce6dbdc510608e3d41eec172ad2d51b9fc61b4217c923cadcf5bac321355ef8be5e5f090cdc2bd0c697d9058247db3ad613fdce87d2955a6d1c948a5160f93da21f731d74137f5d1f53a1923adb513d2e6e1589d44cc079f4c6ddd471d38ac82d20d8b1d21f8d65f3b6907086809f4123e08d86fb38729585de026a485d8f0e703fd4772f6668febf67df947b82195fa3867e3a3065", ++ "6f09a0b62699337c497b0b" ++ } ++ } ++ }, ++ { ++ "A 2049-bit RSA Test vectors for the Bleichenbacher workaround", ++ "0155f889556a1775f1c7a7786a50b18bc28c9e986ede5667cab39b84124e90eba75c1db083ac3e443bba94dc23560f75e3a81693a2a43bdc7426d8c4eafe68c85de0fe757f6e49bb9ed447e602430800dbb04ceb22e7fa57a18d338fb66026cdb467e70cc040e7d367ef403c7bf1e3df624650094631f21eafd2fb5bc915ff04379acd1112f732c0b46607c178d38a20f52eda509f2f9c0405d51069e80ccf941554d0470467505c3cf541ea0897dfc9f400cecb298ffc753372d9f6933af174cc40ed96d467031733b97f8cddd3f92bc3a03ea8576c417f24007b5e4f7501105b544de9fadcdffadf98dfb4bb05b8199f3f85acfd91f7a9a094b9a383f5049097", ++ "010001", ++ "0119c2b3f50a7ad6152679d7ff510958ac2d8ca6f0028592f332d55a16736178a8e67f17e705ce300e3e87547251006013f974d0a3db49ef344ca5a26a34c0450704d0e422e0ce23a69425c15fefb6f26e106eeff64cc8b9d7442e4da4e8c85008eaeb365859a2294fa3937bc26be56332e7d81e2c160ef635cc528aa7be55e633a723dbc1e16ba29e52b29aef2f9e5654fdc0666bb0fc254acbe80e63874f0f5f020782e3c9dcfc2520d0c9c4a7b634e4503fbb493e1aafeeb3f88bd7a13398725dae6fe399e775cd5d4cf09fc838347c4c98dab1a4883cce620513615afaa10a63368e6d7b79df4166ab162739ef515a4402ee1e0601c5a55bc71df0e30edf81", ++ { ++ { ++ "1. malformed that generates length specified by 3rd last value from PRF", ++ NULL, ++ "", ++ "00b26f6404b82649629f2704494282443776929122e279a9cf30b0c6fe8122a0a9042870d97cc8ef65490fe58f031eb2442352191f5fbc311026b5147d32df914599f38b825ebb824af0d63f2d541a245c5775d1c4b78630e4996cc5fe413d38455a776cf4edcc0aa7fccb31c584d60502ed2b77398f536e137ff7ba6430e9258e21c2db5b82f5380f566876110ac4c759178900fbad7ab70ea07b1daf7a1639cbb4196543a6cbe8271f35dddb8120304f6eef83059e1c5c5678710f904a6d760c4d1d8ad076be17904b9e69910040b47914a0176fb7eea0c06444a6c4b86d674d19a556a1de5490373cb01ce31bbd15a5633362d3d2cd7d4af1b4c5121288b894", ++ "42" ++ },{ ++ "2. simple positive test case", ++ NULL, ++ "", ++ "013300edbf0bb3571e59889f7ed76970bf6d57e1c89bbb6d1c3991d9df8e65ed54b556d928da7d768facb395bbcc81e9f8573b45cf8195dbd85d83a59281cddf4163aec11b53b4140053e3bd109f787a7c3cec31d535af1f50e0598d85d96d91ea01913d07097d25af99c67464ebf2bb396fb28a9233e56f31f7e105d71a23e9ef3b736d1e80e713d1691713df97334779552fc94b40dd733c7251bc522b673d3ec9354af3dd4ad44fa71c0662213a57ada1d75149697d0eb55c053aaed5ffd0b815832f454179519d3736fb4faf808416071db0d0f801aca8548311ee708c131f4be658b15f6b54256872c2903ac708bd43b017b073b5707bc84c2cd9da70e967", ++ "6c6f72656d20697073756d" ++ },{ ++ "3. positive test case with null padded ciphertext", ++ NULL, ++ "", ++ "0002aadf846a329fadc6760980303dbd87bfadfa78c2015ce4d6c5782fd9d3f1078bd3c0a2c5bfbdd1c024552e5054d98b5bcdc94e476dd280e64d650089326542ce7c61d4f1ab40004c2e6a88a883613568556a10f3f9edeab67ae8dddc1e6b0831c2793d2715de943f7ce34c5c05d1b09f14431fde566d17e76c9feee90d86a2c158616ec81dda0c642f58c0ba8fa4495843124a7235d46fb4069715a51bf710fd024259131ba94da73597ace494856c94e7a3ec261545793b0990279b15fa91c7fd13dbfb1df2f221dab9fa9f7c1d21e48aa49f6aaecbabf5ee76dc6c2af2317ffb4e303115386a97f8729afc3d0c89419669235f1a3a69570e0836c79fc162", ++ "6c6f72656d20697073756d" ++ },{ ++ "4. positive test case with null truncated ciphertext", ++ NULL, ++ "", ++ "02aadf846a329fadc6760980303dbd87bfadfa78c2015ce4d6c5782fd9d3f1078bd3c0a2c5bfbdd1c024552e5054d98b5bcdc94e476dd280e64d650089326542ce7c61d4f1ab40004c2e6a88a883613568556a10f3f9edeab67ae8dddc1e6b0831c2793d2715de943f7ce34c5c05d1b09f14431fde566d17e76c9feee90d86a2c158616ec81dda0c642f58c0ba8fa4495843124a7235d46fb4069715a51bf710fd024259131ba94da73597ace494856c94e7a3ec261545793b0990279b15fa91c7fd13dbfb1df2f221dab9fa9f7c1d21e48aa49f6aaecbabf5ee76dc6c2af2317ffb4e303115386a97f8729afc3d0c89419669235f1a3a69570e0836c79fc162", ++ "6c6f72656d20697073756d" ++ },{ ++ "5. positive test case with double null padded ciphertext", ++ NULL, ++ "", ++ "0000f36da3b72d8ff6ded74e7efd08c01908f3f5f0de7b55eab92b5f875190809c39d4162e1e6649618f854fd84aeab03970d16bb814e999852c06de38d82b95c0f32e2a7b5714021fe303389be9c0eac24c90a6b7210f929d390fabf903d44e04110bb7a7fd6c383c275804721efa6d7c93aa64c0bb2b18d97c5220a846c66a4895ae52adddbe2a9996825e013585adcec4b32ba61d782737bd343e5fabd68e8a95b8b1340318559860792dd70dffbe05a1052b54cbfb48cfa7bb3c19cea52076bddac5c25ee276f153a610f6d06ed696d192d8ae4507ffae4e5bdda10a625d6b67f32f7cffcd48dee2431fe66f6105f9d17e611cdcc674868e81692a360f4052", ++ "6c6f72656d20697073756d" ++ },{ ++ "6. positive test case with double null truncated ciphertext", ++ NULL, ++ "", ++ "f36da3b72d8ff6ded74e7efd08c01908f3f5f0de7b55eab92b5f875190809c39d4162e1e6649618f854fd84aeab03970d16bb814e999852c06de38d82b95c0f32e2a7b5714021fe303389be9c0eac24c90a6b7210f929d390fabf903d44e04110bb7a7fd6c383c275804721efa6d7c93aa64c0bb2b18d97c5220a846c66a4895ae52adddbe2a9996825e013585adcec4b32ba61d782737bd343e5fabd68e8a95b8b1340318559860792dd70dffbe05a1052b54cbfb48cfa7bb3c19cea52076bddac5c25ee276f153a610f6d06ed696d192d8ae4507ffae4e5bdda10a625d6b67f32f7cffcd48dee2431fe66f6105f9d17e611cdcc674868e81692a360f4052", ++ "6c6f72656d20697073756d" ++ },{ ++ "7. a random negative test case that generates an 11 byte long message", ++ NULL, ++ "", ++ "00f910200830fc8fff478e99e145f1474b312e2512d0f90b8cef77f8001d09861688c156d1cbaf8a8957f7ebf35f724466952d0524cad48aad4fba1e45ce8ea27e8f3ba44131b7831b62d60c0762661f4c1d1a88cd06263a259abf1ba9e6b0b172069afb86a7e88387726f8ab3adb30bfd6b3f6be6d85d5dfd044e7ef052395474a9cbb1c3667a92780b43a22693015af6c513041bdaf87d43b24ddd244e791eeaea1066e1f4917117b3a468e22e0f7358852bb981248de4d720add2d15dccba6280355935b67c96f9dcb6c419cc38ab9f6fba2d649ef2066e0c34c9f788ae49babd9025fa85b21113e56ce4f43aa134c512b030dd7ac7ce82e76f0be9ce09ebca", ++ "1189b6f5498fd6df532b00" ++ },{ ++ "8. otherwise correct plaintext, but with wrong first byte (0x01 instead of 0x00)", ++ NULL, ++ "", ++ "002c9ddc36ba4cf0038692b2d3a1c61a4bb3786a97ce2e46a3ba74d03158aeef456ce0f4db04dda3fe062268a1711250a18c69778a6280d88e133a16254e1f0e30ce8dac9b57d2e39a2f7d7be3ee4e08aec2fdbe8dadad7fdbf442a29a8fb40857407bf6be35596b8eefb5c2b3f58b894452c2dc54a6123a1a38d642e23751746597e08d71ac92704adc17803b19e131b4d1927881f43b0200e6f95658f559f912c889b4cd51862784364896cd6e8618f485a992f82997ad6a0917e32ae5872eaf850092b2d6c782ad35f487b79682333c1750c685d7d32ab3e1538f31dcaa5e7d5d2825875242c83947308dcf63ba4bfff20334c9c140c837dbdbae7a8dee72ff", ++ "f6d0f5b78082fe61c04674" ++ },{ ++ "9. otherwise correct plaintext, but with wrong second byte (0x01 instead of 0x02)", ++ NULL, ++ "", ++ "00c5d77826c1ab7a34d6390f9d342d5dbe848942e2618287952ba0350d7de6726112e9cebc391a0fae1839e2bf168229e3e0d71d4161801509f1f28f6e1487ca52df05c466b6b0a6fbbe57a3268a970610ec0beac39ec0fa67babce1ef2a86bf77466dc127d7d0d2962c20e66593126f276863cd38dc6351428f884c1384f67cad0a0ffdbc2af16711fb68dc559b96b37b4f04cd133ffc7d79c43c42ca4948fa895b9daeb853150c8a5169849b730cc77d68b0217d6c0e3dbf38d751a1998186633418367e7576530566c23d6d4e0da9b038d0bb5169ce40133ea076472d055001f0135645940fd08ea44269af2604c8b1ba225053d6db9ab43577689401bdc0f3", ++ "1ab287fcef3ff17067914d" ++ },{ ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ } ++ } ++ }, ++ { ++ "RSA decrypt with 3072 bit keys", ++ "afd71caad5e9f5b8c6c367070a47f19d7e66aede18a5b2741fb3c4d33434560692a2d909ef6888ec602ff6b93af258ee74303c301afcd4edbec43311ddc8ddbf00ddbbe386d33b8d0e22b1b44936dc489871b85237b34ce747ad8fdb0c4e4d1daa7aadf07385c5c8732ccb7d5a49e2e50c883c7d7ac10ed6a74d9ac90df9129905a17d4a087210fc78b6d04b1eb969482c11a6eeb79c50e5b16f3f254f7571528b2f1716ab816d6eca0727bdea98059329730eb8c33ce71d61dd4ac393b6256e07ac1d124f0200d1c3e05a4c1bc7f1ed2fc83e57199cfe5908b10087e27fbd97d2c24214619c7147c8fbefca39bc256762a6823531f7e234d68eae7a0d9faf10dd15e9523780c7d5ae58094ad525a9063b4c33f95e1006da2eb12d3743689495c1f2023e407353c5eb3e4ca1c48cff81a10900d14820eb801af4f1a596c4b9ce9a531fcf8a54d9ffd724258b6eec20108df6fdfd76d4ae03ba7ea598dcb0e4a280849587286f4d7f256ce85e5eb5679b1dacc1f9095649b72e5fa072aeb00379", ++ "010001", ++ "2517eacb3afef4bffae60398df9957a5d2a154a83368d8e15842b2f59ee09f79197bd2ef1e9addaf8786f6b4127447405e3042b21f2f50b7aa73771680c3bbcb6c225a5d5ff6b56c471c1882a0a33b0af165a3ed6c249dc7783e6bc758ac37e6572d33fe325078ed952650f2eb9604902ef99a511a1119d13c4fc9a43a175dcdfbfb1a1400fe17093b69cd3cdb895f65432ea2195f90511c7336b58a685dacff2daf4c5e92e565b1665ae60e512baa9965b808d5ff119ceb7cd692cbf920067afacd809f66be706da26810ac790db156c948e6fe581bc9849157f4da493f3a64b0c6e119e031b107f8436ce29160b458b8f9f1095fdeb19263384ff5387557bc4f10b4034de841703bad2c1e769c23853eb630a36d1061dd46e2a6bbaf743a97f0b32c36f50c1a3722def3a394d91c2e078bf09d795ecde5e56b8202f974026f75fc56e9a0dd6a88f2e7cb78ef1298cc6c65207ca45bd37188807b4fcdb1e60dd8e5b85648fb7efa8b6fdd448f39741a8d9809fe163af3de45bac24a5a841c81", ++ { ++ { ++ "1. a random invalid ciphertext that generates an empty synthethic one", ++ NULL, ++ "", ++ "5e956cd9652f4a2ece902931013e09662b6a9257ad1e987fb75f73a0606df2a4b04789770820c2e02322c4e826f767bd895734a01e20609c3be4517a7a2a589ea1cdc137beb73eb38dac781b52e863de9620f79f9b90fd5b953651fcbfef4a9f1cc07421d511a87dd6942caab6a5a0f4df473e62defb529a7de1509ab99c596e1dff1320402298d8be73a896cc86c38ae3f2f576e9ea70cc28ad575cb0f854f0be43186baa9c18e29c47c6ca77135db79c811231b7c1730955887d321fdc06568382b86643cf089b10e35ab23e827d2e5aa7b4e99ff2e914f302351819eb4d1693243b35f8bf1d42d08f8ec4acafa35f747a4a975a28643ec630d8e4fa5be59d81995660a14bb64c1fea5146d6b11f92da6a3956dd5cb5e0d747cf2ea23f81617769185336263d46ef4c144b754de62a6337342d6c85a95f19f015724546ee3fc4823eca603dbc1dc01c2d5ed50bd72d8e96df2dc048edde0081284068283fc5e73a6139851abf2f29977d0b3d160c883a42a37efba1be05c1a0b1741d7ddf59", ++ "" ++ },{ ++ "2. a random invalid that has PRF output with a length one byte too long", ++ NULL, ++ "", ++ "7db0390d75fcf9d4c59cf27b264190d856da9abd11e92334d0e5f71005cfed865a711dfa28b791188374b61916dbc11339bf14b06f5f3f68c206c5607380e13da3129bfb744157e1527dd6fdf6651248b028a496ae1b97702d44706043cdaa7a59c0f41367303f21f268968bf3bd2904db3ae5239b55f8b438d93d7db9d1666c071c0857e2ec37757463769c54e51f052b2a71b04c2869e9e7049a1037b8429206c99726f07289bac18363e7eb2a5b417f47c37a55090cda676517b3549c873f2fe95da9681752ec9864b069089a2ed2f340c8b04ee00079055a817a3355b46ac7dc00d17f4504ccfbcfcadb0c04cb6b22069e179385ae1eafabad5521bac2b8a8ee1dfff59a22eb3fdacfc87175d10d7894cfd869d056057dd9944b869c1784fcc27f731bc46171d39570fbffbadf082d33f6352ecf44aca8d9478e53f5a5b7c852b401e8f5f74da49da91e65bdc97765a9523b7a0885a6f8afe5759d58009fbfa837472a968e6ae92026a5e0202a395483095302d6c3985b5f5831c521a271", ++ "56a3bea054e01338be9b7d7957539c" ++ },{ ++ "3. a random invalid that generates a synthethic of maximum size", ++ NULL, ++ "", ++ "1715065322522dff85049800f6a29ab5f98c465020467414b2a44127fe9446da47fa18047900f99afe67c2df6f50160bb8e90bff296610fde632b3859d4d0d2e644f23835028c46cca01b84b88231d7e03154edec6627bcba23de76740d839851fa12d74c8f92e540c73fe837b91b7d699b311997d5f0f7864c486d499c3a79c111faaacbe4799597a25066c6200215c3d158f3817c1aa57f18bdaad0be1658da9da93f5cc6c3c4dd72788af57adbb6a0c26f42d32d95b8a4f95e8c6feb2f8a5d53b19a50a0b7cbc25e055ad03e5ace8f3f7db13e57759f67b65d143f08cca15992c6b2aae643390483de111c2988d4e76b42596266005103c8de6044fb7398eb3c28a864fa672de5fd8774510ff45e05969a11a4c7d3f343e331190d2dcf24fb9154ba904dc94af98afc5774a9617d0418fe6d13f8245c7d7626c176138dd698a23547c25f27c2b98ea4d8a45c7842b81888e4cc14e5b72e9cf91f56956c93dbf2e5f44a8282a7813157fc481ff1371a0f66b31797e81ebdb09a673d4db96d6", ++ "7b036fcd6243900e4236c894e2462c17738acc87e01a76f4d95cb9a328d9acde81650283b8e8f60a217e3bdee835c7b222ad4c85d0acdb9a309bd2a754609a65dec50f3aa04c6d5891034566b9563d42668ede1f8992b17753a2132e28970584e255efc8b45a41c5dbd7567f014acec5fe6fdb6d484790360a913ebb9defcd74ff377f2a8ba46d2ed85f733c9a3da08eb57ecedfafda806778f03c66b2c5d2874cec1c291b2d49eb194c7b5d0dd2908ae90f4843268a2c45563092ade08acb6ab481a08176102fc803fbb2f8ad11b0e1531bd37df543498daf180b12017f4d4d426ca29b4161075534bfb914968088a9d13785d0adc0e2580d3548494b2a9e91605f2b27e6cc701c796f0de7c6f471f6ab6cb9272a1ed637ca32a60d117505d82af3c1336104afb537d01a8f70b510e1eebf4869cb976c419473795a66c7f5e6e20a8094b1bb603a74330c537c5c0698c31538bd2e138c1275a1bdf24c5fa8ab3b7b526324e7918a382d1363b3d463764222150e04" ++ },{ ++ "4. a positive test case that decrypts to 9 byte long value", ++ NULL, ++ "", ++ "6c60845a854b4571f678941ae35a2ac03f67c21e21146f9db1f2306be9f136453b86ad55647d4f7b5c9e62197aaff0c0e40a3b54c4cde14e774b1c5959b6c2a2302896ffae1f73b00b862a20ff4304fe06cea7ff30ecb3773ca9af27a0b54547350d7c07dfb0a39629c7e71e83fc5af9b2adbaf898e037f1de696a3f328cf45af7ec9aff7173854087fb8fbf34be981efbd8493f9438d1b2ba2a86af082662aa46ae9adfbec51e5f3d9550a4dd1dcb7c8969c9587a6edc82a8cabbc785c40d9fbd12064559fb769450ac3e47e87bc046148130d7eaa843e4b3ccef3675d0630500803cb7ffee3882378c1a404e850c3e20707bb745e42b13c18786c4976076ed9fa8fd0ff15e571bef02cbbe2f90c908ac3734a433b73e778d4d17fcc28f49185ebc6e8536a06d293202d94496453bfdf1c2c7833a3f99fa38ca8a81f42eaa529d603b890308a319c0ab63a35ff8ebac965f6278f5a7e5d622be5d5fe55f0ca3ec993d55430d2bf59c5d3e860e90c16d91a04596f6fdf60d89ed95d88c036dde", ++ "666f7274792074776f" ++ },{ ++ "5. a positive test case with null padded ciphertext", ++ NULL, ++ "", ++ "00f4d565a3286784dbb85327db8807ae557ead229f92aba945cecda5225f606a7d6130edeeb6f26724d1eff1110f9eb18dc3248140ee3837e6688391e78796c526791384f045e21b6b853fb6342a11f309eb77962f37ce23925af600847fbd30e6e07e57de50b606e6b7f288cc777c1a6834f27e6edace508452128916eef7788c8bb227e3548c6a761cc4e9dd1a3584176dc053ba3500adb1d5e1611291654f12dfc5722832f635db3002d73f9defc310ace62c63868d341619c7ee15b20243b3371e05078e11219770c701d9f341af35df1bc729de294825ff2e416aa11526612852777eb131f9c45151eb144980d70608d2fc4043477368369aa0fe487a48bd57e66b00c3c58f941549f5ec050fca64449debe7a0c4ac51e55cb71620a70312aa4bd85fac1410c9c7f9d6ec610b7d11bf8faeffa20255d1a1bead9297d0aa8765cd2805847d639bc439f4a6c896e2008f746f9590ff4596de5ddde000ed666c452c978043ff4298461eb5a26d5e63d821438627f91201924bf7f2aeee1727", ++ "666f7274792074776f" ++ },{ ++ "6. a positive test case with double null padded ciphertext", ++ NULL, ++ "", ++ "00001ec97ac981dfd9dcc7a7389fdfa9d361141dac80c23a060410d472c16094e6cdffc0c3684d84aa402d7051dfccb2f6da33f66985d2a259f5b7fbf39ac537e95c5b7050eb18844a0513abef812cc8e74a3c5240009e6e805dcadf532bc1a2702d5acc9e585fad5b89d461fcc1397351cdce35171523758b171dc041f412e42966de7f94856477356d06f2a6b40e3ff0547562a4d91bbf1338e9e049facbee8b20171164505468cd308997447d3dc4b0acb49e7d368fedd8c734251f30a83491d2506f3f87318cc118823244a393dc7c5c739a2733d93e1b13db6840a9429947357f47b23fbe39b7d2d61e5ee26f9946c4632f6c4699e452f412a26641d4751135400713cd56ec66f0370423d55d2af70f5e7ad0adea8e4a0d904a01e4ac272eba4af1a029dd53eb71f115bf31f7a6c8b19a6523adeecc0d4c3c107575e38572a8f8474ccad163e46e2e8b08111132aa97a16fb588c9b7e37b3b3d7490381f3c55d1a9869a0fd42cd86fed59ecec78cb6b2dfd06a497f5afe3419691314ba0", ++ "666f7274792074776f" ++ },{ ++ "7. a positive test case with double null truncated ciphertext", ++ NULL, ++ "", ++ "1ec97ac981dfd9dcc7a7389fdfa9d361141dac80c23a060410d472c16094e6cdffc0c3684d84aa402d7051dfccb2f6da33f66985d2a259f5b7fbf39ac537e95c5b7050eb18844a0513abef812cc8e74a3c5240009e6e805dcadf532bc1a2702d5acc9e585fad5b89d461fcc1397351cdce35171523758b171dc041f412e42966de7f94856477356d06f2a6b40e3ff0547562a4d91bbf1338e9e049facbee8b20171164505468cd308997447d3dc4b0acb49e7d368fedd8c734251f30a83491d2506f3f87318cc118823244a393dc7c5c739a2733d93e1b13db6840a9429947357f47b23fbe39b7d2d61e5ee26f9946c4632f6c4699e452f412a26641d4751135400713cd56ec66f0370423d55d2af70f5e7ad0adea8e4a0d904a01e4ac272eba4af1a029dd53eb71f115bf31f7a6c8b19a6523adeecc0d4c3c107575e38572a8f8474ccad163e46e2e8b08111132aa97a16fb588c9b7e37b3b3d7490381f3c55d1a9869a0fd42cd86fed59ecec78cb6b2dfd06a497f5afe3419691314ba0", ++ "666f7274792074776f" ++ },{ ++ "8. a random negative test case that generates a 9 byte long message", ++ NULL, ++ "", ++ "5c8555f5cef627c15d37f85c7f5fd6e499264ea4b8e3f9112023aeb722eb38d8eac2be3751fd5a3785ab7f2d59fa3728e5be8c3de78a67464e30b21ee23b5484bb3cd06d0e1c6ad25649c8518165653eb80488bfb491b20c04897a6772f69292222fc5ef50b5cf9efc6d60426a449b6c489569d48c83488df629d695653d409ce49a795447fcec2c58a1a672e4a391401d428baaf781516e11e323d302fcf20f6eab2b2dbe53a48c987e407c4d7e1cb41131329138313d330204173a4f3ff06c6fadf970f0ed1005d0b27e35c3d11693e0429e272d583e57b2c58d24315c397856b34485dcb077665592b747f889d34febf2be8fce66c265fd9fc3575a6286a5ce88b4b413a08efc57a07a8f57a999605a837b0542695c0d189e678b53662ecf7c3d37d9dbeea585eebfaf79141118e06762c2381fe27ca6288edddc19fd67cd64f16b46e06d8a59ac530f22cd83cc0bc4e37feb52015cbb2283043ccf5e78a4eb7146827d7a466b66c8a4a4826c1bad68123a7f2d00fc1736525ff90c058f56", ++ "257906ca6de8307728" ++ },{ ++ "9. a random negative test case that generates a 9 byte long message based on second to last value from PRF", ++ NULL, ++ "", ++ "758c215aa6acd61248062b88284bf43c13cb3b3d02410be4238607442f1c0216706e21a03a2c10eb624a63322d854da195c017b76fea83e274fa371834dcd2f3b7accf433fc212ad76c0bac366e1ed32e25b279f94129be7c64d6e162adc08ccebc0cfe8e926f01c33ab9c065f0e0ac83ae5137a4cb66702615ad68a35707d8676d2740d7c1a954680c83980e19778ed11eed3a7c2dbdfc461a9bbef671c1bc00c882d361d29d5f80c42bdf5efec886c34138f83369c6933b2ac4e93e764265351b4a0083f040e14f511f09b22f96566138864e4e6ff24da4810095da98e0585410951538ced2f757a277ff8e17172f06572c9024eeae503f176fd46eb6c5cd9ba07af11cde31dccac12eb3a4249a7bfd3b19797ad1656984bfcbf6f74e8f99d8f1ac420811f3d166d87f935ef15ae858cf9e72c8e2b547bf16c3fb09a8c9bf88fd2e5d38bf24ed610896131a84df76b9f920fe76d71fff938e9199f3b8cd0c11fd0201f9139d7673a871a9e7d4adc3bbe360c8813617cd60a90128fbe34c9d5", ++ "043383c929060374ed" ++ },{ ++ "10. a random negative test that generates message based on 3rd last value from PRF", ++ NULL, ++ "", ++ "7b22d5e62d287968c6622171a1f75db4b0fd15cdf3134a1895d235d56f8d8fe619f2bf4868174a91d7601a82975d2255190d28b869141d7c395f0b8c4e2be2b2c1b4ffc12ce749a6f6803d4cfe7fba0a8d6949c04151f981c0d84592aa2ff25d1bd3ce5d10cb03daca6b496c6ad40d30bfa8acdfd02cdb9326c4bdd93b949c9dc46caa8f0e5f429785bce64136a429a3695ee674b647452bea1b0c6de9c5f1e8760d5ef6d5a9cfff40457b023d3c233c1dcb323e7808103e73963b2eafc928c9eeb0ee3294955415c1ddd9a1bb7e138fecd79a3cb89c57bd2305524624814aaf0fd1acbf379f7f5b39421f12f115ba488d380586095bb53f174fae424fa4c8e3b299709cd344b9f949b1ab57f1c645d7ed3c8f81d5594197355029fee8960970ff59710dc0e5eb50ea6f4c3938e3f89ed7933023a2c2ddffaba07be147f686828bd7d520f300507ed6e71bdaee05570b27bc92741108ac2eb433f028e138dd6d63067bc206ea2d826a7f41c0d613daed020f0f30f4e272e9618e0a8c39018a83", ++ "70263fa6050534b9e0" ++ },{ ++ "11. an otherwise valid plaintext, but with wrong first byte (0x01 instead of 0x00)", ++ NULL, ++ "", ++ "6db80adb5ff0a768caf1378ecc382a694e7d1bde2eff4ba12c48aaf794ded7a994a5b2b57acec20dbec4ae385c9dd531945c0f197a5496908725fc99d88601a17d3bb0b2d38d2c1c3100f39955a4cb3dbed5a38bf900f23d91e173640e4ec655c84fdfe71fcdb12a386108fcf718c9b7af37d39703e882436224c877a2235e8344fba6c951eb7e2a4d1d1de81fb463ac1b880f6cc0e59ade05c8ce35179ecd09546731fc07b141d3d6b342a97ae747e61a9130f72d37ac5a2c30215b6cbd66c7db893810df58b4c457b4b54f34428247d584e0fa71062446210db08254fb9ead1ba1a393c724bd291f0cf1a7143f32df849051dc896d7d176fef3b57ab6dffd626d0c3044e9edb2e3d012ace202d2581df01bec7e9aa0727a6650dd373d374f0bc0f4a611f8139dfe97d63e70c6188f4df5b672e47c51d8aa567097293fbff127c75ec690b43407578b73c85451710a0cece58fd497d7f7bd36a8a92783ef7dc6265dff52aac8b70340b996508d39217f2783ce6fc91a1cc94bb2ac487b84f62", ++ "6d8d3a094ff3afff4c" ++ },{ ++ "12. an otherwise valid plaintext, but with wrong second byte (0x01 instead of 0x02)", ++ NULL, ++ "", ++ "417328c034458563079a4024817d0150340c34e25ae16dcad690623f702e5c748a6ebb3419ff48f486f83ba9df35c05efbd7f40613f0fc996c53706c30df6bba6dcd4a40825f96133f3c21638a342bd4663dffbd0073980dac47f8c1dd8e97ce1412e4f91f2a8adb1ac2b1071066efe8d718bbb88ca4a59bd61500e826f2365255a409bece0f972df97c3a55e09289ef5fa815a2353ef393fd1aecfc888d611c16aec532e5148be15ef1bf2834b8f75bb26db08b66d2baad6464f8439d1986b533813321dbb180080910f233bcc4dd784fb21871aef41be08b7bfad4ecc3b68f228cb5317ac6ec1227bc7d0e452037ba918ee1da9fdb8393ae93b1e937a8d4691a17871d5092d2384b6190a53df888f65b951b05ed4ad57fe4b0c6a47b5b22f32a7f23c1a234c9feb5d8713d949686760680da4db454f4acad972470033472b9864d63e8d23eefc87ebcf464ecf33f67fbcdd48eab38c5292586b36aef5981ed2fa07b2f9e23fc57d9eb71bfff4111c857e9fff23ceb31e72592e70c874b4936", ++ "c6ae80ffa80bc184b0" ++ },{ ++ "13. an otherwise valid plaintext, but with zero byte in first byte of padding", ++ NULL, ++ "", ++ "8542c626fe533467acffcd4e617692244c9b5a3bf0a215c5d64891ced4bf4f9591b4b2aedff9843057986d81631b0acb3704ec2180e5696e8bd15b217a0ec36d2061b0e2182faa3d1c59bd3f9086a10077a3337a3f5da503ec3753535ffd25b837a12f2541afefd0cffb0224b8f874e4bed13949e105c075ed44e287c5ae03b155e06b90ed247d2c07f1ef3323e3508cce4e4074606c54172ad74d12f8c3a47f654ad671104bf7681e5b061862747d9afd37e07d8e0e2291e01f14a95a1bb4cbb47c304ef067595a3947ee2d722067e38a0f046f43ec29cac6a8801c6e3e9a2331b1d45a7aa2c6af3205be382dd026e389614ee095665a611ab2e8dced2ee1c9d08ac9de11aef5b3803fc9a9ce8231ec87b5fed386fb92ee3db995a89307bcba844bd0a691c29ae51216e949dfc813133cb06a07265fd807bcb3377f6adb0a481d9b7f442003115895939773e6b95371c4febef29edae946fa245e7c50729e2e558cfaad773d1fd5f67b457a6d9d17a847c6fcbdb103a86f35f228cefc06cea0", ++ "a8a9301daa01bb25c7" ++ },{ ++ "14. an otherwise valid plaintext, but with zero byte in eight byte of padding", ++ NULL, ++ "", ++ "449dfa237a70a99cb0351793ec8677882021c2aa743580bf6a0ea672055cffe8303ac42855b1d1f3373aae6af09cb9074180fc963e9d1478a4f98b3b4861d3e7f0aa8560cf603711f139db77667ca14ba3a1acdedfca9ef4603d6d7eb0645bfc805304f9ad9d77d34762ce5cd84bd3ec9d35c30e3be72a1e8d355d5674a141b5530659ad64ebb6082e6f73a80832ab6388912538914654d34602f4b3b1c78589b4a5d964b2efcca1dc7004c41f6cafcb5a7159a7fc7c0398604d0edbd4c8f4f04067da6a153a05e7cbeea13b5ee412400ef7d4f3106f4798da707ec37a11286df2b7a204856d5ff773613fd1e453a7114b78e347d3e8078e1cb3276b3562486ba630bf719697e0073a123c3e60ebb5c7a1ccff4279faffa2402bc1109f8d559d6766e73591943dfcf25ba10c3762f02af85187799b8b4b135c3990793a6fd32642f1557405ba55cc7cf7336a0e967073c5fa50743f9cc5e3017c172d9898d2af83345e71b3e0c22ab791eacb6484a32ec60ebc226ec9deaee91b1a0560c2b571", ++ "6c716fe01d44398018" ++ },{ ++ "15. an otherwise valid plaintext, but with null separator missing", ++ NULL, ++ "", ++ "a7a5c99e50da48769ecb779d9abe86ef9ec8c38c6f43f17c7f2d7af608a4a1bd6cf695b47e97c191c61fb5a27318d02f495a176b9fae5a55b5d3fabd1d8aae4957e3879cb0c60f037724e11be5f30f08fc51c033731f14b44b414d11278cd3dba7e1c8bfe208d2b2bb7ec36366dacb6c88b24cd79ab394adf19dbbc21dfa5788bacbadc6a62f79cf54fd8cf585c615b5c0eb94c35aa9de25321c8ffefb8916bbaa2697cb2dd82ee98939df9b6704cee77793edd2b4947d82e00e5749664970736c59a84197bd72b5c71e36aae29cd39af6ac73a368edbc1ca792e1309f442aafcd77c992c88f8e4863149f221695cb7b0236e75b2339a02c4ea114854372c306b9412d8eedb600a31532002f2cea07b4df963a093185e4607732e46d753b540974fb5a5c3f9432df22e85bb17611370966c5522fd23f2ad3484341ba7fd8885fc8e6d379a611d13a2aca784fba2073208faad2137bf1979a0fa146c1880d4337db3274269493bab44a1bcd0681f7227ffdf589c2e925ed9d36302509d1109ba4", ++ "aa2de6cde4e2442884" ++ },{ ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ NULL, ++ } ++ } + } + }; +diff --git a/tests/pkcs1v2.c b/tests/pkcs1v2.c +index ab070a94..a2153728 100644 +--- a/tests/pkcs1v2.c ++++ b/tests/pkcs1v2.c +@@ -82,7 +82,7 @@ data_from_hex (const char *string, size_t *r_length) + + static int + extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected, +- const char *description) ++ const char *description, int quiet) + { + gcry_sexp_t l1; + const void *a; +@@ -96,13 +96,15 @@ extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected, + b = data_from_hex (expected, &blen); + if (!a) + { +- info ("%s: parameter \"%s\" missing in key\n", description, name); ++ if (!quiet) ++ info ("%s: parameter \"%s\" missing in key\n", description, name); + rc = 1; + } + else if ( alen != blen || memcmp (a, b, alen) ) + { +- info ("%s: parameter \"%s\" does not match expected value\n", +- description, name); ++ if (!quiet) ++ info ("%s: parameter \"%s\" does not match expected value\n", ++ description, name); + rc = 1; + } + gcry_free (b); +@@ -192,7 +194,7 @@ check_oaep (void) + else + { + if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr, +- tbl[tno].m[mno].desc)) ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("encrypt result:\n", ciph); + fail ("mismatch in gcry_pk_encrypt\n"); +@@ -223,7 +225,7 @@ check_oaep (void) + else + { + if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg, +- tbl[tno].m[mno].desc)) ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("decrypt result:\n", plain); + fail ("mismatch in gcry_pk_decrypt\n"); +@@ -326,7 +328,7 @@ check_pss (void) + else + { + if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign, +- tbl[tno].m[mno].desc)) ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("sign result:\n", sig); + fail ("mismatch in gcry_pk_sign\n"); +@@ -429,45 +431,89 @@ check_v15crypt (void) + size_t mesg_len, seed_len, encr_len; + gcry_sexp_t plain, ciph; + ++ if (tbl[tno].m[mno].desc == NULL) ++ break; ++ + if (verbose) + info ("running test: %s\n", tbl[tno].m[mno].desc); + +- mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); +- seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); ++ if (tbl[tno].m[mno].mesg) ++ { ++ mesg = data_from_hex (tbl[tno].m[mno].mesg, &mesg_len); ++ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); ++ ++ err = gcry_sexp_build (&plain, NULL, ++ "(data (flags pkcs1)" ++ "(value %b)(random-override %b))", ++ (int)mesg_len, mesg, ++ (int)seed_len, seed); ++ if (err) ++ die ("constructing plain data failed: %s\n", gpg_strerror (err)); ++ gcry_free (mesg); ++ gcry_free (seed); ++ ++ err = gcry_pk_encrypt (&ciph, plain, pub_key); ++ if (err) ++ { ++ show_sexp ("plain:\n", ciph); ++ fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err)); ++ } ++ else ++ { ++ if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr, ++ tbl[tno].m[mno].desc, 0)) ++ { ++ show_sexp ("encrypt result:\n", ciph); ++ fail ("mismatch in gcry_pk_encrypt\n"); ++ } ++ gcry_sexp_release (ciph); ++ ciph = NULL; ++ } ++ gcry_sexp_release (plain); ++ plain = NULL; ++ } + +- err = gcry_sexp_build (&plain, NULL, +- "(data (flags pkcs1)(hash-algo sha1)" +- "(value %b)(random-override %b))", +- (int)mesg_len, mesg, +- (int)seed_len, seed); ++ /* Now test the decryption. */ ++ encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len); ++ seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); ++ ++#ifdef WITH_MARVIN_WORKAROUND ++ /* First try without implicit rejection -- this should fail for invalid inputs */ ++ err = gcry_sexp_build (&ciph, NULL, ++ "(enc-val (flags pkcs1 no-implicit-rejection)" ++ "(rsa (a %b)))", ++ (int)encr_len, encr); + if (err) +- die ("constructing plain data failed: %s\n", gpg_strerror (err)); +- gcry_free (mesg); +- gcry_free (seed); ++ die ("constructing cipher data failed: %s\n", gpg_strerror (err)); + +- err = gcry_pk_encrypt (&ciph, plain, pub_key); ++ err = gcry_pk_decrypt (&plain, ciph, sec_key); + if (err) + { +- show_sexp ("plain:\n", ciph); +- fail ("gcry_pk_encrypt failed: %s\n", gpg_strerror (err)); ++ /* If the message is not set, the padding is invalid and failure is expected */ ++ if (tbl[tno].m[mno].mesg != NULL) ++ { ++ show_sexp ("ciph:\n", ciph); ++ fail ("gcry_pk_decrypt failed: %s\n", gpg_strerror (err)); ++ } + } + else + { +- if (extract_cmp_data (ciph, "a", tbl[tno].m[mno].encr, +- tbl[tno].m[mno].desc)) ++ /* If the message is not set, it is in the synthetic field */ ++ const char *msg = tbl[tno].m[mno].mesg; ++ if (msg == NULL) ++ msg = tbl[tno].m[mno].synt; ++ if (extract_cmp_data (plain, "value", msg, ++ tbl[tno].m[mno].desc, 0)) + { +- show_sexp ("encrypt result:\n", ciph); +- fail ("mismatch in gcry_pk_encrypt\n"); ++ show_sexp ("decrypt result:\n", plain); ++ fail ("mismatch in gcry_pk_decrypt.\n"); + } +- gcry_sexp_release (ciph); +- ciph = NULL; ++ gcry_sexp_release (plain); ++ plain = NULL; + } +- gcry_sexp_release (plain); +- plain = NULL; +- +- /* Now test the decryption. */ +- seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); +- encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len); ++ gcry_sexp_release (ciph); ++ ciph = NULL; ++#endif /* WITH_MARVIN_WORKAROUND */ + + err = gcry_sexp_build (&ciph, NULL, + "(enc-val (flags pkcs1)(hash-algo sha1)" +@@ -484,15 +530,19 @@ check_v15crypt (void) + } + else + { +- if (extract_cmp_data (plain, "value", tbl[tno].m[mno].mesg, +- tbl[tno].m[mno].desc)) ++ /* If the message is not set, expect the synthetic message here */ ++ const char *msg = tbl[tno].m[mno].mesg; ++ if (msg == NULL) ++ msg = tbl[tno].m[mno].synt; ++ if (extract_cmp_data (plain, "value", msg, ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("decrypt result:\n", plain); +- fail ("mismatch in gcry_pk_decrypt\n"); ++ fail ("mismatch in gcry_pk_decrypt. Expected %s\n", msg); + } +- gcry_sexp_release (plain); +- plain = NULL; + } ++ gcry_sexp_release (plain); ++ plain = NULL; + gcry_sexp_release (ciph); + ciph = NULL; + } +@@ -584,7 +634,7 @@ check_v15sign (void) + else + { + if (extract_cmp_data (sig, "s", tbl[tno].m[mno].sign, +- tbl[tno].m[mno].desc)) ++ tbl[tno].m[mno].desc, 0)) + { + show_sexp ("sign result:\n", sig); + fail ("mismatch in gcry_pk_sign\n"); +-- +2.46.0 + diff --git a/libgcrypt.spec b/libgcrypt.spec index 2c08d1c..de9064d 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -27,6 +27,8 @@ Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch # https://dev.gnupg.org/T7220 Patch3: libgcrypt-1.11.0-cf-protection.patch Patch4: libgcrypt-1.11.0-pac-bti-protection.patch +# https://gitlab.com/redhat-crypto/libgcrypt/libgcrypt-mirror/-/merge_requests/19/ +Patch5: libgcrypt-1.11.0-marvin.patch %global gcrylibdir %{_libdir} %global gcrysoname libgcrypt.so.20 @@ -65,6 +67,7 @@ applications using libgcrypt. %patch 2 -p1 %patch 3 -p1 %patch 4 -p1 +%patch 5 -p1 %build # should be all algorithms except SM3 and SM4, aria @@ -85,6 +88,7 @@ autoreconf -f --disable-O-flag-munging \ --enable-digests="$DIGESTS" \ --enable-ciphers="$CIPHERS" \ + --enable-marvin-workaround \ --with-fips-module-version="$FIPS_MODULE_NAME %{version}-%{srpmhash}" sed -i -e '/^sys_lib_dlsearch_path_spec/s,/lib /usr/lib,/usr/lib /lib64 /usr/lib64 /lib,g' libtool %make_build From 2e86b5c745b3e499f55c4db0e0befd6f945e84c1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Wed, 7 Aug 2024 09:05:52 +0200 Subject: [PATCH 83/88] 1.11.0-4 --- libgcrypt.spec | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index de9064d..cf992f5 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.0 -Release: 3%{?dist} +Release: 4%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -181,6 +181,12 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue Oct 29 2024 Jakub Jelen - 1.11.0-4 +- Run annocheck as part of the build +- Use upstream CF protection patches +- Fix PAC/BTI protection for Aarch64 +- Fix CVE-2024-2236 (#2274128) + * Thu Jul 25 2024 Jakub Jelen - 1.11.0-3 - Disable -O flag munging and remove needles modification of LTO flags. From 2f265169e5cb5e83f7901ffa6d5a7348cf475e1e Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Fri, 17 Jan 2025 11:17:27 +0000 Subject: [PATCH 84/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index cf992f5..eb5c8cb 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.0 -Release: 4%{?dist} +Release: 5%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -181,6 +181,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Fri Jan 17 2025 Fedora Release Engineering - 1.11.0-5 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild + * Tue Oct 29 2024 Jakub Jelen - 1.11.0-4 - Run annocheck as part of the build - Use upstream CF protection patches From 5f28c0a7f0829efa11968a3d4fabfd0460979cb1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 13 May 2025 10:25:59 +0200 Subject: [PATCH 85/88] 1.11.1-1 --- .gitignore | 2 + ...e-SHA3-s390x-acceleration-for-CSHAKE.patch | 63 ---- libgcrypt-1.11.0-cf-protection.patch | 328 ------------------ libgcrypt-1.11.0-marvin.patch | 13 +- libgcrypt-1.11.0-pac-bti-protection.patch | 229 ------------ libgcrypt.spec | 20 +- sources | 4 +- 7 files changed, 18 insertions(+), 641 deletions(-) delete mode 100644 libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch delete mode 100644 libgcrypt-1.11.0-cf-protection.patch delete mode 100644 libgcrypt-1.11.0-pac-bti-protection.patch diff --git a/.gitignore b/.gitignore index 069ccb4..544f5c1 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.10.3.tar.bz2.sig /libgcrypt-1.11.0.tar.bz2 /libgcrypt-1.11.0.tar.bz2.sig +/libgcrypt-1.11.1.tar.bz2 +/libgcrypt-1.11.1.tar.bz2.sig diff --git a/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch b/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch deleted file mode 100644 index 0267ea0..0000000 --- a/libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 2486d9b5ae015c1786cb84466a751da4bc0d7122 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Thu, 20 Jun 2024 20:10:09 +0300 -Subject: [PATCH] Disable SHA3 s390x acceleration for CSHAKE - -* cipher/keccak.c (keccak_final_s390x): Add assert check for -expected SHAKE suffix. -(_gcry_cshake_customize, cshake_hash_buffers): Disable s390x -acceleration when selecting CSHAKE suffix. --- - -Signed-off-by: Jussi Kivilinna ---- - cipher/keccak.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/cipher/keccak.c b/cipher/keccak.c -index aaf83a62..44cc9f71 100644 ---- a/cipher/keccak.c -+++ b/cipher/keccak.c -@@ -745,6 +745,8 @@ keccak_final_s390x (void *context) - } - else - { -+ gcry_assert(ctx->suffix == SHAKE_DELIMITED_SUFFIX); -+ - klmd_shake_execute (ctx->kimd_func, &ctx->state, NULL, 0, ctx->buf, - ctx->count); - ctx->count = 0; -@@ -1497,9 +1499,14 @@ _gcry_cshake_customize (void *context, struct gcry_cshake_customization *p) - /* No customization */ - return 0; - -+ ctx->suffix = CSHAKE_DELIMITED_SUFFIX; -+#ifdef USE_S390X_CRYPTO -+ /* CSHAKE suffix is not supported by s390x/kimd. */ -+ ctx->kimd_func = 0; -+#endif -+ - len_written = cshake_input_n (ctx, p->n, p->n_len); - cshake_input_s (ctx, p->s, p->s_len, len_written); -- ctx->suffix = CSHAKE_DELIMITED_SUFFIX; - return 0; - } - -@@ -1536,9 +1543,14 @@ cshake_hash_buffers (const gcry_md_spec_t *spec, void *outbuf, size_t nbytes, - size_t s_len = iov[1].len; - size_t len; - -+ ctx.suffix = CSHAKE_DELIMITED_SUFFIX; -+#ifdef USE_S390X_CRYPTO -+ /* CSHAKE suffix is not supported by s390x/kimd. */ -+ ctx.kimd_func = 0; -+#endif -+ - len = cshake_input_n (&ctx, n, n_len); - cshake_input_s (&ctx, s, s_len, len); -- ctx.suffix = CSHAKE_DELIMITED_SUFFIX; - } - iovcnt -= 2; - iov += 2; --- -2.43.0 diff --git a/libgcrypt-1.11.0-cf-protection.patch b/libgcrypt-1.11.0-cf-protection.patch deleted file mode 100644 index ece660e..0000000 --- a/libgcrypt-1.11.0-cf-protection.patch +++ /dev/null @@ -1,328 +0,0 @@ -From 7ee2e73495d051ca09dd57c90132a7a9cc53bc62 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Fri, 26 Jul 2024 11:00:30 +0300 -Subject: [PATCH] asm-common-amd64: add missing CFI directives for large memory - model code - -* cipher/asm-common-amd64.h [__code_model_large__] -(GET_EXTERN_POINTER): Add CFI_PUSH/CFI_POP directives. --- - -Signed-off-by: Jussi Kivilinna ---- - cipher/asm-common-amd64.h | 6 +++++- - 1 file changed, 5 insertions(+), 1 deletion(-) - -diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h -index 870fef9a..3fa065e8 100644 ---- a/cipher/asm-common-amd64.h -+++ b/cipher/asm-common-amd64.h -@@ -59,14 +59,18 @@ - # ifdef __code_model_large__ - # define GET_EXTERN_POINTER(name, reg) \ - pushq %r15; \ -+ CFI_PUSH(%r15); \ - pushq %r14; \ -+ CFI_PUSH(%r14); \ - 1: leaq 1b(%rip), reg; \ - movabsq $_GLOBAL_OFFSET_TABLE_-1b, %r14; \ - movabsq $name@GOT, %r15; \ - addq %r14, reg; \ - popq %r14; \ -+ CFI_POP(%r14); \ - movq (reg, %r15), reg; \ -- popq %r15; -+ popq %r15; \ -+ CFI_POP(%r15); - # else - # define GET_EXTERN_POINTER(name, reg) movq name@GOTPCREL(%rip), reg - # endif --- -2.45.2 - -From dd42a4e03e066c49a6d83e0d3a07e4261d77121a Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Sat, 27 Jul 2024 08:16:56 +0300 -Subject: [PATCH] Do not build i386 assembly on x86-64 - -* configure.ac: Enable building i386 "rijndael-vaes" only -on i?86 host instead of x86 MPI arch ("i?86 + x86-64"). --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - configure.ac | 9 +++++---- - 1 file changed, 5 insertions(+), 4 deletions(-) - -diff --git a/configure.ac b/configure.ac -index d3dffb4b..1e182552 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3025,6 +3025,11 @@ if test "$found" = "1" ; then - AC_DEFINE(USE_AES, 1, [Defined if this module should be included]) - - case "${host}" in -+ i?86-*-*) -+ # Build with the VAES/AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-i386.lo" -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-avx2-i386.lo" -+ ;; - x86_64-*-*) - # Build with the assembly implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-amd64.lo" -@@ -3089,10 +3094,6 @@ if test "$found" = "1" ; then - - # Build with the Padlock implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-padlock.lo" -- -- # Build with the VAES/AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-i386.lo" -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS rijndael-vaes-avx2-i386.lo" - ;; - esac - fi --- -2.45.2 - -From 5797d75e3b916caf504bed73a8629c6c168be58d Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Sat, 27 Jul 2024 08:50:57 +0300 -Subject: [PATCH] Do not build amd64 assembly on i386 - -* configure.ac: Build "serpent-avx2-amd64" and -"camellia-*-amd64" only on x86-64. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - configure.ac | 50 +++++++++++++++++++++++++++----------------------- - 1 file changed, 27 insertions(+), 23 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 1e182552..191aa38d 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3133,14 +3133,14 @@ if test "$found" = "1" ; then - x86_64-*-*) - # Build with the SSE2 implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-sse2-amd64.lo" -+ -+ if test x"$avx2support" = xyes ; then -+ # Build with the AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" -+ fi - ;; - esac - -- if test x"$avx2support" = xyes ; then -- # Build with the AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" -- fi -- - if test x"$avx512support" = xyes ; then - # Build with the AVX512 implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx512-x86.lo" -@@ -3186,28 +3186,32 @@ if test "$found" = "1" ; then - ;; - esac - -- if test x"$avxsupport" = xyes ; then -- if test x"$aesnisupport" = xyes ; then -- # Build with the AES-NI/AVX implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx-amd64.lo" -- fi -- fi -+ case "${host}" in -+ x86_64-*-*) -+ if test x"$avxsupport" = xyes ; then -+ if test x"$aesnisupport" = xyes ; then -+ # Build with the AES-NI/AVX implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx-amd64.lo" -+ fi -+ fi - -- if test x"$avx2support" = xyes ; then -- if test x"$aesnisupport" = xyes ; then -- # Build with the AES-NI/AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx2-amd64.lo" -+ if test x"$avx2support" = xyes ; then -+ if test x"$aesnisupport" = xyes ; then -+ # Build with the AES-NI/AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-aesni-avx2-amd64.lo" - -- # Build with the VAES/AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-vaes-avx2-amd64.lo" -+ # Build with the VAES/AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-vaes-avx2-amd64.lo" - -- # Build with the GFNI/AVX2 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx2-amd64.lo" -+ # Build with the GFNI/AVX2 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx2-amd64.lo" - -- # Build with the GFNI/AVX512 implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx512-amd64.lo" -- fi -- fi -+ # Build with the GFNI/AVX512 implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS camellia-gfni-avx512-amd64.lo" -+ fi -+ fi -+ ;; -+ esac - fi - - LIST_MEMBER(idea, $enabled_ciphers) --- -2.45.2 - -From d69e6a29b986cf1cb21e09d337a0de2564ef34f2 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Fri, 26 Jul 2024 10:59:12 +0300 -Subject: [PATCH] Add CET support for x86-64 assembly - -* cipher/asm-common-amd64.h (ENDBRANCH): New. -(CFI_STARTPROC): Add ENDBRANCH. -[__CET__] (note.gnu.property): Add CET property section. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - cipher/asm-common-amd64.h | 30 ++++++++++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - -diff --git a/cipher/asm-common-amd64.h b/cipher/asm-common-amd64.h -index 3fa065e8..465ef62b 100644 ---- a/cipher/asm-common-amd64.h -+++ b/cipher/asm-common-amd64.h -@@ -76,9 +76,15 @@ - # endif - #endif - -+#ifdef __CET__ -+#define ENDBRANCH endbr64 -+#else -+#define ENDBRANCH /*_*/ -+#endif -+ - #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES - /* CFI directives to emit DWARF stack unwinding information. */ --# define CFI_STARTPROC() .cfi_startproc -+# define CFI_STARTPROC() .cfi_startproc; ENDBRANCH - # define CFI_ENDPROC() .cfi_endproc - # define CFI_REMEMBER_STATE() .cfi_remember_state - # define CFI_RESTORE_STATE() .cfi_restore_state -@@ -146,7 +152,7 @@ - DW_SLEB128_28BIT(rsp_offs) - - #else --# define CFI_STARTPROC() -+# define CFI_STARTPROC() ENDBRANCH - # define CFI_ENDPROC() - # define CFI_REMEMBER_STATE() - # define CFI_RESTORE_STATE() -@@ -214,4 +220,24 @@ - vpopcntb xmm16, xmm16; /* Supported only by newer AVX512 CPUs. */ \ - vpxord ymm16, ymm16, ymm16; - -+#ifdef __CET__ -+/* Generate CET property for all assembly files including this header. */ -+ELF(.section .note.gnu.property,"a") -+ELF(.align 8) -+ELF(.long 1f - 0f) -+ELF(.long 4f - 1f) -+ELF(.long 5) -+ELF(0:) -+ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ -+ELF(1:) -+ELF(.align 8) -+ELF(.long 0xc0000002) -+ELF(.long 3f - 2f) -+ELF(2:) -+ELF(.long 0x3) -+ELF(3:) -+ELF(.align 8) -+ELF(4:) -+#endif -+ - #endif /* GCRY_ASM_COMMON_AMD64_H */ --- -2.45.2 - -From 64ec13d11b08fbe31cc6f83e9464e7e251d41019 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Fri, 26 Jul 2024 11:09:37 +0300 -Subject: [PATCH] Add CET support for i386 assembly - -* cipher/asm-common-i386.h (ENDBRANCH): New. -(CFI_STARTPROC): Add ENDBRANCH. -[__CET__] (note.gnu.property): Add CET property section. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - cipher/asm-common-i386.h | 30 ++++++++++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - -diff --git a/cipher/asm-common-i386.h b/cipher/asm-common-i386.h -index d746ebc4..346a8ff2 100644 ---- a/cipher/asm-common-i386.h -+++ b/cipher/asm-common-i386.h -@@ -59,9 +59,15 @@ - movl name##@GOT(%reg), %reg; - #endif - -+#ifdef __CET__ -+#define ENDBRANCH endbr32 -+#else -+#define ENDBRANCH /*_*/ -+#endif -+ - #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES - /* CFI directives to emit DWARF stack unwinding information. */ --# define CFI_STARTPROC() .cfi_startproc -+# define CFI_STARTPROC() .cfi_startproc; ENDBRANCH - # define CFI_ENDPROC() .cfi_endproc - # define CFI_REMEMBER_STATE() .cfi_remember_state - # define CFI_RESTORE_STATE() .cfi_restore_state -@@ -121,7 +127,7 @@ - DW_SLEB128_28BIT(esp_offs) - - #else --# define CFI_STARTPROC() -+# define CFI_STARTPROC() ENDBRANCH - # define CFI_ENDPROC() - # define CFI_REMEMBER_STATE() - # define CFI_RESTORE_STATE() -@@ -158,4 +164,24 @@ - vpopcntb xmm7, xmm7; /* Supported only by newer AVX512 CPUs. */ \ - vpxord ymm7, ymm7, ymm7; - -+#ifdef __CET__ -+/* Generate CET property for all assembly files including this header. */ -+ELF(.section .note.gnu.property,"a") -+ELF(.align 4) -+ELF(.long 1f - 0f) -+ELF(.long 4f - 1f) -+ELF(.long 5) -+ELF(0:) -+ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ -+ELF(1:) -+ELF(.align 4) -+ELF(.long 0xc0000002) -+ELF(.long 3f - 2f) -+ELF(2:) -+ELF(.long 0x3) -+ELF(3:) -+ELF(.align 4) -+ELF(4:) -+#endif -+ - #endif /* GCRY_ASM_COMMON_AMD64_H */ --- -2.45.2 - diff --git a/libgcrypt-1.11.0-marvin.patch b/libgcrypt-1.11.0-marvin.patch index d2998f0..78b6809 100644 --- a/libgcrypt-1.11.0-marvin.patch +++ b/libgcrypt-1.11.0-marvin.patch @@ -759,17 +759,17 @@ index 245967eb..74055a4b 100644 static inline size_t ct_lt_s (size_t a, size_t b) @@ -112,6 +121,7 @@ unsigned int _gcry_ct_memequal (const void *b1, const void *b2, size_t len); - #endif DEFINE_CT_TYPE_GEN_MASK(uintptr, uintptr_t) DEFINE_CT_TYPE_GEN_MASK(ulong, unsigned long) + DEFINE_CT_TYPE_GEN_MASK(int16, int16_t) +DEFINE_CT_TYPE_GEN_MASK(uchar, unsigned char) /* * Return all bits set if A is 0 and return 1 otherwise. @@ -137,6 +147,7 @@ DEFINE_CT_TYPE_GEN_MASK(int16, int16_t) - #endif DEFINE_CT_TYPE_GEN_INV_MASK(uintptr, uintptr_t) DEFINE_CT_TYPE_GEN_INV_MASK(ulong, unsigned long) + DEFINE_CT_TYPE_GEN_INV_MASK(int16, int16_t) +DEFINE_CT_TYPE_GEN_INV_MASK(uchar, unsigned char) /* @@ -1582,9 +1582,9 @@ index 74055a4b..5e656e15 100644 static inline size_t @@ -164,6 +164,7 @@ DEFINE_CT_TYPE_GEN_INV_MASK(uchar, unsigned char) - } DEFINE_CT_TYPE_SELECT_FUNC(uintptr, uintptr_t) DEFINE_CT_TYPE_SELECT_FUNC(ulong, unsigned long) + DEFINE_CT_TYPE_SELECT_FUNC(int16, int16_t) +DEFINE_CT_TYPE_SELECT_FUNC(uchar, unsigned char) /* @@ -1969,7 +1969,7 @@ index ab070a94..a2153728 100644 { show_sexp ("sign result:\n", sig); fail ("mismatch in gcry_pk_sign\n"); -@@ -429,45 +431,89 @@ check_v15crypt (void) +@@ -429,44 +431,89 @@ check_v15crypt (void) size_t mesg_len, seed_len, encr_len; gcry_sexp_t plain, ciph; @@ -2018,7 +2018,7 @@ index ab070a94..a2153728 100644 + } - err = gcry_sexp_build (&plain, NULL, -- "(data (flags pkcs1)(hash-algo sha1)" +- "(data (flags pkcs1)" - "(value %b)(random-override %b))", - (int)mesg_len, mesg, - (int)seed_len, seed); @@ -2076,14 +2076,13 @@ index ab070a94..a2153728 100644 - plain = NULL; - - /* Now test the decryption. */ -- seed = data_from_hex (tbl[tno].m[mno].seed, &seed_len); - encr = data_from_hex (tbl[tno].m[mno].encr, &encr_len); + gcry_sexp_release (ciph); + ciph = NULL; +#endif /* WITH_MARVIN_WORKAROUND */ err = gcry_sexp_build (&ciph, NULL, - "(enc-val (flags pkcs1)(hash-algo sha1)" + "(enc-val (flags pkcs1)" @@ -484,15 +530,19 @@ check_v15crypt (void) } else diff --git a/libgcrypt-1.11.0-pac-bti-protection.patch b/libgcrypt-1.11.0-pac-bti-protection.patch deleted file mode 100644 index 3c713ab..0000000 --- a/libgcrypt-1.11.0-pac-bti-protection.patch +++ /dev/null @@ -1,229 +0,0 @@ -From afdd68b162103820edb72ad170f8ee26f206b396 Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Sun, 4 Aug 2024 18:51:34 +0300 -Subject: [PATCH] Add PAC/BTI support for AArch64 assembly - -* cipher/asm-common-aarch64.h (AARCH64_BTI_PROPERTY_FLAG) -(AARCH64_HINT_BTI_C, AARCH64_PAC_PROPERTY_FLAG) -(note.gnu.property): New. -(CFI_STARTPROC): Add AARCH64_HINT_BTI_C. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - cipher/asm-common-aarch64.h | 50 +++++++++++++++++++++++++++++++++++-- - 1 file changed, 48 insertions(+), 2 deletions(-) - -diff --git a/cipher/asm-common-aarch64.h b/cipher/asm-common-aarch64.h -index 3a72d7c4..ff65ea6a 100644 ---- a/cipher/asm-common-aarch64.h -+++ b/cipher/asm-common-aarch64.h -@@ -45,9 +45,25 @@ - add reg, reg, #:lo12:name ; - #endif - -+#if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT == 1 -+# define AARCH64_BTI_PROPERTY_FLAG (1 << 0) -+# define AARCH64_HINT_BTI_C \ -+ hint #34 -+#else -+# define AARCH64_BTI_PROPERTY_FLAG 0 /* No BTI */ -+# define AARCH64_HINT_BTI_C /*_*/ -+#endif -+ -+#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 3) != 0 -+/* PAC enabled, signed with either A or B key. */ -+# define AARCH64_PAC_PROPERTY_FLAG (1 << 1) -+#else -+# define AARCH64_PAC_PROPERTY_FLAG 0 /* No PAC */ -+#endif -+ - #ifdef HAVE_GCC_ASM_CFI_DIRECTIVES - /* CFI directives to emit DWARF stack unwinding information. */ --# define CFI_STARTPROC() .cfi_startproc -+# define CFI_STARTPROC() .cfi_startproc; AARCH64_HINT_BTI_C - # define CFI_ENDPROC() .cfi_endproc - # define CFI_REMEMBER_STATE() .cfi_remember_state - # define CFI_RESTORE_STATE() .cfi_restore_state -@@ -89,7 +105,7 @@ - DW_SLEB128_28BIT(rsp_offs) - - #else --# define CFI_STARTPROC() -+# define CFI_STARTPROC() AARCH64_HINT_BTI_C - # define CFI_ENDPROC() - # define CFI_REMEMBER_STATE() - # define CFI_RESTORE_STATE() -@@ -129,4 +145,34 @@ - ldp d8, d9, [sp], #16; \ - CFI_ADJUST_CFA_OFFSET(-16); - -+#if (AARCH64_BTI_PROPERTY_FLAG | AARCH64_PAC_PROPERTY_FLAG) -+/* Generate PAC/BTI property for all assembly files including this header. -+ * -+ * libgcrypt support these extensions: -+ * - Armv8.3-A Pointer Authentication (PAC): -+ * As currently all AArch64 assembly functions are leaf functions and do -+ * not store/load link register LR, we just mark PAC as supported. -+ * -+ * - Armv8.5-A Branch Target Identification (BTI): -+ * All AArch64 assembly functions get branch target instruction through -+ * CFI_STARTPROC macro. -+ */ -+ELF(.section .note.gnu.property,"a") -+ELF(.balign 8) -+ELF(.long 1f - 0f) -+ELF(.long 4f - 1f) -+ELF(.long 5) -+ELF(0:) -+ELF(.byte 0x47, 0x4e, 0x55, 0) /* string "GNU" */ -+ELF(1:) -+ELF(.balign 8) -+ELF(.long 0xc0000000) -+ELF(.long 3f - 2f) -+ELF(2:) -+ELF(.long (AARCH64_BTI_PROPERTY_FLAG | AARCH64_PAC_PROPERTY_FLAG)) -+ELF(3:) -+ELF(.balign 8) -+ELF(4:) -+#endif -+ - #endif /* GCRY_ASM_COMMON_AARCH64_H */ --- -2.43.0 - -From 07706d69f238f6a3bfc3f74145686a02decbee9c Mon Sep 17 00:00:00 2001 -From: Jussi Kivilinna -Date: Mon, 5 Aug 2024 20:18:05 +0300 -Subject: [PATCH] Do not build 32-bit ARM assembly on Aarch64 - -* configure.ac: Build "serpent-armv7-neon", "salsa20-armv7-neon", -"chacha20-armv7-neon", "sha512-armv7-neon" and "keccak-armv7-neon" -only on 32-bit ARM. --- - -GnuPG-bug-id: 7220 -Signed-off-by: Jussi Kivilinna ---- - configure.ac | 54 ++++++++++++++++++++++++++++------------------------ - 1 file changed, 29 insertions(+), 25 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 191aa38d..2b6ddb7b 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -3139,17 +3139,18 @@ if test "$found" = "1" ; then - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx2-amd64.lo" - fi - ;; -+ arm*-*-*) -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-armv7-neon.lo" -+ fi -+ ;; - esac - - if test x"$avx512support" = xyes ; then - # Build with the AVX512 implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-avx512-x86.lo" - fi -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS serpent-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(rfc2268, $enabled_ciphers) -@@ -3230,12 +3231,13 @@ if test "$found" = "1" ; then - # Build with the assembly implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-amd64.lo" - ;; -+ arm*-*-*) -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-armv7-neon.lo" -+ fi -+ ;; - esac -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS salsa20-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(gost28147, $enabled_ciphers) -@@ -3256,6 +3258,12 @@ if test "$found" = "1" ; then - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-amd64-avx2.lo" - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-amd64-avx512.lo" - ;; -+ arm*-*-*) -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-armv7-neon.lo" -+ fi -+ ;; - aarch64-*-*) - # Build with the assembly implementation - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-aarch64.lo" -@@ -3282,11 +3290,6 @@ if test "$found" = "1" ; then - GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-s390x.lo" - ;; - esac -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_CIPHERS="$GCRYPT_ASM_CIPHERS chacha20-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(sm4, $enabled_ciphers) -@@ -3491,6 +3494,11 @@ if test "$found" = "1" ; then - arm*-*-*) - # Build with the assembly implementation - GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-arm.lo" -+ -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-armv7-neon.lo" -+ fi - ;; - aarch64-*-*) - # Build with the assembly implementation -@@ -3510,11 +3518,6 @@ if test "$found" = "1" ; then - # Build with the crypto extension implementation - GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-ppc.lo" - esac -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS sha512-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(sha3, $enabled_digests) -@@ -3527,12 +3530,13 @@ if test "$found" = "1" ; then - # Build with the assembly implementation - GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-amd64-avx512.lo" - ;; -+ arm*-*-*) -+ if test x"$neonsupport" = xyes ; then -+ # Build with the NEON implementation -+ GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-armv7-neon.lo" -+ fi -+ ;; - esac -- -- if test x"$neonsupport" = xyes ; then -- # Build with the NEON implementation -- GCRYPT_ASM_DIGESTS="$GCRYPT_ASM_DIGESTS keccak-armv7-neon.lo" -- fi - fi - - LIST_MEMBER(tiger, $enabled_digests) --- -2.43.0 - diff --git a/libgcrypt.spec b/libgcrypt.spec index eb5c8cb..4e539f6 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,19 +14,14 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.11.0 -Release: 5%{?dist} +Version: 1.11.1 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig Source2: https://gnupg.org/signature_key.asc # Pass the annobin flags to the libgcrypt.so (#2016349) Patch1: libgcrypt-1.10.1-annobin.patch -# https://dev.gnupg.org/T7167 -Patch2: libgcrypt-1.11.0-Disable-SHA3-s390x-acceleration-for-CSHAKE.patch -# https://dev.gnupg.org/T7220 -Patch3: libgcrypt-1.11.0-cf-protection.patch -Patch4: libgcrypt-1.11.0-pac-bti-protection.patch # https://gitlab.com/redhat-crypto/libgcrypt/libgcrypt-mirror/-/merge_requests/19/ Patch5: libgcrypt-1.11.0-marvin.patch @@ -64,9 +59,6 @@ applications using libgcrypt. %{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' %setup -q %patch 1 -p1 -%patch 2 -p1 -%patch 3 -p1 -%patch 4 -p1 %patch 5 -p1 %build @@ -98,10 +90,11 @@ make check # try in faked FIPS mode too LIBGCRYPT_FORCE_FIPS_MODE=1 make check -PROFILE=%{?dist} annocheck --ignore-unknown --verbose --profile=${PROFILE:1} $RPM_BUILD_ROOT%{gcrylibdir}/libgcrypt.so.20.5.0 +%define libpath $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname}.?.? + +PROFILE=%{?dist} annocheck --ignore-unknown --verbose --profile=${PROFILE:1} %{libpath} # Add generation of HMAC checksums of the final stripped binaries -%define libpath $RPM_BUILD_ROOT%{gcrylibdir}/%{gcrysoname}.?.? %define __spec_install_post \ %{?__debug_package:%{__debug_install_post}} \ %{__arch_install_post} \ @@ -181,6 +174,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Tue May 13 2025 Jakub Jelen - 1.11.1-1 +- New upstream release (#2364878) + * Fri Jan 17 2025 Fedora Release Engineering - 1.11.0-5 - Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild diff --git a/sources b/sources index 4ef369d..a713620 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.11.0.tar.bz2) = 8e093e69e3c45d30838625ca008e995556f0d5b272de1c003d44ef94633bcc0d0ef5d95e8725eb531bfafb4490ac273488633e0c801200d4666194f86c3e270e -SHA512 (libgcrypt-1.11.0.tar.bz2.sig) = 8c5ceb50d70ccdedcc1ff4b31a65a07198567b85f582e3e67699cc3e5d012bebf7b1d4903652d11905a9cd845976ad7d3642474804777d0bdc46c6847d92fe38 +SHA512 (libgcrypt-1.11.1.tar.bz2) = 85846d62ce785e4250a2bf8a2b13ec24837e48ab8e10d537ad4a18d650d2cca747f82fd1501feab47ad3114b9593b36c9fa7a892f48139e2a71ef61295a47678 +SHA512 (libgcrypt-1.11.1.tar.bz2.sig) = a9b9e2466f32623f417574537656f776baf9a933fba96fd969dda26b6bf13864ee5765112654b269f79a7f20a4a0712cf8cec7be759966088045bca040e01edc From 891b7aeee36921d11a6a54959d7be5c3db613b1d Mon Sep 17 00:00:00 2001 From: Fedora Release Engineering Date: Thu, 24 Jul 2025 19:41:03 +0000 Subject: [PATCH 86/88] Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild --- libgcrypt.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libgcrypt.spec b/libgcrypt.spec index 4e539f6..c4fac5c 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -15,7 +15,7 @@ print(string.sub(hash, 0, 16)) Name: libgcrypt Version: 1.11.1 -Release: 1%{?dist} +Release: 2%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -174,6 +174,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Thu Jul 24 2025 Fedora Release Engineering - 1.11.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild + * Tue May 13 2025 Jakub Jelen - 1.11.1-1 - New upstream release (#2364878) From baffb13bdca386a97d06e7e8f758bbe182e4ba31 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Tue, 29 Jul 2025 12:52:21 +0200 Subject: [PATCH 87/88] Migrate STI tests to fmf + update the test to actually work Resolves: #2382944 --- .fmf/version | 1 + tests/smoke-test/main.fmf | 25 +++++++++++++++++++++++ tests/smoke-test/runtest.sh | 40 ++++++++++++++++--------------------- tests/tests.yml | 20 ------------------- 4 files changed, 43 insertions(+), 43 deletions(-) create mode 100644 .fmf/version create mode 100644 tests/smoke-test/main.fmf delete mode 100644 tests/tests.yml diff --git a/.fmf/version b/.fmf/version new file mode 100644 index 0000000..d00491f --- /dev/null +++ b/.fmf/version @@ -0,0 +1 @@ +1 diff --git a/tests/smoke-test/main.fmf b/tests/smoke-test/main.fmf new file mode 100644 index 0000000..70bd1ba --- /dev/null +++ b/tests/smoke-test/main.fmf @@ -0,0 +1,25 @@ +summary: Test calls upstream test suite. +test: ./runtest.sh +enabled: true +framework: beakerlib +require: + - library(distribution/fips) +recommend: + - libgcrypt + - nfs-utils + - rpm-build + - autoconf + - automake + - libtool + - gawk + - gcc-c++ + - libgpg-error-devel + - pkgconfig + - texinfo + - fipscheck + - libkcapi-fipscheck + - crypto-policies-scripts + - bc + - annobin-annocheck + - gnupg2 +duration: 45m diff --git a/tests/smoke-test/runtest.sh b/tests/smoke-test/runtest.sh index ddd0182..0f5bc82 100755 --- a/tests/smoke-test/runtest.sh +++ b/tests/smoke-test/runtest.sh @@ -54,41 +54,35 @@ rlJournalStart rlRun "pushd $TOPDIR" 0 rlRun "rm -rf BUILD/libgcrypt-*" 0-255 rlRun "rpmbuild -vv -bc SPECS/libgcrypt.spec" 0 - rlRun "pushd BUILD/libgcrypt-*" 0 + libgcrypt_dir="libgcrypt-`rpm -q --qf "%{VERSION}\n" libgcrypt | head -1`" + if [ -d "BUILD/$libgcrypt_dir-build" ]; then + BUILDDIR="BUILD/$libgcrypt_dir-build/$libgcrypt_dir" + else + BUILDDIR="BUILD/$libgcrypt_dir" + fi + rlRun "pushd $BUILDDIR" 0 rlRun "fipshmac src/.libs/libgcrypt.so.??" 0 rlRun "popd" rlRun "popd" rlPhaseEnd rlPhaseStartTest "Upstream testsuite" - rlRun "pushd $TOPDIR/BUILD/libgcrypt-*" 0 + rlRun "pushd $TOPDIR/$BUILDDIR" 0 exp_fails=() - if [[ $fipsMode = 'enabled' ]]; then - if rlIsFedora 33; then - exp_fails+=("basic") - exp_fails+=("basic-disable-all-hwf") - exp_fails+=("t-kdf") - exp_fails+=("t-secmem") - elif rlIsFedora 34; then - exp_fails+=("basic") - exp_fails+=("basic-disable-all-hwf") - exp_fails+=("t-kdf") - exp_fails+=("t-secmem") - exp_fails+=("t-x448") - elif rlIsFedora 35; then # Fedora-35 - exp_fails+=("curves") - fi - fi + rlRun "echo 'Expecting ${#exp_fails[@]} fails'" exp_exitcode=0 if [[ ${#exp_fails[@]} -gt 0 ]]; then exp_exitcode=2; fi rlRun "make check &> $TmpDir/make_check.out" $exp_exitcode rlRun "grep ^FAIL: $TmpDir/make_check.out" 0,1 "Print fails" if [[ ${#exp_fails[@]} -gt 0 ]]; then - for f in "${exp_fails[@]}"; do - rlAssertGrep "^FAIL: $f\$" $TmpDir/make_check.out + for f in $(grep '^FAIL:' $TmpDir/make_check.out | awk -F ': ' '{print $2}'); do + if [[ "${exp_fails[@]}" =~ "$f" ]]; then + rlLog "$f failure is expected" + else + rlFail "$f failure is not expected" + fi done - [[ $(grep -c '^FAIL:' $TmpDir/make_check.out) -eq ${#exp_fails[@]} ]] || rlFail "Unexpected fails present" else rlRun "grep \"All [0-9]\+ tests passed\" $TmpDir/make_check.out" 0 \ "All tests passed" @@ -119,12 +113,12 @@ rlJournalStart for i in `seq 1 $N_SAMPLES`; do # run with HW optimizations ENAbled rm -f $HWF_DENY_FILE - $TOPDIR/BUILD/libgcrypt-*/tests/bench-slope $alg_type $algorithm |grep "$alg_line" >>$algorithm.ena + $TOPDIR/$BUILDDIR/tests/bench-slope $alg_type $algorithm |grep "$alg_line" >>$algorithm.ena # run with HW optimizations DISabled # this looks idiotic, but I wasn't able to make --disable-hwf work echo "all" >$HWF_DENY_FILE - $TOPDIR/BUILD/libgcrypt-*/tests/bench-slope $dis_arg $alg_type $algorithm |grep "$alg_line" >>$algorithm.dis + $TOPDIR/$BUILDDIR/tests/bench-slope $dis_arg $alg_type $algorithm |grep "$alg_line" >>$algorithm.dis done rlLogInfo "Performance measurements finished" rlRun "cat $algorithm.ena" diff --git a/tests/tests.yml b/tests/tests.yml deleted file mode 100644 index dd115e9..0000000 --- a/tests/tests.yml +++ /dev/null @@ -1,20 +0,0 @@ -- hosts: localhost - tags: - - classic - - container - roles: - - role: standard-test-beakerlib - tests: - - smoke-test - required_packages: - - fipscheck - - gawk - - gcc-c++ - - libgcrypt - - libgpg-error-devel - - libselinux-utils - - nfs-utils - - pkgconfig - - rpm-build - - texinfo - - wget From 42572cdcf22a43f0d0c562e7b9f97d046a9d97e1 Mon Sep 17 00:00:00 2001 From: Jakub Jelen Date: Mon, 3 Nov 2025 10:29:58 +0100 Subject: [PATCH 88/88] 1.11.2-1 --- .gitignore | 2 ++ libgcrypt.spec | 7 +++++-- sources | 4 ++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/.gitignore b/.gitignore index 544f5c1..552f393 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,5 @@ libgcrypt-1.4.5-hobbled.tar.bz2 /libgcrypt-1.11.0.tar.bz2.sig /libgcrypt-1.11.1.tar.bz2 /libgcrypt-1.11.1.tar.bz2.sig +/libgcrypt-1.11.2.tar.bz2 +/libgcrypt-1.11.2.tar.bz2.sig diff --git a/libgcrypt.spec b/libgcrypt.spec index c4fac5c..23ec779 100644 --- a/libgcrypt.spec +++ b/libgcrypt.spec @@ -14,8 +14,8 @@ print(string.sub(hash, 0, 16)) } Name: libgcrypt -Version: 1.11.1 -Release: 2%{?dist} +Version: 1.11.2 +Release: 1%{?dist} URL: https://www.gnupg.org/ Source0: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2 Source1: https://www.gnupg.org/ftp/gcrypt/libgcrypt/libgcrypt-%{version}.tar.bz2.sig @@ -174,6 +174,9 @@ mkdir -p -m 755 $RPM_BUILD_ROOT/etc/gcrypt %license COPYING %changelog +* Mon Nov 03 2025 Jakub Jelen - 1.11.2-1 +- New upstream release (#2406804) + * Thu Jul 24 2025 Fedora Release Engineering - 1.11.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild diff --git a/sources b/sources index a713620..90c992c 100644 --- a/sources +++ b/sources @@ -1,2 +1,2 @@ -SHA512 (libgcrypt-1.11.1.tar.bz2) = 85846d62ce785e4250a2bf8a2b13ec24837e48ab8e10d537ad4a18d650d2cca747f82fd1501feab47ad3114b9593b36c9fa7a892f48139e2a71ef61295a47678 -SHA512 (libgcrypt-1.11.1.tar.bz2.sig) = a9b9e2466f32623f417574537656f776baf9a933fba96fd969dda26b6bf13864ee5765112654b269f79a7f20a4a0712cf8cec7be759966088045bca040e01edc +SHA512 (libgcrypt-1.11.2.tar.bz2) = b706cea602cc8f0896e57ce979643bf78974b05faec27c1b053b773c57d8b04250e30e95a4ef5899e1df981d01d8d08f0a36e10b5820a5ec4183e74c02e5f1f0 +SHA512 (libgcrypt-1.11.2.tar.bz2.sig) = e63d240a9b97aa218c98c5baa72a30321ae85412d4a8748e36578bd9498fe8c8ee2ba84835d1783cdfc1e5dfb66b0a89409d6263e9c06f4cd11e919d4bce0cd2