diff --git a/.gitignore b/.gitignore index 8f73d36..d82cdcb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ -SOURCES/gnutls-3.7.3.tar.xz -SOURCES/gpgkey-462225C3B46F34879FC8496CD605848ED7E69871.gpg +SOURCES/gmp-6.2.1.tar.xz +SOURCES/gnutls-3.7.6.tar.xz +SOURCES/gnutls-release-keyring.gpg diff --git a/.gnutls.metadata b/.gnutls.metadata index aa8ffa9..0e7b56f 100644 --- a/.gnutls.metadata +++ b/.gnutls.metadata @@ -1,2 +1,3 @@ -552c337be97d2379ae7233ebf55e949010ef7837 SOURCES/gnutls-3.7.3.tar.xz -648ec46f9539fe756fb90131b85ae4759ed2ed21 SOURCES/gpgkey-462225C3B46F34879FC8496CD605848ED7E69871.gpg +0578d48607ec0e272177d175fd1807c30b00fdf2 SOURCES/gmp-6.2.1.tar.xz +47591374259451fe2cd86c5fe7c345e769a6c79b SOURCES/gnutls-3.7.6.tar.xz +befcf25b9dcd1d36b8bdb754c80c639eca45baa0 SOURCES/gnutls-release-keyring.gpg diff --git a/SOURCES/gmp-6.2.1-intel-cet.patch b/SOURCES/gmp-6.2.1-intel-cet.patch new file mode 100644 index 0000000..137b06c --- /dev/null +++ b/SOURCES/gmp-6.2.1-intel-cet.patch @@ -0,0 +1,3515 @@ +From 4faa667ce4e1a318db2c55ce83084cbe4924a892 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Thu, 18 Aug 2022 15:55:31 +0900 +Subject: [PATCH] gmp-intel-cet.patch + +--- + acinclude.m4 | 100 +++++++++++++++++++++++++ + configure.ac | 1 + + mpn/x86/aors_n.asm | 5 +- + mpn/x86/aorsmul_1.asm | 1 + + mpn/x86/atom/sse2/aorsmul_1.asm | 1 + + mpn/x86/atom/sse2/mul_basecase.asm | 1 + + mpn/x86/atom/sse2/sqr_basecase.asm | 1 + + mpn/x86/bdiv_dbm1c.asm | 1 + + mpn/x86/copyd.asm | 1 + + mpn/x86/copyi.asm | 1 + + mpn/x86/divrem_1.asm | 1 + + mpn/x86/divrem_2.asm | 1 + + mpn/x86/k6/aors_n.asm | 1 + + mpn/x86/k6/aorsmul_1.asm | 1 + + mpn/x86/k6/divrem_1.asm | 1 + + mpn/x86/k6/k62mmx/copyd.asm | 1 + + mpn/x86/k6/k62mmx/lshift.asm | 1 + + mpn/x86/k6/k62mmx/rshift.asm | 1 + + mpn/x86/k6/mmx/com.asm | 1 + + mpn/x86/k6/mmx/logops_n.asm | 1 + + mpn/x86/k6/mmx/lshift.asm | 1 + + mpn/x86/k6/mmx/popham.asm | 1 + + mpn/x86/k6/mmx/rshift.asm | 1 + + mpn/x86/k6/mod_34lsub1.asm | 1 + + mpn/x86/k6/mul_1.asm | 1 + + mpn/x86/k6/mul_basecase.asm | 1 + + mpn/x86/k6/pre_mod_1.asm | 1 + + mpn/x86/k6/sqr_basecase.asm | 1 + + mpn/x86/k7/aors_n.asm | 1 + + mpn/x86/k7/mmx/com.asm | 1 + + mpn/x86/k7/mmx/copyd.asm | 1 + + mpn/x86/k7/mmx/copyi.asm | 1 + + mpn/x86/k7/mmx/divrem_1.asm | 1 + + mpn/x86/k7/mmx/lshift.asm | 1 + + mpn/x86/k7/mmx/popham.asm | 1 + + mpn/x86/k7/mmx/rshift.asm | 1 + + mpn/x86/k7/mod_1_1.asm | 1 + + mpn/x86/k7/mod_1_4.asm | 1 + + mpn/x86/k7/mod_34lsub1.asm | 1 + + mpn/x86/k7/mul_basecase.asm | 1 + + mpn/x86/k7/sqr_basecase.asm | 1 + + mpn/x86/lshift.asm | 1 + + mpn/x86/mmx/sec_tabselect.asm | 1 + + mpn/x86/mod_34lsub1.asm | 1 + + mpn/x86/mul_1.asm | 1 + + mpn/x86/mul_basecase.asm | 1 + + mpn/x86/p6/aors_n.asm | 3 +- + mpn/x86/p6/aorsmul_1.asm | 3 +- + mpn/x86/p6/copyd.asm | 1 + + mpn/x86/p6/gcd_11.asm | 1 + + mpn/x86/p6/lshsub_n.asm | 3 +- + mpn/x86/p6/mmx/divrem_1.asm | 1 + + mpn/x86/p6/mod_34lsub1.asm | 1 + + mpn/x86/p6/mul_basecase.asm | 3 +- + mpn/x86/p6/sqr_basecase.asm | 3 +- + mpn/x86/pentium/aors_n.asm | 1 + + mpn/x86/pentium/aorsmul_1.asm | 1 + + mpn/x86/pentium/com.asm | 1 + + mpn/x86/pentium/copyd.asm | 1 + + mpn/x86/pentium/copyi.asm | 1 + + mpn/x86/pentium/logops_n.asm | 1 + + mpn/x86/pentium/lshift.asm | 1 + + mpn/x86/pentium/mmx/lshift.asm | 1 + + mpn/x86/pentium/mmx/mul_1.asm | 1 + + mpn/x86/pentium/mmx/rshift.asm | 1 + + mpn/x86/pentium/mod_34lsub1.asm | 1 + + mpn/x86/pentium/mul_1.asm | 1 + + mpn/x86/pentium/mul_2.asm | 1 + + mpn/x86/pentium/mul_basecase.asm | 1 + + mpn/x86/pentium/rshift.asm | 1 + + mpn/x86/pentium/sqr_basecase.asm | 1 + + mpn/x86/pentium4/copyd.asm | 1 + + mpn/x86/pentium4/copyi.asm | 1 + + mpn/x86/pentium4/mmx/popham.asm | 1 + + mpn/x86/pentium4/sse2/add_n.asm | 1 + + mpn/x86/pentium4/sse2/addlsh1_n.asm | 1 + + mpn/x86/pentium4/sse2/addmul_1.asm | 1 + + mpn/x86/pentium4/sse2/cnd_add_n.asm | 1 + + mpn/x86/pentium4/sse2/cnd_sub_n.asm | 1 + + mpn/x86/pentium4/sse2/divrem_1.asm | 1 + + mpn/x86/pentium4/sse2/mod_1_1.asm | 1 + + mpn/x86/pentium4/sse2/mod_1_4.asm | 1 + + mpn/x86/pentium4/sse2/mod_34lsub1.asm | 1 + + mpn/x86/pentium4/sse2/mul_1.asm | 1 + + mpn/x86/pentium4/sse2/mul_basecase.asm | 1 + + mpn/x86/pentium4/sse2/rsh1add_n.asm | 1 + + mpn/x86/pentium4/sse2/sqr_basecase.asm | 1 + + mpn/x86/pentium4/sse2/sub_n.asm | 1 + + mpn/x86/pentium4/sse2/submul_1.asm | 1 + + mpn/x86/rshift.asm | 1 + + mpn/x86/sec_tabselect.asm | 1 + + mpn/x86/sqr_basecase.asm | 1 + + mpn/x86/udiv.asm | 1 + + mpn/x86/umul.asm | 1 + + mpn/x86/x86-defs.m4 | 7 +- + mpn/x86_64/addaddmul_1msb0.asm | 1 + + mpn/x86_64/aorrlsh1_n.asm | 1 + + mpn/x86_64/aorrlshC_n.asm | 1 + + mpn/x86_64/aorrlsh_n.asm | 1 + + mpn/x86_64/aors_err1_n.asm | 1 + + mpn/x86_64/aors_err2_n.asm | 1 + + mpn/x86_64/aors_err3_n.asm | 1 + + mpn/x86_64/aors_n.asm | 1 + + mpn/x86_64/aorsmul_1.asm | 1 + + mpn/x86_64/atom/addmul_2.asm | 1 + + mpn/x86_64/atom/aorrlsh1_n.asm | 1 + + mpn/x86_64/atom/aorrlsh2_n.asm | 1 + + mpn/x86_64/atom/lshift.asm | 1 + + mpn/x86_64/atom/lshiftc.asm | 1 + + mpn/x86_64/atom/mul_2.asm | 1 + + mpn/x86_64/atom/rsh1aors_n.asm | 1 + + mpn/x86_64/atom/rshift.asm | 1 + + mpn/x86_64/atom/sublsh1_n.asm | 1 + + mpn/x86_64/bd1/addmul_2.asm | 1 + + mpn/x86_64/bd1/hamdist.asm | 1 + + mpn/x86_64/bd1/mul_2.asm | 1 + + mpn/x86_64/bd1/mul_basecase.asm | 1 + + mpn/x86_64/bd1/popcount.asm | 1 + + mpn/x86_64/bd2/gcd_11.asm | 1 + + mpn/x86_64/bd2/gcd_22.asm | 1 + + mpn/x86_64/bd4/gcd_11.asm | 1 + + mpn/x86_64/bdiv_dbm1c.asm | 1 + + mpn/x86_64/bdiv_q_1.asm | 1 + + mpn/x86_64/bt1/aors_n.asm | 1 + + mpn/x86_64/bt1/aorsmul_1.asm | 1 + + mpn/x86_64/bt1/copyd.asm | 1 + + mpn/x86_64/bt1/copyi.asm | 1 + + mpn/x86_64/bt1/gcd_11.asm | 1 + + mpn/x86_64/bt1/mul_1.asm | 1 + + mpn/x86_64/bt1/mul_basecase.asm | 1 + + mpn/x86_64/bt1/sqr_basecase.asm | 1 + + mpn/x86_64/cnd_aors_n.asm | 1 + + mpn/x86_64/com.asm | 1 + + mpn/x86_64/copyd.asm | 1 + + mpn/x86_64/copyi.asm | 1 + + mpn/x86_64/core2/aors_err1_n.asm | 1 + + mpn/x86_64/core2/aors_n.asm | 1 + + mpn/x86_64/core2/aorsmul_1.asm | 1 + + mpn/x86_64/core2/divrem_1.asm | 1 + + mpn/x86_64/core2/gcd_11.asm | 1 + + mpn/x86_64/core2/gcd_22.asm | 1 + + mpn/x86_64/core2/hamdist.asm | 1 + + mpn/x86_64/core2/logops_n.asm | 1 + + mpn/x86_64/core2/lshift.asm | 1 + + mpn/x86_64/core2/lshiftc.asm | 1 + + mpn/x86_64/core2/mul_basecase.asm | 5 ++ + mpn/x86_64/core2/mullo_basecase.asm | 1 + + mpn/x86_64/core2/popcount.asm | 1 + + mpn/x86_64/core2/rsh1aors_n.asm | 1 + + mpn/x86_64/core2/rshift.asm | 1 + + mpn/x86_64/core2/sqr_basecase.asm | 1 + + mpn/x86_64/core2/sublshC_n.asm | 1 + + mpn/x86_64/coreibwl/addmul_1.asm | 24 ++++-- + mpn/x86_64/coreibwl/mul_1.asm | 24 ++++-- + mpn/x86_64/coreibwl/mul_basecase.asm | 47 ++++++++---- + mpn/x86_64/coreibwl/mullo_basecase.asm | 1 + + mpn/x86_64/coreibwl/sqr_basecase.asm | 49 ++++++++---- + mpn/x86_64/coreihwl/addmul_2.asm | 1 + + mpn/x86_64/coreihwl/aors_n.asm | 1 + + mpn/x86_64/coreihwl/aorsmul_1.asm | 1 + + mpn/x86_64/coreihwl/gcd_22.asm | 1 + + mpn/x86_64/coreihwl/mul_2.asm | 1 + + mpn/x86_64/coreihwl/mul_basecase.asm | 1 + + mpn/x86_64/coreihwl/mullo_basecase.asm | 1 + + mpn/x86_64/coreihwl/redc_1.asm | 1 + + mpn/x86_64/coreihwl/sqr_basecase.asm | 1 + + mpn/x86_64/coreinhm/aorrlsh_n.asm | 1 + + mpn/x86_64/coreinhm/hamdist.asm | 1 + + mpn/x86_64/coreinhm/popcount.asm | 1 + + mpn/x86_64/coreisbr/addmul_2.asm | 1 + + mpn/x86_64/coreisbr/aorrlshC_n.asm | 1 + + mpn/x86_64/coreisbr/aorrlsh_n.asm | 1 + + mpn/x86_64/coreisbr/aors_n.asm | 1 + + mpn/x86_64/coreisbr/cnd_add_n.asm | 1 + + mpn/x86_64/coreisbr/cnd_sub_n.asm | 1 + + mpn/x86_64/coreisbr/mul_1.asm | 1 + + mpn/x86_64/coreisbr/mul_2.asm | 1 + + mpn/x86_64/coreisbr/mul_basecase.asm | 1 + + mpn/x86_64/coreisbr/mullo_basecase.asm | 1 + + mpn/x86_64/coreisbr/rsh1aors_n.asm | 1 + + mpn/x86_64/coreisbr/sqr_basecase.asm | 1 + + mpn/x86_64/div_qr_1n_pi1.asm | 1 + + mpn/x86_64/div_qr_2n_pi1.asm | 1 + + mpn/x86_64/div_qr_2u_pi1.asm | 1 + + mpn/x86_64/dive_1.asm | 1 + + mpn/x86_64/divrem_1.asm | 1 + + mpn/x86_64/divrem_2.asm | 1 + + mpn/x86_64/fastavx/copyd.asm | 1 + + mpn/x86_64/fastavx/copyi.asm | 1 + + mpn/x86_64/fastsse/com-palignr.asm | 1 + + mpn/x86_64/fastsse/com.asm | 1 + + mpn/x86_64/fastsse/copyd-palignr.asm | 1 + + mpn/x86_64/fastsse/copyd.asm | 1 + + mpn/x86_64/fastsse/copyi-palignr.asm | 1 + + mpn/x86_64/fastsse/copyi.asm | 1 + + mpn/x86_64/fastsse/lshift-movdqu2.asm | 1 + + mpn/x86_64/fastsse/lshift.asm | 1 + + mpn/x86_64/fastsse/lshiftc-movdqu2.asm | 1 + + mpn/x86_64/fastsse/lshiftc.asm | 1 + + mpn/x86_64/fastsse/rshift-movdqu2.asm | 1 + + mpn/x86_64/fastsse/sec_tabselect.asm | 1 + + mpn/x86_64/fat/fat_entry.asm | 1 + + mpn/x86_64/gcd_11.asm | 1 + + mpn/x86_64/gcd_22.asm | 1 + + mpn/x86_64/k10/gcd_22.asm | 1 + + mpn/x86_64/k10/hamdist.asm | 1 + + mpn/x86_64/k10/popcount.asm | 5 +- + mpn/x86_64/k8/addmul_2.asm | 1 + + mpn/x86_64/k8/aorrlsh_n.asm | 1 + + mpn/x86_64/k8/bdiv_q_1.asm | 1 + + mpn/x86_64/k8/div_qr_1n_pi1.asm | 1 + + mpn/x86_64/k8/mul_basecase.asm | 8 ++ + mpn/x86_64/k8/mullo_basecase.asm | 12 ++- + mpn/x86_64/k8/mulmid_basecase.asm | 9 +++ + mpn/x86_64/k8/redc_1.asm | 18 +++-- + mpn/x86_64/k8/sqr_basecase.asm | 18 +++-- + mpn/x86_64/logops_n.asm | 1 + + mpn/x86_64/lshift.asm | 1 + + mpn/x86_64/lshiftc.asm | 1 + + mpn/x86_64/lshsub_n.asm | 1 + + mpn/x86_64/missing.asm | 1 + + mpn/x86_64/mod_1_2.asm | 1 + + mpn/x86_64/mod_1_4.asm | 1 + + mpn/x86_64/mod_34lsub1.asm | 28 ++++--- + mpn/x86_64/mode1o.asm | 1 + + mpn/x86_64/mul_1.asm | 1 + + mpn/x86_64/mul_2.asm | 1 + + mpn/x86_64/nano/dive_1.asm | 1 + + mpn/x86_64/pentium4/aors_n.asm | 1 + + mpn/x86_64/pentium4/mod_34lsub1.asm | 1 + + mpn/x86_64/pentium4/rsh1aors_n.asm | 1 + + mpn/x86_64/pentium4/rshift.asm | 1 + + mpn/x86_64/popham.asm | 1 + + mpn/x86_64/rsh1aors_n.asm | 1 + + mpn/x86_64/rshift.asm | 1 + + mpn/x86_64/sec_tabselect.asm | 1 + + mpn/x86_64/sqr_diag_addlsh1.asm | 1 + + mpn/x86_64/sublsh1_n.asm | 1 + + mpn/x86_64/x86_64-defs.m4 | 5 ++ + mpn/x86_64/zen/aorrlsh_n.asm | 25 +++++-- + mpn/x86_64/zen/mul_basecase.asm | 1 + + mpn/x86_64/zen/mullo_basecase.asm | 1 + + mpn/x86_64/zen/sbpi1_bdiv_r.asm | 1 + + mpn/x86_64/zen/sqr_basecase.asm | 1 + + 244 files changed, 537 insertions(+), 89 deletions(-) + +diff --git a/acinclude.m4 b/acinclude.m4 +index 86175ce..84e880b 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -3135,6 +3135,106 @@ __sparc_get_pc_thunk.l7: + GMP_DEFINE_RAW(["define(,<$gmp_cv_asm_sparc_shared_thunks>)"]) + ]) + ++dnl GMP_ASM_X86_CET_MACROS(ABI) ++dnl ------------ ++dnl Define ++dnl 1. X86_ENDBR for endbr32/endbr64. ++dnl 2. X86_NOTRACK for notrack prefix. ++dnl 3. X86_GNU_PROPERTY to add a .note.gnu.property section to mark ++dnl Intel CET support if needed. ++dnl .section ".note.gnu.property", "a" ++dnl .p2align POINTER-ALIGN ++dnl .long 1f - 0f ++dnl .long 4f - 1f ++dnl .long 5 ++dnl 0: ++dnl .asciz "GNU" ++dnl 1: ++dnl .p2align POINTER-ALIGN ++dnl .long 0xc0000002 ++dnl .long 3f - 2f ++dnl 2: ++dnl .long 3 ++dnl 3: ++dnl .p2align POINTER-ALIGN ++dnl 4: ++AC_DEFUN([GMP_ASM_X86_CET_MACROS],[ ++dnl AC_REQUIRE([AC_PROG_CC]) GMP uses something else ++AC_CACHE_CHECK([if Intel CET is enabled], ++ gmp_cv_asm_x86_intel_cet, [dnl ++ cat > conftest.c </dev/null]) ++ then ++ gmp_cv_asm_x86_intel_cet=yes ++ else ++ gmp_cv_asm_x86_intel_cet=no ++ fi ++ rm -f conftest*]) ++ if test "$gmp_cv_asm_x86_intel_cet" = yes; then ++ case $1 in ++ 32) ++ endbr=endbr32 ++ p2align=2 ++ ;; ++ 64) ++ endbr=endbr64 ++ p2align=3 ++ ;; ++ x32) ++ endbr=endbr64 ++ p2align=2 ++ ;; ++ esac ++ AC_CACHE_CHECK([if .note.gnu.property section is needed], ++ gmp_cv_asm_x86_gnu_property, [dnl ++ cat > conftest.c </dev/null]) ++ then ++ gmp_cv_asm_x86_gnu_property=yes ++ else ++ gmp_cv_asm_x86_gnu_property=no ++ fi ++ rm -f conftest*]) ++ echo ["define(,<$endbr>)"] >> $gmp_tmpconfigm4 ++ echo ["define(,)"] >> $gmp_tmpconfigm4 ++ else ++ gmp_cv_asm_x86_gnu_property=no ++ echo ["define(,<>)"] >> $gmp_tmpconfigm4 ++ echo ["define(,<>)"] >> $gmp_tmpconfigm4 ++ fi ++ if test "$gmp_cv_asm_x86_gnu_property" = yes; then ++ echo ["define(, < ++ .section \".note.gnu.property\", \"a\" ++ .p2align $p2align ++ .long 1f - 0f ++ .long 4f - 1f ++ .long 5 ++0: ++ .asciz \"GNU\" ++1: ++ .p2align $p2align ++ .long 0xc0000002 ++ .long 3f - 2f ++2: ++ .long 3 ++3: ++ .p2align $p2align ++4:>)"] >> $gmp_tmpconfigm4 ++ else ++ echo ["define(,<>)"] >> $gmp_tmpconfigm4 ++ fi ++]) ++ + + dnl GMP_C_ATTRIBUTE_CONST + dnl --------------------- +diff --git a/configure.ac b/configure.ac +index cafdb3c..0fb8b21 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -3813,6 +3813,7 @@ yes + esac + ;; + esac ++ GMP_ASM_X86_CET_MACROS($ABI) + ;; + esac + fi +diff --git a/mpn/x86/aors_n.asm b/mpn/x86/aors_n.asm +index 5d359f5..7ea7814 100644 +--- a/mpn/x86/aors_n.asm ++++ b/mpn/x86/aors_n.asm +@@ -112,7 +112,7 @@ L(0a): leal (%eax,%eax,8),%eax + shrl %ebp C shift bit 0 into carry + popl %ebp FRAME_popl() + +- jmp *%eax C jump into loop ++ X86_NOTRACK jmp *%eax C jump into loop + + EPILOGUE() + +@@ -153,7 +153,7 @@ L(0b): leal (%eax,%eax,8),%eax + C Calculate start address in loop for non-PIC. + leal L(oop)-3(%eax,%eax,8),%eax + ') +- jmp *%eax C jump into loop ++ X86_NOTRACK jmp *%eax C jump into loop + + L(oopgo): + pushl %ebp FRAME_pushl() +@@ -200,3 +200,4 @@ L(oop): movl (%esi),%eax + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/aorsmul_1.asm b/mpn/x86/aorsmul_1.asm +index 54a8905..0ab1e01 100644 +--- a/mpn/x86/aorsmul_1.asm ++++ b/mpn/x86/aorsmul_1.asm +@@ -154,3 +154,4 @@ L(end): movl %ebx,%eax + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/atom/sse2/aorsmul_1.asm b/mpn/x86/atom/sse2/aorsmul_1.asm +index 969a14a..20658e1 100644 +--- a/mpn/x86/atom/sse2/aorsmul_1.asm ++++ b/mpn/x86/atom/sse2/aorsmul_1.asm +@@ -172,3 +172,4 @@ PROLOGUE(func_1c) + mov 20(%esp), %edx C carry + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/atom/sse2/mul_basecase.asm b/mpn/x86/atom/sse2/mul_basecase.asm +index 97d3aeb..74171aa 100644 +--- a/mpn/x86/atom/sse2/mul_basecase.asm ++++ b/mpn/x86/atom/sse2/mul_basecase.asm +@@ -499,3 +499,4 @@ L(done): + pop %edi + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/atom/sse2/sqr_basecase.asm b/mpn/x86/atom/sse2/sqr_basecase.asm +index af19ed8..0031812 100644 +--- a/mpn/x86/atom/sse2/sqr_basecase.asm ++++ b/mpn/x86/atom/sse2/sqr_basecase.asm +@@ -632,3 +632,4 @@ L(one): pmuludq %mm7, %mm7 + pop %edi + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/bdiv_dbm1c.asm b/mpn/x86/bdiv_dbm1c.asm +index 0288c47..7a3b1a6 100644 +--- a/mpn/x86/bdiv_dbm1c.asm ++++ b/mpn/x86/bdiv_dbm1c.asm +@@ -127,3 +127,4 @@ L(b1): add $-4, %ebp + pop %esi + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/copyd.asm b/mpn/x86/copyd.asm +index 51fa195..0e588d9 100644 +--- a/mpn/x86/copyd.asm ++++ b/mpn/x86/copyd.asm +@@ -89,3 +89,4 @@ PROLOGUE(mpn_copyd) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/copyi.asm b/mpn/x86/copyi.asm +index f6b0354..6efbb90 100644 +--- a/mpn/x86/copyi.asm ++++ b/mpn/x86/copyi.asm +@@ -97,3 +97,4 @@ PROLOGUE(mpn_copyi) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/divrem_1.asm b/mpn/x86/divrem_1.asm +index 255d493..b1af920 100644 +--- a/mpn/x86/divrem_1.asm ++++ b/mpn/x86/divrem_1.asm +@@ -231,3 +231,4 @@ deflit(`FRAME',8) + popl %edi + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/divrem_2.asm b/mpn/x86/divrem_2.asm +index 4c38ad0..c2920c2 100644 +--- a/mpn/x86/divrem_2.asm ++++ b/mpn/x86/divrem_2.asm +@@ -197,3 +197,4 @@ L(35): sub 20(%esp), %ebp + movl $1, 32(%esp) + jmp L(8) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/aors_n.asm b/mpn/x86/k6/aors_n.asm +index 168f9b4..257ba59 100644 +--- a/mpn/x86/k6/aors_n.asm ++++ b/mpn/x86/k6/aors_n.asm +@@ -335,3 +335,4 @@ L(inplace_done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/aorsmul_1.asm b/mpn/x86/k6/aorsmul_1.asm +index eaa92eb..78be9d2 100644 +--- a/mpn/x86/k6/aorsmul_1.asm ++++ b/mpn/x86/k6/aorsmul_1.asm +@@ -389,3 +389,4 @@ Zdisp( M4_inst,%ecx, disp0,(%edi)) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/divrem_1.asm b/mpn/x86/k6/divrem_1.asm +index b4cea4f..ca41a3f 100644 +--- a/mpn/x86/k6/divrem_1.asm ++++ b/mpn/x86/k6/divrem_1.asm +@@ -201,3 +201,4 @@ deflit(`FRAME',8) + popl %edi + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/k62mmx/copyd.asm b/mpn/x86/k6/k62mmx/copyd.asm +index f80a5a1..fc329f5 100644 +--- a/mpn/x86/k6/k62mmx/copyd.asm ++++ b/mpn/x86/k6/k62mmx/copyd.asm +@@ -116,3 +116,4 @@ L(zero): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/k62mmx/lshift.asm b/mpn/x86/k6/k62mmx/lshift.asm +index c86575f..728fb5b 100644 +--- a/mpn/x86/k6/k62mmx/lshift.asm ++++ b/mpn/x86/k6/k62mmx/lshift.asm +@@ -292,3 +292,4 @@ deflit(`FRAME',4) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/k62mmx/rshift.asm b/mpn/x86/k6/k62mmx/rshift.asm +index f604a7b..bd673f3 100644 +--- a/mpn/x86/k6/k62mmx/rshift.asm ++++ b/mpn/x86/k6/k62mmx/rshift.asm +@@ -291,3 +291,4 @@ L(finish_even): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/mmx/com.asm b/mpn/x86/k6/mmx/com.asm +index b747454..646d16b 100644 +--- a/mpn/x86/k6/mmx/com.asm ++++ b/mpn/x86/k6/mmx/com.asm +@@ -101,3 +101,4 @@ L(no_extra): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/mmx/logops_n.asm b/mpn/x86/k6/mmx/logops_n.asm +index e17930b..acfd7df 100644 +--- a/mpn/x86/k6/mmx/logops_n.asm ++++ b/mpn/x86/k6/mmx/logops_n.asm +@@ -224,3 +224,4 @@ L(no_extra): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/mmx/lshift.asm b/mpn/x86/k6/mmx/lshift.asm +index 45be582..eee1eb8 100644 +--- a/mpn/x86/k6/mmx/lshift.asm ++++ b/mpn/x86/k6/mmx/lshift.asm +@@ -128,3 +128,4 @@ L(top): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/mmx/popham.asm b/mpn/x86/k6/mmx/popham.asm +index 2b19d0b..efeb1b4 100644 +--- a/mpn/x86/k6/mmx/popham.asm ++++ b/mpn/x86/k6/mmx/popham.asm +@@ -234,3 +234,4 @@ HAM(` nop C code alignment') + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/mmx/rshift.asm b/mpn/x86/k6/mmx/rshift.asm +index cd0382f..ae53711 100644 +--- a/mpn/x86/k6/mmx/rshift.asm ++++ b/mpn/x86/k6/mmx/rshift.asm +@@ -128,3 +128,4 @@ Zdisp( movd, %mm0, 0,(%ecx,%eax,4)) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/mod_34lsub1.asm b/mpn/x86/k6/mod_34lsub1.asm +index 7e30503..05f8979 100644 +--- a/mpn/x86/k6/mod_34lsub1.asm ++++ b/mpn/x86/k6/mod_34lsub1.asm +@@ -188,3 +188,4 @@ L(combine): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/mul_1.asm b/mpn/x86/k6/mul_1.asm +index 3ef7ec2..2139f36 100644 +--- a/mpn/x86/k6/mul_1.asm ++++ b/mpn/x86/k6/mul_1.asm +@@ -290,3 +290,4 @@ L(finish_not_one): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/mul_basecase.asm b/mpn/x86/k6/mul_basecase.asm +index 7030001..ab202a2 100644 +--- a/mpn/x86/k6/mul_basecase.asm ++++ b/mpn/x86/k6/mul_basecase.asm +@@ -610,3 +610,4 @@ Zdisp( addl, %ecx, disp0,(%edi)) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/pre_mod_1.asm b/mpn/x86/k6/pre_mod_1.asm +index 34db20d..1e4cb17 100644 +--- a/mpn/x86/k6/pre_mod_1.asm ++++ b/mpn/x86/k6/pre_mod_1.asm +@@ -144,3 +144,4 @@ L(q1_ff): + + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k6/sqr_basecase.asm b/mpn/x86/k6/sqr_basecase.asm +index b7ecb5c..f3a101a 100644 +--- a/mpn/x86/k6/sqr_basecase.asm ++++ b/mpn/x86/k6/sqr_basecase.asm +@@ -678,3 +678,4 @@ L(pic_calc): + + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/aors_n.asm b/mpn/x86/k7/aors_n.asm +index 1a08072..bfdf3d4 100644 +--- a/mpn/x86/k7/aors_n.asm ++++ b/mpn/x86/k7/aors_n.asm +@@ -256,3 +256,4 @@ L(even): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mmx/com.asm b/mpn/x86/k7/mmx/com.asm +index a258c22..cf48fac 100644 +--- a/mpn/x86/k7/mmx/com.asm ++++ b/mpn/x86/k7/mmx/com.asm +@@ -123,3 +123,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mmx/copyd.asm b/mpn/x86/k7/mmx/copyd.asm +index 59ece40..3bc9ff8 100644 +--- a/mpn/x86/k7/mmx/copyd.asm ++++ b/mpn/x86/k7/mmx/copyd.asm +@@ -142,3 +142,4 @@ L(done): + + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mmx/copyi.asm b/mpn/x86/k7/mmx/copyi.asm +index 9a28f92..f0648fa 100644 +--- a/mpn/x86/k7/mmx/copyi.asm ++++ b/mpn/x86/k7/mmx/copyi.asm +@@ -155,3 +155,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mmx/divrem_1.asm b/mpn/x86/k7/mmx/divrem_1.asm +index cf34328..370bfbb 100644 +--- a/mpn/x86/k7/mmx/divrem_1.asm ++++ b/mpn/x86/k7/mmx/divrem_1.asm +@@ -830,3 +830,4 @@ L(fraction_entry): + jmp L(fraction_done) + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mmx/lshift.asm b/mpn/x86/k7/mmx/lshift.asm +index b3383cf..4140e82 100644 +--- a/mpn/x86/k7/mmx/lshift.asm ++++ b/mpn/x86/k7/mmx/lshift.asm +@@ -479,3 +479,4 @@ L(end_even_unaligned): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mmx/popham.asm b/mpn/x86/k7/mmx/popham.asm +index 95965b7..f29540a 100644 +--- a/mpn/x86/k7/mmx/popham.asm ++++ b/mpn/x86/k7/mmx/popham.asm +@@ -211,3 +211,4 @@ L(loaded): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mmx/rshift.asm b/mpn/x86/k7/mmx/rshift.asm +index 345d23a..0da1f93 100644 +--- a/mpn/x86/k7/mmx/rshift.asm ++++ b/mpn/x86/k7/mmx/rshift.asm +@@ -478,3 +478,4 @@ L(end_even_unaligned): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mod_1_1.asm b/mpn/x86/k7/mod_1_1.asm +index 1bbe6f9..8da9519 100644 +--- a/mpn/x86/k7/mod_1_1.asm ++++ b/mpn/x86/k7/mod_1_1.asm +@@ -219,3 +219,4 @@ PROLOGUE(mpn_mod_1_1p_cps) + pop %ebp + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mod_1_4.asm b/mpn/x86/k7/mod_1_4.asm +index bb7597e..fe1da5b 100644 +--- a/mpn/x86/k7/mod_1_4.asm ++++ b/mpn/x86/k7/mod_1_4.asm +@@ -258,3 +258,4 @@ C CAUTION: This is the same code as in pentium4/sse2/mod_1_4.asm + pop %ebp + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mod_34lsub1.asm b/mpn/x86/k7/mod_34lsub1.asm +index ee3ad04..0c1b8c8 100644 +--- a/mpn/x86/k7/mod_34lsub1.asm ++++ b/mpn/x86/k7/mod_34lsub1.asm +@@ -186,3 +186,4 @@ L(combine): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/mul_basecase.asm b/mpn/x86/k7/mul_basecase.asm +index 4dfb500..b96fda7 100644 +--- a/mpn/x86/k7/mul_basecase.asm ++++ b/mpn/x86/k7/mul_basecase.asm +@@ -600,3 +600,4 @@ deflit(`disp1', eval(disp0-0 + 4)) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/k7/sqr_basecase.asm b/mpn/x86/k7/sqr_basecase.asm +index 7b6a97e..df47ee4 100644 +--- a/mpn/x86/k7/sqr_basecase.asm ++++ b/mpn/x86/k7/sqr_basecase.asm +@@ -633,3 +633,4 @@ L(diag): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/lshift.asm b/mpn/x86/lshift.asm +index 6ee6153..95f5321 100644 +--- a/mpn/x86/lshift.asm ++++ b/mpn/x86/lshift.asm +@@ -104,3 +104,4 @@ L(end): shll %cl,%ebx C compute least significant limb + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/mmx/sec_tabselect.asm b/mpn/x86/mmx/sec_tabselect.asm +index aae158a..543dec1 100644 +--- a/mpn/x86/mmx/sec_tabselect.asm ++++ b/mpn/x86/mmx/sec_tabselect.asm +@@ -161,3 +161,4 @@ L(b00): pop %ebp + emms + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/mod_34lsub1.asm b/mpn/x86/mod_34lsub1.asm +index e09e702..df52d37 100644 +--- a/mpn/x86/mod_34lsub1.asm ++++ b/mpn/x86/mod_34lsub1.asm +@@ -181,3 +181,4 @@ L(combine): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/mul_1.asm b/mpn/x86/mul_1.asm +index 421de62..dbbc0e3 100644 +--- a/mpn/x86/mul_1.asm ++++ b/mpn/x86/mul_1.asm +@@ -138,3 +138,4 @@ L(end): movl %ebx,%eax + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/mul_basecase.asm b/mpn/x86/mul_basecase.asm +index 8339732..c32fd7e 100644 +--- a/mpn/x86/mul_basecase.asm ++++ b/mpn/x86/mul_basecase.asm +@@ -221,3 +221,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/aors_n.asm b/mpn/x86/p6/aors_n.asm +index df51c2e..ab172df 100644 +--- a/mpn/x86/p6/aors_n.asm ++++ b/mpn/x86/p6/aors_n.asm +@@ -90,7 +90,7 @@ L(here): + ') + + shr %edx C set cy flag +- jmp *%eax ++ X86_NOTRACK jmp *%eax + + ifdef(`PIC',` + L(pic_calc): +@@ -154,3 +154,4 @@ PROLOGUE(func_nc) + movl 20(%esp), %edx + jmp L(start) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/aorsmul_1.asm b/mpn/x86/p6/aorsmul_1.asm +index bc8c49c..2a3b122 100644 +--- a/mpn/x86/p6/aorsmul_1.asm ++++ b/mpn/x86/p6/aorsmul_1.asm +@@ -240,7 +240,7 @@ L(here): + cmovnz( %ebx, %ecx) C high,low carry other way around + cmovnz( %eax, %ebx) + +- jmp *%edx ++ X86_NOTRACK jmp *%edx + + + ifdef(`PIC',` +@@ -318,3 +318,4 @@ deflit(`disp0', eval(UNROLL_BYTES ifelse(UNROLL_BYTES,256,-128))) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/copyd.asm b/mpn/x86/p6/copyd.asm +index 1be7636..bd42da1 100644 +--- a/mpn/x86/p6/copyd.asm ++++ b/mpn/x86/p6/copyd.asm +@@ -176,3 +176,4 @@ L(zero): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/gcd_11.asm b/mpn/x86/p6/gcd_11.asm +index 80e055e..a7fc6a8 100644 +--- a/mpn/x86/p6/gcd_11.asm ++++ b/mpn/x86/p6/gcd_11.asm +@@ -81,3 +81,4 @@ L(end): mov %edx, %eax + pop %edi + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/lshsub_n.asm b/mpn/x86/p6/lshsub_n.asm +index 7ada213..17db5d5 100644 +--- a/mpn/x86/p6/lshsub_n.asm ++++ b/mpn/x86/p6/lshsub_n.asm +@@ -82,7 +82,7 @@ L(here): + pxor %mm1, %mm1 + pxor %mm0, %mm0 + +- jmp *%eax ++ X86_NOTRACK jmp *%eax + + ifdef(`PIC',` + L(pic_calc): +@@ -167,3 +167,4 @@ L(ent): mov 0(up,n,4), %eax + jmp L(top) + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/mmx/divrem_1.asm b/mpn/x86/p6/mmx/divrem_1.asm +index 5300616..b6057dd 100644 +--- a/mpn/x86/p6/mmx/divrem_1.asm ++++ b/mpn/x86/p6/mmx/divrem_1.asm +@@ -765,3 +765,4 @@ L(fraction_top): + jmp L(fraction_done) + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/mod_34lsub1.asm b/mpn/x86/p6/mod_34lsub1.asm +index b88ab5d..46b3806 100644 +--- a/mpn/x86/p6/mod_34lsub1.asm ++++ b/mpn/x86/p6/mod_34lsub1.asm +@@ -188,3 +188,4 @@ L(done_0): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/mul_basecase.asm b/mpn/x86/p6/mul_basecase.asm +index d87bc12..521b31e 100644 +--- a/mpn/x86/p6/mul_basecase.asm ++++ b/mpn/x86/p6/mul_basecase.asm +@@ -524,7 +524,7 @@ L(unroll_outer_entry): + xorl %eax, %ebx C carries other way for odd index + xorl %eax, %ecx + +- jmp *%edx ++ X86_NOTRACK jmp *%edx + + + C ----------------------------------------------------------------------------- +@@ -605,3 +605,4 @@ deflit(`disp1', eval(disp0 + 4)) + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/p6/sqr_basecase.asm b/mpn/x86/p6/sqr_basecase.asm +index 8fc7fdf..f71304f 100644 +--- a/mpn/x86/p6/sqr_basecase.asm ++++ b/mpn/x86/p6/sqr_basecase.asm +@@ -447,7 +447,7 @@ define(cmovX,`ifelse(eval(UNROLL_COUNT%2),1,`cmovz($@)',`cmovnz($@)')') + cmovX( %ebx, %ecx) C high carry reverse + cmovX( %eax, %ebx) C low carry reverse + movl %edx, VAR_JMP +- jmp *%edx ++ X86_NOTRACK jmp *%edx + + + C Must be on an even address here so the low bit of the jump address +@@ -647,3 +647,4 @@ L(pic_calc): + + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/aors_n.asm b/mpn/x86/pentium/aors_n.asm +index 01ebfb9..ca124a5 100644 +--- a/mpn/x86/pentium/aors_n.asm ++++ b/mpn/x86/pentium/aors_n.asm +@@ -201,3 +201,4 @@ L(end2): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/aorsmul_1.asm b/mpn/x86/pentium/aorsmul_1.asm +index d83cc45..5cec8b3 100644 +--- a/mpn/x86/pentium/aorsmul_1.asm ++++ b/mpn/x86/pentium/aorsmul_1.asm +@@ -142,3 +142,4 @@ L(top): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/com.asm b/mpn/x86/pentium/com.asm +index b080545..00064ff 100644 +--- a/mpn/x86/pentium/com.asm ++++ b/mpn/x86/pentium/com.asm +@@ -179,3 +179,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/copyd.asm b/mpn/x86/pentium/copyd.asm +index 72a543b..c7f74b5 100644 +--- a/mpn/x86/pentium/copyd.asm ++++ b/mpn/x86/pentium/copyd.asm +@@ -144,3 +144,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/copyi.asm b/mpn/x86/pentium/copyi.asm +index d983d6b..bc7744e 100644 +--- a/mpn/x86/pentium/copyi.asm ++++ b/mpn/x86/pentium/copyi.asm +@@ -162,3 +162,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/logops_n.asm b/mpn/x86/pentium/logops_n.asm +index 1877317..41a9477 100644 +--- a/mpn/x86/pentium/logops_n.asm ++++ b/mpn/x86/pentium/logops_n.asm +@@ -174,3 +174,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/lshift.asm b/mpn/x86/pentium/lshift.asm +index 2a31f36..68cba52 100644 +--- a/mpn/x86/pentium/lshift.asm ++++ b/mpn/x86/pentium/lshift.asm +@@ -241,3 +241,4 @@ L(L1): movl %edx,(%edi) C store last limb + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/mmx/lshift.asm b/mpn/x86/pentium/mmx/lshift.asm +index 04b0ddc..9e18c86 100644 +--- a/mpn/x86/pentium/mmx/lshift.asm ++++ b/mpn/x86/pentium/mmx/lshift.asm +@@ -461,3 +461,4 @@ L(finish_zero_unaligned): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/mmx/mul_1.asm b/mpn/x86/pentium/mmx/mul_1.asm +index 4ced577..b04a718 100644 +--- a/mpn/x86/pentium/mmx/mul_1.asm ++++ b/mpn/x86/pentium/mmx/mul_1.asm +@@ -369,3 +369,4 @@ L(small_done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/mmx/rshift.asm b/mpn/x86/pentium/mmx/rshift.asm +index e3b274b..5493d20 100644 +--- a/mpn/x86/pentium/mmx/rshift.asm ++++ b/mpn/x86/pentium/mmx/rshift.asm +@@ -466,3 +466,4 @@ L(finish_zero_unaligned): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/mod_34lsub1.asm b/mpn/x86/pentium/mod_34lsub1.asm +index 2d88223..0945de8 100644 +--- a/mpn/x86/pentium/mod_34lsub1.asm ++++ b/mpn/x86/pentium/mod_34lsub1.asm +@@ -190,3 +190,4 @@ L(combine): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/mul_1.asm b/mpn/x86/pentium/mul_1.asm +index a0858af..2c49130 100644 +--- a/mpn/x86/pentium/mul_1.asm ++++ b/mpn/x86/pentium/mul_1.asm +@@ -175,3 +175,4 @@ L(top): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/mul_2.asm b/mpn/x86/pentium/mul_2.asm +index 4c7beb5..e94e071 100644 +--- a/mpn/x86/pentium/mul_2.asm ++++ b/mpn/x86/pentium/mul_2.asm +@@ -148,3 +148,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/mul_basecase.asm b/mpn/x86/pentium/mul_basecase.asm +index e1d0f05..ff269bb 100644 +--- a/mpn/x86/pentium/mul_basecase.asm ++++ b/mpn/x86/pentium/mul_basecase.asm +@@ -140,3 +140,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/rshift.asm b/mpn/x86/pentium/rshift.asm +index 2105c4c..d98080d 100644 +--- a/mpn/x86/pentium/rshift.asm ++++ b/mpn/x86/pentium/rshift.asm +@@ -241,3 +241,4 @@ L(L1): movl %edx,(%edi) C store last limb + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium/sqr_basecase.asm b/mpn/x86/pentium/sqr_basecase.asm +index b11d767..ee64eb3 100644 +--- a/mpn/x86/pentium/sqr_basecase.asm ++++ b/mpn/x86/pentium/sqr_basecase.asm +@@ -526,3 +526,4 @@ L(diag): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/copyd.asm b/mpn/x86/pentium4/copyd.asm +index 82af81c..bf06a05 100644 +--- a/mpn/x86/pentium4/copyd.asm ++++ b/mpn/x86/pentium4/copyd.asm +@@ -69,3 +69,4 @@ L(end): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/copyi.asm b/mpn/x86/pentium4/copyi.asm +index b614887..acbb3f4 100644 +--- a/mpn/x86/pentium4/copyi.asm ++++ b/mpn/x86/pentium4/copyi.asm +@@ -91,3 +91,4 @@ L(replmovs): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/mmx/popham.asm b/mpn/x86/pentium4/mmx/popham.asm +index 9563cb5..f7a6124 100644 +--- a/mpn/x86/pentium4/mmx/popham.asm ++++ b/mpn/x86/pentium4/mmx/popham.asm +@@ -201,3 +201,4 @@ L(loaded): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/add_n.asm b/mpn/x86/pentium4/sse2/add_n.asm +index 8e2380e..e329635 100644 +--- a/mpn/x86/pentium4/sse2/add_n.asm ++++ b/mpn/x86/pentium4/sse2/add_n.asm +@@ -99,3 +99,4 @@ L(top): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/addlsh1_n.asm b/mpn/x86/pentium4/sse2/addlsh1_n.asm +index 93b63b2..e801f7b 100644 +--- a/mpn/x86/pentium4/sse2/addlsh1_n.asm ++++ b/mpn/x86/pentium4/sse2/addlsh1_n.asm +@@ -106,3 +106,4 @@ L(top): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/addmul_1.asm b/mpn/x86/pentium4/sse2/addmul_1.asm +index 7810207..62a7675 100644 +--- a/mpn/x86/pentium4/sse2/addmul_1.asm ++++ b/mpn/x86/pentium4/sse2/addmul_1.asm +@@ -187,3 +187,4 @@ PROLOGUE(mpn_addmul_1c) + movd 20(%esp), %mm6 + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/cnd_add_n.asm b/mpn/x86/pentium4/sse2/cnd_add_n.asm +index b3f3474..7183b94 100644 +--- a/mpn/x86/pentium4/sse2/cnd_add_n.asm ++++ b/mpn/x86/pentium4/sse2/cnd_add_n.asm +@@ -93,3 +93,4 @@ L(top): movd (%ebx,%ecx,4), %mm2 + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/cnd_sub_n.asm b/mpn/x86/pentium4/sse2/cnd_sub_n.asm +index 339a23e..ba0fc47 100644 +--- a/mpn/x86/pentium4/sse2/cnd_sub_n.asm ++++ b/mpn/x86/pentium4/sse2/cnd_sub_n.asm +@@ -112,3 +112,4 @@ L(done_mm1): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/divrem_1.asm b/mpn/x86/pentium4/sse2/divrem_1.asm +index 0146fab..d8619e0 100644 +--- a/mpn/x86/pentium4/sse2/divrem_1.asm ++++ b/mpn/x86/pentium4/sse2/divrem_1.asm +@@ -643,3 +643,4 @@ L(fraction_top): + jmp L(fraction_done) + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/mod_1_1.asm b/mpn/x86/pentium4/sse2/mod_1_1.asm +index ee88bab..2e5a514 100644 +--- a/mpn/x86/pentium4/sse2/mod_1_1.asm ++++ b/mpn/x86/pentium4/sse2/mod_1_1.asm +@@ -164,3 +164,4 @@ C CAUTION: This is the same code as in k7/mod_1_1.asm + pop %ebp + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/mod_1_4.asm b/mpn/x86/pentium4/sse2/mod_1_4.asm +index eb2edb6..5ef3c4a 100644 +--- a/mpn/x86/pentium4/sse2/mod_1_4.asm ++++ b/mpn/x86/pentium4/sse2/mod_1_4.asm +@@ -267,3 +267,4 @@ C CAUTION: This is the same code as in k7/mod_1_4.asm + pop %ebp + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/mod_34lsub1.asm b/mpn/x86/pentium4/sse2/mod_34lsub1.asm +index 31e25b7..5b6b9a7 100644 +--- a/mpn/x86/pentium4/sse2/mod_34lsub1.asm ++++ b/mpn/x86/pentium4/sse2/mod_34lsub1.asm +@@ -173,3 +173,4 @@ L(combine): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/mul_1.asm b/mpn/x86/pentium4/sse2/mul_1.asm +index 6347b8b..9e4f3fc 100644 +--- a/mpn/x86/pentium4/sse2/mul_1.asm ++++ b/mpn/x86/pentium4/sse2/mul_1.asm +@@ -162,3 +162,4 @@ PROLOGUE(mpn_mul_1c) + movd 20(%esp), %mm6 + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/mul_basecase.asm b/mpn/x86/pentium4/sse2/mul_basecase.asm +index 6e3775a..0bad756 100644 +--- a/mpn/x86/pentium4/sse2/mul_basecase.asm ++++ b/mpn/x86/pentium4/sse2/mul_basecase.asm +@@ -660,3 +660,4 @@ L(oel3): + pop %esi C 3 + ret C 3 + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/rsh1add_n.asm b/mpn/x86/pentium4/sse2/rsh1add_n.asm +index f421d13..543a637 100644 +--- a/mpn/x86/pentium4/sse2/rsh1add_n.asm ++++ b/mpn/x86/pentium4/sse2/rsh1add_n.asm +@@ -124,3 +124,4 @@ L(done): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/sqr_basecase.asm b/mpn/x86/pentium4/sse2/sqr_basecase.asm +index 2dd57d2..9695d42 100644 +--- a/mpn/x86/pentium4/sse2/sqr_basecase.asm ++++ b/mpn/x86/pentium4/sse2/sqr_basecase.asm +@@ -703,3 +703,4 @@ L(diag): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/sub_n.asm b/mpn/x86/pentium4/sse2/sub_n.asm +index 5ba1c01..2cd5b22 100644 +--- a/mpn/x86/pentium4/sse2/sub_n.asm ++++ b/mpn/x86/pentium4/sse2/sub_n.asm +@@ -117,3 +117,4 @@ L(done_mm1): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/pentium4/sse2/submul_1.asm b/mpn/x86/pentium4/sse2/submul_1.asm +index 020675b..1172f0a 100644 +--- a/mpn/x86/pentium4/sse2/submul_1.asm ++++ b/mpn/x86/pentium4/sse2/submul_1.asm +@@ -180,3 +180,4 @@ L(eod): paddq %mm6, %mm4 C add 0xFFFFFFFE00000001 + movd %mm0, 8(%edx) C result + jmp L(rt) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/rshift.asm b/mpn/x86/rshift.asm +index a60dcaa..1cedc0d 100644 +--- a/mpn/x86/rshift.asm ++++ b/mpn/x86/rshift.asm +@@ -106,3 +106,4 @@ L(end): shrl %cl,%ebx C compute most significant limb + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/sec_tabselect.asm b/mpn/x86/sec_tabselect.asm +index c7c2e05..3a8fa17 100644 +--- a/mpn/x86/sec_tabselect.asm ++++ b/mpn/x86/sec_tabselect.asm +@@ -113,3 +113,4 @@ L(outer_end): + pop %edi + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/sqr_basecase.asm b/mpn/x86/sqr_basecase.asm +index 39f8a89..3414b05 100644 +--- a/mpn/x86/sqr_basecase.asm ++++ b/mpn/x86/sqr_basecase.asm +@@ -357,3 +357,4 @@ L(diag): + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/udiv.asm b/mpn/x86/udiv.asm +index a3ee088..2531ef7 100644 +--- a/mpn/x86/udiv.asm ++++ b/mpn/x86/udiv.asm +@@ -50,3 +50,4 @@ deflit(`FRAME',0) + movl %edx, (%ecx) + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/umul.asm b/mpn/x86/umul.asm +index 34fe434..5c1da35 100644 +--- a/mpn/x86/umul.asm ++++ b/mpn/x86/umul.asm +@@ -49,3 +49,4 @@ deflit(`FRAME',0) + movl %edx, %eax + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86/x86-defs.m4 b/mpn/x86/x86-defs.m4 +index 81309b2..b3520d2 100644 +--- a/mpn/x86/x86-defs.m4 ++++ b/mpn/x86/x86-defs.m4 +@@ -123,6 +123,7 @@ m4_assert_defined(`WANT_PROFILING') + TYPE($1,`function') + COFF_TYPE($1) + $1: ++ X86_ENDBR + ifelse(WANT_PROFILING,`prof', ` call_mcount') + ifelse(WANT_PROFILING,`gprof', ` call_mcount') + ifelse(WANT_PROFILING,`instrument',` call_instrument(enter)') +@@ -992,7 +993,11 @@ L(movl_eip_`'substr($2,1)): + + dnl ASM_END + +-define(`ASM_END',`load_eip') ++define(`ASM_END', ++`load_eip ++X86_GNU_PROPERTY ++') ++ + + define(`load_eip', `') dnl updated in LEA/LEAL + +diff --git a/mpn/x86_64/addaddmul_1msb0.asm b/mpn/x86_64/addaddmul_1msb0.asm +index 87c21b4..2d03ddb 100644 +--- a/mpn/x86_64/addaddmul_1msb0.asm ++++ b/mpn/x86_64/addaddmul_1msb0.asm +@@ -168,3 +168,4 @@ L(end): cmp $1, R32(n) + pop %r12 + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/aorrlsh1_n.asm b/mpn/x86_64/aorrlsh1_n.asm +index 6ee0872..1441a6c 100644 +--- a/mpn/x86_64/aorrlsh1_n.asm ++++ b/mpn/x86_64/aorrlsh1_n.asm +@@ -168,3 +168,4 @@ ifdef(`OPERATION_rsblsh1_n',` + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/aorrlshC_n.asm b/mpn/x86_64/aorrlshC_n.asm +index de00154..691abde 100644 +--- a/mpn/x86_64/aorrlshC_n.asm ++++ b/mpn/x86_64/aorrlshC_n.asm +@@ -170,3 +170,4 @@ ifelse(ADDSUB,add,` + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/aorrlsh_n.asm b/mpn/x86_64/aorrlsh_n.asm +index 5ca128f..57f0e77 100644 +--- a/mpn/x86_64/aorrlsh_n.asm ++++ b/mpn/x86_64/aorrlsh_n.asm +@@ -174,3 +174,4 @@ L(end): add R32(%rbx), R32(%rbx) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/aors_err1_n.asm b/mpn/x86_64/aors_err1_n.asm +index 54d0b3f..8c42ea1 100644 +--- a/mpn/x86_64/aors_err1_n.asm ++++ b/mpn/x86_64/aors_err1_n.asm +@@ -223,3 +223,4 @@ L(end): + pop %rbx + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/aors_err2_n.asm b/mpn/x86_64/aors_err2_n.asm +index ce5c2a4..0227e5d 100644 +--- a/mpn/x86_64/aors_err2_n.asm ++++ b/mpn/x86_64/aors_err2_n.asm +@@ -170,3 +170,4 @@ L(end): + pop %rbx + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/aors_err3_n.asm b/mpn/x86_64/aors_err3_n.asm +index bb6d0c5..37047db 100644 +--- a/mpn/x86_64/aors_err3_n.asm ++++ b/mpn/x86_64/aors_err3_n.asm +@@ -154,3 +154,4 @@ L(end): + pop %rbx + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/aors_n.asm b/mpn/x86_64/aors_n.asm +index d5a314a..b516c4d 100644 +--- a/mpn/x86_64/aors_n.asm ++++ b/mpn/x86_64/aors_n.asm +@@ -176,3 +176,4 @@ L(end): lea 32(up), up + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/aorsmul_1.asm b/mpn/x86_64/aorsmul_1.asm +index dfe4dc4..e3bb2f9 100644 +--- a/mpn/x86_64/aorsmul_1.asm ++++ b/mpn/x86_64/aorsmul_1.asm +@@ -188,3 +188,4 @@ IFDOS(``pop %rdi '') + IFDOS(``pop %rsi '') + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/addmul_2.asm b/mpn/x86_64/atom/addmul_2.asm +index c1dcdc4..c1d9451 100644 +--- a/mpn/x86_64/atom/addmul_2.asm ++++ b/mpn/x86_64/atom/addmul_2.asm +@@ -184,3 +184,4 @@ L(end): mul v1 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/aorrlsh1_n.asm b/mpn/x86_64/atom/aorrlsh1_n.asm +index f44de19..693a302 100644 +--- a/mpn/x86_64/atom/aorrlsh1_n.asm ++++ b/mpn/x86_64/atom/aorrlsh1_n.asm +@@ -236,3 +236,4 @@ IFDOS(` mov 56(%rsp), %r8 ') + sbb R32(%rbp), R32(%rbp) C save acy + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/aorrlsh2_n.asm b/mpn/x86_64/atom/aorrlsh2_n.asm +index 02fb29d..c6ded74 100644 +--- a/mpn/x86_64/atom/aorrlsh2_n.asm ++++ b/mpn/x86_64/atom/aorrlsh2_n.asm +@@ -189,3 +189,4 @@ ifdef(`OPERATION_rsblsh2_n',` + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/lshift.asm b/mpn/x86_64/atom/lshift.asm +index 1b37d5d..894b912 100644 +--- a/mpn/x86_64/atom/lshift.asm ++++ b/mpn/x86_64/atom/lshift.asm +@@ -121,3 +121,4 @@ L(end): shl R8(%rcx), %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/lshiftc.asm b/mpn/x86_64/atom/lshiftc.asm +index 7385f8f..40d8fff 100644 +--- a/mpn/x86_64/atom/lshiftc.asm ++++ b/mpn/x86_64/atom/lshiftc.asm +@@ -125,3 +125,4 @@ L(end): shl R8(%rcx), %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/mul_2.asm b/mpn/x86_64/atom/mul_2.asm +index 4bc22cd..87414d9 100644 +--- a/mpn/x86_64/atom/mul_2.asm ++++ b/mpn/x86_64/atom/mul_2.asm +@@ -188,3 +188,4 @@ L(end): mul v1 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/rsh1aors_n.asm b/mpn/x86_64/atom/rsh1aors_n.asm +index 6f5f638..f3952c0 100644 +--- a/mpn/x86_64/atom/rsh1aors_n.asm ++++ b/mpn/x86_64/atom/rsh1aors_n.asm +@@ -285,3 +285,4 @@ L(cj1): pop %r15 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/rshift.asm b/mpn/x86_64/atom/rshift.asm +index 29c027d..f4c59e1 100644 +--- a/mpn/x86_64/atom/rshift.asm ++++ b/mpn/x86_64/atom/rshift.asm +@@ -119,3 +119,4 @@ L(end): shr R8(cnt), %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/atom/sublsh1_n.asm b/mpn/x86_64/atom/sublsh1_n.asm +index 1306acd..762e1ee 100644 +--- a/mpn/x86_64/atom/sublsh1_n.asm ++++ b/mpn/x86_64/atom/sublsh1_n.asm +@@ -240,3 +240,4 @@ IFDOS(` mov 56(%rsp), %r8 ') + sbb R32(%rbp), R32(%rbp) C save acy + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bd1/addmul_2.asm b/mpn/x86_64/bd1/addmul_2.asm +index b54e91a..b1c149b 100644 +--- a/mpn/x86_64/bd1/addmul_2.asm ++++ b/mpn/x86_64/bd1/addmul_2.asm +@@ -233,3 +233,4 @@ L(end): mul v0 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bd1/hamdist.asm b/mpn/x86_64/bd1/hamdist.asm +index 29e78a3..f93ce4d 100644 +--- a/mpn/x86_64/bd1/hamdist.asm ++++ b/mpn/x86_64/bd1/hamdist.asm +@@ -204,3 +204,4 @@ DEF_OBJECT(L(cnsts),16,`JUMPTABSECT') + .byte 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f + END_OBJECT(L(cnsts)) + ') ++ASM_END() +diff --git a/mpn/x86_64/bd1/mul_2.asm b/mpn/x86_64/bd1/mul_2.asm +index 85fa7aa..e910cee 100644 +--- a/mpn/x86_64/bd1/mul_2.asm ++++ b/mpn/x86_64/bd1/mul_2.asm +@@ -193,3 +193,4 @@ L(end): mov -8(up), %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bd1/mul_basecase.asm b/mpn/x86_64/bd1/mul_basecase.asm +index e47ba58..ebae74d 100644 +--- a/mpn/x86_64/bd1/mul_basecase.asm ++++ b/mpn/x86_64/bd1/mul_basecase.asm +@@ -414,3 +414,4 @@ L(ret2):pop %rbp + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bd1/popcount.asm b/mpn/x86_64/bd1/popcount.asm +index 28ce461..063c2cc 100644 +--- a/mpn/x86_64/bd1/popcount.asm ++++ b/mpn/x86_64/bd1/popcount.asm +@@ -189,3 +189,4 @@ DEF_OBJECT(L(cnsts),16,`JUMPTABSECT') + .byte 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f + END_OBJECT(L(cnsts)) + ') ++ASM_END() +diff --git a/mpn/x86_64/bd2/gcd_11.asm b/mpn/x86_64/bd2/gcd_11.asm +index b167077..3d1c788 100644 +--- a/mpn/x86_64/bd2/gcd_11.asm ++++ b/mpn/x86_64/bd2/gcd_11.asm +@@ -94,3 +94,4 @@ L(end): mov v0, %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bd2/gcd_22.asm b/mpn/x86_64/bd2/gcd_22.asm +index 070cb3e..491f0d9 100644 +--- a/mpn/x86_64/bd2/gcd_22.asm ++++ b/mpn/x86_64/bd2/gcd_22.asm +@@ -140,3 +140,4 @@ L(end): C mov v0, %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bd4/gcd_11.asm b/mpn/x86_64/bd4/gcd_11.asm +index 4176b85..d172e32 100644 +--- a/mpn/x86_64/bd4/gcd_11.asm ++++ b/mpn/x86_64/bd4/gcd_11.asm +@@ -94,3 +94,4 @@ L(end): C rax = result + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bdiv_dbm1c.asm b/mpn/x86_64/bdiv_dbm1c.asm +index a53bd52..c383ee3 100644 +--- a/mpn/x86_64/bdiv_dbm1c.asm ++++ b/mpn/x86_64/bdiv_dbm1c.asm +@@ -104,3 +104,4 @@ L(lo1): sub %rax, %r8 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bdiv_q_1.asm b/mpn/x86_64/bdiv_q_1.asm +index 85538c9..c983c7f 100644 +--- a/mpn/x86_64/bdiv_q_1.asm ++++ b/mpn/x86_64/bdiv_q_1.asm +@@ -193,3 +193,4 @@ L(one): shr R8(%rcx), %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bt1/aors_n.asm b/mpn/x86_64/bt1/aors_n.asm +index 9b6b5c7..04d81dd 100644 +--- a/mpn/x86_64/bt1/aors_n.asm ++++ b/mpn/x86_64/bt1/aors_n.asm +@@ -157,3 +157,4 @@ PROLOGUE(func_nc) + IFDOS(` mov 56(%rsp), %r8 ') + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bt1/aorsmul_1.asm b/mpn/x86_64/bt1/aorsmul_1.asm +index 41e1d8a..d309321 100644 +--- a/mpn/x86_64/bt1/aorsmul_1.asm ++++ b/mpn/x86_64/bt1/aorsmul_1.asm +@@ -189,3 +189,4 @@ IFDOS(` pop %rdi ') + IFDOS(` pop %rsi ') + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bt1/copyd.asm b/mpn/x86_64/bt1/copyd.asm +index 877714e..23fb80b 100644 +--- a/mpn/x86_64/bt1/copyd.asm ++++ b/mpn/x86_64/bt1/copyd.asm +@@ -89,3 +89,4 @@ L(end): cmp $-4, R32(n) + L(ret): FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bt1/copyi.asm b/mpn/x86_64/bt1/copyi.asm +index ee0f578..25718e6 100644 +--- a/mpn/x86_64/bt1/copyi.asm ++++ b/mpn/x86_64/bt1/copyi.asm +@@ -92,3 +92,4 @@ L(end): cmp $4, R32(n) + L(ret): FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bt1/gcd_11.asm b/mpn/x86_64/bt1/gcd_11.asm +index ef53392..03bc06d 100644 +--- a/mpn/x86_64/bt1/gcd_11.asm ++++ b/mpn/x86_64/bt1/gcd_11.asm +@@ -117,3 +117,4 @@ L(count_better): + bsf u0, cnt + jmp L(shr) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bt1/mul_1.asm b/mpn/x86_64/bt1/mul_1.asm +index 4394d6e..634cb35 100644 +--- a/mpn/x86_64/bt1/mul_1.asm ++++ b/mpn/x86_64/bt1/mul_1.asm +@@ -239,3 +239,4 @@ IFDOS(` pop %rdi ') + IFDOS(` pop %rsi ') + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bt1/mul_basecase.asm b/mpn/x86_64/bt1/mul_basecase.asm +index e7d46bf..1726190 100644 +--- a/mpn/x86_64/bt1/mul_basecase.asm ++++ b/mpn/x86_64/bt1/mul_basecase.asm +@@ -484,3 +484,4 @@ L(ret): pop %r13 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/bt1/sqr_basecase.asm b/mpn/x86_64/bt1/sqr_basecase.asm +index 0e417a1..8f665d1 100644 +--- a/mpn/x86_64/bt1/sqr_basecase.asm ++++ b/mpn/x86_64/bt1/sqr_basecase.asm +@@ -563,3 +563,4 @@ L(esd): add %rbx, w0 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/cnd_aors_n.asm b/mpn/x86_64/cnd_aors_n.asm +index 13a2ab3..b720ecb 100644 +--- a/mpn/x86_64/cnd_aors_n.asm ++++ b/mpn/x86_64/cnd_aors_n.asm +@@ -181,3 +181,4 @@ L(end): neg R32(%rax) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/com.asm b/mpn/x86_64/com.asm +index 006acaf..ec72e19 100644 +--- a/mpn/x86_64/com.asm ++++ b/mpn/x86_64/com.asm +@@ -93,3 +93,4 @@ L(e10): movq 24(up,n,8), %r9 + L(ret): FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/copyd.asm b/mpn/x86_64/copyd.asm +index a5e6e59..02ab53f 100644 +--- a/mpn/x86_64/copyd.asm ++++ b/mpn/x86_64/copyd.asm +@@ -91,3 +91,4 @@ L(end): shr R32(n) + mov %r9, -16(rp) + 1: ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/copyi.asm b/mpn/x86_64/copyi.asm +index bafce7a..8c6dbdc 100644 +--- a/mpn/x86_64/copyi.asm ++++ b/mpn/x86_64/copyi.asm +@@ -90,3 +90,4 @@ L(end): shr R32(n) + mov %r9, 16(rp) + 1: ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/aors_err1_n.asm b/mpn/x86_64/core2/aors_err1_n.asm +index 3f875ae..c9c6c36 100644 +--- a/mpn/x86_64/core2/aors_err1_n.asm ++++ b/mpn/x86_64/core2/aors_err1_n.asm +@@ -223,3 +223,4 @@ L(end): + pop %rbx + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/aors_n.asm b/mpn/x86_64/core2/aors_n.asm +index f9e0039..7981b7f 100644 +--- a/mpn/x86_64/core2/aors_n.asm ++++ b/mpn/x86_64/core2/aors_n.asm +@@ -148,3 +148,4 @@ PROLOGUE(func_nc) + IFDOS(` mov 56(%rsp), %r8 ') + jmp L(start) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/aorsmul_1.asm b/mpn/x86_64/core2/aorsmul_1.asm +index a7a5d6e..b2b067a 100644 +--- a/mpn/x86_64/core2/aorsmul_1.asm ++++ b/mpn/x86_64/core2/aorsmul_1.asm +@@ -186,3 +186,4 @@ L(n1): mov 8(rp), %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/divrem_1.asm b/mpn/x86_64/core2/divrem_1.asm +index 1b3f139..d41c494 100644 +--- a/mpn/x86_64/core2/divrem_1.asm ++++ b/mpn/x86_64/core2/divrem_1.asm +@@ -241,3 +241,4 @@ L(ret): pop %rbx + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/gcd_11.asm b/mpn/x86_64/core2/gcd_11.asm +index b00451f..b730a55 100644 +--- a/mpn/x86_64/core2/gcd_11.asm ++++ b/mpn/x86_64/core2/gcd_11.asm +@@ -91,3 +91,4 @@ L(end): C rax = result + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/gcd_22.asm b/mpn/x86_64/core2/gcd_22.asm +index b5aa73b..0ccde8a 100644 +--- a/mpn/x86_64/core2/gcd_22.asm ++++ b/mpn/x86_64/core2/gcd_22.asm +@@ -135,3 +135,4 @@ L(end): C mov v0, %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/hamdist.asm b/mpn/x86_64/core2/hamdist.asm +index a78753d..be451d7 100644 +--- a/mpn/x86_64/core2/hamdist.asm ++++ b/mpn/x86_64/core2/hamdist.asm +@@ -208,3 +208,4 @@ DEF_OBJECT(L(cnsts),16,`JUMPTABSECT') + .byte 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f + .byte 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f + END_OBJECT(L(cnsts)) ++ASM_END() +diff --git a/mpn/x86_64/core2/logops_n.asm b/mpn/x86_64/core2/logops_n.asm +index 5ff174c..451d556 100644 +--- a/mpn/x86_64/core2/logops_n.asm ++++ b/mpn/x86_64/core2/logops_n.asm +@@ -283,3 +283,4 @@ L(ret): FUNC_EXIT() + ret + EPILOGUE() + ') ++ASM_END() +diff --git a/mpn/x86_64/core2/lshift.asm b/mpn/x86_64/core2/lshift.asm +index 9016a71..62053c2 100644 +--- a/mpn/x86_64/core2/lshift.asm ++++ b/mpn/x86_64/core2/lshift.asm +@@ -143,3 +143,4 @@ L(1): shl R8(cnt), %r9 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/lshiftc.asm b/mpn/x86_64/core2/lshiftc.asm +index c428f13..cdd4e11 100644 +--- a/mpn/x86_64/core2/lshiftc.asm ++++ b/mpn/x86_64/core2/lshiftc.asm +@@ -157,3 +157,4 @@ L(1): shl R8(cnt), %r9 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/mul_basecase.asm b/mpn/x86_64/core2/mul_basecase.asm +index d16be85..0dcf0f8 100644 +--- a/mpn/x86_64/core2/mul_basecase.asm ++++ b/mpn/x86_64/core2/mul_basecase.asm +@@ -347,6 +347,7 @@ L(m2e0):mul v1 + jz L(ret2) + + L(do_am0): ++ X86_ENDBR + push %r15 + push vn_param + +@@ -520,6 +521,7 @@ L(m2e1):mul v1 + jz L(ret2) + + L(do_am1): ++ X86_ENDBR + push %r15 + push vn_param + +@@ -693,6 +695,7 @@ L(m2e2):mul v1 + jz L(ret2) + + L(do_am2): ++ X86_ENDBR + push %r15 + push vn_param + +@@ -866,6 +869,7 @@ L(m2e3):mul v1 + jz L(ret2) + + L(do_am3): ++ X86_ENDBR + push %r15 + push vn_param + +@@ -973,3 +977,4 @@ L(lo3): mul v0 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/mullo_basecase.asm b/mpn/x86_64/core2/mullo_basecase.asm +index 0f03d86..11814d5 100644 +--- a/mpn/x86_64/core2/mullo_basecase.asm ++++ b/mpn/x86_64/core2/mullo_basecase.asm +@@ -425,3 +425,4 @@ L(n3): mov (vp_param), %r9 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/popcount.asm b/mpn/x86_64/core2/popcount.asm +index 39d8c5d..5e03ef3 100644 +--- a/mpn/x86_64/core2/popcount.asm ++++ b/mpn/x86_64/core2/popcount.asm +@@ -183,3 +183,4 @@ DEF_OBJECT(L(cnsts),16,`JUMPTABSECT') + .byte 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f + .byte 0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f + END_OBJECT(L(cnsts)) ++ASM_END() +diff --git a/mpn/x86_64/core2/rsh1aors_n.asm b/mpn/x86_64/core2/rsh1aors_n.asm +index 27eed37..5b4fe7e 100644 +--- a/mpn/x86_64/core2/rsh1aors_n.asm ++++ b/mpn/x86_64/core2/rsh1aors_n.asm +@@ -167,3 +167,4 @@ L(end): shrd $1, %rbx, %rbp + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/rshift.asm b/mpn/x86_64/core2/rshift.asm +index 7578a53..86cc804 100644 +--- a/mpn/x86_64/core2/rshift.asm ++++ b/mpn/x86_64/core2/rshift.asm +@@ -141,3 +141,4 @@ L(1): shr R8(cnt), %r9 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/sqr_basecase.asm b/mpn/x86_64/core2/sqr_basecase.asm +index a112c1b..65286b0 100644 +--- a/mpn/x86_64/core2/sqr_basecase.asm ++++ b/mpn/x86_64/core2/sqr_basecase.asm +@@ -982,3 +982,4 @@ L(n3): mov %rax, %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/core2/sublshC_n.asm b/mpn/x86_64/core2/sublshC_n.asm +index 272700d..e30562b 100644 +--- a/mpn/x86_64/core2/sublshC_n.asm ++++ b/mpn/x86_64/core2/sublshC_n.asm +@@ -156,3 +156,4 @@ L(end): shr $RSH, %r11 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreibwl/addmul_1.asm b/mpn/x86_64/coreibwl/addmul_1.asm +index ee7e4ee..4ea5580 100644 +--- a/mpn/x86_64/coreibwl/addmul_1.asm ++++ b/mpn/x86_64/coreibwl/addmul_1.asm +@@ -110,33 +110,39 @@ L(tab): JMPENT( L(f0), L(tab)) + JMPENT( L(f7), L(tab)) + TEXT + +-L(f0): mulx( (up), %r10, %r8) ++L(f0): X86_ENDBR ++ mulx( (up), %r10, %r8) + lea -8(up), up + lea -8(rp), rp + lea -1(n), n + jmp L(b0) + +-L(f3): mulx( (up), %r9, %rax) ++L(f3): X86_ENDBR ++ mulx( (up), %r9, %rax) + lea 16(up), up + lea -48(rp), rp + jmp L(b3) + +-L(f4): mulx( (up), %r10, %r8) ++L(f4): X86_ENDBR ++ mulx( (up), %r10, %r8) + lea 24(up), up + lea -40(rp), rp + jmp L(b4) + +-L(f5): mulx( (up), %r9, %rax) ++L(f5): X86_ENDBR ++ mulx( (up), %r9, %rax) + lea 32(up), up + lea -32(rp), rp + jmp L(b5) + +-L(f6): mulx( (up), %r10, %r8) ++L(f6): X86_ENDBR ++ mulx( (up), %r10, %r8) + lea 40(up), up + lea -24(rp), rp + jmp L(b6) + +-L(f1): mulx( (up), %r9, %rax) ++L(f1): X86_ENDBR ++ mulx( (up), %r9, %rax) + jrcxz L(1) + jmp L(b1) + L(1): add (rp), %r9 +@@ -156,7 +162,8 @@ ifdef(`PIC', + ` nop;nop;nop;nop', + ` nop;nop;nop;nop;nop;nop;nop;nop;nop;nop;nop') + +-L(f2): mulx( (up), %r10, %r8) ++L(f2): X86_ENDBR ++ mulx( (up), %r10, %r8) + lea 8(up), up + lea 8(rp), rp + mulx( (up), %r9, %rax) +@@ -200,7 +207,8 @@ L(b3): adox( 48,(rp), %r9) + mulx( (up), %r9, %rax) + jmp L(top) + +-L(f7): mulx( (up), %r9, %rax) ++L(f7): X86_ENDBR ++ mulx( (up), %r9, %rax) + lea -16(up), up + lea -16(rp), rp + jmp L(b7) +diff --git a/mpn/x86_64/coreibwl/mul_1.asm b/mpn/x86_64/coreibwl/mul_1.asm +index b7fae2f..77121a5 100644 +--- a/mpn/x86_64/coreibwl/mul_1.asm ++++ b/mpn/x86_64/coreibwl/mul_1.asm +@@ -108,48 +108,56 @@ L(tab): JMPENT( L(f0), L(tab)) + JMPENT( L(f7), L(tab)) + TEXT + +-L(f0): mulx( (up), %r10, %r8) ++L(f0): X86_ENDBR ++ mulx( (up), %r10, %r8) + lea 56(up), up + lea -8(rp), rp + jmp L(b0) + +-L(f3): mulx( (up), %r9, %rax) ++L(f3): X86_ENDBR ++ mulx( (up), %r9, %rax) + lea 16(up), up + lea 16(rp), rp + inc n + jmp L(b3) + +-L(f4): mulx( (up), %r10, %r8) ++L(f4): X86_ENDBR ++ mulx( (up), %r10, %r8) + lea 24(up), up + lea 24(rp), rp + inc n + jmp L(b4) + +-L(f5): mulx( (up), %r9, %rax) ++L(f5): X86_ENDBR ++ mulx( (up), %r9, %rax) + lea 32(up), up + lea 32(rp), rp + inc n + jmp L(b5) + +-L(f6): mulx( (up), %r10, %r8) ++L(f6): X86_ENDBR ++ mulx( (up), %r10, %r8) + lea 40(up), up + lea 40(rp), rp + inc n + jmp L(b6) + +-L(f7): mulx( (up), %r9, %rax) ++L(f7): X86_ENDBR ++ mulx( (up), %r9, %rax) + lea 48(up), up + lea 48(rp), rp + inc n + jmp L(b7) + +-L(f1): mulx( (up), %r9, %rax) ++L(f1): X86_ENDBR ++ mulx( (up), %r9, %rax) + test n, n + jnz L(b1) + L(1): mov %r9, (rp) + ret + +-L(f2): mulx( (up), %r10, %r8) ++L(f2): X86_ENDBR ++ mulx( (up), %r10, %r8) + lea 8(up), up + lea 8(rp), rp + mulx( (up), %r9, %rax) +diff --git a/mpn/x86_64/coreibwl/mul_basecase.asm b/mpn/x86_64/coreibwl/mul_basecase.asm +index 42ca976..c5e60e7 100644 +--- a/mpn/x86_64/coreibwl/mul_basecase.asm ++++ b/mpn/x86_64/coreibwl/mul_basecase.asm +@@ -157,45 +157,53 @@ ifdef(`PIC', + jmp *(%r10,%rax,8) + ') + +-L(mf0): mulx( (up), w2, w3) ++L(mf0): X86_ENDBR ++ mulx( (up), w2, w3) + lea 56(up), up + lea -8(rp), rp + jmp L(mb0) + +-L(mf3): mulx( (up), w0, w1) ++L(mf3): X86_ENDBR ++ mulx( (up), w0, w1) + lea 16(up), up + lea 16(rp), rp + inc n + jmp L(mb3) + +-L(mf4): mulx( (up), w2, w3) ++L(mf4): X86_ENDBR ++ mulx( (up), w2, w3) + lea 24(up), up + lea 24(rp), rp + inc n + jmp L(mb4) + +-L(mf5): mulx( (up), w0, w1) ++L(mf5): X86_ENDBR ++ mulx( (up), w0, w1) + lea 32(up), up + lea 32(rp), rp + inc n + jmp L(mb5) + +-L(mf6): mulx( (up), w2, w3) ++L(mf6): X86_ENDBR ++ mulx( (up), w2, w3) + lea 40(up), up + lea 40(rp), rp + inc n + jmp L(mb6) + +-L(mf7): mulx( (up), w0, w1) ++L(mf7): X86_ENDBR ++ mulx( (up), w0, w1) + lea 48(up), up + lea 48(rp), rp + inc n + jmp L(mb7) + +-L(mf1): mulx( (up), w0, w1) ++L(mf1): X86_ENDBR ++ mulx( (up), w0, w1) + jmp L(mb1) + +-L(mf2): mulx( (up), w2, w3) ++L(mf2): X86_ENDBR ++ mulx( (up), w2, w3) + lea 8(up), up + lea 8(rp), rp + mulx( (up), w0, w1) +@@ -256,32 +264,39 @@ L(outer): + lea 8(vp), vp + jmp *jaddr + +-L(f0): mulx( 8,(up), w2, w3) ++L(f0): X86_ENDBR ++ mulx( 8,(up), w2, w3) + lea 8(rp,unneg,8), rp + lea -1(n), n + jmp L(b0) + +-L(f3): mulx( -16,(up), w0, w1) ++L(f3): X86_ENDBR ++ mulx( -16,(up), w0, w1) + lea -56(rp,unneg,8), rp + jmp L(b3) + +-L(f4): mulx( -24,(up), w2, w3) ++L(f4): X86_ENDBR ++ mulx( -24,(up), w2, w3) + lea -56(rp,unneg,8), rp + jmp L(b4) + +-L(f5): mulx( -32,(up), w0, w1) ++L(f5): X86_ENDBR ++ mulx( -32,(up), w0, w1) + lea -56(rp,unneg,8), rp + jmp L(b5) + +-L(f6): mulx( -40,(up), w2, w3) ++L(f6): X86_ENDBR ++ mulx( -40,(up), w2, w3) + lea -56(rp,unneg,8), rp + jmp L(b6) + +-L(f7): mulx( 16,(up), w0, w1) ++L(f7): X86_ENDBR ++ mulx( 16,(up), w0, w1) + lea 8(rp,unneg,8), rp + jmp L(b7) + +-L(f1): mulx( (up), w0, w1) ++L(f1): X86_ENDBR ++ mulx( (up), w0, w1) + lea 8(rp,unneg,8), rp + jmp L(b1) + +@@ -303,6 +318,7 @@ L(done): + ret + + L(f2): ++ X86_ENDBR + mulx( -8,(up), w2, w3) + lea 8(rp,unneg,8), rp + mulx( (up), w0, w1) +@@ -367,3 +383,4 @@ L(atab):JMPENT( L(f0), L(atab)) + JMPENT( L(f7), L(atab)) + TEXT + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreibwl/mullo_basecase.asm b/mpn/x86_64/coreibwl/mullo_basecase.asm +index 5cdb209..b3e435b 100644 +--- a/mpn/x86_64/coreibwl/mullo_basecase.asm ++++ b/mpn/x86_64/coreibwl/mullo_basecase.asm +@@ -393,3 +393,4 @@ L(mtab):JMPENT( L(mf7), L(mtab)) + JMPENT( L(mf4), L(mtab)) + JMPENT( L(mf5), L(mtab)) + JMPENT( L(mf6), L(mtab)) ++ASM_END() +diff --git a/mpn/x86_64/coreibwl/sqr_basecase.asm b/mpn/x86_64/coreibwl/sqr_basecase.asm +index e81b01b..cd523cf 100644 +--- a/mpn/x86_64/coreibwl/sqr_basecase.asm ++++ b/mpn/x86_64/coreibwl/sqr_basecase.asm +@@ -181,14 +181,16 @@ ifdef(`PIC', + jmp *(%r10,%rax,8) + ') + +-L(mf0): mulx( u0, w0, w1) C up[0]^2 ++L(mf0): X86_ENDBR ++ mulx( u0, w0, w1) C up[0]^2 + add u0, u0 + mulx( 8,(up), w2, w3) + lea 64(up), up + add w1, w2 + jmp L(mb0) + +-L(mf3): mulx( u0, w2, w3) C up[0]^2 ++L(mf3): X86_ENDBR ++ mulx( u0, w2, w3) C up[0]^2 + add u0, u0 + mov w2, (rp) + mulx( 8,(up), w0, w1) +@@ -197,7 +199,8 @@ L(mf3): mulx( u0, w2, w3) C up[0]^2 + add w3, w0 + jmp L(mb3) + +-L(mf4): mulx( u0, w0, w1) C up[0]^2 ++L(mf4): X86_ENDBR ++ mulx( u0, w0, w1) C up[0]^2 + add u0, u0 + mulx( 8,(up), w2, w3) + mov w0, (rp) +@@ -206,7 +209,8 @@ L(mf4): mulx( u0, w0, w1) C up[0]^2 + add w1, w2 + jmp L(mb4) + +-L(mf5): mulx( u0, w2, w3) C up[0]^2 ++L(mf5): X86_ENDBR ++ mulx( u0, w2, w3) C up[0]^2 + add u0, u0 + mulx( 8,(up), w0, w1) + mov w2, (rp) +@@ -215,7 +219,8 @@ L(mf5): mulx( u0, w2, w3) C up[0]^2 + add w3, w0 + jmp L(mb5) + +-L(mf6): mulx( u0, w0, w1) C up[0]^2 ++L(mf6): X86_ENDBR ++ mulx( u0, w0, w1) C up[0]^2 + add u0, u0 + mulx( 8,(up), w2, w3) + mov w0, (rp) +@@ -224,7 +229,8 @@ L(mf6): mulx( u0, w0, w1) C up[0]^2 + add w1, w2 + jmp L(mb6) + +-L(mf7): mulx( u0, w2, w3) C up[0]^2 ++L(mf7): X86_ENDBR ++ mulx( u0, w2, w3) C up[0]^2 + add u0, u0 + mulx( 8,(up), w0, w1) + mov w2, (rp) +@@ -233,7 +239,8 @@ L(mf7): mulx( u0, w2, w3) C up[0]^2 + add w3, w0 + jmp L(mb7) + +-L(mf1): mulx( u0, w2, w3) C up[0]^2 ++L(mf1): X86_ENDBR ++ mulx( u0, w2, w3) C up[0]^2 + add u0, u0 + mulx( 8,(up), w0, w1) + mov w2, (rp) +@@ -242,7 +249,8 @@ L(mf1): mulx( u0, w2, w3) C up[0]^2 + add w3, w0 + jmp L(mb1) + +-L(mf2): mulx( u0, w0, w1) C up[0]^2 ++L(mf2): X86_ENDBR ++ mulx( u0, w0, w1) C up[0]^2 + add u0, u0 + mulx( 8,(up), w2, w3) + mov w0, (rp) +@@ -300,7 +308,8 @@ ifdef(`PIC', + + L(ed0): adox( (rp), w0) + adox( %rcx, w1) C relies on rcx = 0 +-L(f7): mov w0, (rp) ++L(f7): X86_ENDBR ++ mov w0, (rp) + adc %rcx, w1 C relies on rcx = 0 + mov w1, 8(rp) + lea -64(up,un_save,8), up +@@ -356,7 +365,8 @@ L(b0): mov w0, (rp) + + L(ed1): adox( (rp), w0) + adox( %rcx, w1) C relies on rcx = 0 +-L(f0): mov w0, (rp) ++L(f0): X86_ENDBR ++ mov w0, (rp) + adc %rcx, w1 C relies on rcx = 0 + mov w1, 8(rp) + lea -64(up,un_save,8), up +@@ -415,7 +425,8 @@ L(b1): mulx( 8,(up), w2, w3) + + L(ed2): adox( (rp), w0) + adox( %rcx, w1) C relies on rcx = 0 +-L(f1): mov w0, (rp) ++L(f1): X86_ENDBR ++ mov w0, (rp) + adc %rcx, w1 C relies on rcx = 0 + mov w1, 8(rp) + lea (up,un_save,8), up +@@ -477,7 +488,8 @@ L(b2): adox( 48,(rp), w0) + + L(ed3): adox( (rp), w0) + adox( %rcx, w1) C relies on rcx = 0 +-L(f2): mov w0, (rp) ++L(f2): X86_ENDBR ++ mov w0, (rp) + adc %rcx, w1 C relies on rcx = 0 + mov w1, 8(rp) + lea (up,un_save,8), up +@@ -535,7 +547,8 @@ L(b3): mulx( -16,(up), w0, w1) + + L(ed4): adox( (rp), w0) + adox( %rcx, w1) C relies on rcx = 0 +-L(f3): mov w0, (rp) ++L(f3): X86_ENDBR ++ mov w0, (rp) + adc %rcx, w1 C relies on rcx = 0 + mov w1, 8(rp) + lea (up,un_save,8), up +@@ -592,7 +605,8 @@ L(b4): mulx( -24,(up), w2, w3) + + L(ed5): adox( (rp), w0) + adox( %rcx, w1) C relies on rcx = 0 +-L(f4): mov w0, (rp) ++L(f4): X86_ENDBR ++ mov w0, (rp) + adc %rcx, w1 C relies on rcx = 0 + mov w1, 8(rp) + lea (up,un_save,8), up +@@ -649,7 +663,8 @@ L(b5): mulx( -32,(up), w0, w1) + + L(ed6): adox( (rp), w0) + adox( %rcx, w1) C relies on rcx = 0 +-L(f5): mov w0, (rp) ++L(f5): X86_ENDBR ++ mov w0, (rp) + adc %rcx, w1 C relies on rcx = 0 + mov w1, 8(rp) + lea (up,un_save,8), up +@@ -706,7 +721,8 @@ L(b6): adcx( w1, w2) + + L(ed7): adox( (rp), w0) + adox( %rcx, w1) C relies on rcx = 0 +-L(f6): mov w0, (rp) ++L(f6): X86_ENDBR ++ mov w0, (rp) + adc %rcx, w1 C relies on rcx = 0 + mov w1, 8(rp) + lea (up,un_save,8), up +@@ -837,3 +853,4 @@ L(atab):JMPENT( L(f6), L(atab)) + JMPENT( L(f5), L(atab)) + TEXT + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/addmul_2.asm b/mpn/x86_64/coreihwl/addmul_2.asm +index 9d1c405..322037e 100644 +--- a/mpn/x86_64/coreihwl/addmul_2.asm ++++ b/mpn/x86_64/coreihwl/addmul_2.asm +@@ -239,3 +239,4 @@ L(end): mulx( v0, %rax, w3) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/aors_n.asm b/mpn/x86_64/coreihwl/aors_n.asm +index fc99627..f9d89f7 100644 +--- a/mpn/x86_64/coreihwl/aors_n.asm ++++ b/mpn/x86_64/coreihwl/aors_n.asm +@@ -259,3 +259,4 @@ L(tab): JMPENT( L(0), L(tab)) + JMPENT( L(5), L(tab)) + JMPENT( L(6), L(tab)) + JMPENT( L(7), L(tab)) ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/aorsmul_1.asm b/mpn/x86_64/coreihwl/aorsmul_1.asm +index 3f43afa..d01c941 100644 +--- a/mpn/x86_64/coreihwl/aorsmul_1.asm ++++ b/mpn/x86_64/coreihwl/aorsmul_1.asm +@@ -199,3 +199,4 @@ L(ret): pop %r13 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/gcd_22.asm b/mpn/x86_64/coreihwl/gcd_22.asm +index b5863b6..e41731e 100644 +--- a/mpn/x86_64/coreihwl/gcd_22.asm ++++ b/mpn/x86_64/coreihwl/gcd_22.asm +@@ -136,3 +136,4 @@ L(end): mov v0, %rax + L(ret): FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/mul_2.asm b/mpn/x86_64/coreihwl/mul_2.asm +index f1f044f..f48e5d8 100644 +--- a/mpn/x86_64/coreihwl/mul_2.asm ++++ b/mpn/x86_64/coreihwl/mul_2.asm +@@ -174,3 +174,4 @@ L(end): mulx( v1, %rdx, %rax) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/mul_basecase.asm b/mpn/x86_64/coreihwl/mul_basecase.asm +index b2656c8..14826e8 100644 +--- a/mpn/x86_64/coreihwl/mul_basecase.asm ++++ b/mpn/x86_64/coreihwl/mul_basecase.asm +@@ -439,3 +439,4 @@ L(ret2):pop %rbp + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/mullo_basecase.asm b/mpn/x86_64/coreihwl/mullo_basecase.asm +index e65559b..b29352c 100644 +--- a/mpn/x86_64/coreihwl/mullo_basecase.asm ++++ b/mpn/x86_64/coreihwl/mullo_basecase.asm +@@ -420,3 +420,4 @@ L(n3): mov (vp), %r9 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/redc_1.asm b/mpn/x86_64/coreihwl/redc_1.asm +index b1d6c0a..3b09a73 100644 +--- a/mpn/x86_64/coreihwl/redc_1.asm ++++ b/mpn/x86_64/coreihwl/redc_1.asm +@@ -435,3 +435,4 @@ L(ret): pop %r15 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreihwl/sqr_basecase.asm b/mpn/x86_64/coreihwl/sqr_basecase.asm +index 641cdf3..b6ea890 100644 +--- a/mpn/x86_64/coreihwl/sqr_basecase.asm ++++ b/mpn/x86_64/coreihwl/sqr_basecase.asm +@@ -504,3 +504,4 @@ L(dend):adc %rbx, %rdx + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreinhm/aorrlsh_n.asm b/mpn/x86_64/coreinhm/aorrlsh_n.asm +index eed64e7..3f25eea 100644 +--- a/mpn/x86_64/coreinhm/aorrlsh_n.asm ++++ b/mpn/x86_64/coreinhm/aorrlsh_n.asm +@@ -198,3 +198,4 @@ IFDOS(` mov 64(%rsp), %r9 ') C cy + sbb R32(%rbx), R32(%rbx) C initialise CF save register + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreinhm/hamdist.asm b/mpn/x86_64/coreinhm/hamdist.asm +index a5a63e4..a84bcbc 100644 +--- a/mpn/x86_64/coreinhm/hamdist.asm ++++ b/mpn/x86_64/coreinhm/hamdist.asm +@@ -194,3 +194,4 @@ L(tab): JMPENT( L(0), L(tab)) + JMPENT( L(1), L(tab)) + JMPENT( L(2), L(tab)) + JMPENT( L(3), L(tab)) ++ASM_END() +diff --git a/mpn/x86_64/coreinhm/popcount.asm b/mpn/x86_64/coreinhm/popcount.asm +index 0a3c867..24c4ebc 100644 +--- a/mpn/x86_64/coreinhm/popcount.asm ++++ b/mpn/x86_64/coreinhm/popcount.asm +@@ -180,3 +180,4 @@ L(tab): JMPENT( L(0), L(tab)) + JMPENT( L(5), L(tab)) + JMPENT( L(6), L(tab)) + JMPENT( L(7), L(tab)) ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/addmul_2.asm b/mpn/x86_64/coreisbr/addmul_2.asm +index 21f0bf4..45c7b15 100644 +--- a/mpn/x86_64/coreisbr/addmul_2.asm ++++ b/mpn/x86_64/coreisbr/addmul_2.asm +@@ -222,3 +222,4 @@ L(end): mul v1 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/aorrlshC_n.asm b/mpn/x86_64/coreisbr/aorrlshC_n.asm +index 23ace41..6af7da8 100644 +--- a/mpn/x86_64/coreisbr/aorrlshC_n.asm ++++ b/mpn/x86_64/coreisbr/aorrlshC_n.asm +@@ -171,3 +171,4 @@ L(end): shr $RSH, %rbp + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/aorrlsh_n.asm b/mpn/x86_64/coreisbr/aorrlsh_n.asm +index db8ee68..56ca497 100644 +--- a/mpn/x86_64/coreisbr/aorrlsh_n.asm ++++ b/mpn/x86_64/coreisbr/aorrlsh_n.asm +@@ -213,3 +213,4 @@ IFDOS(` mov 64(%rsp), %r9 ') C cy + sbb R32(%rbx), R32(%rbx) C initialise CF save register + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/aors_n.asm b/mpn/x86_64/coreisbr/aors_n.asm +index 61fee3e..d466248 100644 +--- a/mpn/x86_64/coreisbr/aors_n.asm ++++ b/mpn/x86_64/coreisbr/aors_n.asm +@@ -201,3 +201,4 @@ PROLOGUE(func_nc) + IFDOS(` mov 56(%rsp), %r8 ') + jmp L(ent) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/cnd_add_n.asm b/mpn/x86_64/coreisbr/cnd_add_n.asm +index 43abcc8..3d72bf8 100644 +--- a/mpn/x86_64/coreisbr/cnd_add_n.asm ++++ b/mpn/x86_64/coreisbr/cnd_add_n.asm +@@ -172,3 +172,4 @@ L(end): neg R32(%rax) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/cnd_sub_n.asm b/mpn/x86_64/coreisbr/cnd_sub_n.asm +index f55492b..3371269 100644 +--- a/mpn/x86_64/coreisbr/cnd_sub_n.asm ++++ b/mpn/x86_64/coreisbr/cnd_sub_n.asm +@@ -198,3 +198,4 @@ L(end): neg R32(%rax) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/mul_1.asm b/mpn/x86_64/coreisbr/mul_1.asm +index a43a117..1f17293 100644 +--- a/mpn/x86_64/coreisbr/mul_1.asm ++++ b/mpn/x86_64/coreisbr/mul_1.asm +@@ -197,3 +197,4 @@ L(00c): add cin, %r10 + mov 8(up,n,8), %rax + jmp L(L0c) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/mul_2.asm b/mpn/x86_64/coreisbr/mul_2.asm +index 781534d..10f1769 100644 +--- a/mpn/x86_64/coreisbr/mul_2.asm ++++ b/mpn/x86_64/coreisbr/mul_2.asm +@@ -165,3 +165,4 @@ L(end): mul v0 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/mul_basecase.asm b/mpn/x86_64/coreisbr/mul_basecase.asm +index 35fd1cc..d5c7e5b 100644 +--- a/mpn/x86_64/coreisbr/mul_basecase.asm ++++ b/mpn/x86_64/coreisbr/mul_basecase.asm +@@ -405,3 +405,4 @@ L(ret2):pop %rbp + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/mullo_basecase.asm b/mpn/x86_64/coreisbr/mullo_basecase.asm +index a41a8ac..acf7776 100644 +--- a/mpn/x86_64/coreisbr/mullo_basecase.asm ++++ b/mpn/x86_64/coreisbr/mullo_basecase.asm +@@ -382,3 +382,4 @@ L(n3): mov (vp_param), %r9 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/rsh1aors_n.asm b/mpn/x86_64/coreisbr/rsh1aors_n.asm +index fd2eaea..eefad99 100644 +--- a/mpn/x86_64/coreisbr/rsh1aors_n.asm ++++ b/mpn/x86_64/coreisbr/rsh1aors_n.asm +@@ -191,3 +191,4 @@ L(end): shrd $1, %rbx, %rbp + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/coreisbr/sqr_basecase.asm b/mpn/x86_64/coreisbr/sqr_basecase.asm +index 46a3612..1600e25 100644 +--- a/mpn/x86_64/coreisbr/sqr_basecase.asm ++++ b/mpn/x86_64/coreisbr/sqr_basecase.asm +@@ -482,3 +482,4 @@ L(dend):add %r8, %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/div_qr_1n_pi1.asm b/mpn/x86_64/div_qr_1n_pi1.asm +index b3d45e2..9fd2633 100644 +--- a/mpn/x86_64/div_qr_1n_pi1.asm ++++ b/mpn/x86_64/div_qr_1n_pi1.asm +@@ -245,3 +245,4 @@ L(q_incr_loop): + lea 8(U1), U1 + jmp L(q_incr_loop) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/div_qr_2n_pi1.asm b/mpn/x86_64/div_qr_2n_pi1.asm +index 5e59a0a..c189c33 100644 +--- a/mpn/x86_64/div_qr_2n_pi1.asm ++++ b/mpn/x86_64/div_qr_2n_pi1.asm +@@ -156,3 +156,4 @@ L(fix): C Unlikely update. u2 >= d1 + sbb d1, u2 + jmp L(bck) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/div_qr_2u_pi1.asm b/mpn/x86_64/div_qr_2u_pi1.asm +index 85af96f..f2ac526 100644 +--- a/mpn/x86_64/div_qr_2u_pi1.asm ++++ b/mpn/x86_64/div_qr_2u_pi1.asm +@@ -198,3 +198,4 @@ L(fix_qh): C Unlikely update. u2 >= d1 + sbb d1, u2 + jmp L(bck_qh) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/dive_1.asm b/mpn/x86_64/dive_1.asm +index 988bdab..1929091 100644 +--- a/mpn/x86_64/dive_1.asm ++++ b/mpn/x86_64/dive_1.asm +@@ -156,3 +156,4 @@ L(one): shr R8(%rcx), %rax + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/divrem_1.asm b/mpn/x86_64/divrem_1.asm +index d4d61ad..edfd893 100644 +--- a/mpn/x86_64/divrem_1.asm ++++ b/mpn/x86_64/divrem_1.asm +@@ -312,3 +312,4 @@ L(ret): pop %rbx + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/divrem_2.asm b/mpn/x86_64/divrem_2.asm +index 20811cc..e10f328 100644 +--- a/mpn/x86_64/divrem_2.asm ++++ b/mpn/x86_64/divrem_2.asm +@@ -190,3 +190,4 @@ L(fix): seta %dl + sbb %r11, %rbx + jmp L(bck) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastavx/copyd.asm b/mpn/x86_64/fastavx/copyd.asm +index 56d472f..a69a624 100644 +--- a/mpn/x86_64/fastavx/copyd.asm ++++ b/mpn/x86_64/fastavx/copyd.asm +@@ -170,3 +170,4 @@ L(bc): test $4, R8(n) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastavx/copyi.asm b/mpn/x86_64/fastavx/copyi.asm +index 7607747..f50aa47 100644 +--- a/mpn/x86_64/fastavx/copyi.asm ++++ b/mpn/x86_64/fastavx/copyi.asm +@@ -167,3 +167,4 @@ L(bc): test $4, R8(n) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/com-palignr.asm b/mpn/x86_64/fastsse/com-palignr.asm +index 69027bc..50cd40f 100644 +--- a/mpn/x86_64/fastsse/com-palignr.asm ++++ b/mpn/x86_64/fastsse/com-palignr.asm +@@ -309,3 +309,4 @@ L(end): test $1, R8(n) + 1: FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/com.asm b/mpn/x86_64/fastsse/com.asm +index c867222..aec7d25 100644 +--- a/mpn/x86_64/fastsse/com.asm ++++ b/mpn/x86_64/fastsse/com.asm +@@ -173,3 +173,4 @@ IFDOS(` add $56, %rsp ') + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/copyd-palignr.asm b/mpn/x86_64/fastsse/copyd-palignr.asm +index fac6f8a..fa1e4a4 100644 +--- a/mpn/x86_64/fastsse/copyd-palignr.asm ++++ b/mpn/x86_64/fastsse/copyd-palignr.asm +@@ -252,3 +252,4 @@ L(end): test $1, R8(n) + 1: FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/copyd.asm b/mpn/x86_64/fastsse/copyd.asm +index b3c4706..ce820c5 100644 +--- a/mpn/x86_64/fastsse/copyd.asm ++++ b/mpn/x86_64/fastsse/copyd.asm +@@ -164,3 +164,4 @@ L(sma): test $8, R8(n) + L(don): FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/copyi-palignr.asm b/mpn/x86_64/fastsse/copyi-palignr.asm +index 9876a47..fb4655f 100644 +--- a/mpn/x86_64/fastsse/copyi-palignr.asm ++++ b/mpn/x86_64/fastsse/copyi-palignr.asm +@@ -298,3 +298,4 @@ L(end): test $1, R8(n) + 1: FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/copyi.asm b/mpn/x86_64/fastsse/copyi.asm +index 97f7865..826caad 100644 +--- a/mpn/x86_64/fastsse/copyi.asm ++++ b/mpn/x86_64/fastsse/copyi.asm +@@ -183,3 +183,4 @@ dnl jnc 1b + L(ret): FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/lshift-movdqu2.asm b/mpn/x86_64/fastsse/lshift-movdqu2.asm +index a05e850..217f2cd 100644 +--- a/mpn/x86_64/fastsse/lshift-movdqu2.asm ++++ b/mpn/x86_64/fastsse/lshift-movdqu2.asm +@@ -180,3 +180,4 @@ L(end8):movq (ap), %xmm0 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/lshift.asm b/mpn/x86_64/fastsse/lshift.asm +index 6a17b93..79a5554 100644 +--- a/mpn/x86_64/fastsse/lshift.asm ++++ b/mpn/x86_64/fastsse/lshift.asm +@@ -171,3 +171,4 @@ L(end8):movq (ap), %xmm0 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/lshiftc-movdqu2.asm b/mpn/x86_64/fastsse/lshiftc-movdqu2.asm +index 8250910..9f14435 100644 +--- a/mpn/x86_64/fastsse/lshiftc-movdqu2.asm ++++ b/mpn/x86_64/fastsse/lshiftc-movdqu2.asm +@@ -191,3 +191,4 @@ L(end8):movq (ap), %xmm0 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/lshiftc.asm b/mpn/x86_64/fastsse/lshiftc.asm +index a616075..a6630cb 100644 +--- a/mpn/x86_64/fastsse/lshiftc.asm ++++ b/mpn/x86_64/fastsse/lshiftc.asm +@@ -181,3 +181,4 @@ L(end8):movq (ap), %xmm0 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/rshift-movdqu2.asm b/mpn/x86_64/fastsse/rshift-movdqu2.asm +index 1e270b1..15bcc02 100644 +--- a/mpn/x86_64/fastsse/rshift-movdqu2.asm ++++ b/mpn/x86_64/fastsse/rshift-movdqu2.asm +@@ -199,3 +199,4 @@ L(bc): dec R32(n) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fastsse/sec_tabselect.asm b/mpn/x86_64/fastsse/sec_tabselect.asm +index e7b7feb..f3b76eb 100644 +--- a/mpn/x86_64/fastsse/sec_tabselect.asm ++++ b/mpn/x86_64/fastsse/sec_tabselect.asm +@@ -202,3 +202,4 @@ IFDOS(` add $88, %rsp ') + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/fat/fat_entry.asm b/mpn/x86_64/fat/fat_entry.asm +index 5f244ac..2322be8 100644 +--- a/mpn/x86_64/fat/fat_entry.asm ++++ b/mpn/x86_64/fat/fat_entry.asm +@@ -207,3 +207,4 @@ PROLOGUE(__gmpn_cpuid) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/gcd_11.asm b/mpn/x86_64/gcd_11.asm +index f9b3bcc..1e5ac68 100644 +--- a/mpn/x86_64/gcd_11.asm ++++ b/mpn/x86_64/gcd_11.asm +@@ -112,3 +112,4 @@ L(shift_alot): + mov u0, %rdx + jmp L(mid) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/gcd_22.asm b/mpn/x86_64/gcd_22.asm +index 78f985f..c3b0b89 100644 +--- a/mpn/x86_64/gcd_22.asm ++++ b/mpn/x86_64/gcd_22.asm +@@ -161,3 +161,4 @@ L(end): C mov v0, %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k10/gcd_22.asm b/mpn/x86_64/k10/gcd_22.asm +index f58b4cc..c7fe668 100644 +--- a/mpn/x86_64/k10/gcd_22.asm ++++ b/mpn/x86_64/k10/gcd_22.asm +@@ -140,3 +140,4 @@ L(end): C mov v0, %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k10/hamdist.asm b/mpn/x86_64/k10/hamdist.asm +index f70494a..d885e2d 100644 +--- a/mpn/x86_64/k10/hamdist.asm ++++ b/mpn/x86_64/k10/hamdist.asm +@@ -107,3 +107,4 @@ L(top): mov (ap,n,8), %r8 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k10/popcount.asm b/mpn/x86_64/k10/popcount.asm +index 3814aea..45bcba5 100644 +--- a/mpn/x86_64/k10/popcount.asm ++++ b/mpn/x86_64/k10/popcount.asm +@@ -79,7 +79,7 @@ C neg R32(%rcx) + + lea L(top)(%rip), %rdx + lea (%rdx,%rcx,2), %rdx +- jmp *%rdx ++ X86_NOTRACK jmp *%rdx + ',` + lea (up,n,8), up + +@@ -101,7 +101,7 @@ C lea (%rcx,%rcx,4), %rcx C 10x + + lea L(top)(%rip), %rdx + add %rcx, %rdx +- jmp *%rdx ++ X86_NOTRACK jmp *%rdx + ') + + ALIGN(32) +@@ -136,3 +136,4 @@ C 1 = n mod 8 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/addmul_2.asm b/mpn/x86_64/k8/addmul_2.asm +index 78bcba1..38caa4d 100644 +--- a/mpn/x86_64/k8/addmul_2.asm ++++ b/mpn/x86_64/k8/addmul_2.asm +@@ -193,3 +193,4 @@ L(end): xor R32(w1), R32(w1) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/aorrlsh_n.asm b/mpn/x86_64/k8/aorrlsh_n.asm +index ff3a184..3ab7050 100644 +--- a/mpn/x86_64/k8/aorrlsh_n.asm ++++ b/mpn/x86_64/k8/aorrlsh_n.asm +@@ -215,3 +215,4 @@ L(cj1): mov %r9, 8(rp,n,8) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/bdiv_q_1.asm b/mpn/x86_64/k8/bdiv_q_1.asm +index 1172b0d..606d54f 100644 +--- a/mpn/x86_64/k8/bdiv_q_1.asm ++++ b/mpn/x86_64/k8/bdiv_q_1.asm +@@ -177,3 +177,4 @@ L(one): shr R8(%rcx), %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/div_qr_1n_pi1.asm b/mpn/x86_64/k8/div_qr_1n_pi1.asm +index 86de08c..e91b809 100644 +--- a/mpn/x86_64/k8/div_qr_1n_pi1.asm ++++ b/mpn/x86_64/k8/div_qr_1n_pi1.asm +@@ -247,3 +247,4 @@ L(q_incr_loop): + lea 8(U1), U1 + jmp L(q_incr_loop) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/mul_basecase.asm b/mpn/x86_64/k8/mul_basecase.asm +index ca2efb9..9126c2b 100644 +--- a/mpn/x86_64/k8/mul_basecase.asm ++++ b/mpn/x86_64/k8/mul_basecase.asm +@@ -335,8 +335,10 @@ C addmul_2 for remaining vp's + C adjusted value of n that is reloaded on each iteration + + L(addmul_outer_0): ++ X86_ENDBR + add $3, un + lea 0(%rip), outer_addr ++ X86_ENDBR + + mov un, n + mov -24(up,un,8), %rax +@@ -348,6 +350,7 @@ L(addmul_outer_0): + jmp L(addmul_entry_0) + + L(addmul_outer_1): ++ X86_ENDBR + mov un, n + mov (up,un,8), %rax + mul v0 +@@ -358,8 +361,10 @@ L(addmul_outer_1): + jmp L(addmul_entry_1) + + L(addmul_outer_2): ++ X86_ENDBR + add $1, un + lea 0(%rip), outer_addr ++ X86_ENDBR + + mov un, n + mov -8(up,un,8), %rax +@@ -372,8 +377,10 @@ L(addmul_outer_2): + jmp L(addmul_entry_2) + + L(addmul_outer_3): ++ X86_ENDBR + add $2, un + lea 0(%rip), outer_addr ++ X86_ENDBR + + mov un, n + mov -16(up,un,8), %rax +@@ -467,3 +474,4 @@ L(ret): pop %r15 + ret + + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/mullo_basecase.asm b/mpn/x86_64/k8/mullo_basecase.asm +index fa00f42..4a931a5 100644 +--- a/mpn/x86_64/k8/mullo_basecase.asm ++++ b/mpn/x86_64/k8/mullo_basecase.asm +@@ -99,12 +99,14 @@ dnl JMPENT( L(2m4), L(tab)) C 10 + dnl JMPENT( L(3m4), L(tab)) C 11 + TEXT + +-L(1): imul %r8, %rax ++L(1): X86_ENDBR ++ imul %r8, %rax + mov %rax, (rp) + FUNC_EXIT() + ret + +-L(2): mov 8(vp_param), %r11 ++L(2): X86_ENDBR ++ mov 8(vp_param), %r11 + imul %rax, %r11 C u0 x v1 + mul %r8 C u0 x v0 + mov %rax, (rp) +@@ -115,7 +117,8 @@ L(2): mov 8(vp_param), %r11 + FUNC_EXIT() + ret + +-L(3): mov 8(vp_param), %r9 C v1 ++L(3): X86_ENDBR ++ mov 8(vp_param), %r9 C v1 + mov 16(vp_param), %r11 + mul %r8 C u0 x v0 -> + mov %rax, (rp) C r0 +@@ -335,6 +338,7 @@ L(mul_2_entry_1): + + + L(addmul_outer_1): ++ X86_ENDBR + lea -2(n), j + mov -16(up,n,8), %rax + mul v0 +@@ -346,6 +350,7 @@ L(addmul_outer_1): + jmp L(addmul_entry_1) + + L(addmul_outer_3): ++ X86_ENDBR + lea 0(n), j + mov -16(up,n,8), %rax + xor R32(w3), R32(w3) +@@ -434,3 +439,4 @@ L(ret): pop %r15 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/mulmid_basecase.asm b/mpn/x86_64/k8/mulmid_basecase.asm +index 86f1414..7d5f158 100644 +--- a/mpn/x86_64/k8/mulmid_basecase.asm ++++ b/mpn/x86_64/k8/mulmid_basecase.asm +@@ -329,6 +329,7 @@ C addmul_2 for remaining vp's + + ALIGN(16) + L(addmul_prologue_0): ++ X86_ENDBR + mov -8(up,n,8), %rax + mul v1 + mov %rax, w1 +@@ -338,6 +339,7 @@ L(addmul_prologue_0): + + ALIGN(16) + L(addmul_prologue_1): ++ X86_ENDBR + mov 16(up,n,8), %rax + mul v1 + mov %rax, w0 +@@ -348,6 +350,7 @@ L(addmul_prologue_1): + + ALIGN(16) + L(addmul_prologue_2): ++ X86_ENDBR + mov 8(up,n,8), %rax + mul v1 + mov %rax, w3 +@@ -357,6 +360,7 @@ L(addmul_prologue_2): + + ALIGN(16) + L(addmul_prologue_3): ++ X86_ENDBR + mov (up,n,8), %rax + mul v1 + mov %rax, w2 +@@ -471,6 +475,7 @@ L(diag_prologue_0): + mov vp, vp_inner + mov vn, n + lea 0(%rip), outer_addr ++ X86_ENDBR + mov -8(up,n,8), %rax + jmp L(diag_entry_0) + +@@ -480,6 +485,7 @@ L(diag_prologue_1): + add $3, vn + mov vn, n + lea 0(%rip), outer_addr ++ X86_ENDBR + mov -8(vp_inner), %rax + jmp L(diag_entry_1) + +@@ -489,6 +495,7 @@ L(diag_prologue_2): + add $2, vn + mov vn, n + lea 0(%rip), outer_addr ++ X86_ENDBR + mov 16(vp_inner), %rax + jmp L(diag_entry_2) + +@@ -507,6 +514,7 @@ L(diag_entry_0): + adc %rdx, w1 + adc $0, w2 + L(diag_entry_3): ++ X86_ENDBR + mov -16(up,n,8), %rax + mulq 8(vp_inner) + add %rax, w0 +@@ -557,3 +565,4 @@ L(ret): pop %r15 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/redc_1.asm b/mpn/x86_64/k8/redc_1.asm +index 9327b21..3e241af 100644 +--- a/mpn/x86_64/k8/redc_1.asm ++++ b/mpn/x86_64/k8/redc_1.asm +@@ -125,7 +125,8 @@ L(tab): JMPENT( L(0), L(tab)) + TEXT + + ALIGN(16) +-L(1): mov (mp_param), %rax ++L(1): X86_ENDBR ++ mov (mp_param), %rax + mul q0 + add 8(up), %rax + adc 16(up), %rdx +@@ -136,7 +137,8 @@ L(1): mov (mp_param), %rax + + + ALIGN(16) +-L(2): mov (mp_param), %rax ++L(2): X86_ENDBR ++ mov (mp_param), %rax + mul q0 + xor R32(%r14), R32(%r14) + mov %rax, %r10 +@@ -171,7 +173,8 @@ L(2): mov (mp_param), %rax + jmp L(ret) + + +-L(3): mov (mp_param), %rax ++L(3): X86_ENDBR ++ mov (mp_param), %rax + mul q0 + mov %rax, %rbx + mov %rdx, %r10 +@@ -248,7 +251,7 @@ L(3): mov (mp_param), %rax + + + ALIGN(16) +-L(2m4): ++L(2m4): X86_ENDBR + L(lo2): mov (mp,nneg,8), %rax + mul q0 + xor R32(%r14), R32(%r14) +@@ -324,7 +327,7 @@ L(le2): add %r10, (up) + + + ALIGN(16) +-L(1m4): ++L(1m4): X86_ENDBR + L(lo1): mov (mp,nneg,8), %rax + xor %r9, %r9 + xor R32(%rbx), R32(%rbx) +@@ -398,7 +401,7 @@ L(le1): add %r10, (up) + + ALIGN(16) + L(0): +-L(0m4): ++L(0m4): X86_ENDBR + L(lo0): mov (mp,nneg,8), %rax + mov nneg, i + mul q0 +@@ -463,7 +466,7 @@ L(le0): add %r10, (up) + + + ALIGN(16) +-L(3m4): ++L(3m4): X86_ENDBR + L(lo3): mov (mp,nneg,8), %rax + mul q0 + mov %rax, %rbx +@@ -589,3 +592,4 @@ L(ret): pop %r15 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/k8/sqr_basecase.asm b/mpn/x86_64/k8/sqr_basecase.asm +index 60cf945..37858b4 100644 +--- a/mpn/x86_64/k8/sqr_basecase.asm ++++ b/mpn/x86_64/k8/sqr_basecase.asm +@@ -131,7 +131,8 @@ L(tab): JMPENT( L(4), L(tab)) + JMPENT( L(3m4), L(tab)) + TEXT + +-L(1): mov (up), %rax ++L(1): X86_ENDBR ++ mov (up), %rax + mul %rax + add $40, %rsp + mov %rax, (rp) +@@ -139,7 +140,8 @@ L(1): mov (up), %rax + FUNC_EXIT() + ret + +-L(2): mov (up), %rax ++L(2): X86_ENDBR ++ mov (up), %rax + mov %rax, %r8 + mul %rax + mov 8(up), %r11 +@@ -165,7 +167,8 @@ L(2): mov (up), %rax + FUNC_EXIT() + ret + +-L(3): mov (up), %rax ++L(3): X86_ENDBR ++ mov (up), %rax + mov %rax, %r10 + mul %rax + mov 8(up), %r11 +@@ -210,7 +213,8 @@ L(3): mov (up), %rax + FUNC_EXIT() + ret + +-L(4): mov (up), %rax ++L(4): X86_ENDBR ++ mov (up), %rax + mov %rax, %r11 + mul %rax + mov 8(up), %rbx +@@ -282,6 +286,7 @@ L(4): mov (up), %rax + + + L(0m4): ++ X86_ENDBR + lea -16(rp,n,8), tp C point tp in middle of result operand + mov (up), v0 + mov 8(up), %rax +@@ -340,6 +345,7 @@ L(L3): xor R32(w1), R32(w1) + + + L(1m4): ++ X86_ENDBR + lea 8(rp,n,8), tp C point tp in middle of result operand + mov (up), v0 C u0 + mov 8(up), %rax C u1 +@@ -418,6 +424,7 @@ L(m2x): mov (up,j,8), %rax + + + L(2m4): ++ X86_ENDBR + lea -16(rp,n,8), tp C point tp in middle of result operand + mov (up), v0 + mov 8(up), %rax +@@ -474,7 +481,7 @@ L(L1): xor R32(w0), R32(w0) + jmp L(dowhile_mid) + + +-L(3m4): ++L(3m4): X86_ENDBR + lea 8(rp,n,8), tp C point tp in middle of result operand + mov (up), v0 C u0 + mov 8(up), %rax C u1 +@@ -805,3 +812,4 @@ L(d1): mov %r11, 24(rp,j,8) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/logops_n.asm b/mpn/x86_64/logops_n.asm +index e25854d..b3969ba 100644 +--- a/mpn/x86_64/logops_n.asm ++++ b/mpn/x86_64/logops_n.asm +@@ -258,3 +258,4 @@ L(ret): FUNC_EXIT() + ret + EPILOGUE() + ') ++ASM_END() +diff --git a/mpn/x86_64/lshift.asm b/mpn/x86_64/lshift.asm +index fff3152..4187bdc 100644 +--- a/mpn/x86_64/lshift.asm ++++ b/mpn/x86_64/lshift.asm +@@ -170,3 +170,4 @@ L(ast): mov (up), %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/lshiftc.asm b/mpn/x86_64/lshiftc.asm +index c4ba04a..f6fe4c9 100644 +--- a/mpn/x86_64/lshiftc.asm ++++ b/mpn/x86_64/lshiftc.asm +@@ -180,3 +180,4 @@ L(ast): mov (up), %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/lshsub_n.asm b/mpn/x86_64/lshsub_n.asm +index 4d428c0..62877d7 100644 +--- a/mpn/x86_64/lshsub_n.asm ++++ b/mpn/x86_64/lshsub_n.asm +@@ -170,3 +170,4 @@ L(end): + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/missing.asm b/mpn/x86_64/missing.asm +index 9b65c89..22dac17 100644 +--- a/mpn/x86_64/missing.asm ++++ b/mpn/x86_64/missing.asm +@@ -128,3 +128,4 @@ PROLOGUE(__gmp_adcx) + ret + EPILOGUE() + PROTECT(__gmp_adcx) ++ASM_END() +diff --git a/mpn/x86_64/mod_1_2.asm b/mpn/x86_64/mod_1_2.asm +index 40fcaeb..fbaae3b 100644 +--- a/mpn/x86_64/mod_1_2.asm ++++ b/mpn/x86_64/mod_1_2.asm +@@ -239,3 +239,4 @@ ifdef(`SHLD_SLOW',` + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/mod_1_4.asm b/mpn/x86_64/mod_1_4.asm +index 6cf304c..8969e42 100644 +--- a/mpn/x86_64/mod_1_4.asm ++++ b/mpn/x86_64/mod_1_4.asm +@@ -270,3 +270,4 @@ ifdef(`SHLD_SLOW',` + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/mod_34lsub1.asm b/mpn/x86_64/mod_34lsub1.asm +index 75421a6..70282b6 100644 +--- a/mpn/x86_64/mod_34lsub1.asm ++++ b/mpn/x86_64/mod_34lsub1.asm +@@ -145,46 +145,55 @@ L(tab): JMPENT( L(0), L(tab)) + JMPENT( L(8), L(tab)) + TEXT + +-L(6): add (ap), %rax ++L(6): X86_ENDBR ++ add (ap), %rax + adc 8(ap), %rcx + adc 16(ap), %rdx + adc $0, %r9 + add $24, ap +-L(3): add (ap), %rax ++L(3): X86_ENDBR ++ add (ap), %rax + adc 8(ap), %rcx + adc 16(ap), %rdx + jmp L(cj1) + +-L(7): add (ap), %rax ++L(7): X86_ENDBR ++ add (ap), %rax + adc 8(ap), %rcx + adc 16(ap), %rdx + adc $0, %r9 + add $24, ap +-L(4): add (ap), %rax ++L(4): X86_ENDBR ++ add (ap), %rax + adc 8(ap), %rcx + adc 16(ap), %rdx + adc $0, %r9 + add $24, ap +-L(1): add (ap), %rax ++L(1): X86_ENDBR ++ add (ap), %rax + adc $0, %rcx + jmp L(cj2) + +-L(8): add (ap), %rax ++L(8): X86_ENDBR ++ add (ap), %rax + adc 8(ap), %rcx + adc 16(ap), %rdx + adc $0, %r9 + add $24, ap +-L(5): add (ap), %rax ++L(5): X86_ENDBR ++ add (ap), %rax + adc 8(ap), %rcx + adc 16(ap), %rdx + adc $0, %r9 + add $24, ap +-L(2): add (ap), %rax ++L(2): X86_ENDBR ++ add (ap), %rax + adc 8(ap), %rcx + + L(cj2): adc $0, %rdx + L(cj1): adc $0, %r9 +-L(0): add %r9, %rax ++L(0): X86_ENDBR ++ add %r9, %rax + adc $0, %rcx + adc $0, %rdx + adc $0, %rax +@@ -213,3 +222,4 @@ L(0): add %r9, %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/mode1o.asm b/mpn/x86_64/mode1o.asm +index 2cd2b08..3377435 100644 +--- a/mpn/x86_64/mode1o.asm ++++ b/mpn/x86_64/mode1o.asm +@@ -169,3 +169,4 @@ L(one): + + EPILOGUE(mpn_modexact_1c_odd) + EPILOGUE(mpn_modexact_1_odd) ++ASM_END() +diff --git a/mpn/x86_64/mul_1.asm b/mpn/x86_64/mul_1.asm +index e1ba89b..44764dd 100644 +--- a/mpn/x86_64/mul_1.asm ++++ b/mpn/x86_64/mul_1.asm +@@ -190,3 +190,4 @@ IFDOS(``pop %rdi '') + IFDOS(``pop %rsi '') + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/mul_2.asm b/mpn/x86_64/mul_2.asm +index d64313b..b6c6bf1 100644 +--- a/mpn/x86_64/mul_2.asm ++++ b/mpn/x86_64/mul_2.asm +@@ -202,3 +202,4 @@ L(m22): mul v1 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/nano/dive_1.asm b/mpn/x86_64/nano/dive_1.asm +index e9a0763..aead4d5 100644 +--- a/mpn/x86_64/nano/dive_1.asm ++++ b/mpn/x86_64/nano/dive_1.asm +@@ -164,3 +164,4 @@ L(one): shr R8(%rcx), %rax + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/pentium4/aors_n.asm b/mpn/x86_64/pentium4/aors_n.asm +index 8e6ee1b..3751e38 100644 +--- a/mpn/x86_64/pentium4/aors_n.asm ++++ b/mpn/x86_64/pentium4/aors_n.asm +@@ -194,3 +194,4 @@ L(ret): mov R32(%rbx), R32(%rax) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/pentium4/mod_34lsub1.asm b/mpn/x86_64/pentium4/mod_34lsub1.asm +index f34b3f0..bf83f62 100644 +--- a/mpn/x86_64/pentium4/mod_34lsub1.asm ++++ b/mpn/x86_64/pentium4/mod_34lsub1.asm +@@ -165,3 +165,4 @@ L(combine): + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/pentium4/rsh1aors_n.asm b/mpn/x86_64/pentium4/rsh1aors_n.asm +index 5528ce4..219a809 100644 +--- a/mpn/x86_64/pentium4/rsh1aors_n.asm ++++ b/mpn/x86_64/pentium4/rsh1aors_n.asm +@@ -332,3 +332,4 @@ L(cj1): or %r14, %rbx + L(c3): mov $1, R8(%rax) + jmp L(rc3) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/pentium4/rshift.asm b/mpn/x86_64/pentium4/rshift.asm +index b7c1ee2..848045f 100644 +--- a/mpn/x86_64/pentium4/rshift.asm ++++ b/mpn/x86_64/pentium4/rshift.asm +@@ -167,3 +167,4 @@ L(ast): movq (up), %mm2 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/popham.asm b/mpn/x86_64/popham.asm +index 3a29b2e..b7ceb17 100644 +--- a/mpn/x86_64/popham.asm ++++ b/mpn/x86_64/popham.asm +@@ -161,3 +161,4 @@ L(end): + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/rsh1aors_n.asm b/mpn/x86_64/rsh1aors_n.asm +index a3e9cc5..797e250 100644 +--- a/mpn/x86_64/rsh1aors_n.asm ++++ b/mpn/x86_64/rsh1aors_n.asm +@@ -187,3 +187,4 @@ L(end): mov %rbx, (rp) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/rshift.asm b/mpn/x86_64/rshift.asm +index 3f344f1..0fc5877 100644 +--- a/mpn/x86_64/rshift.asm ++++ b/mpn/x86_64/rshift.asm +@@ -174,3 +174,4 @@ L(ast): mov (up), %r10 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/sec_tabselect.asm b/mpn/x86_64/sec_tabselect.asm +index e8aed26..5dce3c1 100644 +--- a/mpn/x86_64/sec_tabselect.asm ++++ b/mpn/x86_64/sec_tabselect.asm +@@ -174,3 +174,4 @@ L(b00): pop %r15 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/sqr_diag_addlsh1.asm b/mpn/x86_64/sqr_diag_addlsh1.asm +index f486125..a1d8767 100644 +--- a/mpn/x86_64/sqr_diag_addlsh1.asm ++++ b/mpn/x86_64/sqr_diag_addlsh1.asm +@@ -114,3 +114,4 @@ L(end): add %r10, %r8 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/sublsh1_n.asm b/mpn/x86_64/sublsh1_n.asm +index c6d829f..c18f32a 100644 +--- a/mpn/x86_64/sublsh1_n.asm ++++ b/mpn/x86_64/sublsh1_n.asm +@@ -158,3 +158,4 @@ L(end): add R32(%rbp), R32(%rax) + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/x86_64-defs.m4 b/mpn/x86_64/x86_64-defs.m4 +index 4e08f2a..9fe328e 100644 +--- a/mpn/x86_64/x86_64-defs.m4 ++++ b/mpn/x86_64/x86_64-defs.m4 +@@ -95,6 +95,7 @@ m4_assert_numargs(1) + TYPE($1,`function') + COFF_TYPE($1) + $1: ++ X86_ENDBR + ') + + +@@ -167,6 +168,10 @@ ifdef(`PIC', + `lea $1(%rip), $2') + ') + ++dnl ASM_END ++ ++define(`ASM_END', `X86_GNU_PROPERTY') ++ + + define(`DEF_OBJECT', + m4_assert_numargs_range(2,3) +diff --git a/mpn/x86_64/zen/aorrlsh_n.asm b/mpn/x86_64/zen/aorrlsh_n.asm +index e049b2f..6e6783f 100644 +--- a/mpn/x86_64/zen/aorrlsh_n.asm ++++ b/mpn/x86_64/zen/aorrlsh_n.asm +@@ -102,26 +102,30 @@ ifdef(`PIC',` + jmp *(%r11,%rax,8) + ') + +-L(0): lea 32(up), up ++L(0): X86_ENDBR ++ lea 32(up), up + lea 32(vp), vp + lea 32(rp), rp + xor R32(%r11), R32(%r11) + jmp L(e0) + +-L(7): mov %r10, %r11 ++L(7): X86_ENDBRmov ++ %r10, %r11 + lea 24(up), up + lea 24(vp), vp + lea 24(rp), rp + xor R32(%r10), R32(%r10) + jmp L(e7) + +-L(6): lea 16(up), up ++L(6): X86_ENDBR ++ movlea 16(up), up + lea 16(vp), vp + lea 16(rp), rp + xor R32(%r11), R32(%r11) + jmp L(e6) + +-L(5): mov %r10, %r11 ++L(5): X86_ENDBRmov ++ mov %r10, %r11 + lea 8(up), up + lea 8(vp), vp + lea 8(rp), rp +@@ -191,23 +195,27 @@ L(e1): shlx( cnt, %r11, %rax) + lea (%r10,%rax), %rax + jmp L(top) + +-L(4): xor R32(%r11), R32(%r11) ++L(4): X86_ENDBRmov ++ xor R32(%r11), R32(%r11) + jmp L(e4) + +-L(3): mov %r10, %r11 ++L(3): X86_ENDBRmov ++ mov %r10, %r11 + lea -8(up), up + lea -8(vp), vp + lea -8(rp), rp + xor R32(%r10), R32(%r10) + jmp L(e3) + +-L(2): lea -16(up), up ++L(2): X86_ENDBRmov ++ lea -16(up), up + lea -16(vp), vp + lea -16(rp), rp + xor R32(%r11), R32(%r11) + jmp L(e2) + +-L(1): mov %r10, %r11 ++L(1): X86_ENDBRmov ++ mov %r10, %r11 + lea -24(up), up + lea 40(vp), vp + lea 40(rp), rp +@@ -224,3 +232,4 @@ L(tab): JMPENT( L(0), L(tab)) + JMPENT( L(5), L(tab)) + JMPENT( L(6), L(tab)) + JMPENT( L(7), L(tab)) ++ASM_END() +diff --git a/mpn/x86_64/zen/mul_basecase.asm b/mpn/x86_64/zen/mul_basecase.asm +index affa3b6..c70d548 100644 +--- a/mpn/x86_64/zen/mul_basecase.asm ++++ b/mpn/x86_64/zen/mul_basecase.asm +@@ -453,3 +453,4 @@ L(wd3): adc %r11, 8(rp) + jne L(3) + jmp L(end) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/zen/mullo_basecase.asm b/mpn/x86_64/zen/mullo_basecase.asm +index 2ae729a..c081698 100644 +--- a/mpn/x86_64/zen/mullo_basecase.asm ++++ b/mpn/x86_64/zen/mullo_basecase.asm +@@ -297,3 +297,4 @@ L(lo0): .byte 0xc4,0xe2,0xe3,0xf6,0x44,0xce,0x18 C mulx 24(up,n,8), %rbx, %rax + inc %r14 + jmp L(outer) + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/zen/sbpi1_bdiv_r.asm b/mpn/x86_64/zen/sbpi1_bdiv_r.asm +index f6e8f9c..277b3c3 100644 +--- a/mpn/x86_64/zen/sbpi1_bdiv_r.asm ++++ b/mpn/x86_64/zen/sbpi1_bdiv_r.asm +@@ -505,3 +505,4 @@ L(ret): mov %rbp, %rax + pop %r15 + ret + EPILOGUE() ++ASM_END() +diff --git a/mpn/x86_64/zen/sqr_basecase.asm b/mpn/x86_64/zen/sqr_basecase.asm +index a7c6127..d185deb 100644 +--- a/mpn/x86_64/zen/sqr_basecase.asm ++++ b/mpn/x86_64/zen/sqr_basecase.asm +@@ -480,3 +480,4 @@ C pop %r14 + FUNC_EXIT() + ret + EPILOGUE() ++ASM_END() +-- +2.37.1 + diff --git a/SOURCES/gnutls-3.7.3-allowlist-api.patch b/SOURCES/gnutls-3.7.3-allowlist-api.patch deleted file mode 100644 index 1019858..0000000 --- a/SOURCES/gnutls-3.7.3-allowlist-api.patch +++ /dev/null @@ -1,2440 +0,0 @@ -From 495ad3d82aff125f237f370a70882b97843edb6f Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Mon, 14 Feb 2022 12:44:57 +0100 -Subject: [PATCH 1/8] lib/priority: split up update_system_wide_priority_string - -This is done in preparation for deferring priority string evaluation. - -Signed-off-by: Alexander Sosedkin ---- - lib/priority.c | 77 ++++++++++++++++++++++++++++++-------------------- - 1 file changed, 47 insertions(+), 30 deletions(-) - -diff --git a/lib/priority.c b/lib/priority.c -index e7698ba7eb..755729da18 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -1735,110 +1735,127 @@ static int cfg_ini_handler(void *_ctx, const char *section, const char *name, co - return 1; - } - --static int --update_system_wide_priority_string(void) -+static int /* not locking system_wide_config */ -+construct_system_wide_priority_string(gnutls_buffer_st* buf) - { -- gnutls_buffer_st buf; - int ret; - size_t i; - -- _gnutls_buffer_init(&buf); -+ _gnutls_buffer_init(buf); - -- ret = _gnutls_buffer_append_str(&buf, "NONE"); -+ ret = _gnutls_buffer_append_str(buf, "NONE"); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - - for (i = 0; system_wide_config.kxs[i] != 0; i++) { -- ret = _gnutls_buffer_append_str(&buf, ":+"); -+ ret = _gnutls_buffer_append_str(buf, ":+"); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - -- ret = _gnutls_buffer_append_str(&buf, -+ ret = _gnutls_buffer_append_str(buf, - gnutls_kx_get_name(system_wide_config.kxs[i])); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - } - - for (i = 0; system_wide_config.groups[i] != 0; i++) { -- ret = _gnutls_buffer_append_str(&buf, ":+GROUP-"); -+ ret = _gnutls_buffer_append_str(buf, ":+GROUP-"); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - -- ret = _gnutls_buffer_append_str(&buf, -+ ret = _gnutls_buffer_append_str(buf, - gnutls_group_get_name(system_wide_config.groups[i])); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - } - - for (i = 0; system_wide_config.ciphers[i] != 0; i++) { -- ret = _gnutls_buffer_append_str(&buf, ":+"); -+ ret = _gnutls_buffer_append_str(buf, ":+"); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - -- ret = _gnutls_buffer_append_str(&buf, -+ ret = _gnutls_buffer_append_str(buf, - gnutls_cipher_get_name(system_wide_config.ciphers[i])); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - } - - for (i = 0; system_wide_config.macs[i] != 0; i++) { -- ret = _gnutls_buffer_append_str(&buf, ":+"); -+ ret = _gnutls_buffer_append_str(buf, ":+"); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - -- ret = _gnutls_buffer_append_str(&buf, -+ ret = _gnutls_buffer_append_str(buf, - gnutls_mac_get_name(system_wide_config.macs[i])); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - } - - for (i = 0; system_wide_config.sigs[i] != 0; i++) { -- ret = _gnutls_buffer_append_str(&buf, ":+SIGN-"); -+ ret = _gnutls_buffer_append_str(buf, ":+SIGN-"); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - -- ret = _gnutls_buffer_append_str(&buf, -+ ret = _gnutls_buffer_append_str(buf, - gnutls_sign_get_name(system_wide_config.sigs[i])); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - } - - for (i = 0; system_wide_config.versions[i] != 0; i++) { -- ret = _gnutls_buffer_append_str(&buf, ":+VERS-"); -+ ret = _gnutls_buffer_append_str(buf, ":+VERS-"); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - -- ret = _gnutls_buffer_append_str(&buf, -+ ret = _gnutls_buffer_append_str(buf, - gnutls_protocol_get_name(system_wide_config.versions[i])); - if (ret < 0) { -- _gnutls_buffer_clear(&buf); -+ _gnutls_buffer_clear(buf); - return ret; - } - } -+ return 0; -+} -+ -+static int /* not locking system_wide_config */ -+update_system_wide_priority_string(void) -+{ -+ /* doesn't do locking, _gnutls_update_system_priorities does */ -+ gnutls_buffer_st buf; -+ int ret; -+ -+ ret = construct_system_wide_priority_string(&buf); -+ if (ret < 0) { -+ _gnutls_debug_log("cfg: unable to construct " -+ "system-wide priority string: %s", -+ gnutls_strerror(ret)); -+ _gnutls_buffer_clear(&buf); -+ return ret; -+ } - - gnutls_free(system_wide_config.priority_string); - system_wide_config.priority_string = gnutls_strdup((char *)buf.data); --- -2.34.1 - - -From a74633975e97e491e1e1cdf12416ce160699b703 Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Mon, 14 Feb 2022 13:48:37 +0100 -Subject: [PATCH 2/8] lib/priority: defer setting system-wide priority string - -Signed-off-by: Alexander Sosedkin ---- - lib/global.c | 2 +- - lib/global.h | 2 +- - lib/priority.c | 112 ++++++++++++++++++++++++++++--------------------- - 3 files changed, 66 insertions(+), 50 deletions(-) - -diff --git a/lib/global.c b/lib/global.c -index 65c0b81709..faa7f0afb2 100644 ---- a/lib/global.c -+++ b/lib/global.c -@@ -365,7 +365,7 @@ static int _gnutls_global_init(unsigned constructor) - _gnutls_fips_mode_reset_zombie(); - } - #endif -- _gnutls_load_system_priorities(); -+ _gnutls_prepare_to_load_system_priorities(); - _gnutls_switch_lib_state(LIB_STATE_OPERATIONAL); - ret = 0; - -diff --git a/lib/global.h b/lib/global.h -index e30187e7ad..16fde08b5c 100644 ---- a/lib/global.h -+++ b/lib/global.h -@@ -46,7 +46,7 @@ extern void gnutls_crypto_deinit(void); - extern void _gnutls_tpm_global_deinit(void); - extern void _gnutls_nss_keylog_deinit(void); - --extern void _gnutls_load_system_priorities(void); -+extern void _gnutls_prepare_to_load_system_priorities(void); - extern void _gnutls_unload_system_priorities(void); - - #endif /* GNUTLS_LIB_GLOBAL_H */ -diff --git a/lib/priority.c b/lib/priority.c -index 755729da18..4faf96fabf 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -1864,11 +1864,12 @@ update_system_wide_priority_string(void) - return 0; - } - --static int _gnutls_update_system_priorities(void) -+static int _gnutls_update_system_priorities(bool defer_system_wide) - { - int ret, err = 0; - struct stat sb; - FILE *fp; -+ gnutls_buffer_st buf; - struct ini_ctx ctx; - - ret = gnutls_rwlock_rdlock(&system_wide_config_rwlock); -@@ -1883,10 +1884,12 @@ static int _gnutls_update_system_priorities(void) - } - - if (system_priority_file_loaded && -- sb.st_mtime == system_priority_last_mod) { -+ system_priority_last_mod == sb.st_mtime) { - _gnutls_debug_log("cfg: system priority %s has not changed\n", - system_priority_file); -- goto out; -+ if (system_wide_config.priority_string) { -+ goto out; /* nothing to do */ -+ } - } - - (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -@@ -1896,54 +1899,71 @@ static int _gnutls_update_system_priorities(void) - return gnutls_assert_val(ret); - } - -- /* Another thread has successfully updated the system wide config (with -- * the same modification time as checked above), while upgrading to -- * write lock; no need to reload. -+ /* Another thread could have successfully re-read system-wide config, -+ * skip re-reading if the mtime it has used is exactly the same. - */ -- if (system_priority_file_loaded && -- system_priority_last_mod == sb.st_mtime) { -- goto out; -+ if (system_priority_file_loaded) { -+ system_priority_file_loaded = -+ (system_priority_last_mod == sb.st_mtime); - } - -- system_priority_file_loaded = 0; -- _name_val_array_clear(&system_wide_config.priority_strings); -+ if (!system_priority_file_loaded) { -+ _name_val_array_clear(&system_wide_config.priority_strings); - -- gnutls_free(system_wide_config.priority_string); -- system_wide_config.priority_string = NULL; -+ gnutls_free(system_wide_config.priority_string); -+ system_wide_config.priority_string = NULL; - -- fp = fopen(system_priority_file, "re"); -- if (fp == NULL) { -- _gnutls_debug_log("cfg: unable to open: %s: %d\n", -- system_priority_file, errno); -- goto out; -- } -- /* Parsing the configuration file needs to be done in 2 phases: first -- * parsing the [global] section and then the other sections, because the -- * [global] section modifies the parsing behavior. -- */ -- memset(&ctx, 0, sizeof(ctx)); -- err = ini_parse_file(fp, global_ini_handler, &ctx); -- if (!err) { -- if (fseek(fp, 0L, SEEK_SET) < 0) { -- _gnutls_debug_log("cfg: unable to rewind: %s\n", -- system_priority_file); -- if (fail_on_invalid_config) -- exit(1); -+ fp = fopen(system_priority_file, "re"); -+ if (fp == NULL) { -+ _gnutls_debug_log("cfg: unable to open: %s: %d\n", -+ system_priority_file, errno); -+ goto out; - } -- err = ini_parse_file(fp, cfg_ini_handler, &ctx); -- } -- fclose(fp); -- if (err) { -+ /* Parsing the configuration file needs to be done in 2 phases: -+ * first parsing the [global] section -+ * and then the other sections, -+ * because the [global] section modifies the parsing behavior. -+ */ -+ memset(&ctx, 0, sizeof(ctx)); -+ err = ini_parse_file(fp, global_ini_handler, &ctx); -+ if (!err) { -+ if (fseek(fp, 0L, SEEK_SET) < 0) { -+ _gnutls_debug_log("cfg: unable to rewind: %s\n", -+ system_priority_file); -+ if (fail_on_invalid_config) -+ exit(1); -+ } -+ err = ini_parse_file(fp, cfg_ini_handler, &ctx); -+ } -+ fclose(fp); -+ if (err) { -+ ini_ctx_deinit(&ctx); -+ _gnutls_debug_log("cfg: unable to parse: %s: %d\n", -+ system_priority_file, err); -+ goto out; -+ } -+ cfg_apply(&system_wide_config, &ctx); - ini_ctx_deinit(&ctx); -- _gnutls_debug_log("cfg: unable to parse: %s: %d\n", -- system_priority_file, err); -- goto out; -+ _gnutls_debug_log("cfg: loaded system config %s mtime %lld\n", -+ system_priority_file, -+ (unsigned long long)sb.st_mtime); -+ - } -- cfg_apply(&system_wide_config, &ctx); -- ini_ctx_deinit(&ctx); - - if (system_wide_config.allowlisting) { -- ret = update_system_wide_priority_string(); -+ if (defer_system_wide) { -+ /* try constructing a priority string, -+ * but don't apply it yet, at this point -+ * we're only interested in whether we can */ -+ ret = construct_system_wide_priority_string(&buf); -+ _gnutls_buffer_clear(&buf); -+ _gnutls_debug_log("cfg: deferred setting " -+ "system-wide priority string\n"); -+ } else { -+ ret = update_system_wide_priority_string(); -+ _gnutls_debug_log("cfg: finalized " -+ "system-wide priority string\n"); -+ } - if (ret < 0) { - _gnutls_debug_log("cfg: unable to build priority string: %s\n", - gnutls_strerror(ret)); -@@ -1953,10 +1973,6 @@ static int _gnutls_update_system_priorities(void) - } - } - -- _gnutls_debug_log("cfg: loaded system priority %s mtime %lld\n", -- system_priority_file, -- (unsigned long long)sb.st_mtime); -- - system_priority_file_loaded = 1; - system_priority_last_mod = sb.st_mtime; - -@@ -1970,7 +1986,7 @@ static int _gnutls_update_system_priorities(void) - return ret; - } - --void _gnutls_load_system_priorities(void) -+void _gnutls_prepare_to_load_system_priorities(void) - { - const char *p; - int ret; -@@ -1983,7 +1999,7 @@ void _gnutls_load_system_priorities(void) - if (p != NULL && p[0] == '1' && p[1] == 0) - fail_on_invalid_config = 1; - -- ret = _gnutls_update_system_priorities(); -+ ret = _gnutls_update_system_priorities(true /* defer_system_wide */); - if (ret < 0) { - _gnutls_debug_log("failed to update system priorities: %s\n", - gnutls_strerror(ret)); -@@ -2050,7 +2066,7 @@ char *_gnutls_resolve_priorities(const char* priorities) - /* Always try to refresh the cached data, to allow it to be - * updated without restarting all applications. - */ -- ret = _gnutls_update_system_priorities(); -+ ret = _gnutls_update_system_priorities(false /* defer_system_wide */); - if (ret < 0) { - _gnutls_debug_log("failed to update system priorities: %s\n", - gnutls_strerror(ret)); --- -2.34.1 - - -From 52d5c8627165ff9bc0e99564b772f178ad1f80dd Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Mon, 21 Feb 2022 18:19:25 +0100 -Subject: [PATCH 3/8] lib/algorithms: add UB warnings on late allowlisting API - invocations - -Signed-off-by: Alexander Sosedkin ---- - lib/algorithms/ecc.c | 3 +++ - lib/algorithms/mac.c | 3 +++ - lib/algorithms/protocols.c | 3 +++ - lib/algorithms/sign.c | 6 ++++++ - 4 files changed, 15 insertions(+) - -diff --git a/lib/algorithms/ecc.c b/lib/algorithms/ecc.c -index 736e5dd07f..52ae1db0e4 100644 ---- a/lib/algorithms/ecc.c -+++ b/lib/algorithms/ecc.c -@@ -389,6 +389,9 @@ void _gnutls_ecc_curve_mark_disabled_all(void) - * enabled through the allowlisting mode in the configuration file, or - * when the setting is modified with a prior call to this function. - * -+ * This function must be called prior to any session priority setting functions; -+ * otherwise the behavior is undefined. -+ * - * Returns: 0 on success or negative error code otherwise. - * - * Since: 3.7.3 -diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c -index a2c66e76bb..166d51d552 100644 ---- a/lib/algorithms/mac.c -+++ b/lib/algorithms/mac.c -@@ -332,6 +332,9 @@ void _gnutls_digest_mark_insecure_all(void) - * through the allowlisting mode in the configuration file, or when - * the setting is modified with a prior call to this function. - * -+ * This function must be called prior to any session priority setting functions; -+ * otherwise the behavior is undefined. -+ * - * Since: 3.7.3 - */ - int -diff --git a/lib/algorithms/protocols.c b/lib/algorithms/protocols.c -index b0f3e0bc30..64c86eba3c 100644 ---- a/lib/algorithms/protocols.c -+++ b/lib/algorithms/protocols.c -@@ -237,6 +237,9 @@ void _gnutls_version_mark_revertible_all(void) - * enabled through the allowlisting mode in the configuration file, or - * when the setting is modified with a prior call to this function. - * -+ * This function must be called prior to any session priority setting functions; -+ * otherwise the behavior is undefined. -+ * - * Returns: 0 on success or negative error code otherwise. - * - * Since: 3.7.3 -diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c -index 543bd19bb5..06abdb4cf8 100644 ---- a/lib/algorithms/sign.c -+++ b/lib/algorithms/sign.c -@@ -516,6 +516,9 @@ void _gnutls_sign_mark_insecure_all(hash_security_level_t level) - * use in certificates. Use gnutls_sign_set_secure_for_certs() to - * mark it secure as well for certificates. - * -+ * This function must be called prior to any session priority setting functions; -+ * otherwise the behavior is undefined. -+ * - * Since: 3.7.3 - */ - int -@@ -560,6 +563,9 @@ gnutls_sign_set_secure(gnutls_sign_algorithm_t sign, - * for the use in certificates. Use gnutls_sign_set_secure() to mark - * it insecure for any uses. - * -+ * This function must be called prior to any session priority setting functions; -+ * otherwise the behavior is undefined. -+ * - * Since: 3.7.3 - */ - int --- -2.34.1 - - -From 52067e1e5b16c30b2f3ce6488a4f72d19d906721 Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Mon, 14 Feb 2022 18:00:25 +0100 -Subject: [PATCH 4/8] lib/priority: move sigalgs filtering to - set_ciphersuite_list - -Signed-off-by: Alexander Sosedkin ---- - lib/priority.c | 25 +++++++------------------ - 1 file changed, 7 insertions(+), 18 deletions(-) - -diff --git a/lib/priority.c b/lib/priority.c -index 4faf96fabf..9775040410 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -1140,9 +1140,6 @@ cfg_apply(struct cfg *cfg, struct ini_ctx *ctx) - } - - if (cfg->allowlisting) { -- unsigned tls_sig_sem = 0; -- size_t j; -- - _gnutls_digest_mark_insecure_all(); - for (i = 0; i < ctx->hashes_size; i++) { - int ret = gnutls_digest_set_secure(ctx->hashes[i], 1); -@@ -1156,6 +1153,7 @@ cfg_apply(struct cfg *cfg, struct ini_ctx *ctx) - if (unlikely(ret < 0)) { - return ret; - } -+ cfg->sigs[i] = ctx->sigs[i]; - } - for (i = 0; i < ctx->sigs_for_cert_size; i++) { - int ret = gnutls_sign_set_secure_for_certs(ctx->sigs_for_cert[i], -@@ -1165,13 +1163,13 @@ cfg_apply(struct cfg *cfg, struct ini_ctx *ctx) - } - } - _gnutls_version_mark_revertible_all(); -- for (i = 0, j = 0; i < ctx->versions_size; i++) { -- const version_entry_st *vers; -- vers = version_to_entry(ctx->versions[i]); -- if (vers && vers->supported) { -- tls_sig_sem |= vers->tls_sig_sem; -- cfg->versions[j++] = vers->id; -+ for (i = 0; i < ctx->versions_size; i++) { -+ int ret; -+ ret = gnutls_protocol_set_enabled(ctx->versions[i], 1); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); - } -+ cfg->versions[i] = ctx->versions[i]; - } - _gnutls_ecc_curve_mark_disabled_all(); - for (i = 0; i < ctx->curves_size; i++) { -@@ -1180,15 +1178,6 @@ cfg_apply(struct cfg *cfg, struct ini_ctx *ctx) - return ret; - } - } -- for (i = 0, j = 0; i < ctx->sigs_size; i++) { -- const gnutls_sign_entry_st *se; -- -- se = _gnutls_sign_to_entry(ctx->sigs[i]); -- if (se != NULL && se->aid.tls_sem & tls_sig_sem && -- _gnutls_sign_is_secure2(se, 0)) { -- cfg->sigs[j++] = se->id; -- } -- } - } else { - for (i = 0; i < ctx->hashes_size; i++) { - int ret = _gnutls_digest_mark_insecure(ctx->hashes[i]); --- -2.34.1 - - -From fa056709aaa974360d5e5dd8ceb52089b4da7858 Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Tue, 15 Feb 2022 14:41:53 +0100 -Subject: [PATCH 5/8] lib/config_int.h: split struct cfg off lib/priority.c - -Signed-off-by: Alexander Sosedkin ---- - lib/Makefile.am | 3 +- - lib/config_int.h | 84 ++++++++++++++++++++++++++++++++++++++++++++++++ - lib/priority.c | 48 +-------------------------- - 3 files changed, 87 insertions(+), 48 deletions(-) - create mode 100644 lib/config_int.h - -diff --git a/lib/Makefile.am b/lib/Makefile.am -index 35df35ee8d..5b540db142 100644 ---- a/lib/Makefile.am -+++ b/lib/Makefile.am -@@ -134,7 +134,8 @@ HFILES = abstract_int.h debug.h cipher.h \ - srp.h auth/srp_kx.h auth/srp_passwd.h \ - file.h supplemental.h crypto.h random.h system.h\ - locks.h mbuffers.h ecc.h pin.h fips.h \ -- priority_options.h secrets.h stek.h cert-cred.h -+ priority_options.h secrets.h stek.h cert-cred.h \ -+ config_int.h - - if ENABLE_PKCS11 - HFILES += pkcs11_int.h pkcs11x.h -diff --git a/lib/config_int.h b/lib/config_int.h -new file mode 100644 -index 0000000000..733536bb98 ---- /dev/null -+++ b/lib/config_int.h -@@ -0,0 +1,84 @@ -+/* -+ * Copyright (C) 2004-2015 Free Software Foundation, Inc. -+ * Copyright (C) 2015-2022 Red Hat, Inc. -+ * -+ * Author: Nikos Mavrogiannopoulos -+ * -+ * This file is part of GnuTLS. -+ * -+ * The GnuTLS is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public License -+ * as published by the Free Software Foundation; either version 2.1 of -+ * the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, but -+ * WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public License -+ * along with this program. If not, see -+ * -+ */ -+ -+/* Code split off from priority.c, `struct cfg` and some operations on it */ -+ -+#ifndef GNUTLS_LIB_CONFIG_INT_H -+#define GNUTLS_LIB_CONFIG_INT_H -+ -+/* -+ * struct cfg -+ */ -+ -+struct cfg { -+ bool allowlisting; -+ -+ name_val_array_t priority_strings; -+ char *priority_string; -+ char *default_priority_string; -+ gnutls_certificate_verification_profiles_t verification_profile; -+ -+ gnutls_cipher_algorithm_t ciphers[MAX_ALGOS+1]; -+ gnutls_mac_algorithm_t macs[MAX_ALGOS+1]; -+ gnutls_group_t groups[MAX_ALGOS+1]; -+ gnutls_kx_algorithm_t kxs[MAX_ALGOS+1]; -+ gnutls_sign_algorithm_t sigs[MAX_ALGOS+1]; -+ gnutls_protocol_t versions[MAX_ALGOS+1]; -+}; -+ -+/* -+ * deinit / partial duplication. no initialization, must be zero-initialized -+ */ -+ -+static inline void -+cfg_deinit(struct cfg *cfg) -+{ -+ if (cfg->priority_strings) { -+ _name_val_array_clear(&cfg->priority_strings); -+ } -+ gnutls_free(cfg->priority_string); -+ gnutls_free(cfg->default_priority_string); -+} -+ -+static inline void -+cfg_steal(struct cfg *dst, struct cfg *src) -+{ -+ dst->verification_profile = src->verification_profile; -+ -+ dst->priority_strings = src->priority_strings; -+ src->priority_strings = NULL; -+ -+ dst->priority_string = src->priority_string; -+ src->priority_string = NULL; -+ -+ dst->default_priority_string = src->default_priority_string; -+ src->default_priority_string = NULL; -+ -+ dst->allowlisting = src->allowlisting; -+ memcpy(dst->ciphers, src->ciphers, sizeof(src->ciphers)); -+ memcpy(dst->macs, src->macs, sizeof(src->macs)); -+ memcpy(dst->groups, src->groups, sizeof(src->groups)); -+ memcpy(dst->kxs, src->kxs, sizeof(src->kxs)); -+} -+ -+#endif /* GNUTLS_LIB_CONFIG_INT_H */ -diff --git a/lib/priority.c b/lib/priority.c -index 9775040410..80b737b938 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -42,6 +42,7 @@ - #include "locks.h" - #include "profiles.h" - #include "name_val_array.h" -+#include "config_int.h" - - #define MAX_ELEMENTS GNUTLS_MAX_ALGORITHM_NUM - -@@ -1008,32 +1009,6 @@ static void dummy_func(gnutls_priority_t c) - - #include - --struct cfg { -- bool allowlisting; -- -- name_val_array_t priority_strings; -- char *priority_string; -- char *default_priority_string; -- gnutls_certificate_verification_profiles_t verification_profile; -- -- gnutls_cipher_algorithm_t ciphers[MAX_ALGOS+1]; -- gnutls_mac_algorithm_t macs[MAX_ALGOS+1]; -- gnutls_group_t groups[MAX_ALGOS+1]; -- gnutls_kx_algorithm_t kxs[MAX_ALGOS+1]; -- gnutls_sign_algorithm_t sigs[MAX_ALGOS+1]; -- gnutls_protocol_t versions[MAX_ALGOS+1]; --}; -- --static inline void --cfg_deinit(struct cfg *cfg) --{ -- if (cfg->priority_strings) { -- _name_val_array_clear(&cfg->priority_strings); -- } -- gnutls_free(cfg->priority_string); -- gnutls_free(cfg->default_priority_string); --} -- - /* Lock for reading and writing system_wide_config */ - GNUTLS_RWLOCK(system_wide_config_rwlock); - static struct cfg system_wide_config; -@@ -1107,27 +1082,6 @@ ini_ctx_deinit(struct ini_ctx *ctx) - gnutls_free(ctx->curves); - } - --static inline void --cfg_steal(struct cfg *dst, struct cfg *src) --{ -- dst->verification_profile = src->verification_profile; -- -- dst->priority_strings = src->priority_strings; -- src->priority_strings = NULL; -- -- dst->priority_string = src->priority_string; -- src->priority_string = NULL; -- -- dst->default_priority_string = src->default_priority_string; -- src->default_priority_string = NULL; -- -- dst->allowlisting = src->allowlisting; -- memcpy(dst->ciphers, src->ciphers, sizeof(src->ciphers)); -- memcpy(dst->macs, src->macs, sizeof(src->macs)); -- memcpy(dst->groups, src->groups, sizeof(src->groups)); -- memcpy(dst->kxs, src->kxs, sizeof(src->kxs)); --} -- - static inline int - cfg_apply(struct cfg *cfg, struct ini_ctx *ctx) - { --- -2.34.1 - - -From 9600788ef81bd424de8c9fcf053bcb717dd50c92 Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Tue, 15 Feb 2022 16:26:52 +0100 -Subject: [PATCH 6/8] lib/priority: extract parts of cfg_apply into - cfg_*_set_array* - -Signed-off-by: Alexander Sosedkin ---- - lib/config_int.h | 151 ++++++++++++++++++++++++++++++++++++++++++++++- - lib/priority.c | 68 +++++++++------------ - 2 files changed, 179 insertions(+), 40 deletions(-) - -diff --git a/lib/config_int.h b/lib/config_int.h -index 733536bb98..be8c71e414 100644 ---- a/lib/config_int.h -+++ b/lib/config_int.h -@@ -44,6 +44,10 @@ struct cfg { - gnutls_kx_algorithm_t kxs[MAX_ALGOS+1]; - gnutls_sign_algorithm_t sigs[MAX_ALGOS+1]; - gnutls_protocol_t versions[MAX_ALGOS+1]; -+ -+ gnutls_digest_algorithm_t hashes[MAX_ALGOS+1]; -+ gnutls_ecc_curve_t ecc_curves[MAX_ALGOS+1]; -+ gnutls_sign_algorithm_t sigs_for_cert[MAX_ALGOS+1]; - }; - - /* -@@ -79,6 +83,151 @@ cfg_steal(struct cfg *dst, struct cfg *src) - memcpy(dst->macs, src->macs, sizeof(src->macs)); - memcpy(dst->groups, src->groups, sizeof(src->groups)); - memcpy(dst->kxs, src->kxs, sizeof(src->kxs)); -+ memcpy(dst->hashes, src->hashes, sizeof(src->hashes)); -+ memcpy(dst->ecc_curves, src->ecc_curves, sizeof(src->ecc_curves)); -+ memcpy(dst->sigs, src->sigs, sizeof(src->sigs)); -+ memcpy(dst->sigs_for_cert, src->sigs_for_cert, -+ sizeof(src->sigs_for_cert)); -+} -+ -+/* -+ * synchronizing changes from struct cfg to global `lib/algorithms` arrays -+ */ -+ -+/* global side-effect! modifies `flags` in `hash_algorithms[]` */ -+static inline int /* allowlisting-only */ -+_cfg_hashes_remark(struct cfg* cfg) -+{ -+ size_t i; -+ _gnutls_digest_mark_insecure_all(); -+ for (i = 0; cfg->hashes[i] != 0; i++) { -+ int ret = gnutls_digest_set_secure(cfg->hashes[i], 1); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); -+ } -+ } -+ return 0; -+} -+ -+/* global side-effect! modifies `flags` in `sign_algorithms[]` */ -+static inline int /* allowlisting-only */ -+_cfg_sigs_remark(struct cfg* cfg) -+{ -+ size_t i; -+ _gnutls_sign_mark_insecure_all(_INSECURE); -+ for (i = 0; cfg->sigs[i] != 0; i++) { -+ int ret = gnutls_sign_set_secure(cfg->sigs[i], 1); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); -+ } -+ } -+ for (i = 0; cfg->sigs_for_cert[i] != 0; i++) { -+ int ret = gnutls_sign_set_secure_for_certs( -+ cfg->sigs_for_cert[i], 1 -+ ); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); -+ } -+ } -+ return 0; -+} -+ -+/* global side-effect! modifies `supported` in `sup_versions[]` */ -+static inline int /* allowlisting-only */ -+_cfg_versions_remark(struct cfg* cfg) -+{ -+ size_t i; -+ _gnutls_version_mark_revertible_all(); -+ for (i = 0; cfg->versions[i] != 0; i++) { -+ int ret = gnutls_protocol_set_enabled(cfg->versions[i], 1); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); -+ } -+ } -+ return 0; -+} -+ -+/* global side-effect! modifies `supported` in `ecc_curves[]` */ -+static inline int /* allowlisting-only */ -+_cfg_ecc_curves_remark(struct cfg* cfg) -+{ -+ size_t i; -+ _gnutls_ecc_curve_mark_disabled_all(); -+ for (i = 0; cfg->ecc_curves[i] != 0; i++) { -+ int ret = gnutls_ecc_curve_set_enabled(cfg->ecc_curves[i], 1); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); -+ } -+ } -+ return 0; -+} -+ -+/* -+ * setting arrays of struct cfg: from other arrays -+ */ -+ -+static inline int /* allowlisting-only */ -+cfg_hashes_set_array(struct cfg* cfg, -+ gnutls_digest_algorithm_t* src, size_t len) -+{ -+ if (unlikely(len >= MAX_ALGOS)) { -+ return gnutls_assert_val(GNUTLS_A_INTERNAL_ERROR); -+ } -+ if (len) { -+ memcpy(cfg->hashes, -+ src, sizeof(gnutls_digest_algorithm_t) * len); -+ } -+ cfg->hashes[len] = 0; -+ return _cfg_hashes_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_sigs_set_arrays(struct cfg* cfg, -+ gnutls_sign_algorithm_t* src, size_t len, -+ gnutls_sign_algorithm_t* src_for_cert, size_t len_for_cert) -+{ -+ if (unlikely(len >= MAX_ALGOS)) { -+ return gnutls_assert_val(GNUTLS_A_INTERNAL_ERROR); -+ } -+ if (unlikely(len_for_cert >= MAX_ALGOS)) { -+ return gnutls_assert_val(GNUTLS_A_INTERNAL_ERROR); -+ } -+ if (len) { -+ memcpy(cfg->sigs, src, sizeof(gnutls_sign_algorithm_t) * len); -+ } -+ if (len_for_cert) { -+ memcpy(cfg->sigs_for_cert, src_for_cert, -+ sizeof(gnutls_sign_algorithm_t) * len_for_cert); -+ } -+ cfg->sigs[len] = 0; -+ cfg->sigs_for_cert[len_for_cert] = 0; -+ return _cfg_sigs_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_versions_set_array(struct cfg* cfg, gnutls_protocol_t* src, size_t len) -+{ -+ if (unlikely(len >= MAX_ALGOS)) { -+ return gnutls_assert_val(GNUTLS_A_INTERNAL_ERROR); -+ } -+ if (len) { -+ memcpy(cfg->versions, src, sizeof(gnutls_protocol_t) * len); -+ } -+ cfg->versions[len] = 0; -+ return _cfg_versions_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_ecc_curves_set_array(struct cfg* cfg, gnutls_ecc_curve_t* src, size_t len) -+{ -+ if (unlikely(len >= MAX_ALGOS)) { -+ return gnutls_assert_val(GNUTLS_A_INTERNAL_ERROR); -+ } -+ if (len) { -+ memcpy(cfg->ecc_curves, src, sizeof(gnutls_ecc_curve_t) * len); -+ } -+ cfg->ecc_curves[len] = 0; -+ return _cfg_ecc_curves_remark(cfg); - } - --#endif /* GNUTLS_LIB_CONFIG_INT_H */ -+#endif /* GNUTLS_LIB_CONFIG_INT_H */ -diff --git a/lib/priority.c b/lib/priority.c -index 80b737b938..8d8428e1da 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -1086,6 +1086,7 @@ static inline int - cfg_apply(struct cfg *cfg, struct ini_ctx *ctx) - { - size_t i; -+ int ret; - - cfg_steal(cfg, &ctx->cfg); - -@@ -1094,72 +1095,61 @@ cfg_apply(struct cfg *cfg, struct ini_ctx *ctx) - } - - if (cfg->allowlisting) { -- _gnutls_digest_mark_insecure_all(); -- for (i = 0; i < ctx->hashes_size; i++) { -- int ret = gnutls_digest_set_secure(ctx->hashes[i], 1); -- if (unlikely(ret < 0)) { -- return ret; -- } -- } -- _gnutls_sign_mark_insecure_all(_INSECURE); -- for (i = 0; i < ctx->sigs_size; i++) { -- int ret = gnutls_sign_set_secure(ctx->sigs[i], 1); -- if (unlikely(ret < 0)) { -- return ret; -- } -- cfg->sigs[i] = ctx->sigs[i]; -+ /* also updates `flags` of global `hash_algorithms[]` */ -+ ret = cfg_hashes_set_array(cfg, ctx->hashes, ctx->hashes_size); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); - } -- for (i = 0; i < ctx->sigs_for_cert_size; i++) { -- int ret = gnutls_sign_set_secure_for_certs(ctx->sigs_for_cert[i], -- 1); -- if (unlikely(ret < 0)) { -- return ret; -- } -+ /* also updates `flags` of global `sign_algorithms[]` */ -+ ret = cfg_sigs_set_arrays(cfg, ctx->sigs, ctx->sigs_size, -+ ctx->sigs_for_cert, -+ ctx->sigs_for_cert_size); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); - } -- _gnutls_version_mark_revertible_all(); -- for (i = 0; i < ctx->versions_size; i++) { -- int ret; -- ret = gnutls_protocol_set_enabled(ctx->versions[i], 1); -- if (unlikely(ret < 0)) { -- return gnutls_assert_val(ret); -- } -- cfg->versions[i] = ctx->versions[i]; -+ /* also updates `supported` field of global `sup_versions[]` */ -+ ret = cfg_versions_set_array(cfg, -+ ctx->versions, ctx->versions_size); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); - } -- _gnutls_ecc_curve_mark_disabled_all(); -- for (i = 0; i < ctx->curves_size; i++) { -- int ret = gnutls_ecc_curve_set_enabled(ctx->curves[i], 1); -- if (unlikely(ret < 0)) { -- return ret; -- } -+ /* also updates `supported` field of global `ecc_curves[]` */ -+ ret = cfg_ecc_curves_set_array(cfg, -+ ctx->curves, ctx->curves_size); -+ if (unlikely(ret < 0)) { -+ return gnutls_assert_val(ret); - } - } else { -+ /* updates same global arrays as above, but doesn't store -+ * the algorithms into the `struct cfg` as allowlisting does. -+ * blocklisting doesn't allow relaxing the restrictions */ - for (i = 0; i < ctx->hashes_size; i++) { -- int ret = _gnutls_digest_mark_insecure(ctx->hashes[i]); -+ ret = _gnutls_digest_mark_insecure(ctx->hashes[i]); - if (unlikely(ret < 0)) { - return ret; - } - } - for (i = 0; i < ctx->sigs_size; i++) { -- int ret = _gnutls_sign_mark_insecure(ctx->sigs[i], -+ ret = _gnutls_sign_mark_insecure(ctx->sigs[i], - _INSECURE); - if (unlikely(ret < 0)) { - return ret; - } - } - for (i = 0; i < ctx->sigs_for_cert_size; i++) { -- int ret = _gnutls_sign_mark_insecure(ctx->sigs_for_cert[i], _INSECURE_FOR_CERTS); -+ ret = _gnutls_sign_mark_insecure(ctx->sigs_for_cert[i], _INSECURE_FOR_CERTS); - if (unlikely(ret < 0)) { - return ret; - } - } - for (i = 0; i < ctx->versions_size; i++) { -- int ret = _gnutls_version_mark_disabled(ctx->versions[i]); -+ ret = _gnutls_version_mark_disabled(ctx->versions[i]); - if (unlikely(ret < 0)) { - return ret; - } - } - for (i = 0; i < ctx->curves_size; i++) { -- int ret = _gnutls_ecc_curve_mark_disabled(ctx->curves[i]); -+ ret = _gnutls_ecc_curve_mark_disabled(ctx->curves[i]); - if (unlikely(ret < 0)) { - return ret; - } --- -2.34.1 - - -From 1767ced4c0abf9d372d334a749b87fd00cd8ab5d Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Wed, 16 Feb 2022 14:28:18 +0100 -Subject: [PATCH 7/8] plumb allowlisting API through the config, restrict usage - to early times - -Signed-off-by: Alexander Sosedkin ---- - lib/algorithms.h | 7 +- - lib/algorithms/ecc.c | 20 +-- - lib/algorithms/mac.c | 18 +- - lib/algorithms/protocols.c | 47 +++-- - lib/algorithms/sign.c | 78 +-------- - lib/config_int.h | 156 ++++++++++++++++- - lib/global.h | 1 + - lib/priority.c | 259 +++++++++++++++++++++++++++- - tests/protocol-set-allowlist.c | 47 +++-- - tests/protocol-set-allowlist.sh | 296 +++++++++++++++++++++----------- - 10 files changed, 663 insertions(+), 266 deletions(-) - -diff --git a/lib/algorithms.h b/lib/algorithms.h -index da72403fba..2c33a7210f 100644 ---- a/lib/algorithms.h -+++ b/lib/algorithms.h -@@ -354,13 +354,18 @@ const gnutls_protocol_t *_gnutls_protocol_list(void); - int _gnutls_version_mark_disabled(gnutls_protocol_t version); - gnutls_protocol_t _gnutls_protocol_get_id_if_supported(const char *name); - -+int _gnutls_digest_set_secure(gnutls_digest_algorithm_t dig, unsigned int secure); -+int _gnutls_sign_set_secure(gnutls_sign_algorithm_t sign, hash_security_level_t slevel); -+int _gnutls_protocol_set_enabled(gnutls_protocol_t version, unsigned int enabled); -+int _gnutls_ecc_curve_set_enabled(gnutls_ecc_curve_t curve, unsigned int enabled); -+ - /* these functions are for revertible settings, meaning that algorithms marked - * as disabled/insecure with mark_*_all functions can be re-enabled with - * mark_{enabled,secure} functions */ - void _gnutls_ecc_curve_mark_disabled_all(void); -+void _gnutls_version_mark_disabled_all(void); - void _gnutls_sign_mark_insecure_all(hash_security_level_t level); - void _gnutls_digest_mark_insecure_all(void); --void _gnutls_version_mark_revertible_all(void); - - #define GNUTLS_SIGN_FLAG_TLS13_OK 1 /* if it is ok to use under TLS1.3 */ - #define GNUTLS_SIGN_FLAG_CRT_VRFY_REVERSE (1 << 1) /* reverse order of bytes in CrtVrfy signature */ -diff --git a/lib/algorithms/ecc.c b/lib/algorithms/ecc.c -index 52ae1db0e4..303a42612f 100644 ---- a/lib/algorithms/ecc.c -+++ b/lib/algorithms/ecc.c -@@ -379,26 +379,8 @@ void _gnutls_ecc_curve_mark_disabled_all(void) - } - } - --/** -- * gnutls_ecc_curve_set_enabled: -- * @curve: is an ECC curve -- * @enabled: whether to enable the curve -- * -- * Modify the previous system wide setting that marked @curve as -- * enabled or disabled. This only has effect when the curve is -- * enabled through the allowlisting mode in the configuration file, or -- * when the setting is modified with a prior call to this function. -- * -- * This function must be called prior to any session priority setting functions; -- * otherwise the behavior is undefined. -- * -- * Returns: 0 on success or negative error code otherwise. -- * -- * Since: 3.7.3 -- */ - int --gnutls_ecc_curve_set_enabled(gnutls_ecc_curve_t curve, -- unsigned int enabled) -+_gnutls_ecc_curve_set_enabled(gnutls_ecc_curve_t curve, unsigned int enabled) - { - gnutls_ecc_curve_entry_st *p; - -diff --git a/lib/algorithms/mac.c b/lib/algorithms/mac.c -index 166d51d552..47fbc226bd 100644 ---- a/lib/algorithms/mac.c -+++ b/lib/algorithms/mac.c -@@ -322,24 +322,8 @@ void _gnutls_digest_mark_insecure_all(void) - #endif - } - --/** -- * gnutls_digest_set_secure: -- * @dig: is a digest algorithm -- * @secure: whether to mark the digest algorithm secure -- * -- * Modify the previous system wide setting that marked @dig as secure -- * or insecure. This only has effect when the algorithm is enabled -- * through the allowlisting mode in the configuration file, or when -- * the setting is modified with a prior call to this function. -- * -- * This function must be called prior to any session priority setting functions; -- * otherwise the behavior is undefined. -- * -- * Since: 3.7.3 -- */ - int --gnutls_digest_set_secure(gnutls_digest_algorithm_t dig, -- unsigned int secure) -+_gnutls_digest_set_secure(gnutls_digest_algorithm_t dig, unsigned int secure) - { - #ifndef DISABLE_SYSTEM_CONFIG - mac_entry_st *p; -diff --git a/lib/algorithms/protocols.c b/lib/algorithms/protocols.c -index 64c86eba3c..5a88123470 100644 ---- a/lib/algorithms/protocols.c -+++ b/lib/algorithms/protocols.c -@@ -192,10 +192,11 @@ static int - version_is_valid_for_session(gnutls_session_t session, - const version_entry_st *v) - { -- if (v->supported && v->transport == session->internals.transport) { -- return 1; -- } -- return 0; -+ if (!v->supported && !(v->supported_revertible && _gnutls_allowlisting_mode())) -+ return 0; -+ if (v->transport != session->internals.transport) -+ return 0; -+ return 1; - } - - /* This is only called by cfg_apply in priority.c, in blocklisting mode. */ -@@ -215,37 +216,20 @@ int _gnutls_version_mark_disabled(gnutls_protocol_t version) - } - - /* This is only called by cfg_apply in priority.c, in allowlisting mode. */ --void _gnutls_version_mark_revertible_all(void) -+void _gnutls_version_mark_disabled_all(void) - { - #ifndef DISABLE_SYSTEM_CONFIG - version_entry_st *p; - - for (p = sup_versions; p->name != NULL; p++) { -+ p->supported = false; - p->supported_revertible = true; - } -- - #endif - } - --/** -- * gnutls_protocol_set_enabled: -- * @version: is a (gnutls) version number -- * @enabled: whether to enable the protocol -- * -- * Mark the previous system wide setting that marked @version as -- * enabled or disabled. This only has effect when the version is -- * enabled through the allowlisting mode in the configuration file, or -- * when the setting is modified with a prior call to this function. -- * -- * This function must be called prior to any session priority setting functions; -- * otherwise the behavior is undefined. -- * -- * Returns: 0 on success or negative error code otherwise. -- * -- * Since: 3.7.3 -- */ - int --gnutls_protocol_set_enabled(gnutls_protocol_t version, -+_gnutls_protocol_set_enabled(gnutls_protocol_t version, - unsigned int enabled) - { - #ifndef DISABLE_SYSTEM_CONFIG -@@ -331,7 +315,10 @@ const version_entry_st *_gnutls_version_max(gnutls_session_t session) - if (p->obsolete != 0) - break; - #endif -- if (!p->supported || p->transport != session->internals.transport) -+ if (!p->supported && !(p->supported_revertible && _gnutls_allowlisting_mode())) -+ break; -+ -+ if (p->transport != session->internals.transport) - break; - - if (p->tls13_sem && (session->internals.flags & INT_FLAG_NO_TLS13)) -@@ -386,7 +373,10 @@ int _gnutls_write_supported_versions(gnutls_session_t session, uint8_t *buffer, - if (p->obsolete != 0) - break; - -- if (!p->supported || p->transport != session->internals.transport) -+ if (!p->supported && !(p->supported_revertible && _gnutls_allowlisting_mode())) -+ break; -+ -+ if (p->transport != session->internals.transport) - break; - - if (p->only_extension) -@@ -569,7 +559,10 @@ _gnutls_nversion_is_supported(gnutls_session_t session, - if (p->tls13_sem && (session->internals.flags & INT_FLAG_NO_TLS13)) - return 0; - -- if (!p->supported || p->transport != session->internals.transport) -+ if (!p->supported && !(p->supported_revertible && _gnutls_allowlisting_mode())) -+ return 0; -+ -+ if (p->transport != session->internals.transport) - return 0; - - version = p->id; -diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c -index 06abdb4cf8..26816feef5 100644 ---- a/lib/algorithms/sign.c -+++ b/lib/algorithms/sign.c -@@ -502,28 +502,9 @@ void _gnutls_sign_mark_insecure_all(hash_security_level_t level) - #endif - } - --/** -- * gnutls_sign_set_secure: -- * @sign: the sign algorithm -- * @secure: whether to mark the sign algorithm secure -- * -- * Modify the previous system wide setting that marked @sign as secure -- * or insecure. This only has effect when the algorithm is marked as -- * secure through the allowlisting mode in the configuration file, or -- * when the setting is modified with a prior call to this function. -- * -- * Even when @secure is true, @sign is not marked as secure for the -- * use in certificates. Use gnutls_sign_set_secure_for_certs() to -- * mark it secure as well for certificates. -- * -- * This function must be called prior to any session priority setting functions; -- * otherwise the behavior is undefined. -- * -- * Since: 3.7.3 -- */ - int --gnutls_sign_set_secure(gnutls_sign_algorithm_t sign, -- unsigned int secure) -+_gnutls_sign_set_secure(gnutls_sign_algorithm_t sign, -+ hash_security_level_t slevel) - { - #ifndef DISABLE_SYSTEM_CONFIG - gnutls_sign_entry_st *p; -@@ -533,60 +514,7 @@ gnutls_sign_set_secure(gnutls_sign_algorithm_t sign, - if (!(p->flags & GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE)) { - return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); - } -- if (secure) { -- if (p->slevel > _INSECURE_FOR_CERTS) { -- p->slevel = _INSECURE_FOR_CERTS; -- } -- } else { -- p->slevel = _INSECURE; -- } -- return 0; -- } -- } --#endif -- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); --} -- --/** -- * gnutls_sign_set_secure_for_certs: -- * @sign: the sign algorithm -- * @secure: whether to mark the sign algorithm secure for certificates -- * -- * Modify the previous system wide setting that marked @sign as secure -- * or insecure for the use in certificates. This only has effect when -- * the algorithm is marked as secure through the allowlisting mode in -- * the configuration file, or when the setting is modified with a -- * prior call to this function. -- * -- * When @secure is true, @sign is marked as secure for any use unlike -- * gnutls_sign_set_secure(). Otherwise, it is marked as insecure only -- * for the use in certificates. Use gnutls_sign_set_secure() to mark -- * it insecure for any uses. -- * -- * This function must be called prior to any session priority setting functions; -- * otherwise the behavior is undefined. -- * -- * Since: 3.7.3 -- */ --int --gnutls_sign_set_secure_for_certs(gnutls_sign_algorithm_t sign, -- unsigned int secure) --{ --#ifndef DISABLE_SYSTEM_CONFIG -- gnutls_sign_entry_st *p; -- -- for(p = sign_algorithms; p->name != NULL; p++) { -- if (p->id && p->id == sign) { -- if (!(p->flags & GNUTLS_SIGN_FLAG_INSECURE_REVERTIBLE)) { -- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -- } -- if (secure) { -- p->slevel = _SECURE; -- } else { -- if (p->slevel < _INSECURE_FOR_CERTS) { -- p->slevel = _INSECURE_FOR_CERTS; -- } -- } -+ p->slevel = slevel; - return 0; - } - } -diff --git a/lib/config_int.h b/lib/config_int.h -index be8c71e414..df39f2bf83 100644 ---- a/lib/config_int.h -+++ b/lib/config_int.h -@@ -101,7 +101,7 @@ _cfg_hashes_remark(struct cfg* cfg) - size_t i; - _gnutls_digest_mark_insecure_all(); - for (i = 0; cfg->hashes[i] != 0; i++) { -- int ret = gnutls_digest_set_secure(cfg->hashes[i], 1); -+ int ret = _gnutls_digest_set_secure(cfg->hashes[i], 1); - if (unlikely(ret < 0)) { - return gnutls_assert_val(ret); - } -@@ -116,15 +116,15 @@ _cfg_sigs_remark(struct cfg* cfg) - size_t i; - _gnutls_sign_mark_insecure_all(_INSECURE); - for (i = 0; cfg->sigs[i] != 0; i++) { -- int ret = gnutls_sign_set_secure(cfg->sigs[i], 1); -+ int ret = _gnutls_sign_set_secure(cfg->sigs[i], -+ _INSECURE_FOR_CERTS); - if (unlikely(ret < 0)) { - return gnutls_assert_val(ret); - } - } - for (i = 0; cfg->sigs_for_cert[i] != 0; i++) { -- int ret = gnutls_sign_set_secure_for_certs( -- cfg->sigs_for_cert[i], 1 -- ); -+ int ret = _gnutls_sign_set_secure(cfg->sigs_for_cert[i], -+ _SECURE); - if (unlikely(ret < 0)) { - return gnutls_assert_val(ret); - } -@@ -137,9 +137,9 @@ static inline int /* allowlisting-only */ - _cfg_versions_remark(struct cfg* cfg) - { - size_t i; -- _gnutls_version_mark_revertible_all(); -+ _gnutls_version_mark_disabled_all(); - for (i = 0; cfg->versions[i] != 0; i++) { -- int ret = gnutls_protocol_set_enabled(cfg->versions[i], 1); -+ int ret = _gnutls_protocol_set_enabled(cfg->versions[i], 1); - if (unlikely(ret < 0)) { - return gnutls_assert_val(ret); - } -@@ -154,7 +154,7 @@ _cfg_ecc_curves_remark(struct cfg* cfg) - size_t i; - _gnutls_ecc_curve_mark_disabled_all(); - for (i = 0; cfg->ecc_curves[i] != 0; i++) { -- int ret = gnutls_ecc_curve_set_enabled(cfg->ecc_curves[i], 1); -+ int ret = _gnutls_ecc_curve_set_enabled(cfg->ecc_curves[i], 1); - if (unlikely(ret < 0)) { - return gnutls_assert_val(ret); - } -@@ -168,7 +168,7 @@ _cfg_ecc_curves_remark(struct cfg* cfg) - - static inline int /* allowlisting-only */ - cfg_hashes_set_array(struct cfg* cfg, -- gnutls_digest_algorithm_t* src, size_t len) -+ gnutls_digest_algorithm_t* src, size_t len) - { - if (unlikely(len >= MAX_ALGOS)) { - return gnutls_assert_val(GNUTLS_A_INTERNAL_ERROR); -@@ -230,4 +230,142 @@ cfg_ecc_curves_set_array(struct cfg* cfg, gnutls_ecc_curve_t* src, size_t len) - return _cfg_ecc_curves_remark(cfg); - } - -+/* -+ * appending to arrays of struct cfg -+ */ -+ -+/* polymorphic way to DRY this operation. other possible approaches: -+ * 1. just unmacro (long) -+ * 2. cast to ints and write a function operating on ints -+ * (hacky, every call is +4 lines, needs a portable static assert) -+ * 3. macro whole functions, not just this operation (harder to find/read) -+ */ -+#define APPEND_TO_NULL_TERMINATED_ARRAY(dst, element) \ -+ do { \ -+ size_t i; \ -+ for (i = 0; dst[i] != 0; i++) { \ -+ if (dst[i] == element) { \ -+ return 0; \ -+ } \ -+ } \ -+ if (unlikely(i >= MAX_ALGOS)) { \ -+ return gnutls_assert_val(GNUTLS_A_INTERNAL_ERROR); \ -+ } \ -+ dst[i] = element; \ -+ dst[i + 1] = 0; \ -+ } while (0) -+ -+static inline int /* allowlisting-only */ -+cfg_hashes_add(struct cfg *cfg, gnutls_digest_algorithm_t dig) -+{ -+ _gnutls_debug_log("cfg: enabling digest algorithm %s\n", -+ gnutls_digest_get_name(dig)); -+ APPEND_TO_NULL_TERMINATED_ARRAY(cfg->hashes, dig); -+ return _cfg_hashes_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_sigs_add(struct cfg *cfg, gnutls_sign_algorithm_t sig) -+{ -+ _gnutls_debug_log("cfg: enabling signature algorithm " -+ "(for non-certificate usage) " -+ "%s\n", gnutls_sign_get_name(sig)); -+ APPEND_TO_NULL_TERMINATED_ARRAY(cfg->sigs, sig); -+ return _cfg_sigs_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_sigs_for_cert_add(struct cfg *cfg, gnutls_sign_algorithm_t sig) -+{ -+ _gnutls_debug_log("cfg: enabling signature algorithm" -+ "(for certificate usage) " -+ "%s\n", gnutls_sign_get_name(sig)); -+ APPEND_TO_NULL_TERMINATED_ARRAY(cfg->sigs_for_cert, sig); -+ return _cfg_sigs_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_versions_add(struct cfg *cfg, gnutls_protocol_t prot) -+{ -+ _gnutls_debug_log("cfg: enabling version %s\n", -+ gnutls_protocol_get_name(prot)); -+ APPEND_TO_NULL_TERMINATED_ARRAY(cfg->versions, prot); -+ return _cfg_versions_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_ecc_curves_add(struct cfg *cfg, gnutls_ecc_curve_t curve) -+{ -+ _gnutls_debug_log("cfg: enabling curve %s\n", -+ gnutls_ecc_curve_get_name(curve)); -+ APPEND_TO_NULL_TERMINATED_ARRAY(cfg->ecc_curves, curve); -+ return _cfg_ecc_curves_remark(cfg); -+} -+ -+#undef APPEND_TO_NULL_TERMINATED_ARRAY -+ -+/* -+ * removing from arrays of struct cfg -+ */ -+ -+/* polymorphic way to DRY this removal, see APPEND_TO_NULL_TERMINATED_ARRAY */ -+#define REMOVE_FROM_NULL_TERMINATED_ARRAY(dst, element) \ -+ do { \ -+ size_t i, j; \ -+ for (i = 0; dst[i] != 0; i++) { \ -+ if (dst[i] == element) { \ -+ for (j = i; dst[j] != 0; j++) { \ -+ dst[j] = dst[j + 1]; \ -+ } \ -+ } \ -+ } \ -+ } while (0) -+ -+static inline int /* allowlisting-only */ -+cfg_hashes_remove(struct cfg *cfg, gnutls_digest_algorithm_t dig) -+{ -+ _gnutls_debug_log("cfg: disabling digest algorithm %s\n", -+ gnutls_digest_get_name(dig)); -+ REMOVE_FROM_NULL_TERMINATED_ARRAY(cfg->hashes, dig); -+ return _cfg_hashes_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_sigs_remove(struct cfg *cfg, gnutls_sign_algorithm_t sig) -+{ -+ _gnutls_debug_log("cfg: disabling signature algorithm " -+ "(for non-certificate usage) " -+ "%s\n", gnutls_sign_get_name(sig)); -+ REMOVE_FROM_NULL_TERMINATED_ARRAY(cfg->sigs, sig); -+ return _cfg_sigs_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_sigs_for_cert_remove(struct cfg *cfg, gnutls_sign_algorithm_t sig) -+{ -+ _gnutls_debug_log("cfg: disabling signature algorithm" -+ "(for certificate usage) " -+ "%s\n", gnutls_sign_get_name(sig)); -+ REMOVE_FROM_NULL_TERMINATED_ARRAY(cfg->sigs_for_cert, sig); -+ return _cfg_sigs_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_versions_remove(struct cfg *cfg, gnutls_protocol_t prot) -+{ -+ _gnutls_debug_log("cfg: disabling version %s\n", -+ gnutls_protocol_get_name(prot)); -+ REMOVE_FROM_NULL_TERMINATED_ARRAY(cfg->versions, prot); -+ return _cfg_versions_remark(cfg); -+} -+ -+static inline int /* allowlisting-only */ -+cfg_ecc_curves_remove(struct cfg *cfg, gnutls_ecc_curve_t curve) -+{ -+ _gnutls_debug_log("cfg: disabling curve %s\n", -+ gnutls_ecc_curve_get_name(curve)); -+ REMOVE_FROM_NULL_TERMINATED_ARRAY(cfg->ecc_curves, curve); -+ return _cfg_ecc_curves_remark(cfg); -+} -+ - #endif /* GNUTLS_LIB_CONFIG_INT_H */ -diff --git a/lib/global.h b/lib/global.h -index 16fde08b5c..6bd70df8e3 100644 ---- a/lib/global.h -+++ b/lib/global.h -@@ -48,5 +48,6 @@ extern void _gnutls_nss_keylog_deinit(void); - - extern void _gnutls_prepare_to_load_system_priorities(void); - extern void _gnutls_unload_system_priorities(void); -+extern bool _gnutls_allowlisting_mode(void); - - #endif /* GNUTLS_LIB_GLOBAL_H */ -diff --git a/lib/priority.c b/lib/priority.c -index 8d8428e1da..c187284024 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -1023,6 +1023,11 @@ static unsigned system_priority_file_loaded = 0; - #define OVERRIDES_SECTION "overrides" - #define MAX_ALGO_NAME 2048 - -+bool _gnutls_allowlisting_mode(void) -+{ -+ return system_wide_config.allowlisting; -+} -+ - static void _clear_default_system_priority(void) - { - gnutls_free(system_wide_config.default_priority_string); -@@ -2215,7 +2220,9 @@ static int set_ciphersuite_list(gnutls_priority_t priority_cache) - /* disable TLS versions which are added but are unsupported */ - for (i = j = 0; i < priority_cache->protocol.num_priorities; i++) { - vers = version_to_entry(priority_cache->protocol.priorities[i]); -- if (!vers || vers->supported) -+ if (!vers || vers->supported || -+ (system_wide_config.allowlisting && \ -+ vers->supported_revertible)) - priority_cache->protocol.priorities[j++] = priority_cache->protocol.priorities[i]; - } - priority_cache->protocol.num_priorities = j; -@@ -3393,3 +3400,253 @@ gnutls_priority_string_list(unsigned iter, unsigned int flags) - } - return NULL; - } -+ -+/* -+ * high-level interface for overriding configuration files -+ */ -+ -+static inline int /* not locking system_wide_config */ -+system_wide_config_is_malleable(void) { -+ if (!system_wide_config.allowlisting) { -+ _gnutls_debug_log("allowlisting is not enabled!\n"); -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+ } -+ if (system_wide_config.priority_string) { -+ _gnutls_debug_log("priority strings have already been " -+ "initialized!\n"); -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+ } -+ return 1; -+} -+ -+/** -+ * gnutls_digest_set_secure: -+ * @dig: is a digest algorithm -+ * @secure: whether to mark the digest algorithm secure -+ * -+ * Modify the previous system wide setting that marked @dig as secure -+ * or insecure. This only has effect when the algorithm is enabled -+ * through the allowlisting mode in the configuration file, or when -+ * the setting is modified with a prior call to this function. -+ * -+ * Since: 3.7.3 -+ */ -+int -+gnutls_digest_set_secure(gnutls_digest_algorithm_t dig, unsigned int secure) -+{ -+#ifndef DISABLE_SYSTEM_CONFIG -+ int ret; -+ ret = gnutls_rwlock_wrlock(&system_wide_config_rwlock); -+ if (ret < 0) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ ret = system_wide_config_is_malleable(); -+ if (ret != 1) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ -+ if (secure) { -+ ret = cfg_hashes_add(&system_wide_config, dig); -+ } else { -+ ret = cfg_hashes_remove(&system_wide_config, dig); -+ } -+ -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return ret; -+#else -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+#endif -+} -+ -+/** -+ * gnutls_sign_set_secure: -+ * @sign: the sign algorithm -+ * @secure: whether to mark the sign algorithm secure -+ * -+ * Modify the previous system wide setting that marked @sign as secure -+ * or insecure. This only has effect when the algorithm is marked as -+ * secure through the allowlisting mode in the configuration file, or -+ * when the setting is modified with a prior call to this function. -+ * -+ * Even when @secure is true, @sign is not marked as secure for the -+ * use in certificates. Use gnutls_sign_set_secure_for_certs() to -+ * mark it secure as well for certificates. -+ * -+ * Since: 3.7.3 -+ */ -+int -+gnutls_sign_set_secure(gnutls_sign_algorithm_t sign, unsigned int secure) -+{ -+#ifndef DISABLE_SYSTEM_CONFIG -+ int ret; -+ ret = gnutls_rwlock_wrlock(&system_wide_config_rwlock); -+ if (ret < 0) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ ret = system_wide_config_is_malleable(); -+ if (ret != 1) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ -+ if (secure) { -+ ret = cfg_sigs_add(&system_wide_config, sign); -+ } else { -+ ret = cfg_sigs_remove(&system_wide_config, sign); -+ if (ret < 0) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return ret; -+ } -+ /* irregularity, distrusting also means distrusting for certs */ -+ ret = cfg_sigs_for_cert_remove(&system_wide_config, sign); -+ } -+ -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return ret; -+#else -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+#endif -+} -+ -+/** -+ * gnutls_sign_set_secure_for_certs: -+ * @sign: the sign algorithm -+ * @secure: whether to mark the sign algorithm secure for certificates -+ * -+ * Modify the previous system wide setting that marked @sign as secure -+ * or insecure for the use in certificates. This only has effect when -+ * the algorithm is marked as secure through the allowlisting mode in -+ * the configuration file, or when the setting is modified with a -+ * prior call to this function. -+ * -+ * When @secure is true, @sign is marked as secure for any use unlike -+ * gnutls_sign_set_secure(). Otherwise, it is marked as insecure only -+ * for the use in certificates. Use gnutls_sign_set_secure() to mark -+ * it insecure for any uses. -+ * -+ * Since: 3.7.3 -+ */ -+int -+gnutls_sign_set_secure_for_certs(gnutls_sign_algorithm_t sign, -+ unsigned int secure) -+{ -+#ifndef DISABLE_SYSTEM_CONFIG -+ int ret; -+ ret = gnutls_rwlock_wrlock(&system_wide_config_rwlock); -+ if (ret < 0) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ ret = system_wide_config_is_malleable(); -+ if (ret != 1) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ -+ if (secure) { -+ /* irregularity, trusting for certs means trusting in general */ -+ ret = cfg_sigs_add(&system_wide_config, sign); -+ if (ret < 0) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return ret; -+ } -+ ret = cfg_sigs_for_cert_add(&system_wide_config, sign); -+ } else { -+ ret = cfg_sigs_for_cert_remove(&system_wide_config, sign); -+ } -+ -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return ret; -+#else -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+#endif -+} -+ -+/** -+ * gnutls_protocol_set_enabled: -+ * @version: is a (gnutls) version number -+ * @enabled: whether to enable the protocol -+ * -+ * Mark the previous system wide setting that marked @version as -+ * enabled or disabled. This only has effect when the version is -+ * enabled through the allowlisting mode in the configuration file, or -+ * when the setting is modified with a prior call to this function. -+ * -+ * Returns: 0 on success or negative error code otherwise. -+ * -+ * Since: 3.7.3 -+ */ -+int /* allowlisting-only */ /* not thread-safe */ -+gnutls_protocol_set_enabled(gnutls_protocol_t version, unsigned int enabled) -+{ -+#ifndef DISABLE_SYSTEM_CONFIG -+ int ret; -+ ret = gnutls_rwlock_wrlock(&system_wide_config_rwlock); -+ if (ret < 0) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ ret = system_wide_config_is_malleable(); -+ if (ret != 1) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ -+ if (enabled) { -+ ret = cfg_versions_add(&system_wide_config, version); -+ } else { -+ ret = cfg_versions_remove(&system_wide_config, version); -+ } -+ -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return ret; -+#else -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+#endif -+} -+ -+/** -+ * gnutls_ecc_curve_set_enabled: -+ * @curve: is an ECC curve -+ * @enabled: whether to enable the curve -+ * -+ * Modify the previous system wide setting that marked @curve as -+ * enabled or disabled. This only has effect when the curve is -+ * enabled through the allowlisting mode in the configuration file, or -+ * when the setting is modified with a prior call to this function. -+ * -+ * Returns: 0 on success or negative error code otherwise. -+ * -+ * Since: 3.7.3 -+ */ -+int -+gnutls_ecc_curve_set_enabled(gnutls_ecc_curve_t curve, unsigned int enabled) -+{ -+#ifndef DISABLE_SYSTEM_CONFIG -+ int ret; -+ ret = gnutls_rwlock_wrlock(&system_wide_config_rwlock); -+ if (ret < 0) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ ret = system_wide_config_is_malleable(); -+ if (ret != 1) { -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return gnutls_assert_val(ret); -+ } -+ -+ if (enabled) { -+ ret = cfg_ecc_curves_add(&system_wide_config, curve); -+ } else { -+ ret = cfg_ecc_curves_remove(&system_wide_config, curve); -+ } -+ -+ (void)gnutls_rwlock_unlock(&system_wide_config_rwlock); -+ return ret; -+#else -+ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); -+#endif -+} -diff --git a/tests/protocol-set-allowlist.c b/tests/protocol-set-allowlist.c -index 754e4d12d1..744d70b315 100644 ---- a/tests/protocol-set-allowlist.c -+++ b/tests/protocol-set-allowlist.c -@@ -37,15 +37,21 @@ - * This is not a test by itself. - * This is a helper for the real test in protocol-set-allowlist.sh. - * It executes sequences of commands like: -- * > connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -- * > protocol_set_disabled TLS1.2 -> OK -- * > connect -> bad priority: (actually, any arrow-less text can go here) -+ * > protocol_set_disabled TLS1.2 -+ * > protocol_set_enabled TLS1.1 -+ * > connect -+ * > protocol_set_enabled TLS1.2 -+ * > protocol_set_disabled TLS1.1 -+ * > connect -> connection established - * where `connect` connects to $TEST_SERVER_PORT using $TEST_SERVER_CA, - * and gnutls_protocol_set_enabled simply call the underlying API. - * leaving the outer test to check return code and output: -- * connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) - * protocol_set_disabled TLS1.2 -> OK -- * connect -> bad priority: No or insufficient priorities were set. -+ * protocol_set_enabled TLS1.1 -> OK -+ * connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) -+ * protocol_set_enabled TLS1.2 -> INVALID_REQUEST -+ * protocol_set_disabled TLS1.1 -> INVALID_REQUEST -+ * connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) - */ - - #define _assert(cond, format, ...) if (!(cond)) \ -@@ -58,6 +64,7 @@ void test_echo_server(gnutls_session_t session); - void cmd_connect(const char* ca_file, unsigned port); - void cmd_protocol_set_disabled(const char* name); - void cmd_protocol_set_enabled(const char* name); -+void cmd_reinit(void); - const char* unprefix(const char* s, const char* prefix); - - -@@ -167,15 +174,32 @@ void cmd_connect(const char* ca_file, unsigned port) - - void cmd_protocol_set_disabled(const char* name) - { -- _check(gnutls_protocol_set_enabled(parse_protocol(name), 0) >= 0); -- printf("protocol_set_disabled %s -> OK\n", name); -+ int ret; -+ ret = gnutls_protocol_set_enabled(parse_protocol(name), 0); -+ printf("protocol_set_disabled %s -> %s\n", name, -+ ret == 0 ? "OK" : -+ ret == GNUTLS_E_INVALID_REQUEST ? "INVALID_REQUEST" : -+ gnutls_strerror(ret)); - } - - - void cmd_protocol_set_enabled(const char* name) - { -- _check(gnutls_protocol_set_enabled(parse_protocol(name), 1) >= 0); -- printf("protocol_set_enabled %s -> OK\n", name); -+ int ret; -+ ret = gnutls_protocol_set_enabled(parse_protocol(name), 1); -+ printf("protocol_set_enabled %s -> %s\n", name, -+ ret == 0 ? "OK" : -+ ret == GNUTLS_E_INVALID_REQUEST ? "INVALID_REQUEST" : -+ gnutls_strerror(ret)); -+} -+ -+ -+void cmd_reinit(void) -+{ -+ int ret; -+ gnutls_global_deinit(); -+ ret = gnutls_global_init(); -+ printf("reinit -> %s\n", ret == 0 ? "OK" : gnutls_strerror(ret)); - } - - -@@ -204,8 +228,6 @@ void doit(void) - _assert(port_str, "TEST_SERVER_PORT is not set"); - port = parse_port(port_str); - -- _check(gnutls_global_init() >= 0); -- - while (!feof(stdin)) { - memset(cmd_buf, '\0', MAX_CMD_LEN + 1); - fgets(cmd_buf, MAX_CMD_LEN, stdin); -@@ -220,6 +242,8 @@ void doit(void) - cmd_protocol_set_disabled(p); - else if ((p = unprefix(cmd_buf, "> protocol_set_enabled "))) - cmd_protocol_set_enabled(p); -+ else if (!strcmp(cmd_buf, "> reinit")) -+ cmd_reinit(); - else if ((p = unprefix(cmd_buf, "> "))) - _fail("Unknown command `%s`\n", p); - else -@@ -227,6 +251,5 @@ void doit(void) - cmd_buf); - } - -- gnutls_global_deinit(); - exit(0); - } -diff --git a/tests/protocol-set-allowlist.sh b/tests/protocol-set-allowlist.sh -index 907f37562f..ee2fe649bd 100755 ---- a/tests/protocol-set-allowlist.sh -+++ b/tests/protocol-set-allowlist.sh -@@ -25,6 +25,7 @@ - # from within the shell wrapper protocol-set-allowlist.sh - # The shell part of it feeds commands into a C helper - # and compares its output to the reference output. -+# Commands are derived from the reference output. - - : ${srcdir=.} - : ${builddir=.} -@@ -161,6 +162,9 @@ fi - ### Harness for the actual tests - - test_with_helper() { -+ echo '#' -+ echo "# $1" -+ echo '#' - ${CAT} > "$TMPFILE_EXPECTED_LOG" - ${SED} 's/\(.*\) -> .*/> \1/' "${TMPFILE_EXPECTED_LOG}" \ - > "${TMPFILE_INPUT_SCRIPT}" -@@ -197,152 +201,234 @@ launch_server --echo --priority "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.2" \ - SERVER_PID=$! - wait_server ${SERVER_PID} - --# ["gnutls_protocol_set_enabled can disable, TLS"] --# With a configuration file allowlisting a specific TLS protocol version (1.2), --# gnutls_protocol_set_enabled can disable it. --test_with_helper < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --protocol_set_disabled TLS1.2 -> OK --connect -> bad priority: No or insufficient priorities were set. - EOF - --# ["gnutls_protocol_set_enabled disables revertibly, TLS"] --# consecutive gnutls_protocol_set_enabled can make connection possible --# (with a different session handle). --test_with_helper < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --protocol_set_disabled TLS1.2 -> OK --connect -> bad priority: No or insufficient priorities were set. --protocol_set_enabled TLS1.2 -> OK -+protocol_set_disabled TLS1.2 -> INVALID_REQUEST - connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) - EOF - --# Just a random long-ish scenario --test_with_helper < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+test_with_helper 'disabling TLS 1.2 leaves us with no versions' < OK - connect -> bad priority: No or insufficient priorities were set. --protocol_set_enabled TLS1.3 -> OK -+protocol_set_enabled TLS1.2 -> INVALID_REQUEST - connect -> bad priority: No or insufficient priorities were set. --protocol_set_disabled TLS1.3 -> OK -+EOF -+ -+test_with_helper \ -+ 'disabling is revertible if done before the first gnutls_init' << EOF -+protocol_set_disabled TLS1.2 -> OK - protocol_set_enabled TLS1.2 -> OK - connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+protocol_set_disabled TLS1.2 -> INVALID_REQUEST -+protocol_set_enabled TLS1.2 -> INVALID_REQUEST -+connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) - EOF - --# !!! CURRENTLY NOT WORKING AS EXPECTED !!! --# Insufficient priority vs handshake failed --#test_with_helper < OK -+#connect -> bad priority: No or insufficient priorities were set. -+#reinit -> OK -+#connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+#EOF -+ -+# Reinit after restricting algorithms has problems with FIPS self-tests -+#test_with_helper \ -+# 'library reinitialization allows new API again, but resets changes' \ -+# < OK - #connect -> bad priority: No or insufficient priorities were set. --#protocol_set_enabled TLS1.3 -> OK --#connect -> handshake failed: A packet with illegal or unsupported version was received. -+#protocol_set_enabled TLS1.2 -> INVALID_REQUEST -+#connect -> bad priority: No or insufficient priorities were set. -+#reinit -> OK -+#connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+#protocol_set_disabled TLS1.2 -> INVALID_REQUEST -+#connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+#reinit -> OK -+#protocol_set_disabled TLS1.2 -> OK -+#protocol_set_enabled TLS1.2 -> OK -+#connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+#protocol_set_disabled TLS1.2 -> INVALID_REQUEST - #EOF - -+test_with_helper 'Insufficient priority vs handshake failed: 1/2' < OK -+connect -> bad priority: No or insufficient priorities were set. -+EOF -+ -+test_with_helper 'Insufficient priority vs handshake failed: 2/2' < OK -+protocol_set_enabled TLS1.3 -> OK -+connect -> handshake failed: A TLS fatal alert has been received. -+EOF -+# TLS 1.3 does some masquerading as TLS 1.2, I guess, so it's not -+# handshake failed: A packet with illegal or unsupported version was received. -+ - terminate_proc ${SERVER_PID} - - ### Tests against a NORMAL server (all three TLS versions enabled) - - eval "${GETPORT}" - # server is launched without allowlisting config file in effect --launch_server -d9 --echo --priority NORMAL \ -+launch_server --echo --priority NORMAL \ - --x509keyfile "${TMPFILE_KEY}" --x509certfile "${TMPFILE_CERT}" - SERVER_PID=$! - wait_server ${SERVER_PID} - --# !!! CURRENTLY NOT WORKING AS EXPECTED !!! --# smoke-test enabling with protocol_set --#test_with_helper < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --#protocol_set_enabled TLS1.3 -> OK --#connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) --#EOF -+# sanity-test -+test_with_helper 'sanity test against liberal server' < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+EOF - --# !!! CURRENTLY NOT WORKING AS EXPECTED !!! --# ["gnutls_protocol_set_enabled enables, TLS"] --# with a configuration file not allowlisting a specific TLS protocol version, --# enabling that version with gnutls_protocol_set_enabled --# allows connecting to a server accepting this TLS protocol version alone --#test_with_helper < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --#protocol_set_enabled TLS1.3 -> OK --#connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) --#EOF -+test_with_helper 'smoke-test enabling' < OK -+connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) -+EOF - --# !!! CURRENTLY NOT WORKING AS EXPECTED !!! --# ["gnutls_protocol_set_enabled enables revertibly, TLS"] --# consecutive gnutls_protocol_set --# can prevent the client from connecting (with a different session handle) --#test_with_helper < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --#protocol_set_enabled TLS1.1 -> OK --#connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --#protocol_set_disabled TLS1.2 -> OK --#connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) --#protocol_set_disabled TLS1.1 -> OK --#connect -> bad priority: No or insufficient priorities were set. --#EOF --# Alternative one --#test_with_helper < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --#protocol_set_enabled TLS1.3 -> OK --#connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) --#protocol_set_disabled TLS1.3 -> OK --#connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --#EOF -+test_with_helper 'going down to TLS1.1' < OK -+protocol_set_disabled TLS1.2 -> OK -+connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) -+EOF - --# !!! CURRENTLY NOT WORKING AS EXPECTED !!! --# ["gnutls_protocol_set_disabled disables selectively, TLS"] --# gnutls_protocol_set_disabled with a specific version --# doesn't disable other previously enabled version. --# ["gnutls_protocol_set_enabled enables selectively, TLS"] --# gnutls_protocol_set_enabled enabling a specific version --# doesn't enable other previously disabled version. --#test_with_helper < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --#protocol_set_enabled TLS1.3 -> OK --#protocol_set_enabled TLS1.2 -> OK --#protocol_set_enabled TLS1.1 -> OK --#connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) --#protocol_set_disabled TLS1.3 -> OK --#connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) --#protocol_set_disabled TLS1.2 -> OK --#connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) --#protocol_set_disabled TLS1.1 -> OK --#connect -> bad priority: No or insufficient priorities were set. --#protocol_set_enabled TLS1.1 -> OK --#connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) --#protocol_set_enabled TLS1.2 -> OK --#connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) --#protocol_set_enabled TLS1.3 -> OK --#connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) --#EOF -+test_with_helper 'going up to TLS 1.3' < OK -+connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) -+EOF -+ -+test_with_helper 'useless toggles' < OK -+protocol_set_disabled TLS1.2 -> OK -+protocol_set_enabled TLS1.2 -> OK -+protocol_set_enabled TLS1.1 -> OK -+protocol_set_enabled TLS1.1 -> OK -+protocol_set_enabled TLS1.3 -> OK -+protocol_set_disabled TLS1.1 -> OK -+protocol_set_disabled TLS1.3 -> OK -+connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+EOF -+ -+test_with_helper 'disable does not overdisable: 1/2' < OK -+protocol_set_enabled TLS1.2 -> OK -+protocol_set_enabled TLS1.1 -> OK -+protocol_set_disabled TLS1.3 -> OK -+protocol_set_disabled TLS1.1 -> OK -+connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+EOF -+ -+test_with_helper 'disable does not overdisable: 2/2' < OK -+protocol_set_enabled TLS1.2 -> OK -+protocol_set_enabled TLS1.1 -> OK -+protocol_set_disabled TLS1.3 -> OK -+protocol_set_disabled TLS1.2 -> OK -+connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) -+EOF - - terminate_proc ${SERVER_PID} - --### Tests against a TLS 1.1 & 1.3 server (1.2 disabled) -+#### Tests against a TLS 1.3 server -+# -+eval "${GETPORT}" -+# server is launched without allowlisting config file in effect -+launch_server --echo \ -+ --priority "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.3" \ -+ --x509keyfile "${TMPFILE_KEY}" --x509certfile "${TMPFILE_CERT}" -+SERVER_PID=$! -+wait_server ${SERVER_PID} -+ -+test_with_helper 'sanity negative' < handshake failed: A TLS fatal alert has been received. -+protocol_set_enabled TLS1.3 -> INVALID_REQUEST -+protocol_set_enabled TLS1.1 -> INVALID_REQUEST -+protocol_set_disabled TLS1.2 -> INVALID_REQUEST -+connect -> handshake failed: A TLS fatal alert has been received. -+EOF -+ -+test_with_helper 'enable 1.3' < OK -+connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) -+EOF -+ -+test_with_helper 'enable 1.3 only' < OK -+protocol_set_enabled TLS1.3 -> OK -+connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) -+EOF -+ -+test_with_helper 'enable 1.1' < OK -+connect -> handshake failed: A TLS fatal alert has been received. -+EOF - -+# A special case according to a comment in set_ciphersuite_list: -+# > we require TLS1.2 to be enabled if TLS1.3 is asked for, and -+# > a pre-TLS1.2 protocol is there; that is because servers which -+# > do not support TLS1.3 will negotiate TLS1.2 if seen a TLS1.3 handshake -+test_with_helper 'enable 1.1 and 1.3 only - does not work as you expect' < OK -+protocol_set_disabled TLS1.2 -> OK -+protocol_set_enabled TLS1.1 -> OK -+connect -> handshake failed: A packet with illegal or unsupported version was received. -+EOF -+ -+test_with_helper 'enable 1.1 and 1.3' < OK -+protocol_set_enabled TLS1.1 -> OK -+connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) -+EOF -+ -+test_with_helper 'enable 1.1 and 1.3, different order' < OK -+protocol_set_enabled TLS1.3 -> OK -+connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) -+EOF -+ -+terminate_proc ${SERVER_PID} -+ -+#### Tests against a TLS 1.1 + TLS 1.2 server -+# - eval "${GETPORT}" - # server is launched without allowlisting config file in effect --launch_server -d9 --echo \ -- --priority "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.3" \ -+launch_server --echo \ -+ --priority "NORMAL:-VERS-TLS-ALL:+VERS-TLS1.1:+VERS-TLS1.2" \ - --x509keyfile "${TMPFILE_KEY}" --x509certfile "${TMPFILE_CERT}" - SERVER_PID=$! - wait_server ${SERVER_PID} - --# !!! CURRENTLY NOT WORKING AS EXPECTED !!! --#test_with_helper < handshake failed: A packet with illegal or unsupported version was received. --#protocol_set_enabled TLS1.1 -> OK --#connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) --#protocol_set_enabled TLS1.3 -> OK --#connect -> connection established: (TLS1.3)-(DHE-FFDHE3072)-(RSA-PSS-RSAE-SHA256)-(AES-128-GCM) --#protocol_set_disabled TLS1.3 -> OK --#connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) --#protocol_set_disabled TLS1.1 -> OK --#connect -> handshake failed: A packet with illegal or unsupported version was received. --#protocol_set_disabled TLS1.2 -> OK --#connect -> bad priority: No or insufficient priorities were set. --#EOF -+test_with_helper 'sanity 1.2' < connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+EOF -+ -+test_with_helper 'enable 1.1' < OK -+connect -> connection established: (TLS1.2)-(RSA)-(AES-128-GCM) -+EOF -+ -+test_with_helper 'enable 1.1 only' < OK -+protocol_set_disabled TLS1.2 -> OK -+connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) -+EOF -+ -+test_with_helper 'enable 1.1 and 1.3 only' < OK -+protocol_set_disabled TLS1.2 -> OK -+protocol_set_enabled TLS1.1 -> OK -+connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) -+EOF -+ -+test_with_helper 'enable 1.1 and 1.3 only, different order' < OK -+protocol_set_disabled TLS1.2 -> OK -+protocol_set_enabled TLS1.3 -> OK -+connect -> connection established: (TLS1.1)-(RSA)-(AES-128-CBC)-(SHA1) -+EOF - - terminate_proc ${SERVER_PID} - --- -2.34.1 - - -From ebcf38f6ac4dce0fe62bdd43114cb7415eee8d16 Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Wed, 16 Feb 2022 14:36:48 +0100 -Subject: [PATCH 8/8] update documentation on allowlisting API - -(in a separate commit so that it's easier to compare) - -Signed-off-by: Alexander Sosedkin ---- - lib/priority.c | 69 +++++++++++++++++++++++++++++++++++++++----------- - 1 file changed, 54 insertions(+), 15 deletions(-) - -diff --git a/lib/priority.c b/lib/priority.c -index c187284024..4e9d2d9cc4 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -3466,14 +3466,25 @@ gnutls_digest_set_secure(gnutls_digest_algorithm_t dig, unsigned int secure) - * @secure: whether to mark the sign algorithm secure - * - * Modify the previous system wide setting that marked @sign as secure -- * or insecure. This only has effect when the algorithm is marked as -- * secure through the allowlisting mode in the configuration file, or -- * when the setting is modified with a prior call to this function. -+ * or insecure. Calling this function is allowed -+ * only if allowlisting mode is set in the configuration file, -+ * and only if the system-wide TLS priority string -+ * has not been initialized yet. -+ * The intended usage is to provide applications with a way -+ * to expressly deviate from the distribution or site defaults -+ * inherited from the configuration file. -+ * The modification is composable with further modifications -+ * performed through the priority string mechanism. -+ * -+ * This function is not thread-safe and is intended to be called -+ * in the main thread at the beginning of the process execution. - * - * Even when @secure is true, @sign is not marked as secure for the - * use in certificates. Use gnutls_sign_set_secure_for_certs() to - * mark it secure as well for certificates. - * -+ * Returns: 0 on success or negative error code otherwise. -+ * - * Since: 3.7.3 - */ - int -@@ -3517,16 +3528,26 @@ gnutls_sign_set_secure(gnutls_sign_algorithm_t sign, unsigned int secure) - * @secure: whether to mark the sign algorithm secure for certificates - * - * Modify the previous system wide setting that marked @sign as secure -- * or insecure for the use in certificates. This only has effect when -- * the algorithm is marked as secure through the allowlisting mode in -- * the configuration file, or when the setting is modified with a -- * prior call to this function. -- * -+ * or insecure for the use in certificates. Calling this fuction is allowed -+ * only if allowlisting mode is set in the configuration file, -+ * and only if the system-wide TLS priority string -+ * has not been initialized yet. -+ * The intended usage is to provide applications with a way -+ * to expressly deviate from the distribution or site defaults -+ * inherited from the configuration file. -+ * The modification is composable with further modifications -+ * performed through the priority string mechanism. -+ * -+ * This function is not thread-safe and is intended to be called -+ * in the main thread at the beginning of the process execution. -+ - * When @secure is true, @sign is marked as secure for any use unlike - * gnutls_sign_set_secure(). Otherwise, it is marked as insecure only - * for the use in certificates. Use gnutls_sign_set_secure() to mark - * it insecure for any uses. - * -+ * Returns: 0 on success or negative error code otherwise. -+ * - * Since: 3.7.3 - */ - int -@@ -3570,10 +3591,19 @@ gnutls_sign_set_secure_for_certs(gnutls_sign_algorithm_t sign, - * @version: is a (gnutls) version number - * @enabled: whether to enable the protocol - * -- * Mark the previous system wide setting that marked @version as -- * enabled or disabled. This only has effect when the version is -- * enabled through the allowlisting mode in the configuration file, or -- * when the setting is modified with a prior call to this function. -+ * Control the previous system-wide setting that marked @version as -+ * enabled or disabled. Calling this fuction is allowed -+ * only if allowlisting mode is set in the configuration file, -+ * and only if the system-wide TLS priority string -+ * has not been initialized yet. -+ * The intended usage is to provide applications with a way -+ * to expressly deviate from the distribution or site defaults -+ * inherited from the configuration file. -+ * The modification is composable with further modifications -+ * performed through the priority string mechanism. -+ * -+ * This function is not thread-safe and is intended to be called -+ * in the main thread at the beginning of the process execution. - * - * Returns: 0 on success or negative error code otherwise. - * -@@ -3614,9 +3644,18 @@ gnutls_protocol_set_enabled(gnutls_protocol_t version, unsigned int enabled) - * @enabled: whether to enable the curve - * - * Modify the previous system wide setting that marked @curve as -- * enabled or disabled. This only has effect when the curve is -- * enabled through the allowlisting mode in the configuration file, or -- * when the setting is modified with a prior call to this function. -+ * enabled or disabled. Calling this fuction is allowed -+ * only if allowlisting mode is set in the configuration file, -+ * and only if the system-wide TLS priority string -+ * has not been initialized yet. -+ * The intended usage is to provide applications with a way -+ * to expressly deviate from the distribution or site defaults -+ * inherited from the configuration file. -+ * The modification is composable with further modifications -+ * performed through the priority string mechanism. -+ * -+ * This function is not thread-safe and is intended to be called -+ * in the main thread at the beginning of the process execution. - * - * Returns: 0 on success or negative error code otherwise. - * --- -2.34.1 - diff --git a/SOURCES/gnutls-3.7.3-fips-dsa-post.patch b/SOURCES/gnutls-3.7.3-fips-dsa-post.patch new file mode 100644 index 0000000..7d1aea2 --- /dev/null +++ b/SOURCES/gnutls-3.7.3-fips-dsa-post.patch @@ -0,0 +1,29 @@ +From 0a29639ad24072afbd79b2ceede9976e51b9e2af Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Fri, 1 Jul 2022 16:46:07 +0900 +Subject: [PATCH] fips: don't run POST for DSA + +Signed-off-by: rpm-build <> +--- + lib/fips.c | 5 ----- + 1 file changed, 5 deletions(-) + +diff --git a/lib/fips.c b/lib/fips.c +index 656d43e..c776690 100644 +--- a/lib/fips.c ++++ b/lib/fips.c +@@ -523,11 +523,6 @@ int _gnutls_fips_perform_self_checks2(void) + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + +- ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA); +- if (ret < 0) { +- return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); +- } +- + ret = gnutls_pk_self_test(0, GNUTLS_PK_EC); + if (ret < 0) { + return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); +-- +2.36.1 + diff --git a/SOURCES/gnutls-3.7.3-fips-pkcs12.patch b/SOURCES/gnutls-3.7.3-fips-pkcs12.patch deleted file mode 100644 index 45a8194..0000000 --- a/SOURCES/gnutls-3.7.3-fips-pkcs12.patch +++ /dev/null @@ -1,471 +0,0 @@ -From 7d8d8feb502ddb20a0d115fa3f63403c849a7168 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Thu, 10 Feb 2022 16:43:08 +0100 -Subject: [PATCH 1/2] pkcs12: mark MAC generation and verification as FIPS - non-approved - -Signed-off-by: Daiki Ueno ---- - lib/x509/pkcs12.c | 39 +++++++++++++++++++++++++--- - tests/pkcs12_encode.c | 59 +++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 94 insertions(+), 4 deletions(-) - -diff --git a/lib/x509/pkcs12.c b/lib/x509/pkcs12.c -index a8f7d8f956..11b9da3ac9 100644 ---- a/lib/x509/pkcs12.c -+++ b/lib/x509/pkcs12.c -@@ -286,13 +286,26 @@ gnutls_pkcs12_export(gnutls_pkcs12_t pkcs12, - gnutls_x509_crt_fmt_t format, void *output_data, - size_t * output_data_size) - { -+ int ret; -+ - if (pkcs12 == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - -- return _gnutls_x509_export_int(pkcs12->pkcs12, format, PEM_PKCS12, -- output_data, output_data_size); -+ ret = _gnutls_x509_export_int(pkcs12->pkcs12, format, PEM_PKCS12, -+ output_data, output_data_size); -+ -+ if (ret < 0) { -+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); -+ } else { -+ /* PKCS#12 export is always non-approved, because the MAC -+ * calculation involves non-approved KDF (PKCS#12 KDF) and -+ * without MAC the protection is insufficient. -+ */ -+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); -+ } -+ return ret; - } - - /** -@@ -317,13 +330,25 @@ int - gnutls_pkcs12_export2(gnutls_pkcs12_t pkcs12, - gnutls_x509_crt_fmt_t format, gnutls_datum_t * out) - { -+ int ret; -+ - if (pkcs12 == NULL) { - gnutls_assert(); - return GNUTLS_E_INVALID_REQUEST; - } - -- return _gnutls_x509_export_int2(pkcs12->pkcs12, format, PEM_PKCS12, -- out); -+ ret = _gnutls_x509_export_int2(pkcs12->pkcs12, format, PEM_PKCS12, -+ out); -+ if (ret < 0) { -+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); -+ } else { -+ /* PKCS#12 export is always non-approved, because the MAC -+ * calculation involves non-approved KDF (PKCS#12 KDF) and -+ * without MAC the protection is insufficient. -+ */ -+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); -+ } -+ return ret; - } - - static int oid2bag(const char *oid) -@@ -1025,9 +1050,12 @@ int gnutls_pkcs12_generate_mac2(gnutls_pkcs12_t pkcs12, gnutls_mac_algorithm_t m - goto cleanup; - } - -+ /* _gnutls_pkcs12_string_to_key is not a FIPS approved operation */ -+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); - return 0; - - cleanup: -+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); - _gnutls_free_datum(&tmp); - return result; - } -@@ -1203,8 +1231,11 @@ pkcs12_try_gost: - goto cleanup; - } - -+ /* _gnutls_pkcs12_string_to_key is not a FIPS approved operation */ -+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); - result = 0; - cleanup: -+ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); - _gnutls_free_datum(&tmp); - _gnutls_free_datum(&salt); - return result; -diff --git a/tests/pkcs12_encode.c b/tests/pkcs12_encode.c -index 3b0e84ef13..b8f7d17267 100644 ---- a/tests/pkcs12_encode.c -+++ b/tests/pkcs12_encode.c -@@ -70,6 +70,29 @@ static void tls_log_func(int level, const char *str) - fprintf(stderr, "|<%d>| %s", level, str); - } - -+#define FIPS_PUSH_CONTEXT() do { \ -+ if (gnutls_fips140_mode_enabled()) { \ -+ ret = gnutls_fips140_push_context(fips_context); \ -+ if (ret < 0) { \ -+ fail("gnutls_fips140_push_context failed\n"); \ -+ } \ -+ } \ -+} while (0) -+ -+#define FIPS_POP_CONTEXT(state) do { \ -+ if (gnutls_fips140_mode_enabled()) { \ -+ ret = gnutls_fips140_pop_context(); \ -+ if (ret < 0) { \ -+ fail("gnutls_fips140_context_pop failed\n"); \ -+ } \ -+ fips_state = gnutls_fips140_get_operation_state(fips_context); \ -+ if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \ -+ fail("operation state is not " # state " (%d)\n", \ -+ fips_state); \ -+ } \ -+ } \ -+} while (0) -+ - void doit(void) - { - gnutls_pkcs12_t pkcs12; -@@ -82,6 +105,8 @@ void doit(void) - char outbuf[10240]; - size_t size; - unsigned tests, i; -+ gnutls_fips140_context_t fips_context; -+ gnutls_fips140_operation_state_t fips_state; - - ret = global_init(); - if (ret < 0) { -@@ -93,6 +118,11 @@ void doit(void) - if (debug) - gnutls_global_set_log_level(4711); - -+ ret = gnutls_fips140_context_init(&fips_context); -+ if (ret < 0) { -+ fail("Cannot initialize FIPS context\n"); -+ } -+ - /* Read certs. */ - ret = gnutls_x509_crt_init(&client); - if (ret < 0) { -@@ -196,6 +226,8 @@ void doit(void) - gnutls_pkcs12_bag_deinit(bag); - } - -+ FIPS_PUSH_CONTEXT(); -+ - /* MAC the structure, export and print. */ - ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA1, "pass"); - if (ret < 0) { -@@ -203,36 +235,60 @@ void doit(void) - exit(1); - } - -+ FIPS_POP_CONTEXT(NOT_APPROVED); -+ -+ FIPS_PUSH_CONTEXT(); -+ - ret = gnutls_pkcs12_verify_mac(pkcs12, "pass"); - if (ret < 0) { - fprintf(stderr, "verify_mac: %s (%d)\n", gnutls_strerror(ret), ret); - exit(1); - } - -+ FIPS_POP_CONTEXT(NOT_APPROVED); -+ -+ FIPS_PUSH_CONTEXT(); -+ - ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA256, "passwd"); - if (ret < 0) { - fprintf(stderr, "generate_mac2: %s (%d)\n", gnutls_strerror(ret), ret); - exit(1); - } - -+ FIPS_POP_CONTEXT(NOT_APPROVED); -+ -+ FIPS_PUSH_CONTEXT(); -+ - ret = gnutls_pkcs12_verify_mac(pkcs12, "passwd"); - if (ret < 0) { - fprintf(stderr, "verify_mac2: %s (%d)\n", gnutls_strerror(ret), ret); - exit(1); - } - -+ FIPS_POP_CONTEXT(NOT_APPROVED); -+ -+ FIPS_PUSH_CONTEXT(); -+ - ret = gnutls_pkcs12_generate_mac2(pkcs12, GNUTLS_MAC_SHA512, "passwd1"); - if (ret < 0) { - fprintf(stderr, "generate_mac2: %s (%d)\n", gnutls_strerror(ret), ret); - exit(1); - } - -+ FIPS_POP_CONTEXT(NOT_APPROVED); -+ -+ FIPS_PUSH_CONTEXT(); -+ - ret = gnutls_pkcs12_verify_mac(pkcs12, "passwd1"); - if (ret < 0) { - fprintf(stderr, "verify_mac2: %s (%d)\n", gnutls_strerror(ret), ret); - exit(1); - } - -+ FIPS_POP_CONTEXT(NOT_APPROVED); -+ -+ FIPS_PUSH_CONTEXT(); -+ - size = sizeof(outbuf); - ret = - gnutls_pkcs12_export(pkcs12, GNUTLS_X509_FMT_PEM, outbuf, -@@ -242,10 +298,13 @@ void doit(void) - exit(1); - } - -+ FIPS_POP_CONTEXT(NOT_APPROVED); -+ - if (debug) - fwrite(outbuf, size, 1, stdout); - - /* Cleanup. */ -+ gnutls_fips140_context_deinit(fips_context); - gnutls_pkcs12_deinit(pkcs12); - gnutls_x509_crt_deinit(client); - gnutls_x509_crt_deinit(ca); --- -2.34.1 - - -From e7f9267342bc2231149a640163c82b63c86f1dfd Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Thu, 10 Feb 2022 17:35:13 +0100 -Subject: [PATCH 2/2] _gnutls_pkcs_raw_{decrypt,encrypt}_data: use public - crypto API - -These functions previously used the internal crypto -API (_gnutls_cipher_*) which does not have algorithm checks for FIPS. - -This change switches the code to use the public crypto -API (gnutls_cipher_*) to trigger proper state transitions under FIPS -mode. - -Signed-off-by: Daiki Ueno ---- - lib/x509/pkcs7-crypt.c | 36 +++++++++++----------------- - tests/pkcs12_encode.c | 54 +++++++++++++++++++++++++++--------------- - 2 files changed, 49 insertions(+), 41 deletions(-) - -diff --git a/lib/x509/pkcs7-crypt.c b/lib/x509/pkcs7-crypt.c -index 4cce52ecf0..2dc5bc4df0 100644 ---- a/lib/x509/pkcs7-crypt.c -+++ b/lib/x509/pkcs7-crypt.c -@@ -1130,8 +1130,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, asn1_node pkcs8_asn, - gnutls_datum_t enc = { NULL, 0 }; - uint8_t *key = NULL; - gnutls_datum_t dkey, d_iv; -- cipher_hd_st ch; -- int ch_init = 0; -+ gnutls_cipher_hd_t ch = NULL; - int key_size, ret; - unsigned int pass_len = 0; - const struct pkcs_cipher_schema_st *p; -@@ -1237,8 +1236,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, asn1_node pkcs8_asn, - d_iv.data = (uint8_t *) enc_params->iv; - d_iv.size = enc_params->iv_size; - -- ret = -- _gnutls_cipher_init(&ch, ce, &dkey, &d_iv, 0); -+ ret = gnutls_cipher_init(&ch, ce->id, &dkey, &d_iv); - - gnutls_free(key); - -@@ -1247,9 +1245,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, asn1_node pkcs8_asn, - goto error; - } - -- ch_init = 1; -- -- ret = _gnutls_cipher_decrypt(&ch, enc.data, enc.size); -+ ret = gnutls_cipher_decrypt(ch, enc.data, enc.size); - if (ret < 0) { - gnutls_assert(); - ret = GNUTLS_E_DECRYPTION_FAILED; -@@ -1281,7 +1277,7 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, asn1_node pkcs8_asn, - decrypted_data->size = enc.size; - } - -- _gnutls_cipher_deinit(&ch); -+ gnutls_cipher_deinit(ch); - - ret = 0; - -@@ -1294,8 +1290,9 @@ _gnutls_pkcs_raw_decrypt_data(schema_id schema, asn1_node pkcs8_asn, - gnutls_free(password); - gnutls_free(enc.data); - gnutls_free(key); -- if (ch_init != 0) -- _gnutls_cipher_deinit(&ch); -+ if (ch) { -+ gnutls_cipher_deinit(ch); -+ } - return ret; - } - -@@ -1725,8 +1722,7 @@ _gnutls_pkcs_raw_encrypt_data(const gnutls_datum_t * plain, - int data_size; - uint8_t *data = NULL; - gnutls_datum_t d_iv; -- cipher_hd_st ch; -- int ch_init = 0; -+ gnutls_cipher_hd_t ch = NULL; - uint8_t pad, pad_size; - const cipher_entry_st *ce; - -@@ -1756,18 +1752,13 @@ _gnutls_pkcs_raw_encrypt_data(const gnutls_datum_t * plain, - - d_iv.data = (uint8_t *) enc_params->iv; - d_iv.size = enc_params->iv_size; -- result = -- _gnutls_cipher_init(&ch, cipher_to_entry(enc_params->cipher), -- key, &d_iv, 1); -- -+ result = gnutls_cipher_init(&ch, enc_params->cipher, key, &d_iv); - if (result < 0) { - gnutls_assert(); - goto error; - } - -- ch_init = 1; -- -- result = _gnutls_cipher_encrypt(&ch, data, data_size); -+ result = gnutls_cipher_encrypt(ch, data, data_size); - if (result < 0) { - gnutls_assert(); - goto error; -@@ -1776,13 +1767,14 @@ _gnutls_pkcs_raw_encrypt_data(const gnutls_datum_t * plain, - encrypted->data = data; - encrypted->size = data_size; - -- _gnutls_cipher_deinit(&ch); -+ gnutls_cipher_deinit(ch); - - return 0; - - error: - gnutls_free(data); -- if (ch_init != 0) -- _gnutls_cipher_deinit(&ch); -+ if (ch) { -+ gnutls_cipher_deinit(ch); -+ } - return result; - } -diff --git a/tests/pkcs12_encode.c b/tests/pkcs12_encode.c -index b8f7d17267..78f6f41b48 100644 ---- a/tests/pkcs12_encode.c -+++ b/tests/pkcs12_encode.c -@@ -104,9 +104,17 @@ void doit(void) - int ret, indx; - char outbuf[10240]; - size_t size; -- unsigned tests, i; -+ unsigned i; - gnutls_fips140_context_t fips_context; - gnutls_fips140_operation_state_t fips_state; -+ size_t n_tests = 0; -+ struct tests { -+ const char *name; -+ gnutls_x509_crt_t crt; -+ const char *friendly_name; -+ unsigned bag_encrypt_flags; -+ int bag_encrypt_expected; -+ } tests[2]; - - ret = global_init(); - if (ret < 0) { -@@ -157,21 +165,34 @@ void doit(void) - exit(1); - } - -- /* Generate and add PKCS#12 cert bags. */ -- if (!gnutls_fips140_mode_enabled()) { -- tests = 2; /* include RC2 */ -+ tests[n_tests].name = "3DES"; -+ tests[n_tests].crt = client; -+ tests[n_tests].friendly_name = "client"; -+ tests[n_tests].bag_encrypt_flags = GNUTLS_PKCS8_USE_PKCS12_3DES; -+ tests[n_tests].bag_encrypt_expected = 0; -+ n_tests++; -+ -+ tests[n_tests].name = "RC2-40"; -+ tests[n_tests].crt = ca; -+ tests[n_tests].friendly_name = "ca"; -+ tests[n_tests].bag_encrypt_flags = GNUTLS_PKCS_USE_PKCS12_RC2_40; -+ if (gnutls_fips140_mode_enabled()) { -+ tests[n_tests].bag_encrypt_expected = -+ GNUTLS_E_UNWANTED_ALGORITHM; - } else { -- tests = 1; -+ tests[n_tests].bag_encrypt_expected = 0; - } -+ n_tests++; - -- for (i = 0; i < tests; i++) { -+ /* Generate and add PKCS#12 cert bags. */ -+ for (i = 0; i < n_tests; i++) { - ret = gnutls_pkcs12_bag_init(&bag); - if (ret < 0) { - fprintf(stderr, "bag_init: %s (%d)\n", gnutls_strerror(ret), ret); - exit(1); - } - -- ret = gnutls_pkcs12_bag_set_crt(bag, i == 0 ? client : ca); -+ ret = gnutls_pkcs12_bag_set_crt(bag, tests[i].crt); - if (ret < 0) { - fprintf(stderr, "set_crt: %s (%d)\n", gnutls_strerror(ret), ret); - exit(1); -@@ -180,16 +201,14 @@ void doit(void) - indx = ret; - - ret = gnutls_pkcs12_bag_set_friendly_name(bag, indx, -- i == -- 0 ? "client" : -- "ca"); -+ tests[i].friendly_name); - if (ret < 0) { - fprintf(stderr, "set_friendly_name: %s (%d)\n", gnutls_strerror(ret), ret); - exit(1); - } - - size = sizeof(key_id_buf); -- ret = gnutls_x509_crt_get_key_id(i == 0 ? client : ca, 0, -+ ret = gnutls_x509_crt_get_key_id(tests[i].crt, 0, - key_id_buf, &size); - if (ret < 0) { - fprintf(stderr, "get_key_id: %s (%d)\n", gnutls_strerror(ret), ret); -@@ -206,14 +225,11 @@ void doit(void) - } - - ret = gnutls_pkcs12_bag_encrypt(bag, "pass", -- i == -- 0 ? -- GNUTLS_PKCS8_USE_PKCS12_3DES -- : -- GNUTLS_PKCS_USE_PKCS12_RC2_40); -- if (ret < 0) { -- fprintf(stderr, "bag_encrypt: %d: %s", ret, -- i == 0 ? "3DES" : "RC2-40"); -+ tests[i].bag_encrypt_flags); -+ if (ret != tests[i].bag_encrypt_expected) { -+ fprintf(stderr, "bag_encrypt: returned %d, expected %d: %s", ret, -+ tests[i].bag_encrypt_expected, -+ tests[i].name); - exit(1); - } - --- -2.34.1 - diff --git a/SOURCES/gnutls-3.7.3-fips-rsa-keygen.patch b/SOURCES/gnutls-3.7.3-fips-rsa-keygen.patch deleted file mode 100644 index f99ddc1..0000000 --- a/SOURCES/gnutls-3.7.3-fips-rsa-keygen.patch +++ /dev/null @@ -1,182 +0,0 @@ -From 9f5a60c1fe576f82bcd5c7998b2ca2b0d60e8e4f Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Thu, 27 Jan 2022 18:17:43 +0100 -Subject: [PATCH 1/2] rsa_generate_fips186_4_keypair: accept a few more modulus - sizes - -While _rsa_generate_fips186_4_keypair was modified to accept modulus -sizes other than 2048 and 3076, rsa_generate_fips186_4_keypair, which -calls that function, was not updated to accept such modulus sizes. - -Spotted by Alexander Sosedkin. - -Signed-off-by: Daiki Ueno ---- - lib/nettle/int/rsa-keygen-fips186.c | 67 ++++++++++++++++------------- - 1 file changed, 36 insertions(+), 31 deletions(-) - -diff --git a/lib/nettle/int/rsa-keygen-fips186.c b/lib/nettle/int/rsa-keygen-fips186.c -index 5b221a030a..c6f7e675af 100644 ---- a/lib/nettle/int/rsa-keygen-fips186.c -+++ b/lib/nettle/int/rsa-keygen-fips186.c -@@ -27,6 +27,7 @@ - #include "config.h" - #endif - -+#include - #include - #include - #include -@@ -248,6 +249,33 @@ cleanup: - return ret; - } - -+/* Return the pre-defined seed length for modulus size, or 0 when the -+ * modulus size is unsupported. -+ */ -+static inline unsigned -+seed_length_for_modulus_size(unsigned modulus_size) -+{ -+ switch (modulus_size) { -+ case 2048: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */ -+ return 14 * 2; -+ case 3072: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */ -+ return 16 * 2; -+ case 4096: /* SP 800-56B rev 2 Appendix D */ -+ return 19 * 2; -+ case 6144: /* SP 800-56B rev 2 Appendix D */ -+ return 22 * 2; -+ case 7680: /* FIPS 140-2 IG 7.5 */ -+ return 24 * 2; -+ case 8192: /* SP 800-56B rev 2 Appendix D */ -+ return 25 * 2; -+ case 15360: /* FIPS 140-2 IG 7.5 */ -+ return 32 * 2; -+ default: -+ return 0; -+ } -+ -+} -+ - /* This generates p,q params using the B.3.2.2 algorithm in FIPS 186-4. - * - * The hash function used is SHA384. -@@ -266,33 +294,15 @@ _rsa_generate_fips186_4_keypair(struct rsa_public_key *pub, - int ret; - struct dss_params_validation_seeds cert; - unsigned l = n_size / 2; -+ unsigned s = seed_length_for_modulus_size(n_size); - -- switch (n_size) { -- case 2048: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */ -- FIPS_RULE(seed_length != 14 * 2, 0, "seed length other than 28 bytes\n"); -- break; -- case 3072: /* SP 800-56B rev 2 Appendix D and FIPS 140-2 IG 7.5 */ -- FIPS_RULE(seed_length != 16 * 2, 0, "seed length other than 32 bytes\n"); -- break; -- case 4096: /* SP 800-56B rev 2 Appendix D */ -- FIPS_RULE(seed_length != 19 * 2, 0, "seed length other than 38 bytes\n"); -- break; -- case 6144: /* SP 800-56B rev 2 Appendix D */ -- FIPS_RULE(seed_length != 22 * 2, 0, "seed length other than 44 bytes\n"); -- break; -- case 7680: /* FIPS 140-2 IG 7.5 */ -- FIPS_RULE(seed_length != 24 * 2, 0, "seed length other than 48 bytes\n"); -- break; -- case 8192: /* SP 800-56B rev 2 Appendix D */ -- FIPS_RULE(seed_length != 25 * 2, 0, "seed length other than 50 bytes\n"); -- break; -- case 15360: /* FIPS 140-2 IG 7.5 */ -- FIPS_RULE(seed_length != 32 * 2, 0, "seed length other than 64 bytes\n"); -- break; -- default: -+ if (!s) { - FIPS_RULE(false, 0, "unsupported modulus size\n"); - } - -+ FIPS_RULE(seed_length != s, 0, -+ "seed length other than %u bytes\n", s); -+ - if (!mpz_tstbit(pub->e, 0)) { - _gnutls_debug_log("Unacceptable e (it is even)\n"); - return 0; -@@ -405,10 +415,6 @@ _rsa_generate_fips186_4_keypair(struct rsa_public_key *pub, - return ret; - } - --/* Not entirely accurate but a good precision -- */ --#define SEED_LENGTH(bits) (_gnutls_pk_bits_to_subgroup_bits(bits)/8) -- - /* This generates p,q params using the B.3.2.2 algorithm in FIPS 186-4. - * - * The hash function used is SHA384. -@@ -429,11 +435,10 @@ rsa_generate_fips186_4_keypair(struct rsa_public_key *pub, - unsigned seed_length; - int ret; - -- FIPS_RULE(n_size != 2048 && n_size != 3072, 0, "size of prime of other than 2048 or 3072\n"); -+ seed_length = seed_length_for_modulus_size(n_size); -+ FIPS_RULE(!seed_length, 0, "unsupported modulus size\n"); - -- seed_length = SEED_LENGTH(n_size); -- if (seed_length > sizeof(seed)) -- return 0; -+ assert(seed_length <= sizeof(seed)); - - random(random_ctx, seed_length, seed); - --- -2.34.1 - - -From 46ae6160489151034bca19aa6c40ba0df6b53bcc Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Tue, 1 Feb 2022 15:19:52 +0100 -Subject: [PATCH 2/2] certtool --generate-privkey: update warnings on RSA key - sizes - -Signed-off-by: Daiki Ueno ---- - src/certtool.c | 18 +++++++++++++++--- - 1 file changed, 15 insertions(+), 3 deletions(-) - -diff --git a/src/certtool.c b/src/certtool.c -index c128500614..71d4aff13e 100644 ---- a/src/certtool.c -+++ b/src/certtool.c -@@ -206,8 +206,12 @@ generate_private_key_int(common_info_st * cinfo) - "Note that DSA keys with size over 1024 may cause incompatibility problems when used with earlier than TLS 1.2 versions.\n\n"); - - if ((HAVE_OPT(SEED) || provable) && GNUTLS_PK_IS_RSA(key_type)) { -- if (bits != 2048 && bits != 3072) { -- fprintf(stderr, "Note that the FIPS 186-4 key generation restricts keys to 2048 and 3072 bits\n"); -+ /* Keep in sync with seed_length_for_modulus_size in -+ * lib/nettle/int/rsa-keygen-fips186.c. */ -+ if (bits != 2048 && bits != 3072 && bits != 4096 && -+ bits != 6144 && bits != 7680 && bits != 8192 && -+ bits != 15360) { -+ fprintf(stderr, "Note that the FIPS 186-4 key generation restricts keys to be of known lengths (2048, 3072, etc)\n"); - } - } - -@@ -225,7 +229,15 @@ generate_private_key_int(common_info_st * cinfo) - kdata[kdata_size++].size = cinfo->seed_size; - - if (GNUTLS_PK_IS_RSA(key_type)) { -- if ((bits == 3072 && cinfo->seed_size != 32) || (bits == 2048 && cinfo->seed_size != 28)) { -+ /* Keep in sync with seed_length_for_modulus_size in -+ * lib/nettle/int/rsa-keygen-fips186.c. */ -+ if ((bits == 2048 && cinfo->seed_size != 28) || -+ (bits == 3072 && cinfo->seed_size != 32) || -+ (bits == 4096 && cinfo->seed_size != 38) || -+ (bits == 6144 && cinfo->seed_size != 44) || -+ (bits == 7680 && cinfo->seed_size != 48) || -+ (bits == 8192 && cinfo->seed_size != 50) || -+ (bits == 15360 && cinfo->seed_size != 64)) { - fprintf(stderr, "The seed size (%d) doesn't match the size of the request security level; use -d 2 for more information.\n", (int)cinfo->seed_size); - } - } else if (key_type == GNUTLS_PK_DSA) { --- -2.34.1 - diff --git a/SOURCES/gnutls-3.7.3-fix-tests-in-fips.patch b/SOURCES/gnutls-3.7.3-fix-tests-in-fips.patch deleted file mode 100644 index a5c8bee..0000000 --- a/SOURCES/gnutls-3.7.3-fix-tests-in-fips.patch +++ /dev/null @@ -1,70 +0,0 @@ -From 2c33761787f6530cf3984310a5f3b7dd05a7b375 Mon Sep 17 00:00:00 2001 -From: Zoltan Fridrich -Date: Thu, 17 Feb 2022 11:46:29 +0100 -Subject: [PATCH] Disable some tests in fips mode - -Signed-off-by: Zoltan Fridrich ---- - tests/pkcs11/pkcs11-eddsa-privkey-test.c | 5 +++++ - tests/pkcs11/tls-neg-pkcs11-key.c | 8 +++++++- - 2 files changed, 12 insertions(+), 1 deletion(-) - -diff --git a/tests/pkcs11/pkcs11-eddsa-privkey-test.c b/tests/pkcs11/pkcs11-eddsa-privkey-test.c -index 44515da3f..ebbfe5278 100644 ---- a/tests/pkcs11/pkcs11-eddsa-privkey-test.c -+++ b/tests/pkcs11/pkcs11-eddsa-privkey-test.c -@@ -107,6 +107,11 @@ void doit(void) - fail("%d: %s\n", ret, gnutls_strerror(ret)); - } - -+ if (gnutls_fips140_mode_enabled()) { -+ gnutls_global_deinit(); -+ return; -+ } -+ - gnutls_pkcs11_set_pin_function(pin_func, NULL); - gnutls_global_set_log_function(tls_log_func); - if (debug) -diff --git a/tests/pkcs11/tls-neg-pkcs11-key.c b/tests/pkcs11/tls-neg-pkcs11-key.c -index fc7c3dc4e..5cc1ae6e2 100644 ---- a/tests/pkcs11/tls-neg-pkcs11-key.c -+++ b/tests/pkcs11/tls-neg-pkcs11-key.c -@@ -268,6 +268,7 @@ typedef struct test_st { - int exp_serv_err; - int needs_eddsa; - int needs_decryption; -+ int nofips; - unsigned requires_pkcs11_pss; - } test_st; - -@@ -340,6 +341,7 @@ static const test_st tests[] = { - .cert = &server_ca3_eddsa_cert, - .key = &server_ca3_eddsa_key, - .exp_kx = GNUTLS_KX_ECDHE_RSA, -+ .nofips = 1 - }, - {.name = "tls1.3: ecc key", - .pk = GNUTLS_PK_ECDSA, -@@ -392,7 +394,8 @@ static const test_st tests[] = { - .prio = "NORMAL:+ECDHE-RSA:+ECDHE-ECDSA", - .cert = &server_ca3_eddsa_cert, - .key = &server_ca3_eddsa_key, -- .exp_kx = GNUTLS_KX_ECDHE_RSA -+ .exp_kx = GNUTLS_KX_ECDHE_RSA, -+ .nofips = 1 - } - }; - -@@ -448,6 +451,9 @@ void doit(void) - have_eddsa = verify_eddsa_presence(); - - for (i=0;i -Date: Mon, 21 Feb 2022 16:28:49 +0100 -Subject: [PATCH] priority: compile out GOST algorithms IDs if they are - disabled - -When compiled with --disable-gost, gnutls-cli --priority NORMAL --list -still prints GOST algorithms for ciphers, MACs, and signatures. This -change adds compile time checks to suppress them. - -Signed-off-by: Daiki Ueno ---- - lib/priority.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/lib/priority.c b/lib/priority.c -index 54d7b1bb45..0c7ac65d7b 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -309,7 +309,9 @@ static const int _kx_priority_secure[] = { - static const int* kx_priority_secure = _kx_priority_secure; - - static const int _kx_priority_gost[] = { -+#ifdef ENABLE_GOST - GNUTLS_KX_VKO_GOST_12, -+#endif - 0, - }; - static const int* kx_priority_gost = _kx_priority_gost; -@@ -507,9 +509,10 @@ static const int _sign_priority_secure192[] = { - static const int* sign_priority_secure192 = _sign_priority_secure192; - - static const int _sign_priority_gost[] = { -+#ifdef ENABLE_GOST - GNUTLS_SIGN_GOST_256, - GNUTLS_SIGN_GOST_512, -- -+#endif - 0 - }; - static const int* sign_priority_gost = _sign_priority_gost; -@@ -531,13 +534,17 @@ static const int *cipher_priority_normal = _cipher_priority_normal_default; - static const int *mac_priority_normal = mac_priority_normal_default; - - static const int _cipher_priority_gost[] = { -+#ifdef ENABLE_GOST - GNUTLS_CIPHER_GOST28147_TC26Z_CNT, -+#endif - 0 - }; - static const int *cipher_priority_gost = _cipher_priority_gost; - - static const int _mac_priority_gost[] = { -+#ifdef ENABLE_GOST - GNUTLS_MAC_GOST28147_TC26Z_IMIT, -+#endif - 0 - }; - static const int *mac_priority_gost = _mac_priority_gost; --- -2.34.1 - -From f2bb30f68922d72f8bed29cc8b2a065087a0969f Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Tue, 22 Feb 2022 17:09:46 +0100 -Subject: [PATCH] algorithms: ensure _list() exclude non-existing algorithms - -This aligns the behavior of _list() function for sign/pk to the one -for cipher/mac: the former previously returned all the algorithms -defined, while the latter returns only algorithms compiled in. - -Signed-off-by: Daiki Ueno ---- - lib/algorithms/publickey.c | 8 +++- - lib/algorithms/sign.c | 4 +- - lib/crypto-backend.h | 2 + - lib/nettle/pk.c | 86 ++++++++++++++++++++++++++++++++++++++ - lib/pk.h | 2 + - 5 files changed, 99 insertions(+), 3 deletions(-) - -diff --git a/lib/algorithms/publickey.c b/lib/algorithms/publickey.c -index b4cd6b1df0..caf53972ab 100644 ---- a/lib/algorithms/publickey.c -+++ b/lib/algorithms/publickey.c -@@ -24,6 +24,7 @@ - #include - #include "errors.h" - #include -+#include "pk.h" - - - /* KX mappings to PK algorithms */ -@@ -203,8 +204,11 @@ const gnutls_pk_algorithm_t *gnutls_pk_list(void) - int i = 0; - - GNUTLS_PK_LOOP( -- if (p->id != GNUTLS_PK_UNKNOWN && supported_pks[i > 0 ? (i - 1) : 0] != p->id) -- supported_pks[i++] = p->id -+ if (p->id != GNUTLS_PK_UNKNOWN && -+ supported_pks[i > 0 ? (i - 1) : 0] != p->id && -+ _gnutls_pk_exists(p->id)) { -+ supported_pks[i++] = p->id; -+ } - ); - supported_pks[i++] = 0; - } -diff --git a/lib/algorithms/sign.c b/lib/algorithms/sign.c -index 06abdb4cf8..4a5aaa75e1 100644 ---- a/lib/algorithms/sign.c -+++ b/lib/algorithms/sign.c -@@ -27,6 +27,7 @@ - #include - #include - #include "c-strcase.h" -+#include "pk.h" - - /* signature algorithms; - */ -@@ -631,7 +632,8 @@ const gnutls_sign_algorithm_t *gnutls_sign_list(void) - - GNUTLS_SIGN_LOOP( - /* list all algorithms, but not duplicates */ -- if (supported_sign[i] != p->id) { -+ if (supported_sign[i] != p->id && -+ _gnutls_pk_sign_exists(p->id)) { - assert(i+1 < MAX_ALGOS); - supported_sign[i++] = p->id; - supported_sign[i+1] = 0; -diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h -index 9874033221..f0f68c337e 100644 ---- a/lib/crypto-backend.h -+++ b/lib/crypto-backend.h -@@ -418,6 +418,8 @@ typedef struct gnutls_crypto_pk { - unsigned int flags); - - int (*curve_exists) (gnutls_ecc_curve_t); /* true/false */ -+ int (*pk_exists) (gnutls_pk_algorithm_t); /* true/false */ -+ int (*sign_exists) (gnutls_sign_algorithm_t); /* true/false */ - } gnutls_crypto_pk_st; - - /* priority: infinity for backend algorithms, 90 for kernel -diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c -index a146568266..eba246f0b3 100644 ---- a/lib/nettle/pk.c -+++ b/lib/nettle/pk.c -@@ -1883,6 +1883,90 @@ static int _wrap_nettle_pk_curve_exists(gnutls_ecc_curve_t curve) - } - } - -+static int _wrap_nettle_pk_exists(gnutls_pk_algorithm_t pk) -+{ -+ switch (pk) { -+ case GNUTLS_PK_RSA: -+ case GNUTLS_PK_DSA: -+ case GNUTLS_PK_DH: -+ case GNUTLS_PK_ECDSA: -+ case GNUTLS_PK_ECDH_X25519: -+ case GNUTLS_PK_RSA_PSS: -+ case GNUTLS_PK_EDDSA_ED25519: -+#if ENABLE_GOST -+ case GNUTLS_PK_GOST_01: -+ case GNUTLS_PK_GOST_12_256: -+ case GNUTLS_PK_GOST_12_512: -+#endif -+ case GNUTLS_PK_ECDH_X448: -+ case GNUTLS_PK_EDDSA_ED448: -+ return 1; -+ default: -+ return 0; -+ } -+} -+ -+static int _wrap_nettle_pk_sign_exists(gnutls_sign_algorithm_t sign) -+{ -+ switch (sign) { -+ case GNUTLS_SIGN_RSA_SHA1: -+ case GNUTLS_SIGN_DSA_SHA1: -+ case GNUTLS_SIGN_RSA_MD5: -+ case GNUTLS_SIGN_RSA_MD2: -+ case GNUTLS_SIGN_RSA_RMD160: -+ case GNUTLS_SIGN_RSA_SHA256: -+ case GNUTLS_SIGN_RSA_SHA384: -+ case GNUTLS_SIGN_RSA_SHA512: -+ case GNUTLS_SIGN_RSA_SHA224: -+ case GNUTLS_SIGN_DSA_SHA224: -+ case GNUTLS_SIGN_DSA_SHA256: -+ case GNUTLS_SIGN_ECDSA_SHA1: -+ case GNUTLS_SIGN_ECDSA_SHA224: -+ case GNUTLS_SIGN_ECDSA_SHA256: -+ case GNUTLS_SIGN_ECDSA_SHA384: -+ case GNUTLS_SIGN_ECDSA_SHA512: -+ case GNUTLS_SIGN_DSA_SHA384: -+ case GNUTLS_SIGN_DSA_SHA512: -+ case GNUTLS_SIGN_ECDSA_SHA3_224: -+ case GNUTLS_SIGN_ECDSA_SHA3_256: -+ case GNUTLS_SIGN_ECDSA_SHA3_384: -+ case GNUTLS_SIGN_ECDSA_SHA3_512: -+ -+ case GNUTLS_SIGN_DSA_SHA3_224: -+ case GNUTLS_SIGN_DSA_SHA3_256: -+ case GNUTLS_SIGN_DSA_SHA3_384: -+ case GNUTLS_SIGN_DSA_SHA3_512: -+ case GNUTLS_SIGN_RSA_SHA3_224: -+ case GNUTLS_SIGN_RSA_SHA3_256: -+ case GNUTLS_SIGN_RSA_SHA3_384: -+ case GNUTLS_SIGN_RSA_SHA3_512: -+ -+ case GNUTLS_SIGN_RSA_PSS_SHA256: -+ case GNUTLS_SIGN_RSA_PSS_SHA384: -+ case GNUTLS_SIGN_RSA_PSS_SHA512: -+ case GNUTLS_SIGN_EDDSA_ED25519: -+ case GNUTLS_SIGN_RSA_RAW: -+ -+ case GNUTLS_SIGN_ECDSA_SECP256R1_SHA256: -+ case GNUTLS_SIGN_ECDSA_SECP384R1_SHA384: -+ case GNUTLS_SIGN_ECDSA_SECP521R1_SHA512: -+ -+ case GNUTLS_SIGN_RSA_PSS_RSAE_SHA256: -+ case GNUTLS_SIGN_RSA_PSS_RSAE_SHA384: -+ case GNUTLS_SIGN_RSA_PSS_RSAE_SHA512: -+ -+#if ENABLE_GOST -+ case GNUTLS_SIGN_GOST_94: -+ case GNUTLS_SIGN_GOST_256: -+ case GNUTLS_SIGN_GOST_512: -+#endif -+ case GNUTLS_SIGN_EDDSA_ED448: -+ return 1; -+ default: -+ return 0; -+ } -+} -+ - /* Generates algorithm's parameters. That is: - * For DSA: p, q, and g are generated. - * For RSA: nothing -@@ -3872,4 +3956,6 @@ gnutls_crypto_pk_st _gnutls_pk_ops = { - .pk_fixup_private_params = wrap_nettle_pk_fixup, - .derive = _wrap_nettle_pk_derive, - .curve_exists = _wrap_nettle_pk_curve_exists, -+ .pk_exists = _wrap_nettle_pk_exists, -+ .sign_exists = _wrap_nettle_pk_sign_exists - }; -diff --git a/lib/pk.h b/lib/pk.h -index cc61e08cef..7f3c9995da 100644 ---- a/lib/pk.h -+++ b/lib/pk.h -@@ -40,6 +40,8 @@ extern gnutls_crypto_pk_st _gnutls_pk_ops; - #define _gnutls_pk_generate_params( algo, bits, priv) _gnutls_pk_ops.generate_params( algo, bits, priv) - #define _gnutls_pk_hash_algorithm( pk, sig, params, hash) _gnutls_pk_ops.hash_algorithm(pk, sig, params, hash) - #define _gnutls_pk_curve_exists( curve) _gnutls_pk_ops.curve_exists(curve) -+#define _gnutls_pk_exists(algo) _gnutls_pk_ops.pk_exists(algo) -+#define _gnutls_pk_sign_exists(algo) _gnutls_pk_ops.sign_exists(algo) - - inline static int - _gnutls_pk_fixup(gnutls_pk_algorithm_t algo, gnutls_direction_t direction, --- -2.34.1 - diff --git a/SOURCES/gnutls-3.7.3-ktls-stub.patch b/SOURCES/gnutls-3.7.3-ktls-stub.patch deleted file mode 100644 index 4d3dace..0000000 --- a/SOURCES/gnutls-3.7.3-ktls-stub.patch +++ /dev/null @@ -1,33 +0,0 @@ -From a97a93e23483aafc3508adee8e6399a2302e0fbc Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Tue, 15 Feb 2022 17:38:20 +0100 -Subject: [PATCH] gnutls_transport_is_ktls_enabled: fix return value of stub - -Signed-off-by: Daiki Ueno ---- - lib/system/ktls.c | 7 +++---- - 1 file changed, 3 insertions(+), 4 deletions(-) - -diff --git a/lib/system/ktls.c b/lib/system/ktls.c -index 7e3cb875ed..f156f08ab2 100644 ---- a/lib/system/ktls.c -+++ b/lib/system/ktls.c -@@ -422,12 +422,11 @@ int _gnutls_ktls_recv_int(gnutls_session_t session, content_type_t type, - - #else //ENABLE_KTLS - gnutls_transport_ktls_enable_flags_t --gnutls_transport_is_ktls_enabled(gnutls_session_t session){ -- return gnutls_assert_val(GNUTLS_E_UNIMPLEMENTED_FEATURE); -+gnutls_transport_is_ktls_enabled(gnutls_session_t session) { -+ return 0; - } - --void _gnutls_ktls_enable(gnutls_session_t session){ -- return; -+void _gnutls_ktls_enable(gnutls_session_t session) { - } - - int _gnutls_ktls_set_keys(gnutls_session_t session) { --- -2.34.1 - diff --git a/SOURCES/gnutls-3.7.3-libtss2-dlopen.patch b/SOURCES/gnutls-3.7.3-libtss2-dlopen.patch deleted file mode 100644 index b4cf45b..0000000 --- a/SOURCES/gnutls-3.7.3-libtss2-dlopen.patch +++ /dev/null @@ -1,719 +0,0 @@ -From f5e5ab910b8b1d69f962ca033d1295c3e1e1e131 Mon Sep 17 00:00:00 2001 -From: Daiki Ueno -Date: Wed, 23 Feb 2022 19:48:52 +0100 -Subject: [PATCH] tpm2: dynamically load tss2 libraries as needed - -libtss2-esys links to OpenSSL or mbed TLS for cryptography, which may -cause packaging issues. This instead dlopen's tss2 libraries as -needed so non-TPM applications continue working without loading -multiple crypto libraries. - -Signed-off-by: Daiki Ueno ---- - configure.ac | 11 +- - lib/Makefile.am | 6 +- - lib/tpm2.c | 2 +- - lib/tpm2.h | 2 +- - lib/tpm2_esys.c | 273 ++++++++++++++++++++++++++++++++++++-------- - tests/Makefile.am | 3 +- - tests/sanity-lib.sh | 40 +++++++ - tests/tpm2.sh | 14 ++- - 8 files changed, 296 insertions(+), 55 deletions(-) - create mode 100644 tests/sanity-lib.sh - -diff --git a/configure.ac b/configure.ac -index 53c3aefca1..721ff208f0 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -882,6 +882,8 @@ AM_CONDITIONAL(P11KIT_0_23_11_API, $PKG_CONFIG --atleast-version=0.23.11 p11-kit - - AM_CONDITIONAL(ENABLE_PKCS11, test "$with_p11_kit" != "no") - -+need_ltlibdl=no -+ - AC_ARG_WITH(tpm2, - AS_HELP_STRING([--without-tpm2], - [Disable TPM2 support.]), -@@ -892,6 +894,7 @@ if test "$with_tpm2" != "no"; then - if test "$have_tpm2" = "yes"; then - tss2lib="tss2-esys tss2-mu tss2-tctildr" - AC_DEFINE([HAVE_TSS2], 1, [Have TSS2]) -+ need_ltlibdl=yes - elif test "$with_tpm2" = "yes"; then - AC_MSG_ERROR([[ - *** -@@ -920,7 +923,8 @@ if test "$with_tpm" != "no"; then - AC_SUBST([TSS_LIBS], [-ltspi]) - AC_SUBST([TSS_CFLAGS], []) - AC_DEFINE([HAVE_TROUSERS], 1, [Enable TPM]) -- with_tpm=yes], -+ with_tpm=yes, -+ need_ltlibdl=yes], - [AC_MSG_RESULT(no) - AC_MSG_WARN([[ - *** -@@ -957,6 +961,9 @@ fi - AC_DEFINE_UNQUOTED([TROUSERS_LIB], ["$ac_trousers_lib"], [the location of the trousers library]) - AC_SUBST(TROUSERS_LIB) - -+ -+AM_CONDITIONAL(NEED_LTLIBDL, test "$need_ltlibdl" = yes) -+ - # For minitasn1. - AC_CHECK_SIZEOF(unsigned long int, 4) - AC_CHECK_SIZEOF(unsigned int, 4) -@@ -1312,7 +1319,7 @@ AC_MSG_NOTICE([External hardware support: - Random gen. variant: $rnd_variant - PKCS#11 support: $with_p11_kit - TPM support: $with_tpm -- TPM2 support: $have_tpm2 -+ TPM2 support: $with_tpm2 - KTLS support: $enable_ktls - ]) - -diff --git a/lib/Makefile.am b/lib/Makefile.am -index 35df35ee8d..e61ee1b6ae 100644 ---- a/lib/Makefile.am -+++ b/lib/Makefile.am -@@ -44,7 +44,7 @@ AM_CPPFLAGS = \ - -I$(srcdir)/x509 \ - $(LIBTASN1_CFLAGS) \ - $(P11_KIT_CFLAGS) \ -- $(TPM2_CFLAGS) -+ $(TSS2_CFLAGS) - - if !HAVE_LIBUNISTRING - SUBDIRS += unistring -@@ -156,7 +156,7 @@ libgnutls_la_LIBADD = ../gl/libgnu.la x509/libgnutls_x509.la \ - auth/libgnutls_auth.la algorithms/libgnutls_alg.la \ - extras/libgnutls_extras.la - thirdparty_libadd = $(LTLIBZ) $(LTLIBINTL) $(LIBSOCKET) $(LTLIBNSL) \ -- $(P11_KIT_LIBS) $(LIB_SELECT) $(TSS2_LIBS) $(GNUTLS_LIBS_PRIVATE) -+ $(P11_KIT_LIBS) $(LIB_SELECT) $(GNUTLS_LIBS_PRIVATE) - - if HAVE_LIBIDN2 - thirdparty_libadd += $(LIBIDN2_LIBS) -@@ -203,7 +203,7 @@ all-local: $(hmac_files) - CLEANFILES = $(hmac_files) - endif - --if ENABLE_TROUSERS -+if NEED_LTLIBDL - thirdparty_libadd += $(LTLIBDL) - endif - -diff --git a/lib/tpm2.c b/lib/tpm2.c -index 076cc7f407..750eadc777 100644 ---- a/lib/tpm2.c -+++ b/lib/tpm2.c -@@ -297,5 +297,5 @@ int _gnutls_load_tpm2_key(gnutls_privkey_t pkey, const gnutls_datum_t *fdata) - - void _gnutls_tpm2_deinit(void) - { -- tpm2_tcti_deinit(); -+ tpm2_esys_deinit(); - } -diff --git a/lib/tpm2.h b/lib/tpm2.h -index e40dc01df7..7966e2d811 100644 ---- a/lib/tpm2.h -+++ b/lib/tpm2.h -@@ -37,7 +37,7 @@ struct tpm2_info_st; - - struct tpm2_info_st *tpm2_info_init(struct pin_info_st *pin); - --void tpm2_tcti_deinit(void); -+void tpm2_esys_deinit(void); - - void release_tpm2_ctx(struct tpm2_info_st *info); - -diff --git a/lib/tpm2_esys.c b/lib/tpm2_esys.c -index 93e54413ba..4000c1b76e 100644 ---- a/lib/tpm2_esys.c -+++ b/lib/tpm2_esys.c -@@ -72,6 +72,170 @@ - #include - #include - -+#include -+ -+/* We don't want to link to libtss2-esys, as it brings in other -+ * crypto libraries. Instead, only dlopen it as needed. -+ */ -+ -+static void *_gnutls_tss2_esys_dlhandle; -+static void *_gnutls_tss2_mu_dlhandle; -+static void *_gnutls_tss2_tctildr_dlhandle; -+ -+static TSS2_RC -+(*_gnutls_tss2_Esys_GetCapability)(ESYS_CONTEXT *esysContext, -+ ESYS_TR shandle1, -+ ESYS_TR shandle2, -+ ESYS_TR shandle3, -+ TPM2_CAP capability, -+ UINT32 property, -+ UINT32 propertyCount, -+ TPMI_YES_NO *moreData, -+ TPMS_CAPABILITY_DATA **capabilityData); -+static void (*_gnutls_tss2_Esys_Free)(void *__ptr); -+static TSS2_RC (*_gnutls_tss2_Esys_TR_SetAuth)(ESYS_CONTEXT *esysContext, -+ ESYS_TR handle, -+ TPM2B_AUTH const *authValue); -+static TSS2_RC -+(*_gnutls_tss2_Esys_CreatePrimary)(ESYS_CONTEXT *esysContext, -+ ESYS_TR primaryHandle, -+ ESYS_TR shandle1, -+ ESYS_TR shandle2, -+ ESYS_TR shandle3, -+ const TPM2B_SENSITIVE_CREATE *inSensitive, -+ const TPM2B_PUBLIC *inPublic, -+ const TPM2B_DATA *outsideInfo, -+ const TPML_PCR_SELECTION *creationPCR, -+ ESYS_TR *objectHandle, -+ TPM2B_PUBLIC **outPublic, -+ TPM2B_CREATION_DATA **creationData, -+ TPM2B_DIGEST **creationHash, -+ TPMT_TK_CREATION **creationTicket); -+static TSS2_RC (*_gnutls_tss2_Esys_Initialize)(ESYS_CONTEXT **esys_context, -+ TSS2_TCTI_CONTEXT *tcti, -+ TSS2_ABI_VERSION *abiVersion); -+static TSS2_RC (*_gnutls_tss2_Esys_Startup)(ESYS_CONTEXT *esysContext, -+ TPM2_SU startupType); -+static TSS2_RC (*_gnutls_tss2_Esys_TR_FromTPMPublic)(ESYS_CONTEXT *esysContext, -+ TPM2_HANDLE tpm_handle, -+ ESYS_TR optionalSession1, -+ ESYS_TR optionalSession2, -+ ESYS_TR optionalSession3, -+ ESYS_TR *object); -+static TSS2_RC (*_gnutls_tss2_Esys_ReadPublic)(ESYS_CONTEXT *esysContext, -+ ESYS_TR objectHandle, -+ ESYS_TR shandle1, -+ ESYS_TR shandle2, -+ ESYS_TR shandle3, -+ TPM2B_PUBLIC **outPublic, -+ TPM2B_NAME **name, -+ TPM2B_NAME **qualifiedName); -+static TSS2_RC (*_gnutls_tss2_Esys_Load)(ESYS_CONTEXT *esysContext, -+ ESYS_TR parentHandle, -+ ESYS_TR shandle1, -+ ESYS_TR shandle2, -+ ESYS_TR shandle3, -+ const TPM2B_PRIVATE *inPrivate, -+ const TPM2B_PUBLIC *inPublic, -+ ESYS_TR *objectHandle); -+static TSS2_RC (*_gnutls_tss2_Esys_FlushContext)(ESYS_CONTEXT *esysContext, -+ ESYS_TR flushHandle); -+static void (*_gnutls_tss2_Esys_Finalize)(ESYS_CONTEXT **context); -+static TSS2_RC -+(*_gnutls_tss2_Esys_RSA_Decrypt)(ESYS_CONTEXT *esysContext, -+ ESYS_TR keyHandle, -+ ESYS_TR shandle1, -+ ESYS_TR shandle2, -+ ESYS_TR shandle3, -+ const TPM2B_PUBLIC_KEY_RSA *cipherText, -+ const TPMT_RSA_DECRYPT *inScheme, -+ const TPM2B_DATA *label, -+ TPM2B_PUBLIC_KEY_RSA **message); -+static TSS2_RC (*_gnutls_tss2_Esys_Sign)(ESYS_CONTEXT *esysContext, -+ ESYS_TR keyHandle, -+ ESYS_TR shandle1, -+ ESYS_TR shandle2, -+ ESYS_TR shandle3, -+ const TPM2B_DIGEST *digest, -+ const TPMT_SIG_SCHEME *inScheme, -+ const TPMT_TK_HASHCHECK *validation, -+ TPMT_SIGNATURE **signature); -+ -+static TSS2_RC -+(*_gnutls_tss2_Tss2_MU_TPM2B_PRIVATE_Unmarshal)(uint8_t const buffer[], -+ size_t buffer_size, -+ size_t *offset, -+ TPM2B_PRIVATE *dest); -+static TSS2_RC -+(*_gnutls_tss2_Tss2_MU_TPM2B_PUBLIC_Unmarshal)(uint8_t const buffer[], -+ size_t buffer_size, -+ size_t *offset, -+ TPM2B_PUBLIC *dest); -+ -+static TSS2_RC -+(*_gnutls_tss2_Tss2_TctiLdr_Initialize)(const char *nameConf, -+ TSS2_TCTI_CONTEXT **context); -+static void (*_gnutls_tss2_Tss2_TctiLdr_Finalize)(TSS2_TCTI_CONTEXT **context); -+ -+#define DLSYM_TSS2(sys, sym) \ -+ _gnutls_tss2_##sym = dlsym(_gnutls_tss2_##sys##_dlhandle, #sym); \ -+ if (!_gnutls_tss2_##sym) { \ -+ return -1; \ -+ } -+ -+static int -+init_tss2_funcs(void) -+{ -+ if (!_gnutls_tss2_esys_dlhandle) { -+ _gnutls_tss2_esys_dlhandle = -+ dlopen("libtss2-esys.so.0", RTLD_NOW | RTLD_GLOBAL); -+ if (!_gnutls_tss2_esys_dlhandle) { -+ _gnutls_debug_log("tpm2: unable to dlopen libtss2-esys\n"); -+ return -1; -+ } -+ } -+ -+ DLSYM_TSS2(esys, Esys_GetCapability) -+ DLSYM_TSS2(esys, Esys_Free) -+ DLSYM_TSS2(esys, Esys_TR_SetAuth) -+ DLSYM_TSS2(esys, Esys_CreatePrimary) -+ DLSYM_TSS2(esys, Esys_Initialize) -+ DLSYM_TSS2(esys, Esys_Startup) -+ DLSYM_TSS2(esys, Esys_TR_FromTPMPublic) -+ DLSYM_TSS2(esys, Esys_ReadPublic) -+ DLSYM_TSS2(esys, Esys_Load) -+ DLSYM_TSS2(esys, Esys_FlushContext) -+ DLSYM_TSS2(esys, Esys_Finalize) -+ DLSYM_TSS2(esys, Esys_RSA_Decrypt) -+ DLSYM_TSS2(esys, Esys_Sign) -+ -+ if (!_gnutls_tss2_mu_dlhandle) { -+ _gnutls_tss2_mu_dlhandle = -+ dlopen("libtss2-mu.so.0", RTLD_NOW | RTLD_GLOBAL); -+ if (!_gnutls_tss2_mu_dlhandle) { -+ _gnutls_debug_log("tpm2: unable to dlopen libtss2-mu\n"); -+ return -1; -+ } -+ } -+ -+ DLSYM_TSS2(mu, Tss2_MU_TPM2B_PRIVATE_Unmarshal) -+ DLSYM_TSS2(mu, Tss2_MU_TPM2B_PUBLIC_Unmarshal) -+ -+ if (!_gnutls_tss2_tctildr_dlhandle) { -+ _gnutls_tss2_tctildr_dlhandle = -+ dlopen("libtss2-tctildr.so.0", RTLD_NOW | RTLD_GLOBAL); -+ if (!_gnutls_tss2_tctildr_dlhandle) { -+ _gnutls_debug_log("tpm2: unable to dlopen libtss2-tctildr\n"); -+ return -1; -+ } -+ } -+ -+ DLSYM_TSS2(tctildr, Tss2_TctiLdr_Initialize) -+ DLSYM_TSS2(tctildr, Tss2_TctiLdr_Finalize) -+ -+ return 0; -+} -+ - struct tpm2_info_st { - TPM2B_PUBLIC pub; - TPM2B_PRIVATE priv; -@@ -227,10 +391,10 @@ get_primary_template(ESYS_CONTEXT *ctx) - UINT32 i; - TSS2_RC rc; - -- rc = Esys_GetCapability (ctx, -- ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, -- TPM2_CAP_ALGS, 0, TPM2_MAX_CAP_ALGS, -- NULL, &capability_data); -+ rc = _gnutls_tss2_Esys_GetCapability(ctx, -+ ESYS_TR_NONE, ESYS_TR_NONE, ESYS_TR_NONE, -+ TPM2_CAP_ALGS, 0, TPM2_MAX_CAP_ALGS, -+ NULL, &capability_data); - if (rc) { - _gnutls_debug_log("tpm2: Esys_GetCapability failed: 0x%x\n", rc); - return NULL; -@@ -239,7 +403,7 @@ get_primary_template(ESYS_CONTEXT *ctx) - for (i = 0; i < capability_data->data.algorithms.count; i++) { - if (capability_data->data.algorithms.algProperties[i].alg == - TPM2_ALG_ECC) { -- Esys_Free(capability_data); -+ _gnutls_tss2_Esys_Free(capability_data); - return &primary_template_ecc; - } - } -@@ -247,12 +411,12 @@ get_primary_template(ESYS_CONTEXT *ctx) - for (i = 0; i < capability_data->data.algorithms.count; i++) { - if (capability_data->data.algorithms.algProperties[i].alg == - TPM2_ALG_RSA) { -- Esys_Free(capability_data); -+ _gnutls_tss2_Esys_Free(capability_data); - return &primary_template_rsa; - } - } - -- Esys_Free(capability_data); -+ _gnutls_tss2_Esys_Free(capability_data); - _gnutls_debug_log("tpm2: unable to find primary template\n"); - return NULL; - } -@@ -320,7 +484,7 @@ static int init_tpm2_primary(struct tpm2_info_st *info, - install_tpm_passphrase(&info->ownerauth, pass); - info->need_ownerauth = false; - } -- rc = Esys_TR_SetAuth(ctx, hierarchy, &info->ownerauth); -+ rc = _gnutls_tss2_Esys_TR_SetAuth(ctx, hierarchy, &info->ownerauth); - if (rc) { - _gnutls_debug_log("tpm2: Esys_TR_SetAuth failed: 0x%x\n", rc); - return gnutls_assert_val(GNUTLS_E_TPM_ERROR); -@@ -329,7 +493,7 @@ static int init_tpm2_primary(struct tpm2_info_st *info, - if (!primary_template) { - return gnutls_assert_val(GNUTLS_E_TPM_ERROR); - } -- rc = Esys_CreatePrimary(ctx, hierarchy, -+ rc = _gnutls_tss2_Esys_CreatePrimary(ctx, hierarchy, - ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, - &primary_sensitive, - primary_template, -@@ -359,14 +523,14 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, - - _gnutls_debug_log("tpm2: establishing connection with TPM\n"); - -- rc = Esys_Initialize(ctx, tcti_ctx, NULL); -+ rc = _gnutls_tss2_Esys_Initialize(ctx, tcti_ctx, NULL); - if (rc) { - gnutls_assert(); - _gnutls_debug_log("tpm2: Esys_Initialize failed: 0x%x\n", rc); - goto error; - } - -- rc = Esys_Startup(*ctx, TPM2_SU_CLEAR); -+ rc = _gnutls_tss2_Esys_Startup(*ctx, TPM2_SU_CLEAR); - if (rc == TPM2_RC_INITIALIZE) { - _gnutls_debug_log("tpm2: was already started up thus false positive failing in tpm2tss log\n"); - } else if (rc) { -@@ -381,7 +545,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, - goto error; - } - } else { -- rc = Esys_TR_FromTPMPublic(*ctx, info->parent, -+ rc = _gnutls_tss2_Esys_TR_FromTPMPublic(*ctx, info->parent, - ESYS_TR_NONE, - ESYS_TR_NONE, - ESYS_TR_NONE, -@@ -399,7 +563,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, - if (!info->did_ownerauth && !info->ownerauth.size) { - TPM2B_PUBLIC *pub = NULL; - -- rc = Esys_ReadPublic(*ctx, parent_handle, -+ rc = _gnutls_tss2_Esys_ReadPublic(*ctx, parent_handle, - ESYS_TR_NONE, - ESYS_TR_NONE, - ESYS_TR_NONE, -@@ -408,7 +572,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, - !(pub->publicArea.objectAttributes & TPMA_OBJECT_NODA)) { - info->need_ownerauth = true; - } -- Esys_Free(pub); -+ _gnutls_tss2_Esys_Free(pub); - } - reauth: - if (info->need_ownerauth) { -@@ -420,7 +584,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, - install_tpm_passphrase(&info->ownerauth, pass); - info->need_ownerauth = false; - } -- rc = Esys_TR_SetAuth(*ctx, parent_handle, &info->ownerauth); -+ rc = _gnutls_tss2_Esys_TR_SetAuth(*ctx, parent_handle, &info->ownerauth); - if (rc) { - gnutls_assert(); - _gnutls_debug_log("tpm2: Esys_TR_SetAuth failed: 0x%x\n", -@@ -432,7 +596,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, - _gnutls_debug_log("tpm2: loading TPM2 key blob, parent handle 0x%x\n", - parent_handle); - -- rc = Esys_Load(*ctx, parent_handle, -+ rc = _gnutls_tss2_Esys_Load(*ctx, parent_handle, - ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, - &info->priv, &info->pub, - key_handle); -@@ -450,7 +614,7 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, - info->did_ownerauth = true; - - if (parent_is_generated(info->parent)) { -- rc = Esys_FlushContext(*ctx, parent_handle); -+ rc = _gnutls_tss2_Esys_FlushContext(*ctx, parent_handle); - if (rc) { - _gnutls_debug_log("tpm2: Esys_FlushContext for generated primary failed: 0x%x\n", - rc); -@@ -461,14 +625,14 @@ static int init_tpm2_key(ESYS_CONTEXT **ctx, ESYS_TR *key_handle, - return 0; - error: - if (parent_is_generated(info->parent) && parent_handle != ESYS_TR_NONE) { -- Esys_FlushContext(*ctx, parent_handle); -+ _gnutls_tss2_Esys_FlushContext(*ctx, parent_handle); - } - if (*key_handle != ESYS_TR_NONE) { -- Esys_FlushContext(*ctx, *key_handle); -+ _gnutls_tss2_Esys_FlushContext(*ctx, *key_handle); - } - *key_handle = ESYS_TR_NONE; - -- Esys_Finalize(ctx); -+ _gnutls_tss2_Esys_Finalize(ctx); - return GNUTLS_E_TPM_ERROR; - } - -@@ -488,7 +652,7 @@ auth_tpm2_key(struct tpm2_info_st *info, ESYS_CONTEXT *ctx, ESYS_TR key_handle) - info->need_userauth = false; - } - -- rc = Esys_TR_SetAuth(ctx, key_handle, &info->userauth); -+ rc = _gnutls_tss2_Esys_TR_SetAuth(ctx, key_handle, &info->userauth); - if (rc) { - _gnutls_debug_log("tpm2: Esys_TR_SetAuth failed: 0x%x\n", rc); - return gnutls_assert_val(GNUTLS_E_TPM_ERROR); -@@ -574,7 +738,7 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, - goto out; - } - -- rc = Esys_RSA_Decrypt(ectx, key_handle, -+ rc = _gnutls_tss2_Esys_RSA_Decrypt(ectx, key_handle, - ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, - &digest, &in_scheme, &label, &tsig); - if (rc_is_key_auth_failed(rc)) { -@@ -591,14 +755,14 @@ int tpm2_rsa_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, - - ret = _gnutls_set_datum(sig, tsig->buffer, tsig->size); - out: -- Esys_Free(tsig); -+ _gnutls_tss2_Esys_Free(tsig); - - if (key_handle != ESYS_TR_NONE) { -- Esys_FlushContext(ectx, key_handle); -+ _gnutls_tss2_Esys_FlushContext(ectx, key_handle); - } - - if (ectx) { -- Esys_Finalize(&ectx); -+ _gnutls_tss2_Esys_Finalize(&ectx); - } - - return ret; -@@ -661,7 +825,7 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, - goto out; - } - -- rc = Esys_Sign(ectx, key_handle, -+ rc = _gnutls_tss2_Esys_Sign(ectx, key_handle, - ESYS_TR_PASSWORD, ESYS_TR_NONE, ESYS_TR_NONE, - &digest, &in_scheme, &validation, - &tsig); -@@ -682,31 +846,23 @@ int tpm2_ec_sign_hash_fn(gnutls_privkey_t key, gnutls_sign_algorithm_t algo, - - ret = gnutls_encode_rs_value(sig, &sig_r, &sig_s); - out: -- Esys_Free(tsig); -+ _gnutls_tss2_Esys_Free(tsig); - - if (key_handle != ESYS_TR_NONE) { -- Esys_FlushContext(ectx, key_handle); -+ _gnutls_tss2_Esys_FlushContext(ectx, key_handle); - } - - if (ectx) { -- Esys_Finalize(&ectx); -+ _gnutls_tss2_Esys_Finalize(&ectx); - } - - return ret; - } - --GNUTLS_ONCE(tcti_once); -- --void --tpm2_tcti_deinit(void) --{ -- if (tcti_ctx) { -- Tss2_TctiLdr_Finalize(&tcti_ctx); -- } --} -+GNUTLS_ONCE(tpm2_esys_once); - - static void --tcti_once_init(void) -+tpm2_esys_once_init(void) - { - const char *tcti; - const char * const tcti_vars[] = { -@@ -718,6 +874,11 @@ tcti_once_init(void) - size_t i; - TSS2_RC rc; - -+ if (init_tss2_funcs() < 0) { -+ _gnutls_debug_log("tpm2: unable to initialize TSS2 functions\n"); -+ return; -+ } -+ - for (i = 0; i < sizeof(tcti_vars) / sizeof(tcti_vars[0]); i++) { - tcti = secure_getenv(tcti_vars[i]); - if (tcti && *tcti != '\0') { -@@ -727,7 +888,7 @@ tcti_once_init(void) - } - } - if (tcti && *tcti != '\0') { -- rc = Tss2_TctiLdr_Initialize(tcti, &tcti_ctx); -+ rc = _gnutls_tss2_Tss2_TctiLdr_Initialize(tcti, &tcti_ctx); - if (rc) { - _gnutls_debug_log("tpm2: TSS2_TctiLdr_Initialize failed: 0x%x\n", - rc); -@@ -735,13 +896,35 @@ tcti_once_init(void) - } - } - -+/* called by the global destructor through _gnutls_tpm2_deinit */ -+void -+tpm2_esys_deinit(void) -+{ -+ if (tcti_ctx) { -+ _gnutls_tss2_Tss2_TctiLdr_Finalize(&tcti_ctx); -+ tcti_ctx = NULL; -+ } -+ if (_gnutls_tss2_esys_dlhandle) { -+ dlclose(_gnutls_tss2_esys_dlhandle); -+ _gnutls_tss2_esys_dlhandle = NULL; -+ } -+ if (_gnutls_tss2_mu_dlhandle) { -+ dlclose(_gnutls_tss2_mu_dlhandle); -+ _gnutls_tss2_mu_dlhandle = NULL; -+ } -+ if (_gnutls_tss2_tctildr_dlhandle) { -+ dlclose(_gnutls_tss2_tctildr_dlhandle); -+ _gnutls_tss2_tctildr_dlhandle = NULL; -+ } -+} -+ - int install_tpm2_key(struct tpm2_info_st *info, gnutls_privkey_t pkey, - unsigned int parent, bool emptyauth, - gnutls_datum_t *privdata, gnutls_datum_t *pubdata) - { - TSS2_RC rc; - -- (void)gnutls_once(&tcti_once, tcti_once_init); -+ (void)gnutls_once(&tpm2_esys_once, tpm2_esys_once_init); - - if (!tcti_ctx) { - return gnutls_assert_val(GNUTLS_E_TPM_ERROR); -@@ -757,16 +940,16 @@ int install_tpm2_key(struct tpm2_info_st *info, gnutls_privkey_t pkey, - - info->parent = parent; - -- rc = Tss2_MU_TPM2B_PRIVATE_Unmarshal(privdata->data, privdata->size, NULL, -- &info->priv); -+ rc = _gnutls_tss2_Tss2_MU_TPM2B_PRIVATE_Unmarshal(privdata->data, privdata->size, NULL, -+ &info->priv); - if (rc) { - _gnutls_debug_log("tpm2: failed to import private key data: 0x%x\n", - rc); - return gnutls_assert_val(GNUTLS_E_TPM_ERROR); - } - -- rc = Tss2_MU_TPM2B_PUBLIC_Unmarshal(pubdata->data, pubdata->size, NULL, -- &info->pub); -+ rc = _gnutls_tss2_Tss2_MU_TPM2B_PUBLIC_Unmarshal(pubdata->data, pubdata->size, NULL, -+ &info->pub); - if (rc) { - _gnutls_debug_log("tpm2: failed to import public key data: 0x%x\n", - rc); -diff --git a/tests/Makefile.am b/tests/Makefile.am -index 529f1cc077..64ce470a02 100644 ---- a/tests/Makefile.am -+++ b/tests/Makefile.am -@@ -515,7 +515,8 @@ dist_check_SCRIPTS += fastopen.sh pkgconfig.sh starttls.sh starttls-ftp.sh start - psktool.sh ocsp-tests/ocsp-load-chain.sh gnutls-cli-save-data.sh gnutls-cli-debug.sh \ - sni-resume.sh ocsp-tests/ocsptool.sh cert-reencoding.sh pkcs7-cat.sh long-crl.sh \ - serv-udp.sh logfile-option.sh gnutls-cli-resume.sh profile-tests.sh \ -- server-weak-keys.sh ocsp-tests/ocsp-signer-verify.sh cfg-test.sh -+ server-weak-keys.sh ocsp-tests/ocsp-signer-verify.sh cfg-test.sh \ -+ sanity-lib.sh - - if !DISABLE_SYSTEM_CONFIG - dist_check_SCRIPTS += system-override-sig.sh system-override-hash.sh \ -diff --git a/tests/sanity-lib.sh b/tests/sanity-lib.sh -new file mode 100644 -index 0000000000..1e3612781b ---- /dev/null -+++ b/tests/sanity-lib.sh -@@ -0,0 +1,40 @@ -+#!/bin/sh -+ -+# Copyright (C) 2022 Red Hat, Inc. -+# -+# Author: Daiki Ueno -+# -+# This file is part of GnuTLS. -+# -+# GnuTLS is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by the -+# Free Software Foundation; either version 3 of the License, or (at -+# your option) any later version. -+# -+# GnuTLS is distributed in the hope that it will be useful, but -+# WITHOUT ANY WARRANTY; without even the implied warranty of -+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+# General Public License for more details. -+# -+# You should have received a copy of the GNU Lesser General Public License -+# along with this program. If not, see -+ -+: ${top_builddir=..} -+: ${CLI_DEBUG=../src/gnutls-cli-debug${EXEEXT}} -+: ${LDD=ldd} -+: ${LIBTOOL=libtool} -+ -+if ! test -x "${CLI_DEBUG}"; then -+ exit 77 -+fi -+ -+# ldd.sh doesn't check recursive dependencies -+${LDD} --version >/dev/null || exit 77 -+ -+# We use gnutls-cli-debug, as it has the fewest dependencies among our -+# commands (e.g., gnutls-cli pulls in OpenSSL through libunbound). -+if ${LIBTOOL} --mode=execute ${LDD} ${CLI_DEBUG} | \ -+ grep '^[[:space:]]*\(libcrypto\.\|libssl\.\|libgcrypt\.\)'; then -+ echo "gnutls-cli-debug links to other crypto library" -+ exit 1 -+fi -diff --git a/tests/tpm2.sh b/tests/tpm2.sh -index 854986c552..6f8e44c64b 100755 ---- a/tests/tpm2.sh -+++ b/tests/tpm2.sh -@@ -21,8 +21,6 @@ - # along with GnuTLS; if not, write to the Free Software Foundation, - # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - --set +e -- - : ${srcdir=.} - : ${CERTTOOL=../src/certtool${EXEEXT}} - KEYPEMFILE=tpmkey.$$.key.pem -@@ -192,6 +190,10 @@ run_tests() - - echo " - Generating ${KEYPEMFILE}" - tpm2tss-genkey -a ${kalg} -o ${OPASS} ${KEYPEMFILE} -+ if [ $? -ne 0 ]; then -+ echo "unable to generate key" -+ return 1 -+ fi - cat ${KEYPEMFILE} - - echo " - Generating certificate based on key" -@@ -200,6 +202,10 @@ run_tests() - "${CERTTOOL}" --generate-self-signed -d 3 \ - --load-privkey "${KEYPEMFILE}" \ - --template "${srcdir}/cert-tests/templates/template-test.tmpl" -+ if [ $? -ne 0 ]; then -+ echo "unable to generate certificate" -+ return 1 -+ fi - - if test "${kalg}" = "rsa";then - echo " - Generating RSA-PSS certificate based on key" -@@ -207,6 +213,10 @@ run_tests() - --load-privkey "${KEYPEMFILE}" \ - --sign-params rsa-pss \ - --template "${srcdir}/cert-tests/templates/template-test.tmpl" -+ if [ $? -ne 0 ]; then -+ echo "unable to generate certificate" -+ return 1 -+ fi - fi - - stop_swtpm --- -2.34.1 - diff --git a/SOURCES/gnutls-3.7.3-max-algos.patch b/SOURCES/gnutls-3.7.3-max-algos.patch deleted file mode 100644 index d283ceb..0000000 --- a/SOURCES/gnutls-3.7.3-max-algos.patch +++ /dev/null @@ -1,44 +0,0 @@ -From b5a2cbce49d94a04a68acbbc31caaa0c5d7b3321 Mon Sep 17 00:00:00 2001 -From: Alexander Sosedkin -Date: Fri, 18 Feb 2022 11:05:15 +0100 -Subject: [PATCH] bump GNUTLS_MAX_ALGORITHM_NUM / MAX_ALGOS - -Fedora 36 LEGACY crypto-policy uses allowlisting format -and is long enough to blow past the 64 priority string -elements mark, causing, effectively, priority string truncation. - -Signed-off-by: Alexander Sosedkin ---- - lib/includes/gnutls/gnutls.h.in | 2 +- - lib/priority.c | 2 +- - 2 files changed, 2 insertions(+), 2 deletions(-) - -diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in -index 6359a0edb6..16140c8787 100644 ---- a/lib/includes/gnutls/gnutls.h.in -+++ b/lib/includes/gnutls/gnutls.h.in -@@ -408,7 +408,7 @@ typedef enum { - /* exported for other gnutls headers. This is the maximum number of - * algorithms (ciphers, kx or macs). - */ --#define GNUTLS_MAX_ALGORITHM_NUM 64 -+#define GNUTLS_MAX_ALGORITHM_NUM 128 - #define GNUTLS_MAX_SESSION_ID_SIZE 32 - - -diff --git a/lib/priority.c b/lib/priority.c -index 54d7b1bb45..e7698ba7eb 100644 ---- a/lib/priority.c -+++ b/lib/priority.c -@@ -43,7 +43,7 @@ - #include "profiles.h" - #include "name_val_array.h" - --#define MAX_ELEMENTS 64 -+#define MAX_ELEMENTS GNUTLS_MAX_ALGORITHM_NUM - - #define ENABLE_PROFILE(c, profile) do { \ - c->additional_verify_flags &= 0x00ffffff; \ --- -2.34.1 - diff --git a/SOURCES/gnutls-3.7.3.tar.xz.sig b/SOURCES/gnutls-3.7.3.tar.xz.sig deleted file mode 100644 index 7555447..0000000 Binary files a/SOURCES/gnutls-3.7.3.tar.xz.sig and /dev/null differ diff --git a/SOURCES/gnutls-3.7.6-aes-gcm-pt-limit.patch b/SOURCES/gnutls-3.7.6-aes-gcm-pt-limit.patch new file mode 100644 index 0000000..dd32866 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-aes-gcm-pt-limit.patch @@ -0,0 +1,720 @@ +From 2f61f102169e4d6652c9b82246353cd276366809 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Mon, 27 Jun 2022 11:14:50 +0900 +Subject: [PATCH] cipher: limit plaintext length supplied to AES-GCM + +According to SP800-38D 5.2.1.1, input data length of AES-GCM +encryption function must be less than or equal to 2^39-256 bits. + +Signed-off-by: Daiki Ueno +--- + NEWS | 3 + + lib/accelerated/aarch64/aes-aarch64.h | 15 ++++ + lib/accelerated/aarch64/aes-gcm-aarch64.c | 9 +++ + lib/accelerated/x86/aes-gcm-padlock.c | 29 ++++--- + lib/accelerated/x86/aes-gcm-x86-aesni.c | 30 +++++--- + lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c | 9 +++ + lib/accelerated/x86/aes-gcm-x86-pclmul.c | 9 +++ + lib/accelerated/x86/aes-gcm-x86-ssse3.c | 30 +++++--- + lib/accelerated/x86/aes-x86.h | 15 ++++ + lib/nettle/cipher.c | 41 ++++++++++ + tests/slow/cipher-api-test.c | 79 ++++++++++++++++++++ + 11 files changed, 240 insertions(+), 29 deletions(-) + +diff --git a/lib/accelerated/aarch64/aes-aarch64.h b/lib/accelerated/aarch64/aes-aarch64.h +index 692d8620d7..0e64f4ed8d 100644 +--- a/lib/accelerated/aarch64/aes-aarch64.h ++++ b/lib/accelerated/aarch64/aes-aarch64.h +@@ -20,6 +20,21 @@ typedef struct { + if (s != 16 && s != 24 && s != 32) \ + return GNUTLS_E_INVALID_REQUEST + ++#include ++#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32) ++static inline int ++record_aes_gcm_encrypt_size(size_t *counter, size_t size) { ++ size_t sum; ++ ++ if (!INT_ADD_OK(*counter, size, &sum) || ++ sum > AES_GCM_ENCRYPT_MAX_BYTES) { ++ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ } ++ *counter = sum; ++ ++ return 0; ++} ++ + int aes_v8_set_encrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); + int aes_v8_set_decrypt_key(const unsigned char *userKey, int bits, AES_KEY *key); + void aes_v8_cbc_encrypt(const unsigned char *in, unsigned char *out, +diff --git a/lib/accelerated/aarch64/aes-gcm-aarch64.c b/lib/accelerated/aarch64/aes-gcm-aarch64.c +index 901bd9f60f..be1e69c784 100644 +--- a/lib/accelerated/aarch64/aes-gcm-aarch64.c ++++ b/lib/accelerated/aarch64/aes-gcm-aarch64.c +@@ -62,6 +62,7 @@ struct aes_gcm_ctx { + struct gcm128_context gcm; + unsigned finished; + unsigned auth_finished; ++ size_t rekey_counter; + }; + + void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]); +@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize) + ctx->gcm.H.u[1] = bswap_64(ctx->gcm.H.u[1]); + + gcm_init_v8(ctx->gcm.Htable, ctx->gcm.H.u); ++ ctx->rekey_counter = 0; + + return 0; + } +@@ -141,6 +143,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size) + ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2; + ctx->finished = 0; + ctx->auth_finished = 0; ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -229,6 +232,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + int exp_blocks = blocks * GCM_BLOCK_SIZE; + int rest = src_size - (exp_blocks); + uint32_t counter; ++ int ret; + + if (unlikely(ctx->finished)) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); +@@ -236,6 +240,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + if (unlikely(length < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + ++ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size); ++ if (ret < 0) { ++ return gnutls_assert_val(ret); ++ } ++ + if (blocks > 0) { + ctr32_encrypt_blocks(src, dst, + blocks, +diff --git a/lib/accelerated/x86/aes-gcm-padlock.c b/lib/accelerated/x86/aes-gcm-padlock.c +index a9c7441d65..739883ab1b 100644 +--- a/lib/accelerated/x86/aes-gcm-padlock.c ++++ b/lib/accelerated/x86/aes-gcm-padlock.c +@@ -43,7 +43,10 @@ + * Actually padlock doesn't include GCM mode. We just use + * the ECB part of padlock and nettle for everything else. + */ +-struct gcm_padlock_aes_ctx GCM_CTX(struct padlock_ctx); ++struct gcm_padlock_aes_ctx { ++ struct GCM_CTX(struct padlock_ctx) inner; ++ size_t rekey_counter; ++}; + + static void padlock_aes_encrypt(const void *_ctx, + size_t length, uint8_t * dst, +@@ -78,7 +81,7 @@ static void padlock_aes256_set_encrypt_key(struct padlock_ctx *_ctx, + + static void aes_gcm_deinit(void *_ctx) + { +- struct padlock_ctx *ctx = _ctx; ++ struct gcm_padlock_aes_ctx *ctx = _ctx; + + zeroize_temp_key(ctx, sizeof(*ctx)); + gnutls_free(ctx); +@@ -108,14 +111,15 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t keysize) + struct gcm_padlock_aes_ctx *ctx = _ctx; + + if (keysize == 16) { +- GCM_SET_KEY(ctx, padlock_aes128_set_encrypt_key, padlock_aes_encrypt, ++ GCM_SET_KEY(&ctx->inner, padlock_aes128_set_encrypt_key, padlock_aes_encrypt, + key); + } else if (keysize == 32) { +- GCM_SET_KEY(ctx, padlock_aes256_set_encrypt_key, padlock_aes_encrypt, ++ GCM_SET_KEY(&ctx->inner, padlock_aes256_set_encrypt_key, padlock_aes_encrypt, + key); + } else + return GNUTLS_E_INVALID_REQUEST; + ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -126,8 +130,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size) + if (iv_size != GCM_BLOCK_SIZE - 4) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + +- GCM_SET_IV(ctx, iv_size, iv); ++ GCM_SET_IV(&ctx->inner, iv_size, iv); + ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -136,11 +141,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + void *dst, size_t length) + { + struct gcm_padlock_aes_ctx *ctx = _ctx; ++ int ret; + + if (unlikely(length < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + +- GCM_ENCRYPT(ctx, padlock_aes_encrypt, src_size, dst, src); ++ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size); ++ if (ret < 0) { ++ return gnutls_assert_val(ret); ++ } ++ ++ GCM_ENCRYPT(&ctx->inner, padlock_aes_encrypt, src_size, dst, src); + + return 0; + } +@@ -154,7 +165,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size, + if (unlikely(dst_size < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + +- GCM_DECRYPT(ctx, padlock_aes_encrypt, src_size, dst, src); ++ GCM_DECRYPT(&ctx->inner, padlock_aes_encrypt, src_size, dst, src); + return 0; + } + +@@ -162,7 +173,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size) + { + struct gcm_padlock_aes_ctx *ctx = _ctx; + +- GCM_UPDATE(ctx, src_size, src); ++ GCM_UPDATE(&ctx->inner, src_size, src); + + return 0; + } +@@ -171,7 +182,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize) + { + struct gcm_padlock_aes_ctx *ctx = _ctx; + +- GCM_DIGEST(ctx, padlock_aes_encrypt, tagsize, tag); ++ GCM_DIGEST(&ctx->inner, padlock_aes_encrypt, tagsize, tag); + } + + #include "aes-gcm-aead.h" +diff --git a/lib/accelerated/x86/aes-gcm-x86-aesni.c b/lib/accelerated/x86/aes-gcm-x86-aesni.c +index b0edaebfba..3be63ddd97 100644 +--- a/lib/accelerated/x86/aes-gcm-x86-aesni.c ++++ b/lib/accelerated/x86/aes-gcm-x86-aesni.c +@@ -36,12 +36,14 @@ + #include + #include + #include +-#include + + /* GCM mode + * It is used when the CPU doesn't include the PCLMUL instructions. + */ +-struct gcm_x86_aes_ctx GCM_CTX(AES_KEY); ++struct gcm_x86_aes_ctx { ++ struct GCM_CTX(AES_KEY) inner; ++ size_t rekey_counter; ++}; + + static void x86_aes_encrypt(const void *_ctx, + size_t length, uint8_t * dst, +@@ -101,17 +103,18 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t length) + struct gcm_x86_aes_ctx *ctx = _ctx; + + if (length == 16) { +- GCM_SET_KEY(ctx, x86_aes128_set_encrypt_key, x86_aes_encrypt, ++ GCM_SET_KEY(&ctx->inner, x86_aes128_set_encrypt_key, x86_aes_encrypt, + key); + } else if (length == 24) { +- GCM_SET_KEY(ctx, x86_aes192_set_encrypt_key, x86_aes_encrypt, ++ GCM_SET_KEY(&ctx->inner, x86_aes192_set_encrypt_key, x86_aes_encrypt, + key); + } else if (length == 32) { +- GCM_SET_KEY(ctx, x86_aes256_set_encrypt_key, x86_aes_encrypt, ++ GCM_SET_KEY(&ctx->inner, x86_aes256_set_encrypt_key, x86_aes_encrypt, + key); + } else + return GNUTLS_E_INVALID_REQUEST; + ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -122,8 +125,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size) + if (iv_size != GCM_BLOCK_SIZE - 4) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + +- GCM_SET_IV(ctx, iv_size, iv); ++ GCM_SET_IV(&ctx->inner, iv_size, iv); + ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -132,11 +136,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + void *dst, size_t length) + { + struct gcm_x86_aes_ctx *ctx = _ctx; ++ int ret; + + if (unlikely(length < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + +- GCM_ENCRYPT(ctx, x86_aes_encrypt, src_size, dst, src); ++ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size); ++ if (ret < 0) { ++ return gnutls_assert_val(ret); ++ } ++ ++ GCM_ENCRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src); + + return 0; + } +@@ -150,7 +160,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size, + if (unlikely(dst_size < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + +- GCM_DECRYPT(ctx, x86_aes_encrypt, src_size, dst, src); ++ GCM_DECRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src); + return 0; + } + +@@ -158,7 +168,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size) + { + struct gcm_x86_aes_ctx *ctx = _ctx; + +- GCM_UPDATE(ctx, src_size, src); ++ GCM_UPDATE(&ctx->inner, src_size, src); + + return 0; + } +@@ -167,7 +177,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize) + { + struct gcm_x86_aes_ctx *ctx = _ctx; + +- GCM_DIGEST(ctx, x86_aes_encrypt, tagsize, tag); ++ GCM_DIGEST(&ctx->inner, x86_aes_encrypt, tagsize, tag); + } + + static void aes_gcm_deinit(void *_ctx) +diff --git a/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c b/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c +index 21aef94440..fbefe432f4 100644 +--- a/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c ++++ b/lib/accelerated/x86/aes-gcm-x86-pclmul-avx.c +@@ -61,6 +61,7 @@ struct aes_gcm_ctx { + struct gcm128_context gcm; + unsigned finished; + unsigned auth_finished; ++ size_t rekey_counter; + }; + + void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]); +@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize) + + gcm_init_avx(ctx->gcm.Htable, ctx->gcm.H.u); + ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -140,6 +142,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size) + ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2; + ctx->finished = 0; + ctx->auth_finished = 0; ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -184,6 +187,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + int exp_blocks = blocks * GCM_BLOCK_SIZE; + int rest = src_size - (exp_blocks); + uint32_t counter; ++ int ret; + + if (unlikely(ctx->finished)) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); +@@ -191,6 +195,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + if (unlikely(length < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + ++ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size); ++ if (ret < 0) { ++ return gnutls_assert_val(ret); ++ } ++ + if (blocks > 0) { + aesni_ctr32_encrypt_blocks(src, dst, + blocks, +diff --git a/lib/accelerated/x86/aes-gcm-x86-pclmul.c b/lib/accelerated/x86/aes-gcm-x86-pclmul.c +index e6b4990cbf..5385acbb6b 100644 +--- a/lib/accelerated/x86/aes-gcm-x86-pclmul.c ++++ b/lib/accelerated/x86/aes-gcm-x86-pclmul.c +@@ -60,6 +60,7 @@ struct aes_gcm_ctx { + struct gcm128_context gcm; + unsigned finished; + unsigned auth_finished; ++ size_t rekey_counter; + }; + + void gcm_init_clmul(u128 Htable[16], const uint64_t Xi[2]); +@@ -116,6 +117,7 @@ aes_gcm_cipher_setkey(void *_ctx, const void *userkey, size_t keysize) + + gcm_init_clmul(ctx->gcm.Htable, ctx->gcm.H.u); + ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -140,6 +142,7 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size) + ctx->gcm.Yi.c[GCM_BLOCK_SIZE - 1] = 2; + ctx->finished = 0; + ctx->auth_finished = 0; ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -184,6 +187,7 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + int exp_blocks = blocks * GCM_BLOCK_SIZE; + int rest = src_size - (exp_blocks); + uint32_t counter; ++ int ret; + + if (unlikely(ctx->finished)) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); +@@ -191,6 +195,11 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + if (unlikely(length < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + ++ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size); ++ if (ret < 0) { ++ return gnutls_assert_val(ret); ++ } ++ + if (blocks > 0) { + aesni_ctr32_encrypt_blocks(src, dst, + blocks, +diff --git a/lib/accelerated/x86/aes-gcm-x86-ssse3.c b/lib/accelerated/x86/aes-gcm-x86-ssse3.c +index 7a2ac50869..f074cb1096 100644 +--- a/lib/accelerated/x86/aes-gcm-x86-ssse3.c ++++ b/lib/accelerated/x86/aes-gcm-x86-ssse3.c +@@ -36,13 +36,15 @@ + #include + #include + #include +-#include + #include + + /* GCM mode + * It is used when the CPU doesn't include the PCLMUL instructions. + */ +-struct gcm_x86_aes_ctx GCM_CTX(AES_KEY); ++struct gcm_x86_aes_ctx { ++ struct GCM_CTX(AES_KEY) inner; ++ size_t rekey_counter; ++}; + + static void x86_aes_encrypt(const void *_ctx, + size_t length, uint8_t * dst, +@@ -110,17 +112,18 @@ aes_gcm_cipher_setkey(void *_ctx, const void *key, size_t keysize) + struct gcm_x86_aes_ctx *ctx = _ctx; + + if (keysize == 16) { +- GCM_SET_KEY(ctx, x86_aes_128_set_encrypt_key, x86_aes_encrypt, ++ GCM_SET_KEY(&ctx->inner, x86_aes_128_set_encrypt_key, x86_aes_encrypt, + key); + } else if (keysize == 24) { +- GCM_SET_KEY(ctx, x86_aes_192_set_encrypt_key, x86_aes_encrypt, ++ GCM_SET_KEY(&ctx->inner, x86_aes_192_set_encrypt_key, x86_aes_encrypt, + key); + } else if (keysize == 32) { +- GCM_SET_KEY(ctx, x86_aes_256_set_encrypt_key, x86_aes_encrypt, ++ GCM_SET_KEY(&ctx->inner, x86_aes_256_set_encrypt_key, x86_aes_encrypt, + key); + } else + return GNUTLS_E_INVALID_REQUEST; + ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -131,8 +134,9 @@ static int aes_gcm_setiv(void *_ctx, const void *iv, size_t iv_size) + if (iv_size != GCM_BLOCK_SIZE - 4) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + +- GCM_SET_IV(ctx, iv_size, iv); ++ GCM_SET_IV(&ctx->inner, iv_size, iv); + ++ ctx->rekey_counter = 0; + return 0; + } + +@@ -141,11 +145,17 @@ aes_gcm_encrypt(void *_ctx, const void *src, size_t src_size, + void *dst, size_t length) + { + struct gcm_x86_aes_ctx *ctx = _ctx; ++ int ret; + + if (unlikely(length < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + +- GCM_ENCRYPT(ctx, x86_aes_encrypt, src_size, dst, src); ++ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, src_size); ++ if (ret < 0) { ++ return gnutls_assert_val(ret); ++ } ++ ++ GCM_ENCRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src); + + return 0; + } +@@ -159,7 +169,7 @@ aes_gcm_decrypt(void *_ctx, const void *src, size_t src_size, + if (unlikely(dst_size < src_size)) + return gnutls_assert_val(GNUTLS_E_SHORT_MEMORY_BUFFER); + +- GCM_DECRYPT(ctx, x86_aes_encrypt, src_size, dst, src); ++ GCM_DECRYPT(&ctx->inner, x86_aes_encrypt, src_size, dst, src); + return 0; + } + +@@ -167,7 +177,7 @@ static int aes_gcm_auth(void *_ctx, const void *src, size_t src_size) + { + struct gcm_x86_aes_ctx *ctx = _ctx; + +- GCM_UPDATE(ctx, src_size, src); ++ GCM_UPDATE(&ctx->inner, src_size, src); + + return 0; + } +@@ -176,7 +186,7 @@ static void aes_gcm_tag(void *_ctx, void *tag, size_t tagsize) + { + struct gcm_x86_aes_ctx *ctx = _ctx; + +- GCM_DIGEST(ctx, x86_aes_encrypt, tagsize, tag); ++ GCM_DIGEST(&ctx->inner, x86_aes_encrypt, tagsize, tag); + } + + static void aes_gcm_deinit(void *_ctx) +diff --git a/lib/accelerated/x86/aes-x86.h b/lib/accelerated/x86/aes-x86.h +index 023b5f7be6..349d3d5d9c 100644 +--- a/lib/accelerated/x86/aes-x86.h ++++ b/lib/accelerated/x86/aes-x86.h +@@ -22,6 +22,21 @@ typedef struct { + if (s != 16 && s != 24 && s != 32) \ + return GNUTLS_E_INVALID_REQUEST + ++#include ++#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32) ++static inline int ++record_aes_gcm_encrypt_size(size_t *counter, size_t size) { ++ size_t sum; ++ ++ if (!INT_ADD_OK(*counter, size, &sum) || ++ sum > AES_GCM_ENCRYPT_MAX_BYTES) { ++ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ } ++ *counter = sum; ++ ++ return 0; ++} ++ + void aesni_ecb_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const AES_KEY * key, int enc); + +diff --git a/lib/nettle/cipher.c b/lib/nettle/cipher.c +index ab4c46d2d0..b41862d1ea 100644 +--- a/lib/nettle/cipher.c ++++ b/lib/nettle/cipher.c +@@ -63,6 +63,7 @@ + #include + #include + #include ++#include + + struct nettle_cipher_ctx; + +@@ -120,8 +121,23 @@ struct nettle_cipher_ctx { + unsigned iv_size; + + bool enc; ++ size_t rekey_counter; + }; + ++#define AES_GCM_ENCRYPT_MAX_BYTES ((1ULL << 36) - 32) ++static inline int ++record_aes_gcm_encrypt_size(size_t *counter, size_t size) { ++ size_t sum; ++ ++ if (!INT_ADD_OK(*counter, size, &sum) || ++ sum > AES_GCM_ENCRYPT_MAX_BYTES) { ++ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ } ++ *counter = sum; ++ ++ return 0; ++} ++ + static void + _stream_encrypt(struct nettle_cipher_ctx *ctx, size_t length, uint8_t * dst, + const uint8_t * src) +@@ -1133,6 +1149,16 @@ wrap_nettle_cipher_setkey(void *_ctx, const void *key, size_t keysize) + else + ctx->cipher->set_decrypt_key(ctx->ctx_ptr, key); + ++ switch (ctx->cipher->algo) { ++ case GNUTLS_CIPHER_AES_128_GCM: ++ case GNUTLS_CIPHER_AES_192_GCM: ++ case GNUTLS_CIPHER_AES_256_GCM: ++ ctx->rekey_counter = 0; ++ break; ++ default: ++ break; ++ } ++ + return 0; + } + +@@ -1147,6 +1173,7 @@ wrap_nettle_cipher_setiv(void *_ctx, const void *iv, size_t iv_size) + case GNUTLS_CIPHER_AES_192_GCM: + case GNUTLS_CIPHER_AES_256_GCM: + FIPS_RULE(iv_size < GCM_IV_SIZE, GNUTLS_E_INVALID_REQUEST, "access to short GCM nonce size\n"); ++ ctx->rekey_counter = 0; + break; + case GNUTLS_CIPHER_SALSA20_256: + case GNUTLS_CIPHER_ESTREAM_SALSA20_256: +@@ -1207,10 +1234,24 @@ wrap_nettle_cipher_encrypt(void *_ctx, const void *plain, size_t plain_size, + void *encr, size_t encr_size) + { + struct nettle_cipher_ctx *ctx = _ctx; ++ int ret; + + if (unlikely(ctx->cipher->encrypt == NULL)) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); + ++ switch (ctx->cipher->algo) { ++ case GNUTLS_CIPHER_AES_128_GCM: ++ case GNUTLS_CIPHER_AES_192_GCM: ++ case GNUTLS_CIPHER_AES_256_GCM: ++ ret = record_aes_gcm_encrypt_size(&ctx->rekey_counter, plain_size); ++ if (ret < 0) { ++ return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ } ++ break; ++ default: ++ break; ++ } ++ + ctx->cipher->encrypt(ctx, plain_size, encr, plain); + + return 0; +diff --git a/tests/slow/cipher-api-test.c b/tests/slow/cipher-api-test.c +index fc880bcc9f..1d267ce312 100644 +--- a/tests/slow/cipher-api-test.c ++++ b/tests/slow/cipher-api-test.c +@@ -21,6 +21,7 @@ + */ + + #include ++#include + #include + #include + #include +@@ -48,6 +49,11 @@ int main(int argc, char **argv) + #include + #include + ++#define AES_GCM_ENCRYPT_PLAINTEXT_MAX ((1ULL << 36) - 32) ++#if SIZE_MAX >= AES_GCM_ENCRYPT_PLAINTEXT_MAX ++#define TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE 1 ++#endif ++ + static void tls_log_func(int level, const char *str) + { + fprintf(stderr, "<%d>| %s", level, str); +@@ -401,6 +407,74 @@ static void test_aead_invalid_short_decrypt(int algo) + return; + } + ++#ifdef TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE ++/* Test whether an invalid call to gnutls_cipher_encrypt() with too ++ * long message is caught */ ++static void test_aead_invalid_too_long_encrypt(int algo) ++{ ++ int ret; ++ gnutls_cipher_hd_t ch; ++ uint8_t key16[64]; ++ uint8_t iv16[32]; ++ uint8_t data[128]; ++ gnutls_datum_t key, iv; ++ ++ if (algo != GNUTLS_CIPHER_AES_128_GCM && ++ algo != GNUTLS_CIPHER_AES_192_GCM && ++ algo != GNUTLS_CIPHER_AES_256_GCM) { ++ return; ++ } ++ ++ key.data = key16; ++ key.size = gnutls_cipher_get_key_size(algo); ++ assert(key.size <= sizeof(key16)); ++ ++ iv.data = iv16; ++ iv.size = gnutls_cipher_get_iv_size(algo); ++ assert(iv.size <= sizeof(iv16)); ++ ++ memset(iv.data, 0xff, iv.size); ++ memset(key.data, 0xfe, key.size); ++ memset(data, 0xfa, sizeof(data)); ++ ++ gnutls_global_set_log_function(tls_log_func); ++ if (debug) ++ gnutls_global_set_log_level(4711); ++ ++ ret = global_init(); ++ if (ret < 0) { ++ fail("Cannot initialize library\n"); /*errcode 1 */ ++ } ++ ++ ret = gnutls_cipher_init(&ch, algo, &key, &iv); ++ if (ret < 0) ++ fail("gnutls_cipher_init failed\n"); /*errcode 1 */ ++ ++ /* Test exceeding AES-GCM plaintext limit */ ++ ret = gnutls_cipher_encrypt(ch, data, sizeof(data)); ++ if (ret < 0) ++ fail("could not encrypt data\n"); ++ ++ /* A few blocks larger than AES_GCM_ENCRYPT_PLAINTEXT_MAX combined with ++ * the previous call. Use NULL for PLAINTEXT so the access to the first ++ * block always results in page fault (in case the limit is not ++ * enforced). ++ */ ++ ret = gnutls_cipher_encrypt(ch, NULL, AES_GCM_ENCRYPT_PLAINTEXT_MAX); ++ if (ret >= 0) ++ fail("succeeded in encrypting too long data\n"); ++ if (ret != GNUTLS_E_INVALID_REQUEST) ++ fail("wrong kind of error on encrypting too long data," ++ "%s instead of GNUTLS_E_INVALID_REQUEST\n", ++ gnutls_strerror_name(ret)); ++ ++ gnutls_cipher_deinit(ch); ++ ++ gnutls_global_deinit(); ++ return; ++} ++#endif ++ + static void check_status(int status) + { + if (WEXITSTATUS(status) != 0 || +@@ -464,6 +538,11 @@ void start(const char *name, int algo, unsigned aead) + + success("trying %s: test_aead_invalid_short_decrypt\n", name); + fork_subtest(test_aead_invalid_short_decrypt, algo); ++ ++#if TEST_AES_GCM_ENCRYPT_PLAINTEXT_SIZE ++ success("trying %s: test_aead_invalid_too_long_encrypt\n", name); ++ fork_subtest(test_aead_invalid_too_long_encrypt, algo); ++#endif + } + } + +-- +2.37.1 + diff --git a/SOURCES/gnutls-3.7.6-cpuid-fixes.patch b/SOURCES/gnutls-3.7.6-cpuid-fixes.patch new file mode 100644 index 0000000..a77c84d --- /dev/null +++ b/SOURCES/gnutls-3.7.6-cpuid-fixes.patch @@ -0,0 +1,119 @@ +From 8ff391fa011e02c88b0d099061ca62e88ab68011 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Mon, 15 Aug 2022 09:39:18 +0900 +Subject: [PATCH] accelerated: clear AVX bits if it cannot be queried through + XSAVE +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +The algorithm to detect AVX is described in 14.3 of "Intel® 64 and IA-32 +Architectures Software Developer’s Manual". + +GnuTLS previously only followed that algorithm when registering the +crypto backend, while the CRYPTOGAMS derived SHA code assembly expects +that the extension bits are propagated to _gnutls_x86_cpuid_s. + +Signed-off-by: Daiki Ueno +--- + lib/accelerated/x86/x86-common.c | 49 +++++++++++++++++++++++++------- + 1 file changed, 38 insertions(+), 11 deletions(-) + +diff --git a/lib/accelerated/x86/x86-common.c b/lib/accelerated/x86/x86-common.c +index 7ddaa594e6..b7a88ddeca 100644 +--- a/lib/accelerated/x86/x86-common.c ++++ b/lib/accelerated/x86/x86-common.c +@@ -81,6 +81,26 @@ unsigned int _gnutls_x86_cpuid_s[4]; + # define bit_AVX 0x10000000 + #endif + ++#ifndef bit_AVX2 ++# define bit_AVX2 0x00000020 ++#endif ++ ++#ifndef bit_AVX512F ++# define bit_AVX512F 0x00010000 ++#endif ++ ++#ifndef bit_AVX512IFMA ++# define bit_AVX512IFMA 0x00200000 ++#endif ++ ++#ifndef bit_AVX512BW ++# define bit_AVX512BW 0x40000000 ++#endif ++ ++#ifndef bit_AVX512VL ++# define bit_AVX512VL 0x80000000 ++#endif ++ + #ifndef bit_OSXSAVE + # define bit_OSXSAVE 0x8000000 + #endif +@@ -89,10 +109,6 @@ unsigned int _gnutls_x86_cpuid_s[4]; + # define bit_MOVBE 0x00400000 + #endif + +-#ifndef OSXSAVE_MASK +-# define OSXSAVE_MASK (bit_OSXSAVE|bit_MOVBE) +-#endif +- + #define bit_PADLOCK (0x3 << 6) + #define bit_PADLOCK_PHE (0x3 << 10) + #define bit_PADLOCK_PHE_SHA512 (0x3 << 25) +@@ -148,7 +164,7 @@ static unsigned check_4th_gen_intel_features(unsigned ecx) + { + uint32_t xcr0; + +- if ((ecx & OSXSAVE_MASK) != OSXSAVE_MASK) ++ if ((ecx & bit_OSXSAVE) != bit_OSXSAVE) + return 0; + + #if defined(_MSC_VER) && !defined(__clang__) +@@ -190,8 +206,9 @@ static void capabilities_to_intel_cpuid(unsigned capabilities) + } + + if (capabilities & INTEL_AVX) { +- if ((a[1] & bit_AVX) && check_4th_gen_intel_features(a[1])) { +- _gnutls_x86_cpuid_s[1] |= bit_AVX|OSXSAVE_MASK; ++ if ((a[1] & bit_AVX) && (a[1] & bit_MOVBE) && ++ check_4th_gen_intel_features(a[1])) { ++ _gnutls_x86_cpuid_s[1] |= bit_AVX|bit_MOVBE; + } else { + _gnutls_debug_log + ("AVX acceleration requested but not available\n"); +@@ -236,10 +253,7 @@ static unsigned check_sha(void) + #ifdef ASM_X86_64 + static unsigned check_avx_movbe(void) + { +- if (check_4th_gen_intel_features(_gnutls_x86_cpuid_s[1]) == 0) +- return 0; +- +- return ((_gnutls_x86_cpuid_s[1] & bit_AVX)); ++ return (_gnutls_x86_cpuid_s[1] & (bit_AVX|bit_MOVBE)) == (bit_AVX|bit_MOVBE); + } + + static unsigned check_pclmul(void) +@@ -884,6 +898,19 @@ void register_x86_intel_crypto(unsigned capabilities) + if (capabilities == 0) { + if (!read_cpuid_vals(_gnutls_x86_cpuid_s)) + return; ++ if (!check_4th_gen_intel_features(_gnutls_x86_cpuid_s[1])) { ++ _gnutls_x86_cpuid_s[1] &= ~bit_AVX; ++ ++ /* Clear AVX2 bits as well, according to what ++ * OpenSSL does. Should we clear ++ * bit_AVX512DQ, bit_AVX512PF, bit_AVX512ER, ++ * and bit_AVX512CD? */ ++ _gnutls_x86_cpuid_s[2] &= ~(bit_AVX2| ++ bit_AVX512F| ++ bit_AVX512IFMA| ++ bit_AVX512BW| ++ bit_AVX512BW); ++ } + } else { + capabilities_to_intel_cpuid(capabilities); + } +-- +2.37.2 + diff --git a/SOURCES/gnutls-3.7.6-drbg-reseed.patch b/SOURCES/gnutls-3.7.6-drbg-reseed.patch new file mode 100644 index 0000000..8fd5f58 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-drbg-reseed.patch @@ -0,0 +1,41 @@ +From 3035e884b3abc68bcebff5adec5bd8819bbc6d7b Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Fri, 5 Aug 2022 16:16:42 +0900 +Subject: [PATCH] gnutls-3.7.6-drbg-reseed.patch + +Signed-off-by: rpm-build +--- + lib/nettle/sysrng-linux.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/lib/nettle/sysrng-linux.c b/lib/nettle/sysrng-linux.c +index 6b3971c..dae9061 100644 +--- a/lib/nettle/sysrng-linux.c ++++ b/lib/nettle/sysrng-linux.c +@@ -31,6 +31,9 @@ + # include + # include + # include ++# include "fips.h" ++#else ++# define _gnutls_fips_mode_enabled() 0 + #endif + + #include +@@ -103,7 +106,12 @@ static int force_getrandom(void *buf, size_t buflen, unsigned int flags) + static int _rnd_get_system_entropy_getrandom(void* _rnd, size_t size) + { + int ret; +- ret = force_getrandom(_rnd, size, 0); ++ unsigned int flags = 0; ++ ++ if (_gnutls_fips_mode_enabled()) { ++ flags |= 2/*GRND_RANDOM*/; ++ } ++ ret = force_getrandom(_rnd, size, flags); + if (ret == -1) { + int e = errno; + gnutls_assert(); +-- +2.37.1 + diff --git a/SOURCES/gnutls-3.7.6-fips-ecdsa-hash-check.patch b/SOURCES/gnutls-3.7.6-fips-ecdsa-hash-check.patch new file mode 100644 index 0000000..9280bb3 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-fips-ecdsa-hash-check.patch @@ -0,0 +1,427 @@ +From 171b934a8c054e98b110892cae4130e1db64e656 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Thu, 29 Sep 2022 21:28:19 +0900 +Subject: [PATCH] gnutls-3.7.6-fips-ecdsa-hash-check.patch + +--- + lib/crypto-backend.h | 12 ++-- + lib/nettle/pk.c | 33 +++++----- + lib/privkey.c | 42 ++++++++---- + lib/pubkey.c | 5 +- + tests/fips-test.c | 150 ++++++++++++++++++++++++++++++++++++++++++- + 5 files changed, 205 insertions(+), 37 deletions(-) + +diff --git a/lib/crypto-backend.h b/lib/crypto-backend.h +index f0f68c3..4dd1ae2 100644 +--- a/lib/crypto-backend.h ++++ b/lib/crypto-backend.h +@@ -247,11 +247,13 @@ typedef enum { + GNUTLS_PK_FLAG_RSA_PSS_FIXED_SALT_LENGTH = 4 + } gnutls_pk_flag_t; + +-#define FIX_SIGN_PARAMS(params, flags, dig) do { \ +- if ((flags) & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE) { \ +- (params).flags |= GNUTLS_PK_FLAG_REPRODUCIBLE; \ +- (params).dsa_dig = (dig); \ +- } \ ++#define FIX_SIGN_PARAMS(params, flags, dig) do { \ ++ if ((flags) & GNUTLS_PRIVKEY_FLAG_REPRODUCIBLE) { \ ++ (params).flags |= GNUTLS_PK_FLAG_REPRODUCIBLE; \ ++ } \ ++ if ((params).pk == GNUTLS_PK_DSA || (params).pk == GNUTLS_PK_ECDSA) { \ ++ (params).dsa_dig = (dig); \ ++ } \ + } while (0) + + void gnutls_pk_params_release(gnutls_pk_params_st * p); +diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c +index f38016b..c098e2a 100644 +--- a/lib/nettle/pk.c ++++ b/lib/nettle/pk.c +@@ -1104,8 +1104,16 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, + me = _gnutls_dsa_q_to_hash(pk_params, + &hash_len); + ++ if (hash_len > vdata->size) { ++ gnutls_assert(); ++ _gnutls_debug_log ++ ("Security level of algorithm requires hash %s(%d) or better\n", ++ _gnutls_mac_get_name(me), hash_len); ++ hash_len = vdata->size; ++ } ++ + /* Only SHA-2 is allowed in FIPS 140-3 */ +- switch (me->id) { ++ switch (DIG_TO_MAC(sign_params->dsa_dig)) { + case GNUTLS_MAC_SHA256: + case GNUTLS_MAC_SHA384: + case GNUTLS_MAC_SHA512: +@@ -1115,14 +1123,6 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, + not_approved = true; + } + +- if (hash_len > vdata->size) { +- gnutls_assert(); +- _gnutls_debug_log +- ("Security level of algorithm requires hash %s(%d) or better\n", +- _gnutls_mac_get_name(me), hash_len); +- hash_len = vdata->size; +- } +- + mpz_init(k); + if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST || + (sign_params->flags & GNUTLS_PK_FLAG_REPRODUCIBLE)) { +@@ -1545,7 +1545,6 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, + struct dsa_signature sig; + int curve_id = pk_params->curve; + const struct ecc_curve *curve; +- const mac_entry_st *me; + + curve = get_supported_nist_curve(curve_id); + if (curve == NULL) { +@@ -1571,11 +1570,14 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, + memcpy(sig.r, tmp[0], SIZEOF_MPZT); + memcpy(sig.s, tmp[1], SIZEOF_MPZT); + +- me = _gnutls_dsa_q_to_hash(pk_params, &hash_len); ++ (void)_gnutls_dsa_q_to_hash(pk_params, &hash_len); ++ ++ if (hash_len > vdata->size) ++ hash_len = vdata->size; + + /* SHA-1 is allowed for SigVer in FIPS 140-3 in legacy + * mode */ +- switch (me->id) { ++ switch (DIG_TO_MAC(sign_params->dsa_dig)) { + case GNUTLS_MAC_SHA1: + case GNUTLS_MAC_SHA256: + case GNUTLS_MAC_SHA384: +@@ -1586,9 +1588,6 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, + not_approved = true; + } + +- if (hash_len > vdata->size) +- hash_len = vdata->size; +- + ret = + ecdsa_verify(&pub, hash_len, vdata->data, + &sig); +@@ -2390,8 +2389,10 @@ static int pct_test(gnutls_pk_algorithm_t algo, const gnutls_pk_params_st* param + + if (algo == GNUTLS_PK_DSA || algo == GNUTLS_PK_EC) { + unsigned hash_len; ++ const mac_entry_st *me; + +- _gnutls_dsa_q_to_hash(params, &hash_len); ++ me = _gnutls_dsa_q_to_hash(params, &hash_len); ++ spki.dsa_dig = MAC_TO_DIG(me->id); + gen_data = gnutls_malloc(hash_len); + gnutls_rnd(GNUTLS_RND_NONCE, gen_data, hash_len); + +diff --git a/lib/privkey.c b/lib/privkey.c +index 0b77443..2069fc0 100644 +--- a/lib/privkey.c ++++ b/lib/privkey.c +@@ -1251,27 +1251,36 @@ gnutls_privkey_sign_hash2(gnutls_privkey_t signer, + se = _gnutls_sign_to_entry(GNUTLS_SIGN_RSA_RAW); + } else { + se = _gnutls_sign_to_entry(algo); +- if (unlikely(se == NULL)) +- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); +- ++ if (unlikely(se == NULL)) { ++ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ goto cleanup; ++ } + } + + ret = _gnutls_privkey_get_spki_params(signer, ¶ms); + if (ret < 0) { + gnutls_assert(); +- return ret; ++ goto cleanup; + } + + ret = _gnutls_privkey_update_spki_params(signer, se->pk, se->hash, + flags, ¶ms); + if (ret < 0) { + gnutls_assert(); +- return ret; ++ goto cleanup; + } + + FIX_SIGN_PARAMS(params, flags, se->hash); + +- return privkey_sign_prehashed(signer, se, hash_data, signature, ¶ms); ++ ret = privkey_sign_prehashed(signer, se, hash_data, signature, ¶ms); ++ ++ cleanup: ++ if (ret < 0) { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); ++ } else { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); ++ } ++ return ret; + } + + int +@@ -1366,14 +1375,14 @@ gnutls_privkey_sign_hash(gnutls_privkey_t signer, + ret = _gnutls_privkey_get_spki_params(signer, ¶ms); + if (ret < 0) { + gnutls_assert(); +- return ret; ++ goto cleanup; + } + + ret = _gnutls_privkey_update_spki_params(signer, signer->pk_algorithm, + hash_algo, flags, ¶ms); + if (ret < 0) { + gnutls_assert(); +- return ret; ++ goto cleanup; + } + + /* legacy callers of this API could use a hash algorithm of 0 (unknown) +@@ -1391,13 +1400,22 @@ gnutls_privkey_sign_hash(gnutls_privkey_t signer, + se = _gnutls_pk_to_sign_entry(params.pk, hash_algo); + } + +- if (unlikely(se == NULL)) +- return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ if (unlikely(se == NULL)) { ++ ret = gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); ++ goto cleanup; ++ } + + FIX_SIGN_PARAMS(params, flags, hash_algo); + +- return privkey_sign_prehashed(signer, se, +- hash_data, signature, ¶ms); ++ ret = privkey_sign_prehashed(signer, se, ++ hash_data, signature, ¶ms); ++ cleanup: ++ if (ret < 0) { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); ++ } else { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); ++ } ++ return ret; + } + + static int +diff --git a/lib/pubkey.c b/lib/pubkey.c +index eba1f5b..35126f3 100644 +--- a/lib/pubkey.c ++++ b/lib/pubkey.c +@@ -1985,7 +1985,7 @@ gnutls_pubkey_import_dsa_raw(gnutls_pubkey_t key, + * parameters (if any) with the signature algorithm */ + static + int fixup_spki_params(const gnutls_pk_params_st *key_params, const gnutls_sign_entry_st *se, +- const mac_entry_st *me, gnutls_x509_spki_st *params) ++ const mac_entry_st *me, gnutls_x509_spki_st *params) + { + unsigned bits; + +@@ -2018,6 +2018,9 @@ int fixup_spki_params(const gnutls_pk_params_st *key_params, const gnutls_sign_e + + if (params->rsa_pss_dig != se->hash) + return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR); ++ } else if (params->pk == GNUTLS_PK_DSA || ++ params->pk == GNUTLS_PK_ECDSA) { ++ params->dsa_dig = se->hash; + } + + return 0; +diff --git a/tests/fips-test.c b/tests/fips-test.c +index 788f4ab..ec0f4b4 100644 +--- a/tests/fips-test.c ++++ b/tests/fips-test.c +@@ -80,8 +80,22 @@ static const gnutls_datum_t rsa2342_sha1_sig = { + .size = sizeof(rsa2342_sha1_sig_data), + }; + ++static const uint8_t ecc256_sha1_sig_data[] = { ++ 0x30, 0x45, 0x02, 0x21, 0x00, 0x9a, 0x28, 0xc9, 0xbf, 0xc8, 0x70, 0x4f, ++ 0x27, 0x2d, 0xe1, 0x66, 0xc4, 0xa5, 0xc6, 0xf2, 0xdc, 0x33, 0xb9, 0x41, ++ 0xdf, 0x78, 0x98, 0x8a, 0x22, 0x4d, 0x29, 0x37, 0xa0, 0x0f, 0x6f, 0xd4, ++ 0xed, 0x02, 0x20, 0x0b, 0x15, 0xca, 0x30, 0x09, 0x2d, 0x55, 0x44, 0xb4, ++ 0x1d, 0x3f, 0x48, 0x7a, 0xc3, 0xd1, 0x2a, 0xc1, 0x0e, 0x47, 0xfa, 0xe6, ++ 0xe9, 0x0f, 0x03, 0xe2, 0x01, 0x4e, 0xe4, 0x73, 0x37, 0xa7, 0x90, ++}; ++ ++static const gnutls_datum_t ecc256_sha1_sig = { ++ .data = (unsigned char *)ecc256_sha1_sig_data, ++ .size = sizeof(ecc256_sha1_sig_data), ++}; ++ + static void +-rsa_import_keypair(gnutls_privkey_t *privkey, gnutls_pubkey_t *pubkey, ++import_keypair(gnutls_privkey_t *privkey, gnutls_pubkey_t *pubkey, + const char *filename) + { + const char *srcdir; +@@ -274,6 +288,8 @@ void doit(void) + gnutls_datum_t signature; + unsigned int bits; + uint8_t hmac[64]; ++ uint8_t hash[64]; ++ gnutls_datum_t hashed_data; + uint8_t pbkdf2[64]; + gnutls_datum_t temp_key = { NULL, 0 }; + +@@ -473,7 +489,7 @@ void doit(void) + + /* Import 2432-bit RSA key; not a security function */ + FIPS_PUSH_CONTEXT(); +- rsa_import_keypair(&privkey, &pubkey, "rsa-2432.pem"); ++ import_keypair(&privkey, &pubkey, "rsa-2432.pem"); + FIPS_POP_CONTEXT(INITIAL); + + /* Create a signature with 2432-bit RSA and SHA256; approved */ +@@ -519,7 +535,7 @@ void doit(void) + + /* Import 512-bit RSA key; not a security function */ + FIPS_PUSH_CONTEXT(); +- rsa_import_keypair(&privkey, &pubkey, "rsa-512.pem"); ++ import_keypair(&privkey, &pubkey, "rsa-512.pem"); + FIPS_POP_CONTEXT(INITIAL); + + /* Create a signature with 512-bit RSA and SHA256; not approved */ +@@ -543,6 +559,134 @@ void doit(void) + gnutls_pubkey_deinit(pubkey); + gnutls_privkey_deinit(privkey); + ++ /* Import ECDSA key; not a security function */ ++ FIPS_PUSH_CONTEXT(); ++ import_keypair(&privkey, &pubkey, "ecc256.pem"); ++ FIPS_POP_CONTEXT(INITIAL); ++ ++ /* Create a signature with ECDSA and SHA256; approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data2(privkey, GNUTLS_SIGN_ECDSA_SHA256, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ /* Verify a signature with ECDSA and SHA256; approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA256, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA256 (old API); approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_data failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ /* Create a SHA256 hashed data for 2-pass signature API; not a ++ * crypto operation */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_hash_fast(GNUTLS_DIG_SHA256, data.data, data.size, hash); ++ if (ret < 0) { ++ fail("gnutls_hash_fast failed\n"); ++ } ++ hashed_data.data = hash; ++ hashed_data.size = 32; ++ FIPS_POP_CONTEXT(INITIAL); ++ ++ /* Create a signature with ECDSA and SHA256 (2-pass API); not-approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_hash2(privkey, GNUTLS_SIGN_ECDSA_SHA256, 0, ++ &hashed_data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_hash2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA256 (2-pass old API); not-approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA256, 0, ++ &hashed_data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_hash failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA-1; not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data2(privkey, GNUTLS_SIGN_ECDSA_SHA1, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ ++ /* Verify a signature created with ECDSA and SHA-1; approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_ECDSA_SHA1, ++ GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, &data, ++ &ecc256_sha1_sig); ++ if (ret < 0) { ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA-1 (old API); not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_data failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a SHA1 hashed data for 2-pass signature API; not a ++ * crypto operation */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_hash_fast(GNUTLS_DIG_SHA1, data.data, data.size, hash); ++ if (ret < 0) { ++ fail("gnutls_hash_fast failed\n"); ++ } ++ hashed_data.data = hash; ++ hashed_data.size = 20; ++ FIPS_POP_CONTEXT(INITIAL); ++ ++ /* Create a signature with ECDSA and SHA1 (2-pass API); not-approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_hash2(privkey, GNUTLS_SIGN_ECDSA_SHA1, 0, ++ &hashed_data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_hash2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with ECDSA and SHA1 (2-pass old API); not-approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_hash(privkey, GNUTLS_DIG_SHA1, 0, ++ &hashed_data, &signature); ++ if (ret < 0) { ++ fail("gnutls_privkey_sign_hash failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); ++ ++ gnutls_pubkey_deinit(pubkey); ++ gnutls_privkey_deinit(privkey); ++ + /* Test RND functions */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_rnd(GNUTLS_RND_RANDOM, key16, sizeof(key16)); +-- +2.37.3 + diff --git a/SOURCES/gnutls-3.7.6-fips-pkcs12-des-cbc.patch b/SOURCES/gnutls-3.7.6-fips-pkcs12-des-cbc.patch new file mode 100644 index 0000000..0061ea6 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-fips-pkcs12-des-cbc.patch @@ -0,0 +1,58 @@ +From de09280b2a8314eb98ec9a2b84eebe3eec2f49bd Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Thu, 4 Aug 2022 16:37:51 +0900 +Subject: [PATCH] _gnutls_decrypt_pbes1_des_md5_data: use public crypto API + +This is a follow-up of e7f9267342bc2231149a640163c82b63c86f1dfd. In +the decryption code path with PBES1, algorithm checks for FIPS was not +applied, because it used internal functions that bypass those checks. + +Signed-off-by: Daiki Ueno +--- + lib/x509/privkey_pkcs8_pbes1.c | 10 ++++------ + 1 file changed, 4 insertions(+), 6 deletions(-) + +diff --git a/lib/x509/privkey_pkcs8_pbes1.c b/lib/x509/privkey_pkcs8_pbes1.c +index c296807974..983530e46a 100644 +--- a/lib/x509/privkey_pkcs8_pbes1.c ++++ b/lib/x509/privkey_pkcs8_pbes1.c +@@ -140,7 +140,7 @@ _gnutls_decrypt_pbes1_des_md5_data(const char *password, + { + int result; + gnutls_datum_t dkey, d_iv; +- cipher_hd_st ch; ++ gnutls_cipher_hd_t ch; + uint8_t key[16]; + const unsigned block_size = 8; + +@@ -158,16 +158,14 @@ _gnutls_decrypt_pbes1_des_md5_data(const char *password, + dkey.size = 8; + d_iv.data = &key[8]; + d_iv.size = 8; +- result = +- _gnutls_cipher_init(&ch, cipher_to_entry(GNUTLS_CIPHER_DES_CBC), +- &dkey, &d_iv, 0); ++ result = gnutls_cipher_init(&ch, GNUTLS_CIPHER_DES_CBC, &dkey, &d_iv); + if (result < 0) { + _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); + return gnutls_assert_val(result); + } + _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); + +- result = _gnutls_cipher_decrypt(&ch, encrypted_data->data, encrypted_data->size); ++ result = gnutls_cipher_decrypt(ch, encrypted_data->data, encrypted_data->size); + if (result < 0) { + gnutls_assert(); + goto error; +@@ -184,7 +182,7 @@ _gnutls_decrypt_pbes1_des_md5_data(const char *password, + + result = 0; + error: +- _gnutls_cipher_deinit(&ch); ++ gnutls_cipher_deinit(ch); + + return result; + } +-- +2.37.1 + diff --git a/SOURCES/gnutls-3.7.6-fips-rsa-key-sizes.patch b/SOURCES/gnutls-3.7.6-fips-rsa-key-sizes.patch new file mode 100644 index 0000000..1857591 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-fips-rsa-key-sizes.patch @@ -0,0 +1,476 @@ +From 237695d30c9f716333cfa077554a6e1ae0d2c589 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Sat, 20 Aug 2022 09:52:08 +0900 +Subject: [PATCH] gnutls-3.7.6-fips-rsa-key-sizes.patch + +--- + lib/nettle/pk.c | 54 ++++--- + tests/Makefile.am | 3 +- + tests/fips-rsa-sizes.c | 328 +++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 361 insertions(+), 24 deletions(-) + create mode 100644 tests/fips-rsa-sizes.c + +diff --git a/lib/nettle/pk.c b/lib/nettle/pk.c +index eba246f..f38016b 100644 +--- a/lib/nettle/pk.c ++++ b/lib/nettle/pk.c +@@ -1247,20 +1247,20 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, + + _rsa_params_to_privkey(pk_params, &priv); + +- /* RSA key size should be 2048-bit or larger in FIPS +- * 140-3. In addition to this, only SHA-2 is allowed +- * for SigGen; it is checked in pk_prepare_hash lib/pk.c +- */ +- if (unlikely(priv.size < 256)) { +- not_approved = true; +- } +- + ret = _rsa_params_to_pubkey(pk_params, &pub); + if (ret < 0) { + gnutls_assert(); + goto cleanup; + } + ++ /* RSA modulus size should be 2048-bit or larger in FIPS ++ * 140-3. In addition to this, only SHA-2 is allowed ++ * for SigGen; it is checked in pk_prepare_hash lib/pk.c ++ */ ++ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) { ++ not_approved = true; ++ } ++ + mpz_init(s); + + if (_gnutls_get_lib_state() == LIB_STATE_SELFTEST) +@@ -1298,22 +1298,22 @@ _wrap_nettle_pk_sign(gnutls_pk_algorithm_t algo, + + _rsa_params_to_privkey(pk_params, &priv); + +- /* RSA key size should be 2048-bit or larger in FIPS ++ ret = _rsa_params_to_pubkey(pk_params, &pub); ++ if (ret < 0) { ++ gnutls_assert(); ++ goto cleanup; ++ } ++ ++ /* RSA modulus size should be 2048-bit or larger in FIPS + * 140-3. In addition to this, only SHA-2 is allowed + * for SigGen; however, Nettle only support SHA256, + * SHA384, and SHA512 for RSA-PSS (see + * _rsa_pss_sign_digest_tr in this file for details). + */ +- if (unlikely(priv.size < 256)) { ++ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) { + not_approved = true; + } + +- ret = _rsa_params_to_pubkey(pk_params, &pub); +- if (ret < 0) { +- gnutls_assert(); +- goto cleanup; +- } +- + mpz_init(s); + + ret = +@@ -1643,6 +1643,7 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, + case GNUTLS_PK_RSA: + { + struct rsa_public_key pub; ++ size_t bits; + + ret = _rsa_params_to_pubkey(pk_params, &pub); + if (ret < 0) { +@@ -1650,12 +1651,19 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, + goto cleanup; + } + +- /* RSA key size should be 2048-bit or larger in FIPS +- * 140-3. In addition to this, only SHA-1 and SHA-2 are +- * allowed for SigVer; it is checked in +- * _pkcs1_rsa_verify_sig in lib/pubkey.c ++ bits = mpz_sizeinbase(pub.n, 2); ++ ++ /* In FIPS 140-3, RSA key size should be larger than ++ * 2048-bit or one of the known lengths (1024, 1280, ++ * 1536, 1792; i.e., multiple of 256-bits). ++ * ++ * In addition to this, only SHA-1 and SHA-2 are allowed ++ * for SigVer; it is checked in _pkcs1_rsa_verify_sig in ++ * lib/pubkey.c. + */ +- if (unlikely(pub.size < 256)) { ++ if (unlikely(bits < 2048 && ++ bits != 1024 && bits != 1280 && ++ bits != 1536 && bits != 1792)) { + not_approved = true; + } + +@@ -1701,13 +1709,13 @@ _wrap_nettle_pk_verify(gnutls_pk_algorithm_t algo, + goto cleanup; + } + +- /* RSA key size should be 2048-bit or larger in FIPS ++ /* RSA modulus size should be 2048-bit or larger in FIPS + * 140-3. In addition to this, only SHA-1 and SHA-2 are + * allowed for SigVer, while Nettle only supports + * SHA256, SHA384, and SHA512 for RSA-PSS (see + * _rsa_pss_verify_digest in this file for the details). + */ +- if (unlikely(pub.size < 256)) { ++ if (unlikely(mpz_sizeinbase(pub.n, 2) < 2048)) { + not_approved = true; + } + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 7a7a4af..dd21e45 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -233,7 +233,8 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei + tls13-without-timeout-func buffer status-request-revoked \ + set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \ + x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \ +- x509-upnconstraint pkcs7-verify-double-free ++ x509-upnconstraint pkcs7-verify-double-free \ ++ fips-rsa-sizes + + ctests += tls-channel-binding + +diff --git a/tests/fips-rsa-sizes.c b/tests/fips-rsa-sizes.c +new file mode 100644 +index 0000000..84b9aff +--- /dev/null ++++ b/tests/fips-rsa-sizes.c +@@ -0,0 +1,328 @@ ++/* ++ * Copyright (C) 2022 Red Hat, Inc. ++ * ++ * Author: Alexander Sosedkin ++ * ++ * This file is part of GnuTLS. ++ * ++ * GnuTLS is free software; you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GnuTLS is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GnuTLS; if not, write to the Free Software Foundation, ++ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA ++ */ ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define FIPS_PUSH_CONTEXT() do { \ ++ ret = gnutls_fips140_push_context(fips_context); \ ++ if (ret < 0) { \ ++ fail("gnutls_fips140_push_context failed\n"); \ ++ } \ ++} while (0) ++ ++#define FIPS_POP_CONTEXT(state) do { \ ++ ret = gnutls_fips140_pop_context(); \ ++ if (ret < 0) { \ ++ fail("gnutls_fips140_context_pop failed\n"); \ ++ } \ ++ fips_state = gnutls_fips140_get_operation_state(fips_context); \ ++ if (fips_state != GNUTLS_FIPS140_OP_ ## state) { \ ++ fail("operation state is not " # state " (%d)\n", \ ++ fips_state); \ ++ } \ ++} while (0) ++ ++ ++void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey, ++ unsigned int size); ++void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey, ++ unsigned int size); ++void sign_verify_successfully(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey); ++void sign_verify_unsuccessfully(gnutls_privkey_t privkey, ++ gnutls_pubkey_t pubkey); ++void nosign_verify(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey); ++ ++ ++void generate_successfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey, ++ unsigned int size) ++{ ++ int ret; ++ gnutls_x509_privkey_t xprivkey; ++ gnutls_fips140_context_t fips_context; ++ gnutls_fips140_operation_state_t fips_state; ++ assert(gnutls_fips140_context_init(&fips_context) == 0); ++ ++ fprintf(stderr, "%d-bit\n", size); ++ ++ /* x509 generation as well just because why not */ ++ FIPS_PUSH_CONTEXT(); ++ assert(gnutls_x509_privkey_init(&xprivkey) == 0); ++ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0); ++ if (ret != GNUTLS_E_SUCCESS) ++ fail("%d-bit x509_privkey_init (%d)\n", size, ret); ++ FIPS_POP_CONTEXT(APPROVED); ++ gnutls_x509_privkey_deinit(xprivkey); ++ ++ FIPS_PUSH_CONTEXT(); ++ assert(gnutls_privkey_init(privkey) == 0); ++ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0); ++ if (ret != GNUTLS_E_SUCCESS) ++ fail("%d-bit privkey_init (%d)\n", size, ret); ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ assert(gnutls_pubkey_init(pubkey) == 0); ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_import_privkey(*pubkey, *privkey, ++ GNUTLS_KEY_DIGITAL_SIGNATURE, 0); ++ if (ret != GNUTLS_E_SUCCESS) ++ fail("%d-bit pubkey_import_privkey (%d)\n", size, ret); ++ FIPS_POP_CONTEXT(INITIAL); ++ ++ gnutls_fips140_context_deinit(fips_context); ++} ++ ++ ++void generate_unsuccessfully(gnutls_privkey_t* privkey, gnutls_pubkey_t* pubkey, ++ unsigned int size) ++{ ++ int ret; ++ gnutls_x509_privkey_t xprivkey; ++ gnutls_fips140_context_t fips_context; ++ gnutls_fips140_operation_state_t fips_state; ++ assert(gnutls_fips140_context_init(&fips_context) == 0); ++ ++ fprintf(stderr, "%d-bit\n", size); ++ ++ /* short x509 generation: ERROR, blocked */ ++ FIPS_PUSH_CONTEXT(); ++ assert(gnutls_x509_privkey_init(&xprivkey) == 0); ++ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0); ++ if (ret != GNUTLS_E_PK_GENERATION_ERROR) ++ fail("%d-bit x509_privkey_init (%d)\n", size, ret); ++ FIPS_POP_CONTEXT(ERROR); ++ gnutls_x509_privkey_deinit(xprivkey); ++ ++ /* short key generation: ERROR, blocked */ ++ FIPS_PUSH_CONTEXT(); ++ assert(gnutls_privkey_init(privkey) == 0); ++ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0); ++ if (ret != GNUTLS_E_PK_GENERATION_ERROR) ++ fail("%d-bit privkey_init (%d)\n", size, ret); ++ FIPS_POP_CONTEXT(ERROR); ++ gnutls_privkey_deinit(*privkey); ++ ++ /* Disable FIPS to generate them anyway */ ++ gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, 0); ++ assert(gnutls_fips140_mode_enabled() == GNUTLS_FIPS140_LAX); ++ ++ assert(gnutls_x509_privkey_init(&xprivkey) == 0); ++ ret = gnutls_x509_privkey_generate(xprivkey, GNUTLS_PK_RSA, size, 0); ++ if (ret != GNUTLS_E_SUCCESS) ++ fail("%d-bit x509_privkey_init (%d)\n", size, ret); ++ gnutls_x509_privkey_deinit(xprivkey); ++ ++ assert(gnutls_privkey_init(privkey) == 0); ++ ret = gnutls_privkey_generate(*privkey, GNUTLS_PK_RSA, size, 0); ++ if (ret != GNUTLS_E_SUCCESS) ++ fail("%d-bit privkey_init (%d)\n", size, ret); ++ ++ assert(gnutls_pubkey_init(pubkey) == 0); ++ ret = gnutls_pubkey_import_privkey(*pubkey, *privkey, ++ GNUTLS_KEY_DIGITAL_SIGNATURE, 0); ++ if (ret != GNUTLS_E_SUCCESS) ++ fail("%d-bit pubkey_import_privkey (%d)\n", size, ret); ++ ++ gnutls_fips140_set_mode(GNUTLS_FIPS140_STRICT, 0); ++ assert(gnutls_fips140_mode_enabled()); ++ ++ gnutls_fips140_context_deinit(fips_context); ++} ++ ++ ++void sign_verify_successfully(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) { ++ int ret; ++ gnutls_fips140_context_t fips_context; ++ gnutls_fips140_operation_state_t fips_state; ++ ++ gnutls_datum_t signature; ++ gnutls_datum_t plaintext = { ++ .data = (unsigned char* const) "Hello world!", ++ .size = 12 ++ }; ++ assert(gnutls_fips140_context_init(&fips_context) == 0); ++ ++ /* RSA sign: approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, ++ &plaintext, &signature); ++ if (ret < 0) ++ fail("gnutls_privkey_sign_data failed\n"); ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ /* RSA verify: approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0, ++ &plaintext, &signature); ++ if (ret < 0) ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ gnutls_free(signature.data); ++ gnutls_fips140_context_deinit(fips_context); ++} ++ ++ ++void sign_verify_unsuccessfully(gnutls_privkey_t privkey, ++ gnutls_pubkey_t pubkey) { ++ int ret; ++ gnutls_fips140_context_t fips_context; ++ gnutls_fips140_operation_state_t fips_state; ++ ++ gnutls_datum_t signature; ++ gnutls_datum_t plaintext = { ++ .data = (unsigned char* const) "Hello world!", ++ .size = 12 ++ }; ++ assert(gnutls_fips140_context_init(&fips_context) == 0); ++ ++ /* small key RSA sign: not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, ++ &plaintext, &signature); ++ if (ret < 0) ++ fail("gnutls_privkey_sign_data failed\n"); ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ ++ /* small key RSA verify: not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0, ++ &plaintext, &signature); ++ if (ret < 0) ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ ++ gnutls_free(signature.data); ++ gnutls_pubkey_deinit(pubkey); ++ gnutls_privkey_deinit(privkey); ++ gnutls_fips140_context_deinit(fips_context); ++} ++ ++ ++void nosign_verify(gnutls_privkey_t privkey, gnutls_pubkey_t pubkey) { ++ int ret; ++ gnutls_fips140_context_t fips_context; ++ gnutls_fips140_operation_state_t fips_state; ++ ++ gnutls_datum_t signature; ++ gnutls_datum_t plaintext = { ++ .data = (unsigned char* const) "Hello world!", ++ .size = 12 ++ }; ++ assert(gnutls_fips140_context_init(&fips_context) == 0); ++ ++ /* 1024, 1280, 1536, 1792 key RSA sign: not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, ++ &plaintext, &signature); ++ if (ret < 0) ++ fail("gnutls_privkey_sign_data failed\n"); ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ ++ /* Disable FIPS to sign them anyway */ ++ gnutls_fips140_set_mode(GNUTLS_FIPS140_LAX, 0); ++ assert(gnutls_fips140_mode_enabled() == GNUTLS_FIPS140_LAX); ++ ++ ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, ++ &plaintext, &signature); ++ if (ret < 0) ++ fail("gnutls_privkey_sign_data failed\n"); ++ ++ gnutls_fips140_set_mode(GNUTLS_FIPS140_STRICT, 0); ++ assert(gnutls_fips140_mode_enabled()); ++ ++ /* 1024, 1280, 1536, 1792 key RSA verify: approved (exception) */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0, ++ &plaintext, &signature); ++ if (ret < 0) ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ gnutls_free(signature.data); ++ gnutls_pubkey_deinit(pubkey); ++ gnutls_privkey_deinit(privkey); ++ gnutls_fips140_context_deinit(fips_context); ++} ++ ++ ++void doit(void) ++{ ++ gnutls_fips140_context_t fips_context; ++ gnutls_privkey_t privkey; ++ gnutls_pubkey_t pubkey; ++ ++ if (gnutls_fips140_mode_enabled() == 0) { ++ success("We are not in FIPS140 mode\n"); ++ exit(77); /* SKIP */ ++ } ++ ++ assert(gnutls_fips140_context_init(&fips_context) == 0); ++ ++ /* 512-bit RSA: no generate, no sign, no verify */ ++ generate_unsuccessfully(&privkey, &pubkey, 512); ++ sign_verify_unsuccessfully(privkey, pubkey); ++ /* 512-bit RSA again (to be safer about going in and out of FIPS) */ ++ generate_unsuccessfully(&privkey, &pubkey, 512); ++ sign_verify_unsuccessfully(privkey, pubkey); ++ /* 600-bit RSA: no generate, no sign, no verify */ ++ generate_unsuccessfully(&privkey, &pubkey, 600); ++ sign_verify_unsuccessfully(privkey, pubkey); ++ ++ /* 768-bit RSA not-an-exception: nogenerate, nosign, verify */ ++ generate_unsuccessfully(&privkey, &pubkey, 768); ++ sign_verify_unsuccessfully(privkey, pubkey); ++ /* 1024-bit RSA exception: nogenerate, nosign, verify */ ++ generate_unsuccessfully(&privkey, &pubkey, 1024); ++ nosign_verify(privkey, pubkey); ++ /* 1280-bit RSA exception: nogenerate, nosign, verify */ ++ generate_unsuccessfully(&privkey, &pubkey, 1280); ++ nosign_verify(privkey, pubkey); ++ /* 1500-bit RSA not-an-exception: nogenerate, nosign, noverify */ ++ generate_unsuccessfully(&privkey, &pubkey, 1500); ++ sign_verify_unsuccessfully(privkey, pubkey); ++ /* 1536-bit RSA exception: nogenerate, nosign, verify */ ++ generate_unsuccessfully(&privkey, &pubkey, 1536); ++ nosign_verify(privkey, pubkey); ++ /* 1792-bit RSA exception: nogenerate, nosign, verify */ ++ generate_unsuccessfully(&privkey, &pubkey, 1792); ++ nosign_verify(privkey, pubkey); ++ /* 2000-bit RSA not-an-exception: nogenerate, nosign, noverify */ ++ generate_unsuccessfully(&privkey, &pubkey, 2000); ++ sign_verify_unsuccessfully(privkey, pubkey); ++ ++ /* 2048-bit RSA: generate, sign, verify */ ++ generate_successfully(&privkey, &pubkey, 2048); ++ sign_verify_successfully(privkey, pubkey); ++ /* 2432-bit RSA: nogenerate, sign, verify */ ++ generate_unsuccessfully(&privkey, &pubkey, 2432); ++ sign_verify_successfully(privkey, pubkey); ++ /* 3072-bit RSA: generate, sign, verify */ ++ generate_successfully(&privkey, &pubkey, 3072); ++ sign_verify_successfully(privkey, pubkey); ++ ++ gnutls_fips140_context_deinit(fips_context); ++} +-- +2.37.2 + diff --git a/SOURCES/gnutls-3.7.6-fips-run-selftests.patch b/SOURCES/gnutls-3.7.6-fips-run-selftests.patch new file mode 100644 index 0000000..d04a35d --- /dev/null +++ b/SOURCES/gnutls-3.7.6-fips-run-selftests.patch @@ -0,0 +1,640 @@ +From 036fb360e5775f01ef25f5e712024a29930c462e Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Fri, 3 Jun 2022 15:43:00 +0900 +Subject: [PATCH] fips: provide function to manually run FIPS self-tests + +FIPS140-3 IG 10.3.E Periodic Self-Testing says: + + At security levels 1 and 2, acceptable means for initiating the + periodic self-tests include a provided service, resetting, rebooting + or power cycling. + +Neither resetting, rebooting, nor power-cycling is suitable because +those involve operations outside of the module. Therefore this patch +adds a new API to manually run the substance of FIPS140 self-tests. + +Suggeested by Richard Costa and Stephan Mueller in: +https://gitlab.com/gnutls/gnutls/-/issues/1364 + +Signed-off-by: Daiki Ueno +--- + NEWS | 5 ++ + devel/libgnutls.abignore | 2 + + devel/symbols.last | 2 + + doc/Makefile.am | 2 + + doc/manpages/Makefile.am | 1 + + lib/fips.c | 139 ++++++++++++++++---------------- + lib/global.c | 14 +++- + lib/includes/gnutls/gnutls.h.in | 2 + + lib/libgnutls.map | 8 ++ + tests/fips-test.c | 7 ++ + 10 files changed, 110 insertions(+), 72 deletions(-) + +diff --git a/NEWS b/NEWS +index 70dd8a12b5..389be8acaa 100644 +--- a/NEWS ++++ b/NEWS +@@ -5,6 +5,11 @@ Copyright (C) 2000-2016 Free Software Foundation, Inc. + Copyright (C) 2013-2019 Nikos Mavrogiannopoulos + See the end for copying conditions. + ++* Version 3.7.7 (unreleased) ++ ++** API and ABI modifications: ++gnutls_fips140_run_self_tests: New function ++ + * Version 3.7.6 (released 2022-05-27) + + ** libgnutls: Fixed invalid write when gnutls_realloc_zero() +diff --git a/doc/Makefile.am b/doc/Makefile.am +index d20a021d97..34ef43866c 100644 +--- a/doc/Makefile.am ++++ b/doc/Makefile.am +@@ -1096,6 +1096,8 @@ FUNCS += functions/gnutls_fips140_pop_context + FUNCS += functions/gnutls_fips140_pop_context.short + FUNCS += functions/gnutls_fips140_push_context + FUNCS += functions/gnutls_fips140_push_context.short ++FUNCS += functions/gnutls_fips140_run_self_tests ++FUNCS += functions/gnutls_fips140_run_self_tests.short + FUNCS += functions/gnutls_fips140_set_mode + FUNCS += functions/gnutls_fips140_set_mode.short + FUNCS += functions/gnutls_get_library_config +diff --git a/doc/manpages/Makefile.am b/doc/manpages/Makefile.am +index d8c5f2854d..90906b0574 100644 +--- a/doc/manpages/Makefile.am ++++ b/doc/manpages/Makefile.am +@@ -380,6 +380,7 @@ APIMANS += gnutls_fips140_get_operation_state.3 + APIMANS += gnutls_fips140_mode_enabled.3 + APIMANS += gnutls_fips140_pop_context.3 + APIMANS += gnutls_fips140_push_context.3 ++APIMANS += gnutls_fips140_run_self_tests.3 + APIMANS += gnutls_fips140_set_mode.3 + APIMANS += gnutls_get_library_config.3 + APIMANS += gnutls_get_system_config_file.3 +diff --git a/lib/fips.c b/lib/fips.c +index e9c27f6df6..656d43e74a 100644 +--- a/lib/fips.c ++++ b/lib/fips.c +@@ -419,8 +419,6 @@ int _gnutls_fips_perform_self_checks1(void) + { + int ret; + +- _gnutls_switch_lib_state(LIB_STATE_SELFTEST); +- + /* Tests the FIPS algorithms used by nettle internally. + * In our case we test AES-CBC since nettle's AES is used by + * the DRBG-AES. +@@ -429,193 +427,153 @@ int _gnutls_fips_perform_self_checks1(void) + /* ciphers - one test per cipher */ + ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_128_CBC); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + return 0; +- +-error: +- _gnutls_switch_lib_state(LIB_STATE_ERROR); +- _gnutls_audit_log(NULL, "FIPS140-2 self testing part1 failed\n"); +- +- return GNUTLS_E_SELF_TEST_ERROR; + } + + int _gnutls_fips_perform_self_checks2(void) + { + int ret; + +- _gnutls_switch_lib_state(LIB_STATE_SELFTEST); +- + /* Tests the FIPS algorithms */ + + /* ciphers - one test per cipher */ + ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_3DES_CBC); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_CBC); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_GCM); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_XTS); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_cipher_self_test(0, GNUTLS_CIPHER_AES_256_CFB8); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + /* Digest tests */ + ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_224); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_256); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_384); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_digest_self_test(0, GNUTLS_DIG_SHA3_512); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + /* MAC (includes message digest test) */ + ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA1); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA224); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA256); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA384); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_mac_self_test(0, GNUTLS_MAC_SHA512); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_mac_self_test(0, GNUTLS_MAC_AES_CMAC_256); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + /* PK */ + ret = gnutls_pk_self_test(0, GNUTLS_PK_RSA); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_pk_self_test(0, GNUTLS_PK_DSA); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_pk_self_test(0, GNUTLS_PK_EC); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + ret = gnutls_pk_self_test(0, GNUTLS_PK_DH); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + /* HKDF */ + ret = gnutls_hkdf_self_test(0, GNUTLS_MAC_SHA256); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + /* PBKDF2 */ + ret = gnutls_pbkdf2_self_test(0, GNUTLS_MAC_SHA256); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + /* TLS-PRF */ + ret = gnutls_tlsprf_self_test(0, GNUTLS_MAC_SHA256); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + if (_gnutls_rnd_ops.self_test == NULL) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + /* this does not require rng initialization */ + ret = _gnutls_rnd_ops.self_test(); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + + if (_skip_integrity_checks == 0) { + ret = check_binary_integrity(); + if (ret < 0) { +- gnutls_assert(); +- goto error; ++ return gnutls_assert_val(GNUTLS_E_SELF_TEST_ERROR); + } + } + + return 0; +- +-error: +- _gnutls_switch_lib_state(LIB_STATE_ERROR); +- _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n"); +- +- return GNUTLS_E_SELF_TEST_ERROR; + } + #endif + +@@ -894,3 +852,48 @@ _gnutls_switch_fips_state(gnutls_fips140_operation_state_t state) + (void)state; + #endif + } ++ ++/** ++ * gnutls_fips140_run_self_tests: ++ * ++ * Manually perform the second round of the FIPS140 self-tests, ++ * including: ++ * ++ * - Known answer tests (KAT) for the selected set of symmetric ++ * cipher, MAC, public key, KDF, and DRBG ++ * - Library integrity checks ++ * ++ * Upon failure with FIPS140 mode enabled, it makes the library ++ * unusable. This function is not thread-safe. ++ * ++ * Returns: 0 upon success, a negative error code otherwise ++ * ++ * Since: 3.7.7 ++ */ ++int ++gnutls_fips140_run_self_tests(void) ++{ ++#ifdef ENABLE_FIPS140 ++ int ret; ++ unsigned prev_lib_state; ++ ++ /* Temporarily switch to LIB_STATE_SELFTEST as some of the ++ * algorithms are implemented using special constructs in ++ * self-tests (such as deterministic variants) */ ++ prev_lib_state = _gnutls_get_lib_state(); ++ _gnutls_switch_lib_state(LIB_STATE_SELFTEST); ++ ++ ret = _gnutls_fips_perform_self_checks2(); ++ if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED && ++ ret < 0) { ++ _gnutls_switch_lib_state(LIB_STATE_ERROR); ++ _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n"); ++ } else { ++ /* Restore the previous library state */ ++ _gnutls_switch_lib_state(prev_lib_state); ++ } ++ return ret; ++#else ++ return 0; ++#endif ++} +diff --git a/lib/global.c b/lib/global.c +index faa7f0afb2..1b372c15bd 100644 +--- a/lib/global.c ++++ b/lib/global.c +@@ -336,9 +336,12 @@ static int _gnutls_global_init(unsigned constructor) + + /* first round of self checks, these are done on the + * nettle algorithms which are used internally */ ++ _gnutls_switch_lib_state(LIB_STATE_SELFTEST); + ret = _gnutls_fips_perform_self_checks1(); +- if (res != 2) { +- if (ret < 0) { ++ if (ret < 0) { ++ _gnutls_switch_lib_state(LIB_STATE_ERROR); ++ _gnutls_audit_log(NULL, "FIPS140-2 self testing part1 failed\n"); ++ if (res != 2) { + gnutls_assert(); + goto out; + } +@@ -355,9 +358,12 @@ static int _gnutls_global_init(unsigned constructor) + * (e.g., AESNI overridden AES). They are after _gnutls_register_accel_crypto() + * intentionally */ + if (res != 0) { ++ _gnutls_switch_lib_state(LIB_STATE_SELFTEST); + ret = _gnutls_fips_perform_self_checks2(); +- if (res != 2) { +- if (ret < 0) { ++ if (ret < 0) { ++ _gnutls_switch_lib_state(LIB_STATE_ERROR); ++ _gnutls_audit_log(NULL, "FIPS140-2 self testing part 2 failed\n"); ++ if (res != 2) { + gnutls_assert(); + goto out; + } +diff --git a/lib/includes/gnutls/gnutls.h.in b/lib/includes/gnutls/gnutls.h.in +index f7fc5d114a..5840f331e9 100644 +--- a/lib/includes/gnutls/gnutls.h.in ++++ b/lib/includes/gnutls/gnutls.h.in +@@ -3416,6 +3416,8 @@ gnutls_fips140_get_operation_state(gnutls_fips140_context_t context); + int gnutls_fips140_push_context(gnutls_fips140_context_t context); + int gnutls_fips140_pop_context(void); + ++int gnutls_fips140_run_self_tests(void); ++ + /* Gnutls error codes. The mapping to a TLS alert is also shown in + * comments. + */ +diff --git a/lib/libgnutls.map b/lib/libgnutls.map +index 0241946c8a..f42d5f9fae 100644 +--- a/lib/libgnutls.map ++++ b/lib/libgnutls.map +@@ -1399,6 +1399,14 @@ GNUTLS_3_7_5 + *; + } GNUTLS_3_7_4; + ++GNUTLS_3_7_7 ++{ ++ global: ++ gnutls_fips140_run_self_tests; ++ local: ++ *; ++} GNUTLS_3_7_5; ++ + GNUTLS_FIPS140_3_4 { + global: + gnutls_cipher_self_test; +diff --git a/tests/fips-test.c b/tests/fips-test.c +index a6a283fa67..31a5e26111 100644 +--- a/tests/fips-test.c ++++ b/tests/fips-test.c +@@ -525,6 +525,13 @@ void doit(void) + } + + gnutls_fips140_context_deinit(fips_context); ++ ++ /* run self-tests manually */ ++ ret = gnutls_fips140_run_self_tests(); ++ if (ret < 0) { ++ fail("gnutls_fips140_run_self_tests failed\n"); ++ } ++ + gnutls_global_deinit(); + return; + } +-- +2.36.1 + +From 354027c0c09db60d3083fa48ae791046d336957b Mon Sep 17 00:00:00 2001 +From: Alexander Sosedkin +Date: Tue, 28 Jun 2022 17:22:36 +0200 +Subject: [PATCH] tests/fips-test: minor extension + +Signed-off-by: Alexander Sosedkin +--- + tests/fips-test.c | 36 +++++++++++++++++++++++++++--------- + 1 file changed, 27 insertions(+), 9 deletions(-) + +diff --git a/tests/fips-test.c b/tests/fips-test.c +index 31a5e26111..f9bd34586a 100644 +--- a/tests/fips-test.c ++++ b/tests/fips-test.c +@@ -427,34 +427,43 @@ void doit(void) + rsa_import_keypair(&privkey, &pubkey, "rsa-2432.pem"); + FIPS_POP_CONTEXT(INITIAL); + +- /* Create a signature with SHA256; approved */ ++ /* Create a signature with 2432-bit RSA and SHA256; approved */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, + &data, &signature); + if (ret < 0) { + fail("gnutls_privkey_sign_data failed\n"); + } +- gnutls_free(signature.data); + FIPS_POP_CONTEXT(APPROVED); + +- /* Create a signature with SHA-1; not approved */ ++ /* Verify a signature with 2432-bit RSA and SHA256; approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ gnutls_free(signature.data); ++ ++ /* Create a signature with 2432-bit RSA and SHA-1; not approved */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA1, 0, + &data, &signature); + if (ret < 0) { + fail("gnutls_privkey_sign_data failed\n"); + } +- gnutls_free(signature.data); + FIPS_POP_CONTEXT(NOT_APPROVED); + +- /* Verify a signature created with SHA-1; approved */ ++ /* Verify a signature created with 2432-bit RSA and SHA-1; approved */ + FIPS_PUSH_CONTEXT(); +- ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, &data, +- &rsa2342_sha1_sig); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, ++ &data, &rsa2342_sha1_sig); + if (ret < 0) { + fail("gnutls_pubkey_verify_data2 failed\n"); + } + FIPS_POP_CONTEXT(APPROVED); ++ gnutls_free(signature.data); + gnutls_pubkey_deinit(pubkey); + gnutls_privkey_deinit(privkey); + +@@ -463,15 +472,24 @@ void doit(void) + rsa_import_keypair(&privkey, &pubkey, "rsa-512.pem"); + FIPS_POP_CONTEXT(INITIAL); + +- /* Create a signature; not approved */ ++ /* Create a signature with 512-bit RSA and SHA256; not approved */ + FIPS_PUSH_CONTEXT(); + ret = gnutls_privkey_sign_data(privkey, GNUTLS_DIG_SHA256, 0, + &data, &signature); + if (ret < 0) { + fail("gnutls_privkey_sign_data failed\n"); + } +- gnutls_free(signature.data); + FIPS_POP_CONTEXT(NOT_APPROVED); ++ ++ /* Verify a signature with 512-bit RSA and SHA256; not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA256, 0, ++ &data, &signature); ++ if (ret < 0) { ++ fail("gnutls_pubkey_verify_data2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ gnutls_free(signature.data); + gnutls_pubkey_deinit(pubkey); + gnutls_privkey_deinit(privkey); + +-- +2.37.3 + +From 5a745120148861d873f47c1428c8c6dcadcf109b Mon Sep 17 00:00:00 2001 +From: Richard Costa +Date: Sat, 9 Jul 2022 00:50:21 +0000 +Subject: [PATCH] Add self-test code inside a FIPS context + +Self-test code exercise lots of different FIPS-related code with +side-effects. So, in order to prevent it from losing information when +executing inside another context, we create an appropriated one. + +If the self-test fails, then the library is placed in error state, so it +doesn't matter for other contexts. + +Signed-off-by: Richard Maciel Costa +--- + lib/fips.c | 19 +++++++++++++++++++ + tests/fips-test.c | 20 ++++++++++++-------- + 2 files changed, 31 insertions(+), 8 deletions(-) + +diff --git a/lib/fips.c b/lib/fips.c +index 31a52a990f..7d143e608e 100644 +--- a/lib/fips.c ++++ b/lib/fips.c +@@ -902,6 +902,16 @@ gnutls_fips140_run_self_tests(void) + #ifdef ENABLE_FIPS140 + int ret; + unsigned prev_lib_state; ++ gnutls_fips140_context_t fips_context = NULL; ++ ++ /* Save the FIPS context, because self tests change it */ ++ if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED) { ++ if (gnutls_fips140_context_init(&fips_context) < 0 || ++ gnutls_fips140_push_context(fips_context) < 0) { ++ gnutls_fips140_context_deinit(fips_context); ++ fips_context = NULL; ++ } ++ } + + /* Temporarily switch to LIB_STATE_SELFTEST as some of the + * algorithms are implemented using special constructs in +@@ -918,6 +928,15 @@ gnutls_fips140_run_self_tests(void) + /* Restore the previous library state */ + _gnutls_switch_lib_state(prev_lib_state); + } ++ ++ /* Restore the previous FIPS context */ ++ if (gnutls_fips140_mode_enabled() != GNUTLS_FIPS140_DISABLED && fips_context) { ++ if (gnutls_fips140_pop_context() < 0) { ++ _gnutls_switch_lib_state(LIB_STATE_ERROR); ++ _gnutls_audit_log(NULL, "FIPS140-2 context restoration failed\n"); ++ } ++ gnutls_fips140_context_deinit(fips_context); ++ } + return ret; + #else + return 0; +diff --git a/tests/fips-test.c b/tests/fips-test.c +index f9bd34586a..475b739197 100644 +--- a/tests/fips-test.c ++++ b/tests/fips-test.c +@@ -457,8 +457,9 @@ void doit(void) + + /* Verify a signature created with 2432-bit RSA and SHA-1; approved */ + FIPS_PUSH_CONTEXT(); +- ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, 0, +- &data, &rsa2342_sha1_sig); ++ ret = gnutls_pubkey_verify_data2(pubkey, GNUTLS_SIGN_RSA_SHA1, ++ GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1, &data, ++ &rsa2342_sha1_sig); + if (ret < 0) { + fail("gnutls_pubkey_verify_data2 failed\n"); + } +@@ -501,6 +502,15 @@ void doit(void) + } + FIPS_POP_CONTEXT(APPROVED); + ++ /* run self-tests manually */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_rnd(GNUTLS_RND_RANDOM, key16, sizeof(key16)); ++ ret = gnutls_fips140_run_self_tests(); ++ if (ret < 0) { ++ fail("gnutls_fips140_run_self_tests failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ + /* Test when FIPS140 is set to error state */ + _gnutls_lib_simulate_error(); + +@@ -544,12 +554,6 @@ void doit(void) + + gnutls_fips140_context_deinit(fips_context); + +- /* run self-tests manually */ +- ret = gnutls_fips140_run_self_tests(); +- if (ret < 0) { +- fail("gnutls_fips140_run_self_tests failed\n"); +- } +- + gnutls_global_deinit(); + return; + } +-- +2.37.3 + diff --git a/SOURCES/gnutls-3.7.6-fips-symkey-limit.patch b/SOURCES/gnutls-3.7.6-fips-symkey-limit.patch new file mode 100644 index 0000000..f9c7952 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-fips-symkey-limit.patch @@ -0,0 +1,310 @@ +From f8a8961cfa176fc74c153cb6e1e68aff5e2d42f2 Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Tue, 27 Sep 2022 10:52:19 +0900 +Subject: [PATCH] gnutls-3.7.6-fips-symkey-limit.patch + +--- + lib/crypto-api.c | 26 ++++++++++++++++++++++--- + tests/fips-test.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++ + tests/kdf-api.c | 9 ++++++++- + 3 files changed, 80 insertions(+), 4 deletions(-) + +diff --git a/lib/crypto-api.c b/lib/crypto-api.c +index b3e1eec..35200fb 100644 +--- a/lib/crypto-api.c ++++ b/lib/crypto-api.c +@@ -896,6 +896,7 @@ gnutls_hash_hd_t gnutls_hash_copy(gnutls_hash_hd_t handle) + int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size) + { + int ret; ++ bool not_approved = false; + + FAIL_IF_LIB_ERROR; + +@@ -912,17 +913,31 @@ int gnutls_key_generate(gnutls_datum_t * key, unsigned int key_size) + key->data = gnutls_malloc(key->size); + if (!key->data) { + gnutls_assert(); +- return GNUTLS_E_MEMORY_ERROR; ++ ret = GNUTLS_E_MEMORY_ERROR; ++ goto error; ++ } ++ ++ /* Key lengths of less than 112 bits are not approved */ ++ if (key_size < 14) { ++ not_approved = true; + } + + ret = gnutls_rnd(GNUTLS_RND_RANDOM, key->data, key->size); + if (ret < 0) { + gnutls_assert(); + _gnutls_free_datum(key); +- return ret; ++ goto error; + } + +- return 0; ++ error: ++ if (ret < 0) { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); ++ } else if (not_approved) { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_NOT_APPROVED); ++ } else { ++ _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_APPROVED); ++ } ++ return ret; + } + + /* AEAD API */ +@@ -2058,6 +2073,11 @@ gnutls_pbkdf2(gnutls_mac_algorithm_t mac, + not_approved = true; + } + ++ /* Key lengths and output sizes of less than 112 bits are not approved */ ++ if (key->size < 14 || length < 14) { ++ not_approved = true; ++ } ++ + ret = _gnutls_kdf_ops.pbkdf2(mac, key->data, key->size, + salt->data, salt->size, iter_count, + output, length); +diff --git a/tests/fips-test.c b/tests/fips-test.c +index 31a5e26..27da414 100644 +--- a/tests/fips-test.c ++++ b/tests/fips-test.c +@@ -274,6 +274,8 @@ void doit(void) + gnutls_datum_t signature; + unsigned int bits; + uint8_t hmac[64]; ++ uint8_t pbkdf2[64]; ++ gnutls_datum_t temp_key = { NULL, 0 }; + + fprintf(stderr, + "Please note that if in FIPS140 mode, you need to assure the library's integrity prior to running this test\n"); +@@ -371,11 +373,58 @@ void doit(void) + } + FIPS_POP_CONTEXT(NOT_APPROVED); + ++ /* PBKDF2 with key equal to or longer than 112 bits: approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100, ++ &pbkdf2, sizeof(pbkdf2)); ++ if (ret < 0) { ++ fail("gnutls_pbkdf2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ /* PBKDF2 with key shorter than 112 bits: not approved */ ++ FIPS_PUSH_CONTEXT(); ++ key.size = 13; ++ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100, ++ &pbkdf2, sizeof(pbkdf2)); ++ if (ret < 0) { ++ fail("gnutls_pbkdf2 failed\n"); ++ } ++ key.size = sizeof(key16); ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ ++ /* PBKDF2 with output shorter than 112 bits: not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_pbkdf2(GNUTLS_MAC_SHA256, &key, &iv, 100, ++ &pbkdf2, 13); ++ if (ret < 0) { ++ fail("gnutls_pbkdf2 failed\n"); ++ } ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ + ret = gnutls_rnd(GNUTLS_RND_NONCE, key16, sizeof(key16)); + if (ret < 0) { + fail("gnutls_rnd failed\n"); + } + ++ /* Symmetric key generation equal to or longer than 112 bits: approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_key_generate(&temp_key, 14); ++ if (ret < 0) { ++ fail("gnutls_key_generate failed\n"); ++ } ++ gnutls_free(temp_key.data); ++ FIPS_POP_CONTEXT(APPROVED); ++ ++ /* Symmetric key generation shorter than 112 bits: not approved */ ++ FIPS_PUSH_CONTEXT(); ++ ret = gnutls_key_generate(&temp_key, 13); ++ if (ret < 0) { ++ fail("gnutls_key_generate failed\n"); ++ } ++ gnutls_free(temp_key.data); ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ + ret = gnutls_pubkey_init(&pubkey); + if (ret < 0) { + fail("gnutls_pubkey_init failed\n"); +diff --git a/tests/kdf-api.c b/tests/kdf-api.c +index 25fbc6a..8a4677c 100644 +--- a/tests/kdf-api.c ++++ b/tests/kdf-api.c +@@ -89,6 +89,7 @@ test_hkdf(gnutls_mac_algorithm_t mac, + + FIPS_PUSH_CONTEXT(); + assert(gnutls_hkdf_extract(mac, &ikm, &salt, buf) >= 0); ++ /* HKDF outside of TLS usage is not approved */ + FIPS_POP_CONTEXT(NOT_APPROVED); + gnutls_free(ikm.data); + gnutls_free(salt.data); +@@ -110,6 +111,7 @@ test_hkdf(gnutls_mac_algorithm_t mac, + + FIPS_PUSH_CONTEXT(); + assert(gnutls_hkdf_expand(mac, &prk, &info, buf, length) >= 0); ++ /* HKDF outside of TLS usage is not approved */ + FIPS_POP_CONTEXT(NOT_APPROVED); + gnutls_free(info.data); + +@@ -151,7 +153,12 @@ test_pbkdf2(gnutls_mac_algorithm_t mac, + + FIPS_PUSH_CONTEXT(); + assert(gnutls_pbkdf2(mac, &ikm, &salt, iter_count, buf, length) >= 0); +- FIPS_POP_CONTEXT(APPROVED); ++ /* Key sizes and output sizes less than 112-bit are not approved. */ ++ if (ikm.size < 14 || length < 14) { ++ FIPS_POP_CONTEXT(NOT_APPROVED); ++ } else { ++ FIPS_POP_CONTEXT(APPROVED); ++ } + gnutls_free(ikm.data); + gnutls_free(salt.data); + +-- +2.37.3 + +From 86eded166f77612c70201c0d85d3abe711edd77d Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Thu, 29 Sep 2022 21:19:26 +0900 +Subject: [PATCH] fips: only mark HMAC as approved in PBKDF2 + +As ACVP only allows HMAC used with PBKDF2[1], this change marks other +hash algorithms not-approved. + +1. https://pages.nist.gov/ACVP/draft-celi-acvp-pbkdf.html + +Signed-off-by: Daiki Ueno +--- + lib/crypto-api.c | 5 ++++- + lib/fips.h | 16 +++++++++++++++- + tests/kdf-api.c | 30 +++++++++++++++++++++++++++++- + 3 files changed, 48 insertions(+), 3 deletions(-) + +diff --git a/lib/crypto-api.c b/lib/crypto-api.c +index d3e601ab3a..9f7e18db11 100644 +--- a/lib/crypto-api.c ++++ b/lib/crypto-api.c +@@ -2229,7 +2229,10 @@ gnutls_pbkdf2(gnutls_mac_algorithm_t mac, + if (!is_mac_algo_allowed(mac)) { + _gnutls_switch_fips_state(GNUTLS_FIPS140_OP_ERROR); + return gnutls_assert_val(GNUTLS_E_UNWANTED_ALGORITHM); +- } else if (!is_mac_algo_approved_in_fips(mac)) { ++ } else if (!is_mac_algo_hmac_approved_in_fips(mac)) { ++ /* ACVP only allows HMAC used with PBKDF2: ++ * https://pages.nist.gov/ACVP/draft-celi-acvp-pbkdf.html ++ */ + not_approved = true; + } + +diff --git a/lib/fips.h b/lib/fips.h +index 3a74f254e7..bf61b36741 100644 +--- a/lib/fips.h ++++ b/lib/fips.h +@@ -76,7 +76,7 @@ void _gnutls_lib_simulate_error(void); + void _gnutls_lib_force_operational(void); + + inline static bool +-is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo) ++is_mac_algo_hmac_approved_in_fips(gnutls_mac_algorithm_t algo) + { + switch (algo) { + case GNUTLS_MAC_SHA1: +@@ -88,6 +88,20 @@ is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo) + case GNUTLS_MAC_SHA3_256: + case GNUTLS_MAC_SHA3_384: + case GNUTLS_MAC_SHA3_512: ++ return true; ++ default: ++ return false; ++ } ++} ++ ++inline static bool ++is_mac_algo_approved_in_fips(gnutls_mac_algorithm_t algo) ++{ ++ if (is_mac_algo_hmac_approved_in_fips(algo)) { ++ return true; ++ } ++ ++ switch (algo) { + case GNUTLS_MAC_AES_CMAC_128: + case GNUTLS_MAC_AES_CMAC_256: + case GNUTLS_MAC_AES_GMAC_128: +diff --git a/tests/kdf-api.c b/tests/kdf-api.c +index 577cbf7a17..4feb22688b 100644 +--- a/tests/kdf-api.c ++++ b/tests/kdf-api.c +@@ -26,6 +26,7 @@ + #include + + #include ++#include + #include + + #include "utils.h" +@@ -133,6 +134,25 @@ test_hkdf(gnutls_mac_algorithm_t mac, + gnutls_free(hex.data); + } + ++inline static bool ++is_mac_algo_hmac_approved_in_fips(gnutls_mac_algorithm_t algo) ++{ ++ switch (algo) { ++ case GNUTLS_MAC_SHA1: ++ case GNUTLS_MAC_SHA256: ++ case GNUTLS_MAC_SHA384: ++ case GNUTLS_MAC_SHA512: ++ case GNUTLS_MAC_SHA224: ++ case GNUTLS_MAC_SHA3_224: ++ case GNUTLS_MAC_SHA3_256: ++ case GNUTLS_MAC_SHA3_384: ++ case GNUTLS_MAC_SHA3_512: ++ return true; ++ default: ++ return false; ++ } ++} ++ + static void + test_pbkdf2(gnutls_mac_algorithm_t mac, + const char *ikm_hex, +@@ -161,7 +181,8 @@ test_pbkdf2(gnutls_mac_algorithm_t mac, + FIPS_PUSH_CONTEXT(); + assert(gnutls_pbkdf2(mac, &ikm, &salt, iter_count, buf, length) >= 0); + /* Key sizes and output sizes less than 112-bit are not approved. */ +- if (ikm.size < 14 || length < 14) { ++ if (ikm.size < 14 || length < 14 || ++ !is_mac_algo_hmac_approved_in_fips(mac)) { + FIPS_POP_CONTEXT(NOT_APPROVED); + } else { + FIPS_POP_CONTEXT(APPROVED); +@@ -208,5 +229,12 @@ doit(void) + 20, + "4b007901b765489abead49d926f721d065a429c1"); + ++ test_pbkdf2(GNUTLS_MAC_AES_CMAC_128, ++ "70617373776f726470617373776f7264", /* "passwordpassword" */ ++ "73616c74", /* "salt" */ ++ 4096, ++ 20, ++ "c4c112c6e1e3b8757640603dec78825ff87605a7"); ++ + gnutls_fips140_context_deinit(fips_context); + } +-- +2.37.3 + diff --git a/SOURCES/gnutls-3.7.6-gmp-static.patch b/SOURCES/gnutls-3.7.6-gmp-static.patch new file mode 100644 index 0000000..6d4bba4 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-gmp-static.patch @@ -0,0 +1,159 @@ +From 88808f0b8906bdc32579c144a2c44401ee97798a Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Fri, 19 Aug 2022 12:32:27 +0900 +Subject: [PATCH] build: allow GMP to be statically linked + +Even though we set the custom allocator[1] to zeroize sensitive data, +it can be easily invalidated if the application sets its own custom +allocator. An approach to prevent that is to link against a static +library of GMP, so the use of GMP is privatized and the custom +allocator configuration is not shared with other applications. + +This patch allows libgnutls to be linked with the static library of +GMP. Note that, to this work libgmp.a needs to be compiled with -fPIC +and libhogweed in Nettle is also linked to the static library of GMP. + +1. https://gitlab.com/gnutls/gnutls/-/merge_requests/1554 + +Signed-off-by: Daiki Ueno +--- + configure.ac | 14 +++++++++++++- + lib/fips.c | 10 ++++++++++ + lib/fipshmac.c | 5 ++++- + lib/global.c | 2 ++ + 4 files changed, 29 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 96894b0be3..e4cf5eab81 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -742,6 +742,8 @@ AC_CHECK_FUNCS(nettle_cmac_kuznyechik_update) + LIBS=$save_LIBS + + # Check sonames of the linked libraries needed for FIPS selftests. ++save_CFLAGS=$CFLAGS ++CFLAGS="$CFLAGS $GMP_CFLAGS" + save_LIBS=$LIBS + LIBS="$LIBS $GMP_LIBS" + AC_MSG_CHECKING([gmp soname]) +@@ -755,9 +757,14 @@ if test -z "$gmp_so"; then + gmp_so=none + fi + AC_MSG_RESULT($gmp_so) +-AC_DEFINE_UNQUOTED([GMP_LIBRARY_SONAME], ["$gmp_so"], [The soname of gmp library]) ++if test "$gmp_so" != none; then ++ AC_DEFINE_UNQUOTED([GMP_LIBRARY_SONAME], ["$gmp_so"], [The soname of gmp library]) ++fi + LIBS=$save_LIBS ++CFLAGS=$save_CFLAGS + ++save_CFLAGS=$CFLAGS ++CFLAGS="$CFLAGS $NETTLE_CFLAGS" + save_LIBS=$LIBS + LIBS="$LIBS $NETTLE_LIBS" + AC_MSG_CHECKING([nettle soname]) +@@ -773,7 +780,11 @@ fi + AC_MSG_RESULT($nettle_so) + AC_DEFINE_UNQUOTED([NETTLE_LIBRARY_SONAME], ["$nettle_so"], [The soname of nettle library]) + LIBS=$save_LIBS ++CFLAGS=$save_CFLAGS + ++save_CFLAGS=$CFLAGS ++# includes ++CFLAGS="$CFLAGS $HOGWEED_CFLAGS $GMP_CFLAGS" + save_LIBS=$LIBS + LIBS="$LIBS $HOGWEED_LIBS" + AC_MSG_CHECKING([hogweed soname]) +@@ -789,6 +800,7 @@ fi + AC_MSG_RESULT($hogweed_so) + AC_DEFINE_UNQUOTED([HOGWEED_LIBRARY_SONAME], ["$hogweed_so"], [The soname of hogweed library]) + LIBS=$save_LIBS ++CFLAGS=$save_CFLAGS + + gnutls_so=libgnutls.so.`expr "$LT_CURRENT" - "$LT_AGE"` + AC_DEFINE_UNQUOTED([GNUTLS_LIBRARY_SONAME], ["$gnutls_so"], [The soname of gnutls library]) +diff --git a/lib/fips.c b/lib/fips.c +index 54eb4a37d4..42124ecf4e 100644 +--- a/lib/fips.c ++++ b/lib/fips.c +@@ -149,7 +149,11 @@ void _gnutls_fips_mode_reset_zombie(void) + #define GNUTLS_LIBRARY_NAME GNUTLS_LIBRARY_SONAME + #define NETTLE_LIBRARY_NAME NETTLE_LIBRARY_SONAME + #define HOGWEED_LIBRARY_NAME HOGWEED_LIBRARY_SONAME ++ ++/* GMP can be statically linked. */ ++#ifdef GMP_LIBRARY_SONAME + #define GMP_LIBRARY_NAME GMP_LIBRARY_SONAME ++#endif + + #define HMAC_SIZE 32 + #define HMAC_ALGO GNUTLS_MAC_SHA256 +@@ -168,7 +172,9 @@ typedef struct + struct hmac_entry gnutls; + struct hmac_entry nettle; + struct hmac_entry hogweed; ++#ifdef GMP_LIBRARY_SONAME + struct hmac_entry gmp; ++#endif + } hmac_file; + + static int get_library_path(const char* lib, const char* symbol, char* path, size_t path_size) +@@ -259,8 +265,10 @@ static int handler(void *user, const char *section, const char *name, const char + return lib_handler(&p->nettle, section, name, value); + } else if (!strcmp(section, HOGWEED_LIBRARY_NAME)) { + return lib_handler(&p->hogweed, section, name, value); ++#ifdef GMP_LIBRARY_SONAME + } else if (!strcmp(section, GMP_LIBRARY_NAME)) { + return lib_handler(&p->gmp, section, name, value); ++#endif + } else { + return 0; + } +@@ -408,9 +416,11 @@ static int check_binary_integrity(void) + ret = check_lib_hmac(&file.hogweed, HOGWEED_LIBRARY_NAME, "nettle_mpz_sizeinbase_256_u"); + if (ret < 0) + return ret; ++#ifdef GMP_LIBRARY_SONAME + ret = check_lib_hmac(&file.gmp, GMP_LIBRARY_NAME, "__gmpz_init"); + if (ret < 0) + return ret; ++#endif + + return 0; + } +diff --git a/lib/fipshmac.c b/lib/fipshmac.c +index b091572bdf..363077f3e2 100644 +--- a/lib/fipshmac.c ++++ b/lib/fipshmac.c +@@ -159,10 +159,13 @@ int main(int argc, char **argv) + ret = print_lib_dl(HOGWEED_LIBRARY_SONAME, "nettle_mpz_sizeinbase_256_u"); + if (ret < 0) + return EXIT_FAILURE; +- ++ ++ /* GMP can be statically linked. */ ++#ifdef GMP_LIBRARY_SONAME + ret = print_lib_dl(GMP_LIBRARY_SONAME, "__gmpz_init"); + if (ret < 0) + return EXIT_FAILURE; ++#endif + + return EXIT_SUCCESS; + } +diff --git a/lib/global.c b/lib/global.c +index 1b372c15bd..9f3c7b22bd 100644 +--- a/lib/global.c ++++ b/lib/global.c +@@ -548,7 +548,9 @@ static const struct gnutls_library_config_st _gnutls_library_config[] = { + { "libgnutls-soname", GNUTLS_LIBRARY_SONAME }, + { "libnettle-soname", NETTLE_LIBRARY_SONAME }, + { "libhogweed-soname", HOGWEED_LIBRARY_SONAME }, ++#ifdef GMP_LIBRARY_SONAME + { "libgmp-soname", GMP_LIBRARY_SONAME }, ++#endif + { "hardware-features", HW_FEATURES }, + { "tls-features", TLS_FEATURES }, + { NULL, NULL } +-- +2.37.1 + diff --git a/SOURCES/gnutls-3.7.6-ktls-disable-by-default.patch b/SOURCES/gnutls-3.7.6-ktls-disable-by-default.patch new file mode 100644 index 0000000..2a88eb3 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-ktls-disable-by-default.patch @@ -0,0 +1,124 @@ +From f41151c8a218f255af08362b74cd6ee0dfd45c00 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Franti=C5=A1ek=20Kren=C5=BEelok?= + +Date: Tue, 14 Jun 2022 16:16:11 +0200 +Subject: [PATCH] KTLS: disable by default enable by config + +KTLS will be disabled by default when build with `--enable-ktls` to +enable it, use config file option `ktls = true` in [global] section. + +Signed-off-by: Frantisek Krenzelok +--- + doc/cha-config.texi | 18 ++++++++---------- + lib/gnutls_int.h | 2 +- + lib/handshake.c | 2 +- + lib/priority.c | 12 ++++++------ + 4 files changed, 16 insertions(+), 18 deletions(-) + +diff --git a/doc/cha-config.texi b/doc/cha-config.texi +index e550f2e4b1..eaab7fd799 100644 +--- a/doc/cha-config.texi ++++ b/doc/cha-config.texi +@@ -26,7 +26,7 @@ used can be queried using @funcref{gnutls_get_system_config_file}. + * Querying for disabled algorithms and protocols:: + * Overriding the parameter verification profile:: + * Overriding the default priority string:: +-* Disabling system/acceleration protocols:: ++* Enabling/Disabling system/acceleration protocols:: + @end menu + + @node Application-specific priority strings +@@ -253,16 +253,14 @@ default-priority-string = SECURE128:-VERS-TLS-ALL:+VERS-TLS1.3 + @end example + + +-@node Disabling system/acceleration protocols +-@section Disabling system/acceleration protocols +-When system/acceleration protocol is enabled during build, it is usually +-enabled by default. The following options can overwrite this behavior +-system-wide. ++@node Enabling/Disabling system/acceleration protocols ++@section Enabling/Disabling system/acceleration protocols ++The following options can overwrite default behavior of protocols system-wide. + @example + [global] +-ktls = false ++ktls = true + + @end example +-@subsection Disabling KTLS +-When GnuTLS is build with -–enable-ktls configuration, it uses KTLS by default. +-This can be overwritten by setting @code{ktls = false} in @code{[global]} section. ++@subsection Enabling KTLS ++When GnuTLS is build with -–enable-ktls configuration, KTLS is disabled by default. ++This can be enabled by setting @code{ktls = true} in @code{[global]} section. +diff --git a/lib/gnutls_int.h b/lib/gnutls_int.h +index 872188696b..8c7bdaa1db 100644 +--- a/lib/gnutls_int.h ++++ b/lib/gnutls_int.h +@@ -1649,6 +1649,6 @@ get_certificate_type(gnutls_session_t session, + + extern unsigned int _gnutls_global_version; + +-bool _gnutls_config_is_ktls_disabled(void); ++bool _gnutls_config_is_ktls_enabled(void); + + #endif /* GNUTLS_LIB_GNUTLS_INT_H */ +diff --git a/lib/handshake.c b/lib/handshake.c +index f3edbbdacb..4dd457bf22 100644 +--- a/lib/handshake.c ++++ b/lib/handshake.c +@@ -2815,7 +2815,7 @@ int gnutls_handshake(gnutls_session_t session) + + session->internals.ktls_enabled = 0; + #ifdef ENABLE_KTLS +- if (_gnutls_config_is_ktls_disabled() == false) ++ if (_gnutls_config_is_ktls_enabled() == true) + _gnutls_ktls_enable(session); + #endif + +diff --git a/lib/priority.c b/lib/priority.c +index 7279c03c88..d163d8169f 100644 +--- a/lib/priority.c ++++ b/lib/priority.c +@@ -1027,7 +1027,7 @@ static void dummy_func(gnutls_priority_t c) + + struct cfg { + bool allowlisting; +- bool ktls_disabled; ++ bool ktls_enabled; + + name_val_array_t priority_strings; + char *priority_string; +@@ -1140,7 +1140,7 @@ cfg_steal(struct cfg *dst, struct cfg *src) + src->default_priority_string = NULL; + + dst->allowlisting = src->allowlisting; +- dst->ktls_disabled = src->ktls_disabled; ++ dst->ktls_enabled = src->ktls_enabled; + memcpy(dst->ciphers, src->ciphers, sizeof(src->ciphers)); + memcpy(dst->macs, src->macs, sizeof(src->macs)); + memcpy(dst->groups, src->groups, sizeof(src->groups)); +@@ -1268,8 +1268,8 @@ static int global_ini_handler(void *ctx, const char *section, const char *name, + } + } else if (c_strcasecmp(name, "ktls") == 0) { + p = clear_spaces(value, str); +- if (c_strcasecmp(p, "false") == 0) { +- cfg->ktls_disabled = true; ++ if (c_strcasecmp(p, "true") == 0) { ++ cfg->ktls_enabled = true; + } else { + _gnutls_debug_log("cfg: unknown ktls mode %s\n", + p); +@@ -3490,6 +3490,6 @@ gnutls_priority_string_list(unsigned iter, unsigned int flags) + return NULL; + } + +-bool _gnutls_config_is_ktls_disabled(void){ +- return system_wide_config.ktls_disabled; ++bool _gnutls_config_is_ktls_enabled(void){ ++ return system_wide_config.ktls_enabled; + } +-- +2.36.1 + diff --git a/SOURCES/gnutls-3.7.6-ktls-fixes.patch b/SOURCES/gnutls-3.7.6-ktls-fixes.patch new file mode 100644 index 0000000..2bef420 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-ktls-fixes.patch @@ -0,0 +1,348 @@ +From 7b700dbcd5907944a7dd2f74cd26ad8586cd4bac Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Tue, 28 Jun 2022 09:37:22 +0900 +Subject: [PATCH 1/3] tests: enable KTLS config while running gnutls_ktls test + +Signed-off-by: Daiki Ueno +--- + tests/Makefile.am | 9 +++++---- + tests/gnutls_ktls.c | 4 ++-- + tests/ktls.sh | 46 +++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 53 insertions(+), 6 deletions(-) + create mode 100755 tests/ktls.sh + +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 4deeb6462b..cba67e8db8 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -441,10 +441,6 @@ ctests += x509self x509dn anonself pskself pskself2 dhepskself \ + resume-with-record-size-limit + endif + +-if ENABLE_KTLS +-ctests += gnutls_ktls +-endif +- + ctests += record-sendfile + + gc_CPPFLAGS = $(AM_CPPFLAGS) \ +@@ -500,6 +496,11 @@ if ENABLE_TPM2 + dist_check_SCRIPTS += tpm2.sh + endif + ++if ENABLE_KTLS ++indirect_tests += gnutls_ktls ++dist_check_SCRIPTS += ktls.sh ++endif ++ + if !WINDOWS + + # +diff --git a/tests/gnutls_ktls.c b/tests/gnutls_ktls.c +index 3966e2b10a..8f9c5fa36e 100644 +--- a/tests/gnutls_ktls.c ++++ b/tests/gnutls_ktls.c +@@ -84,7 +84,7 @@ static void client(int fd, const char *prio) + + ret = gnutls_transport_is_ktls_enabled(session); + if (!(ret & GNUTLS_KTLS_RECV)){ +- fail("client: KTLS was not properly inicialized\n"); ++ fail("client: KTLS was not properly initialized\n"); + goto end; + } + +@@ -208,7 +208,7 @@ static void server(int fd, const char *prio) + + ret = gnutls_transport_is_ktls_enabled(session); + if (!(ret & GNUTLS_KTLS_SEND)){ +- fail("server: KTLS was not properly inicialized\n"); ++ fail("server: KTLS was not properly initialized\n"); + goto end; + } + do { +diff --git a/tests/ktls.sh b/tests/ktls.sh +new file mode 100755 +index 0000000000..ba52bd5775 +--- /dev/null ++++ b/tests/ktls.sh +@@ -0,0 +1,46 @@ ++#!/bin/sh ++ ++# Copyright (C) 2022 Red Hat, Inc. ++# ++# Author: Daiki Ueno ++# ++# This file is part of GnuTLS. ++# ++# GnuTLS is free software; you can redistribute it and/or modify it ++# under the terms of the GNU General Public License as published by the ++# Free Software Foundation; either version 3 of the License, or (at ++# your option) any later version. ++# ++# GnuTLS is distributed in the hope that it will be useful, but ++# WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++# General Public License for more details. ++# ++# You should have received a copy of the GNU General Public License ++# along with GnuTLS; if not, write to the Free Software Foundation, ++# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. ++ ++: ${builddir=.} ++ ++. "$srcdir/scripts/common.sh" ++ ++if ! grep '^tls ' /proc/modules 2>1 >& /dev/null; then ++ exit 77 ++fi ++ ++testdir=`create_testdir ktls` ++ ++cfg="$testdir/config" ++ ++cat < "$cfg" ++[global] ++ktls = true ++EOF ++ ++GNUTLS_SYSTEM_PRIORITY_FAIL_ON_INVALID=1 \ ++GNUTLS_SYSTEM_PRIORITY_FILE="$cfg" \ ++"$builddir/gnutls_ktls" "$@" ++rc=$? ++ ++rm -rf "$testdir" ++exit $rc +-- +2.36.1 + + +From 4a492462535a7f3a831685d3cf420b50ef219511 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Tue, 28 Jun 2022 10:23:33 +0900 +Subject: [PATCH 2/3] handshake: do not reset KTLS enablement in + gnutls_handshake + +As gnutls_handshake can be repeatedly called upon non-blocking setup, +we shouldn't try to call setsockopt for KTLS upon every call. + +Signed-off-by: Daiki Ueno +--- + lib/handshake.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/lib/handshake.c b/lib/handshake.c +index 4dd457bf22..3886306eb4 100644 +--- a/lib/handshake.c ++++ b/lib/handshake.c +@@ -2813,12 +2813,6 @@ int gnutls_handshake(gnutls_session_t session) + const version_entry_st *vers = get_version(session); + int ret; + +- session->internals.ktls_enabled = 0; +-#ifdef ENABLE_KTLS +- if (_gnutls_config_is_ktls_enabled() == true) +- _gnutls_ktls_enable(session); +-#endif +- + if (unlikely(session->internals.initial_negotiation_completed)) { + if (vers->tls13_sem) { + if (session->security_parameters.entity == GNUTLS_CLIENT) { +@@ -2864,6 +2858,12 @@ int gnutls_handshake(gnutls_session_t session) + end->tv_nsec = + (start->tv_nsec + tmo_ms * 1000000LL) % 1000000000LL; + } ++ ++#ifdef ENABLE_KTLS ++ if (_gnutls_config_is_ktls_enabled()) { ++ _gnutls_ktls_enable(session); ++ } ++#endif + } + + if (session->internals.recv_state == RECV_STATE_FALSE_START) { +-- +2.36.1 + + +From ce13208e13b5dec73993c583d4c64ab7714e4a7a Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Tue, 28 Jun 2022 10:53:55 +0900 +Subject: [PATCH 3/3] ktls: _gnutls_ktls_enable: fix GNUTLS_KTLS_SEND + calculation + +Previously, if the first setsockopt for GNUTLS_KTLS_RECV fails and the +same socket is used for both sending and receiving, GNUTLS_KTLS_SEND +was unconditionally set. This fixes the conditions and also adds more +logging. + +Signed-off-by: Daiki Ueno +--- + lib/system/ktls.c | 21 ++++++++++++++++----- + 1 file changed, 16 insertions(+), 5 deletions(-) + +diff --git a/lib/system/ktls.c b/lib/system/ktls.c +index b9f7a73fb5..ddf27fac76 100644 +--- a/lib/system/ktls.c ++++ b/lib/system/ktls.c +@@ -47,7 +47,7 @@ + gnutls_transport_ktls_enable_flags_t + gnutls_transport_is_ktls_enabled(gnutls_session_t session){ + if (unlikely(!session->internals.initial_negotiation_completed)){ +- _gnutls_debug_log("Initial negotiation is not yet complete"); ++ _gnutls_debug_log("Initial negotiation is not yet complete\n"); + return 0; + } + +@@ -57,16 +57,27 @@ gnutls_transport_is_ktls_enabled(gnutls_session_t session){ + void _gnutls_ktls_enable(gnutls_session_t session) + { + int sockin, sockout; ++ + gnutls_transport_get_int2(session, &sockin, &sockout); + +- if (setsockopt(sockin, SOL_TCP, TCP_ULP, "tls", sizeof ("tls")) == 0) ++ if (setsockopt(sockin, SOL_TCP, TCP_ULP, "tls", sizeof ("tls")) == 0) { + session->internals.ktls_enabled |= GNUTLS_KTLS_RECV; ++ if (sockin == sockout) { ++ session->internals.ktls_enabled |= GNUTLS_KTLS_SEND; ++ } ++ } else { ++ _gnutls_record_log("Unable to set TCP_ULP for read socket: %d\n", ++ errno); ++ } + + if (sockin != sockout) { +- if (setsockopt(sockout, SOL_TCP, TCP_ULP, "tls", sizeof ("tls")) == 0) ++ if (setsockopt(sockout, SOL_TCP, TCP_ULP, "tls", sizeof ("tls")) == 0) { + session->internals.ktls_enabled |= GNUTLS_KTLS_SEND; +- } else +- session->internals.ktls_enabled |= GNUTLS_KTLS_SEND; ++ } else { ++ _gnutls_record_log("Unable to set TCP_ULP for write socket: %d\n", ++ errno); ++ } ++ } + } + + int _gnutls_ktls_set_keys(gnutls_session_t session) +-- +2.36.1 + +From 2d3cba6bb21acb40141180298f3924c73c7de8f8 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Tue, 26 Jul 2022 11:38:41 +0900 +Subject: [PATCH 1/2] handshake: do not enable KTLS if custom pull/push + functions are set + +If gnutls_transport_set_pull_function or +gnutls_transport_set_push_function is used, we can't assume the +underlying transport handle is an FD. + +Signed-off-by: Daiki Ueno +--- + lib/handshake.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/lib/handshake.c b/lib/handshake.c +index 3886306eb4..cf025a84f6 100644 +--- a/lib/handshake.c ++++ b/lib/handshake.c +@@ -2861,7 +2861,14 @@ int gnutls_handshake(gnutls_session_t session) + + #ifdef ENABLE_KTLS + if (_gnutls_config_is_ktls_enabled()) { +- _gnutls_ktls_enable(session); ++ if (session->internals.pull_func || ++ session->internals.push_func) { ++ _gnutls_audit_log(session, ++ "Not enabling KTLS with " ++ "custom pull/push function\n"); ++ } else { ++ _gnutls_ktls_enable(session); ++ } + } + #endif + } +-- +2.37.1 + + +From f7160e4fb970b4ba6f96e85e21f8395eae735d95 Mon Sep 17 00:00:00 2001 +From: Daiki Ueno +Date: Tue, 26 Jul 2022 11:39:57 +0900 +Subject: [PATCH 2/2] socket: only set pull/push functions when --save-*-trace + is used + +This allows gnutls-cli to use KTLS for the transport, unless either +--save-client-trace or --save-server-trace is used. + +Signed-off-by: Daiki Ueno +--- + src/socket.c | 16 ++++++++-------- + 1 file changed, 8 insertions(+), 8 deletions(-) + +diff --git a/src/socket.c b/src/socket.c +index 39f18dbe18..36ac292700 100644 +--- a/src/socket.c ++++ b/src/socket.c +@@ -586,16 +586,16 @@ socket_open2(socket_st * hd, const char *hostname, const char *service, + gnutls_session_set_data(hd->session, hd->rdata.data, hd->rdata.size); + } + +- if (server_trace) ++ if (client_trace || server_trace) { + hd->server_trace = server_trace; +- +- if (client_trace) + hd->client_trace = client_trace; +- +- gnutls_transport_set_push_function(hd->session, wrap_push); +- gnutls_transport_set_pull_function(hd->session, wrap_pull); +- gnutls_transport_set_pull_timeout_function(hd->session, wrap_pull_timeout_func); +- gnutls_transport_set_ptr(hd->session, hd); ++ gnutls_transport_set_push_function(hd->session, wrap_push); ++ gnutls_transport_set_pull_function(hd->session, wrap_pull); ++ gnutls_transport_set_pull_timeout_function(hd->session, wrap_pull_timeout_func); ++ gnutls_transport_set_ptr(hd->session, hd); ++ } else { ++ gnutls_transport_set_int(hd->session, hd->fd); ++ } + } + + if (!(flags & SOCKET_FLAG_RAW) && !(flags & SOCKET_FLAG_SKIP_INIT)) { +-- +2.37.1 + +From a5b671fc9105cb5dbe6e6a1c0f39fa787d862076 Mon Sep 17 00:00:00 2001 +From: Frantisek Krenzelok +Date: Fri, 29 Jul 2022 10:38:42 +0200 +Subject: [PATCH] KTLS: hotfix + +session->internals.pull_func is set to system_read during gnutls_init() +so check for user set pull/push function added in commit mentioned +bellow will never pass. + +source: 2d3cba6bb21acb40141180298f3924c73c7de8f8 + +Signed-off-by: Frantisek Krenzelok +--- + lib/handshake.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/lib/handshake.c b/lib/handshake.c +index cf025a84f6..21edc5ece9 100644 +--- a/lib/handshake.c ++++ b/lib/handshake.c +@@ -2861,7 +2861,8 @@ int gnutls_handshake(gnutls_session_t session) + + #ifdef ENABLE_KTLS + if (_gnutls_config_is_ktls_enabled()) { +- if (session->internals.pull_func || ++ if ((session->internals.pull_func && ++ session->internals.pull_func != system_read) || + session->internals.push_func) { + _gnutls_audit_log(session, + "Not enabling KTLS with " +-- +2.37.1 + diff --git a/SOURCES/gnutls-3.7.6-pkcs7-verify.patch b/SOURCES/gnutls-3.7.6-pkcs7-verify.patch new file mode 100644 index 0000000..001a6a4 --- /dev/null +++ b/SOURCES/gnutls-3.7.6-pkcs7-verify.patch @@ -0,0 +1,263 @@ +From 57afc290cd3ce2e9752a0ce5cba41ecc78fdc1bd Mon Sep 17 00:00:00 2001 +From: rpm-build +Date: Sun, 31 Jul 2022 10:39:53 +0900 +Subject: [PATCH] gnutls-3.7.6-pkcs7-verify.patch + +--- + lib/x509/pkcs7.c | 3 +- + tests/Makefile.am | 2 +- + tests/pkcs7-verify-double-free.c | 215 +++++++++++++++++++++++++++++++ + 3 files changed, 218 insertions(+), 2 deletions(-) + create mode 100644 tests/pkcs7-verify-double-free.c + +diff --git a/lib/x509/pkcs7.c b/lib/x509/pkcs7.c +index 1f35fab..d5be7f4 100644 +--- a/lib/x509/pkcs7.c ++++ b/lib/x509/pkcs7.c +@@ -1318,7 +1318,8 @@ gnutls_x509_crt_t find_signer(gnutls_pkcs7_t pkcs7, gnutls_x509_trust_list_t tl, + issuer = find_verified_issuer_of(pkcs7, issuer, purpose, vflags); + + if (issuer != NULL && gnutls_x509_crt_check_issuer(issuer, issuer)) { +- if (prev) gnutls_x509_crt_deinit(prev); ++ if (prev && prev != signer) ++ gnutls_x509_crt_deinit(prev); + prev = issuer; + break; + } +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 26e39fb..7a7a4af 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -233,7 +233,7 @@ ctests += mini-record-2 simple gnutls_hmac_fast set_pkcs12_cred cert certuniquei + tls13-without-timeout-func buffer status-request-revoked \ + set_x509_ocsp_multi_cli kdf-api keylog-func handshake-write \ + x509cert-dntypes id-on-xmppAddr tls13-compat-mode ciphersuite-name \ +- x509-upnconstraint ++ x509-upnconstraint pkcs7-verify-double-free + + ctests += tls-channel-binding + +diff --git a/tests/pkcs7-verify-double-free.c b/tests/pkcs7-verify-double-free.c +new file mode 100644 +index 0000000..fadf307 +--- /dev/null ++++ b/tests/pkcs7-verify-double-free.c +@@ -0,0 +1,215 @@ ++/* ++ * Copyright (C) 2022 Red Hat, Inc. ++ * ++ * Author: Zoltan Fridrich ++ * ++ * This file is part of GnuTLS. ++ * ++ * GnuTLS is free software: you can redistribute it and/or modify it ++ * under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * GnuTLS is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with GnuTLS. If not, see . ++ */ ++ ++#ifdef HAVE_CONFIG_H ++#include ++#endif ++ ++#include ++#include ++#include ++ ++#include "utils.h" ++ ++static char rca_pem[] = ++ "-----BEGIN CERTIFICATE-----\n" ++ "MIIDCjCCAfKgAwIBAgIBATANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQKDApFeGFt\n" ++ "cGxlIENBMCAXDTE3MDcyMTE0NDMzNloYDzIyMjIwNzIxMTQ0MzM2WjAVMRMwEQYD\n" ++ "VQQKDApFeGFtcGxlIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA\n" ++ "v8hnKPJ/IA0SQB/A/a0Uh+npZ67vsgIMrtTQo0r0kJkmkBz5323xO3DVuJfB3QmX\n" ++ "v9zvoeCQLuDvWar5Aixfxgm6s5Q+yPvJj9t3NebDrU+Y4+qyewBIJUF8EF/5iBPC\n" ++ "ZHONmzbfIRWvQWGGgb2CRcOHp2J7AY/QLB6LsWPaLjs/DHva28Q13JaTTHIpdu8v\n" ++ "t6vHr0nXf66DN4MvtoF3N+o+v3snJCMsfXOqASi4tbWR7gtOfCfiz9uBjh0W2Dut\n" ++ "/jclBQkJkLe6esNSM+f4YiOpctVDjmfj8yoHCp394vt0wFqhG38wsTFAyVP6qIcf\n" ++ "5zoSu9ovEt2cTkhnZHjiiwIDAQABo2MwYTAPBgNVHRMBAf8EBTADAQH/MA4GA1Ud\n" ++ "DwEB/wQEAwIBBjAdBgNVHQ4EFgQUhjeO6Uc5imbjOl2I2ltVA27Hu9YwHwYDVR0j\n" ++ "BBgwFoAUhjeO6Uc5imbjOl2I2ltVA27Hu9YwDQYJKoZIhvcNAQELBQADggEBAD+r\n" ++ "i/7FsbG0OFKGF2+JOnth6NjJQcMfM8LiglqAuBUijrv7vltoZ0Z3FJH1Vi4OeMXn\n" ++ "l7X/9tWUve0uFl75MfjDrf0+lCEdYRY1LCba2BrUgpbbkLywVUdnbsvndehegCgS\n" ++ "jss2/zys3Hlo3ZaHlTMQ/NQ4nrxcxkjOvkZSEOqgxJTLpzm6pr7YUts4k6c6lNiB\n" ++ "FSiJiDzsJCmWR9C3fBbUlfDfTJYGN3JwqX270KchXDElo8gNoDnF7jBMpLFFSEKm\n" ++ "MyfbNLX/srh+CEfZaN/OZV4A3MQ0L8vQEp6M4CJhvRLIuMVabZ2coJ0AzystrOMU\n" ++ "LirBWjg89RoAjFQ7bTE=\n" ++ "-----END CERTIFICATE-----\n"; ++ ++static char ca_pem[] = ++ "-----BEGIN CERTIFICATE-----\n" ++ "MIIDFzCCAf+gAwIBAgIBAjANBgkqhkiG9w0BAQsFADAVMRMwEQYDVQQKDApFeGFt\n" ++ "cGxlIENBMCAXDTE3MDcyMTE0NDQzNFoYDzIyMjIwNzIxMTQ0NDM0WjAiMSAwHgYD\n" ++ "VQQKDBdFeGFtcGxlIGludGVybWVkaWF0ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQAD\n" ++ "ggEPADCCAQoCggEBAKb9ACB8u//sP6MfNU1OsVw68xz3eTPLgKxS0vpqexm6iGVg\n" ++ "ug/o9uYRLzqiEukv/eyz9WzHmY7sqlOJjOFdv92+SaNg79Jc51WHPFXgea4/qyfr\n" ++ "4y14PGs0SNxm6T44sXurUs7cXydQVUgnq2VCaWFOTUdxXoAWkV8r8GaUoPD/klVz\n" ++ "RqxSZVETmX1XBKhsMnnov41kRwVph2C+VfUspsbaUZaz/o/S1/nokhXRACzKsMBr\n" ++ "obqiGxbY35uVzsmbAW5ErhQz98AWJL3Bub1fsEMXg6OEMmPH4AtX888dTIYZNw0E\n" ++ "bUIESspz1kjJQTtVQDHTprhwz16YiSVeUonlLgMCAwEAAaNjMGEwDwYDVR0TAQH/\n" ++ "BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFPBjxDWjMhjXERirKF9O\n" ++ "o/5Cllc5MB8GA1UdIwQYMBaAFIY3julHOYpm4zpdiNpbVQNux7vWMA0GCSqGSIb3\n" ++ "DQEBCwUAA4IBAQCTm+vv3hBa6lL5IT+Fw8aTxQ2Ne7mZ5oyazhvXYwwfKNMX3SML\n" ++ "W2JdPaL64ZwbxxxYvW401o5Z0CEgru3YFrsqB/hEdl0Uf8UWWJmE1rRa+miTmbjt\n" ++ "lrLNCWdrs6CiwvsPITTHg7jevB4KyZYsTSxQFcyr3N3xF+6EmOTC4IkhPPnXYXcp\n" ++ "248ih+WOavSYoRvzgB/Dip1WnPYU2mfIV3O8JReRryngA0TzWCLPLUoWR3R4jwtC\n" ++ "+1uSLoqaenz3qv3F1WEbke37az9YJuXx/5D8CqFQiZ62TUUtI6fYd8mkMBM4Qfh6\n" ++ "NW9XrCkI9wlpL5K9HllhuW0BhKeJkuPpyQ2p\n" ++ "-----END CERTIFICATE-----\n"; ++ ++static char ee_pem[] = ++ "-----BEGIN CERTIFICATE-----\n" ++ "MIIDIjCCAgqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQKDBdFeGFt\n" ++ "cGxlIGludGVybWVkaWF0ZSBDQTAgFw0yMjA3MjExNDQ1MzdaGA8yMjIyMDcyMTE0\n" ++ "NDUzN1owFTETMBEGA1UEAwwKSm9obiBTbWl0aDCCASIwDQYJKoZIhvcNAQEBBQAD\n" ++ "ggEPADCCAQoCggEBAMb1uuxppBFY+WVD45iyHUq7DkIJNNOI/JRaybVJfPktWq2E\n" ++ "eNe7XhV05KKnqZTbDO2iYqNHqGhZ8pz/IstDRTZP3z/q1vXTG0P9Gx28rEy5TaUY\n" ++ "QjtD+ZoFUQm0ORMDBjd8jikqtJ87hKeuOPMH4rzdydotMaPQSm7KLzHBGBr6gg7z\n" ++ "g1IxPWkhMyHapoMqqrhjwjzoTY97UIXpZTEoIA+KpEC8f9CciBtL0i1MPBjWozB6\n" ++ "Jma9q5iEwZXuRr3cnPYeIPlK2drgDZCMuSFcYiT8ApLw5OhKqY1m2EvfZ2ox2s9R\n" ++ "68/HzYdPi3kZwiNEtlBvMlpt5yKBJAflp76d7DkCAwEAAaNuMGwwCwYDVR0PBAQD\n" ++ "AgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAdBgNVHQ4EFgQUc+Mi\n" ++ "kr8WMCk00SQo+P2iggp/oQkwHwYDVR0jBBgwFoAU8GPENaMyGNcRGKsoX06j/kKW\n" ++ "VzkwDQYJKoZIhvcNAQELBQADggEBAKU9+CUR0Jcfybd1+8Aqgh1RH96yQygnVuyt\n" ++ "Na9rFz4fM3ij9tGXDHXrkZw8bW1dWLU9quu8zeTxKxc3aiDIw739Alz0tukttDo7\n" ++ "dW7YqIb77zsIsWB9p7G9dlxT6ieUy+5IKk69BbeK8KR0vAciAG4KVQxPhuPy/LGX\n" ++ "PzqlJIJ4h61s3UOroReHPB1keLZgpORqrvtpClOmABH9TLFRJA/WFg8Q2XYB/p0x\n" ++ "l/pWiaoBC+8wK9cDoMUK5yOwXeuCLffCb+UlAD0+z/qxJ2pisE8E9X8rRKRrWI+i\n" ++ "G7LtJCEn86EQK8KuRlJxKgj8lClZhoULB0oL4jbblBuNow9WRmM=\n" ++ "-----END CERTIFICATE-----\n"; ++ ++static char msg_pem[] = ++ "-----BEGIN PKCS7-----\n" ++ "MIIK2QYJKoZIhvcNAQcCoIIKyjCCCsYCAQExDTALBglghkgBZQMEAgEwCwYJKoZI\n" ++ "hvcNAQcBoIIJTzCCAwowggHyoAMCAQICAQEwDQYJKoZIhvcNAQELBQAwFTETMBEG\n" ++ "A1UECgwKRXhhbXBsZSBDQTAgFw0xNzA3MjExNDQzMjFaGA8yMjIyMDcyMTE0NDMy\n" ++ "MVowFTETMBEGA1UECgwKRXhhbXBsZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" ++ "ADCCAQoCggEBAL51eyE4j8wAKQKMGlO9HEY2iaGvsdPSJmidSdmCi1jnNK39Lx4Y\n" ++ "31h279hSHF5wtI6VM91HHfeLf1mjEZHlKrXXJQzBPLpbHWapD778drHBitOP8e56\n" ++ "fDMIfofLV4tkMk8690vPe4cJH1UHGspMyz6EQF9kPRaW80XtMV/6dalgL/9Esmaw\n" ++ "XBNPJAS1VutDuXQkJ/3/rWFLmkpYHHtGPjX782YRmT1s+VOVTsLqmKx0TEL8A381\n" ++ "bbElHPUAMjPcyWR5qqA8KWnS5Dwqk3LwI0AvuhQytCq0S7Xl4DXauvxwTRXv0UU7\n" ++ "W8r3MLAw9DnlnJiD/RFjw5rbGO3wMePk/qUCAwEAAaNjMGEwDwYDVR0TAQH/BAUw\n" ++ "AwEB/zAOBgNVHQ8BAf8EBAMCAQYwHQYDVR0OBBYEFIh2KRoKJoe2VtpOwWMkRAkR\n" ++ "mLWKMB8GA1UdIwQYMBaAFIh2KRoKJoe2VtpOwWMkRAkRmLWKMA0GCSqGSIb3DQEB\n" ++ "CwUAA4IBAQBovvlOjoy0MCT5U0eWfcPQQjY4Ssrn3IiPNlVkqSNo+FHX+2baTLVQ\n" ++ "5QTHxwXwzdIJiwtjFWDdGEQXqmuIvnFG+u/whGbeg6oQygfnQ5Y+q6epOxCsPgLQ\n" ++ "mKKEaF7mvh8DauUx4QSbYCNGCctOZuB1vlN9bJ3/5QbH+2pFPOfCr5CAyPDwHo6S\n" ++ "qO3yPcutRwT9xS7gXEHM9HhLp+DmdCGh4eVBPiFilyZm1d92lWxU8oxoSfXgzDT/\n" ++ "GCzlMykNZNs4JD9QmiRClP/3U0dQbOhah/Fda+N+L90xaqEgGcvwKKZa3pzo59pl\n" ++ "BbkcIP4YPyHeinwkgAn5UVJg9DOxNCS0MIIDFzCCAf+gAwIBAgIBAjANBgkqhkiG\n" ++ "9w0BAQsFADAVMRMwEQYDVQQKDApFeGFtcGxlIENBMCAXDTE3MDcyMTE0NDQxM1oY\n" ++ "DzIyMjIwNzIxMTQ0NDEzWjAiMSAwHgYDVQQKDBdFeGFtcGxlIGludGVybWVkaWF0\n" ++ "ZSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMPFDEvDANwvhviu\n" ++ "pwXTvaKyxyX94jVu1wgAhIRyQBVRiMbrn8MEufLG8oA0vKd8s92gv/lWe1jFb2rn\n" ++ "91jMkZWsjWjiJFD6SzqFfBo+XxOGikEqO1MAf92UqavmSGlXVRG1Vy7T7dWibZP0\n" ++ "WODhHYWayR0Y6owSz5IqNfrHXzDME+lSJxHgRFI7pK+b0OgiVmvyXDKFPvyU6GrP\n" ++ "lxXDi/XbjyPvC5gpiwtTgm+s8KERwmdlfZUNjkh2PpHx1g1joijHT3wIvO/Pek1E\n" ++ "C+Xs6w3XxGgL6TTL7FDuv4AjZVX9KK66/yBhX3aN8bkqAg+hs9XNk3zzWC0XEFOS\n" ++ "Qoh2va0CAwEAAaNjMGEwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYw\n" ++ "HQYDVR0OBBYEFHwi/7dUWGjkMWJctOm7MCjjQj1cMB8GA1UdIwQYMBaAFIh2KRoK\n" ++ "Joe2VtpOwWMkRAkRmLWKMA0GCSqGSIb3DQEBCwUAA4IBAQCF6sHCBdYRwBwvfCve\n" ++ "og9cPnmPqZrG4AtmSvtoSsMvgvKb/4z3/gG8oPtTBkeRcAHoMoEp/oA+B2ylwIAc\n" ++ "S5U7jx+lYH/Pqih0X/OcOLbaMv8uzGSGQxk+L9LuuIT6E/THfRRIPEvkDkzC+/uk\n" ++ "7vUbG17bSEWeF0o/6sjzAY2aH1jnbCDyu0UC78GXkc6bZ5QlH98uLMDMrOmqcZjS\n" ++ "JFfvuRDQyKV5yBdBkYaobsIWSQDsgYxJzf/2y8c3r+HXqT+jhrXPWJ3btgMPxpu7\n" ++ "E8KmoFgp9EM+48oYlXJ66rk08/KjaVmgN7R+Hm3e2+MFT2kme4fBKalLjcazTe3x\n" ++ "0FisMIIDIjCCAgqgAwIBAgIBATANBgkqhkiG9w0BAQsFADAiMSAwHgYDVQQKDBdF\n" ++ "eGFtcGxlIGludGVybWVkaWF0ZSBDQTAgFw0yMjA3MjExNDQ1MzBaGA8yMjIyMDcy\n" ++ "MTE0NDUzMVowFTETMBEGA1UEAwwKSm9obiBTbWl0aDCCASIwDQYJKoZIhvcNAQEB\n" ++ "BQADggEPADCCAQoCggEBAMjhSqhdD5RjmOm6W3hG7zkgKBP9whRN/SipcdEMlkgc\n" ++ "F/U3QMu66qIfKwheNdWalC1JLtruLDWP92ysa6Vw+CCG8aSax1AgB//RKQB7kgPA\n" ++ "9js9hi/oCdBmCv2HJxhWSLz+MVoxgzW4C7S9FenI+btxe/99Uw4nOw7kwjsYDLKr\n" ++ "tMw8myv7aCW/63CuBYGtohiZupM3RI3kKFcZots+KRPLlZpjv+I2h9xSln8VxKNb\n" ++ "XiMrYwGfHB7iX7ghe1TvFjKatEUhsqa7AvIq7nfe/cyq97f0ODQO814njgZtk5iQ\n" ++ "JVavXHdhTVaypt1HdAFMuHX5UATylHxx9tRCgSIijUsCAwEAAaNuMGwwCwYDVR0P\n" ++ "BAQDAgWgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDAdBgNVHQ4EFgQU\n" ++ "31+vHl4E/2Jpnwinbzf+d7usshcwHwYDVR0jBBgwFoAUfCL/t1RYaOQxYly06bsw\n" ++ "KONCPVwwDQYJKoZIhvcNAQELBQADggEBAAWe63DcNwmleQ3INFGDJZ/m2I/R/cBa\n" ++ "nnrxgR5Ey1ljHdA/x1z1JLTGmGVwqGExs5DNG9Q//Pmc9pZ1yPa8J4Xf8AvFcmkY\n" ++ "mWoH1HvW0xu/RF1UN5SAoD2PRQ+Vq4OSPD58IlEu/u4o1wZV7Wl91Cv6VNpiAb63\n" ++ "j9PA1YacOpOtcRqG59Vuj9HFm9f30ejHVo2+KJcpo290cR3Zg4fOm8mtjeMdt/QS\n" ++ "Atq+RqPAQ7yxqvEEv8zPIZj2kAOQm3mh/yYqBrR68lQUD/dBTP7ApIZkhUK3XK6U\n" ++ "nf9JvoF6Fn2+Cnqb//FLBgHSnoeqeQNwDLUXTsD02iYxHzJrhokSY4YxggFQMIIB\n" ++ "TAIBATAnMCIxIDAeBgNVBAoMF0V4YW1wbGUgaW50ZXJtZWRpYXRlIENBAgEBMAsG\n" ++ "CWCGSAFlAwQCATANBgkqhkiG9w0BAQEFAASCAQATHg6wNsBcs/Ub1GQfKwTpKCk5\n" ++ "8QXuNnZ0u7b6mKgrSY2Gf47fpL2aRgaR+BAQncbctu5EH/IL38pWjaGtOhFAj/5q\n" ++ "7luVQW11kuyJN3Bd/dtLqawWOwMmAIEigw6X50l5ZHnEVzFfxt+RKTNhk4XWVtbi\n" ++ "2iIlITOplW0rnvxYAwCxKL9ocaB7etK8au7ixMxbFp75Ts4iLX8dhlAFdCuFCk8k\n" ++ "B8mi9HHuwr3QYRqMPW61hu1wBL3yB8eoZNOwPXb0gkIh6ZvgptxgQzm/cc+Iw9fP\n" ++ "QkR0fTM7ElJ5QZmSV98AUbZDHmDvpmcjcUxfSPMc3IoT8T300usRu7QHqKJi\n" ++ "-----END PKCS7-----\n"; ++ ++const gnutls_datum_t rca_datum = { (void *)rca_pem, sizeof(rca_pem) - 1 }; ++const gnutls_datum_t ca_datum = { (void *)ca_pem, sizeof(ca_pem) - 1 }; ++const gnutls_datum_t ee_datum = { (void *)ee_pem, sizeof(ee_pem) - 1 }; ++const gnutls_datum_t msg_datum = { (void *)msg_pem, sizeof(msg_pem) - 1 }; ++ ++static void tls_log_func(int level, const char *str) ++{ ++ fprintf(stderr, "%s |<%d>| %s", "err", level, str); ++} ++ ++#define CHECK(X)\ ++{\ ++ r = X;\ ++ if (r < 0)\ ++ fail("error in %d: %s\n", __LINE__, gnutls_strerror(r));\ ++}\ ++ ++void doit(void) ++{ ++ int r; ++ gnutls_x509_crt_t rca_cert = NULL; ++ gnutls_x509_crt_t ca_cert = NULL; ++ gnutls_x509_crt_t ee_cert = NULL; ++ gnutls_x509_trust_list_t tlist = NULL; ++ gnutls_pkcs7_t pkcs7 = NULL; ++ gnutls_datum_t data = { (unsigned char *)"xxx", 3 }; ++ ++ if (debug) { ++ gnutls_global_set_log_function(tls_log_func); ++ gnutls_global_set_log_level(4711); ++ } ++ ++ // Import certificates ++ CHECK(gnutls_x509_crt_init(&rca_cert)); ++ CHECK(gnutls_x509_crt_import(rca_cert, &rca_datum, GNUTLS_X509_FMT_PEM)); ++ CHECK(gnutls_x509_crt_init(&ca_cert)); ++ CHECK(gnutls_x509_crt_import(ca_cert, &ca_datum, GNUTLS_X509_FMT_PEM)); ++ CHECK(gnutls_x509_crt_init(&ee_cert)); ++ CHECK(gnutls_x509_crt_import(ee_cert, &ee_datum, GNUTLS_X509_FMT_PEM)); ++ ++ // Setup trust store ++ CHECK(gnutls_x509_trust_list_init(&tlist, 0)); ++ CHECK(gnutls_x509_trust_list_add_named_crt(tlist, rca_cert, "rca", 3, 0)); ++ CHECK(gnutls_x509_trust_list_add_named_crt(tlist, ca_cert, "ca", 2, 0)); ++ CHECK(gnutls_x509_trust_list_add_named_crt(tlist, ee_cert, "ee", 2, 0)); ++ ++ // Setup pkcs7 structure ++ CHECK(gnutls_pkcs7_init(&pkcs7)); ++ CHECK(gnutls_pkcs7_import(pkcs7, &msg_datum, GNUTLS_X509_FMT_PEM)); ++ ++ // Signature verification ++ gnutls_pkcs7_verify(pkcs7, tlist, NULL, 0, 0, &data, 0); ++ ++ gnutls_x509_crt_deinit(rca_cert); ++ gnutls_x509_crt_deinit(ca_cert); ++ gnutls_x509_crt_deinit(ee_cert); ++ gnutls_x509_trust_list_deinit(tlist, 0); ++ gnutls_pkcs7_deinit(pkcs7); ++} +-- +2.37.1 + diff --git a/SOURCES/gnutls-3.7.6.tar.xz.sig b/SOURCES/gnutls-3.7.6.tar.xz.sig new file mode 100644 index 0000000..70cb359 Binary files /dev/null and b/SOURCES/gnutls-3.7.6.tar.xz.sig differ diff --git a/SPECS/gnutls.spec b/SPECS/gnutls.spec index 959127c..e6fab98 100644 --- a/SPECS/gnutls.spec +++ b/SPECS/gnutls.spec @@ -12,23 +12,31 @@ sha256sum:close() print(string.sub(hash, 0, 16)) } -Version: 3.7.3 -Release: 9%{?dist} -Patch1: gnutls-3.6.7-no-now-guile.patch -Patch2: gnutls-3.2.7-rpath.patch -Patch3: gnutls-3.7.2-enable-intel-cet.patch -Patch4: gnutls-3.7.2-no-explicit-init.patch -Patch5: gnutls-3.7.3-fips-rsa-keygen.patch -Patch6: gnutls-3.7.3-ktls-stub.patch -Patch7: gnutls-3.7.3-fips-pkcs12.patch -Patch8: gnutls-3.7.3-fix-tests-in-fips.patch -Patch9: gnutls-3.7.3-gost-ifdef.patch -Patch10: gnutls-3.7.3-max-algos.patch -Patch11: gnutls-3.7.3-allowlist-api.patch -Patch12: gnutls-3.7.3-libtss2-dlopen.patch +Version: 3.7.6 +Release: 12%{?dist} +# not upstreamed +Patch: gnutls-3.6.7-no-now-guile.patch +Patch: gnutls-3.2.7-rpath.patch +Patch: gnutls-3.7.2-enable-intel-cet.patch +Patch: gnutls-3.7.2-no-explicit-init.patch + +# upstreamed +Patch: gnutls-3.7.6-fips-run-selftests.patch +Patch: gnutls-3.7.6-ktls-disable-by-default.patch +Patch: gnutls-3.7.6-ktls-fixes.patch +Patch: gnutls-3.7.6-aes-gcm-pt-limit.patch +Patch: gnutls-3.7.6-pkcs7-verify.patch +Patch: gnutls-3.7.6-fips-pkcs12-des-cbc.patch +Patch: gnutls-3.7.6-fips-rsa-key-sizes.patch +Patch: gnutls-3.7.6-fips-symkey-limit.patch +Patch: gnutls-3.7.6-fips-ecdsa-hash-check.patch # not upstreamed -Patch100: gnutls-3.7.3-disable-config-reload.patch +Patch: gnutls-3.7.3-disable-config-reload.patch +Patch: gnutls-3.7.3-fips-dsa-post.patch +Patch: gnutls-3.7.6-drbg-reseed.patch +Patch: gnutls-3.7.6-cpuid-fixes.patch +Patch: gnutls-3.7.6-gmp-static.patch %bcond_without bootstrap %bcond_without dane @@ -42,13 +50,18 @@ Patch100: gnutls-3.7.3-disable-config-reload.patch %bcond_with tpm12 %bcond_without tpm2 %bcond_with gost +%bcond_with certificate_compression +%bcond_without tests Summary: A TLS protocol implementation Name: gnutls # The libraries are LGPLv2.1+, utilities are GPLv3+ License: GPLv3+ and LGPLv2+ BuildRequires: p11-kit-devel >= 0.21.3, gettext-devel -BuildRequires: zlib-devel, readline-devel, libtasn1-devel >= 4.3 +BuildRequires: readline-devel, libtasn1-devel >= 4.3 +%if %{with certificate_compression} +BuildRequires: zlib-devel, brotli-devel, libzstd-devel +%endif %if %{with bootstrap} BuildRequires: automake, autoconf, gperf, libtool %endif @@ -64,9 +77,7 @@ BuildRequires: libidn2-devel BuildRequires: libunistring-devel BuildRequires: net-tools, datefudge, softhsm, gcc, gcc-c++ BuildRequires: gnupg2 -%if %{with fips} -BuildRequires: fipscheck -%endif +BuildRequires: git-core # for a sanity check on cert loading BuildRequires: p11-kit-trust, ca-certificates @@ -88,7 +99,11 @@ BuildRequires: make URL: http://www.gnutls.org/ Source0: https://www.gnupg.org/ftp/gcrypt/gnutls/v3.7/%{name}-%{version}.tar.xz Source1: https://www.gnupg.org/ftp/gcrypt/gnutls/v3.7/%{name}-%{version}.tar.xz.sig -Source2: gpgkey-462225C3B46F34879FC8496CD605848ED7E69871.gpg +Source2: gnutls-release-keyring.gpg + +Source100: gmp-6.2.1.tar.xz +# Taken from the main gmp package +Source101: gmp-6.2.1-intel-cet.patch # Wildcard bundling exception https://fedorahosted.org/fpc/ticket/174 Provides: bundled(gnulib) = 20130424 @@ -181,11 +196,38 @@ This package contains Guile bindings for the library. %endif %prep -%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' +# Workaround: to allow building the package under FIPS, do not treat +# errors in the GPG check as fatal, where EdDSA signature verification +# is not allowed: +%{gpgverify} --keyring='%{SOURCE2}' --signature='%{SOURCE1}' --data='%{SOURCE0}' || : + +%autosetup -p1 -S git + +%if %{with fips} +mkdir -p bundled_gmp +pushd bundled_gmp +tar --strip-components=1 -xf %{SOURCE100} +patch -p1 < %{SOURCE101} +popd +%endif + +%build +%ifarch aarch64 ppc64le +%define _lto_cflags %{nil} +%endif + +%if %{with fips} +pushd bundled_gmp +autoreconf -ifv +%configure --disable-cxx --disable-shared --enable-fat --with-pic +%make_build +popd + +export GMP_CFLAGS="-I$PWD/bundled_gmp" +export GMP_LIBS="$PWD/bundled_gmp/.libs/libgmp.a" +%endif -%autosetup -p1 %if %{with bootstrap} -rm -f src/libopts/*.c src/libopts/*.h src/libopts/compat/*.c src/libopts/compat/*.h autoreconf -fi %endif @@ -194,14 +236,6 @@ rm -f lib/minitasn1/*.c lib/minitasn1/*.h echo "SYSTEM=NORMAL" >> tests/system.prio -# Note that we explicitly enable SHA1, as SHA1 deprecation is handled -# via the crypto policies - -%build -%ifarch aarch64 ppc64le -%define _lto_cflags %{nil} -%endif - %if %{with guile} # These should be checked by m4/guile.m4 instead of configure.ac # taking into account of _guile_suffix @@ -213,7 +247,7 @@ export GUILD %if %{with fips} eval $(sed -n 's/^\(\(NAME\|VERSION_ID\)=.*\)/OS_\1/p' /etc/os-release) -export FIPS_MODULE_NAME="$OS_NAME $OS_VERSION_ID %name" +export FIPS_MODULE_NAME="$OS_NAME ${OS_VERSION_ID%%.*} %name" %endif %configure \ @@ -243,6 +277,7 @@ export FIPS_MODULE_NAME="$OS_NAME $OS_VERSION_ID %name" %else --without-tpm2 \ %endif + --enable-ktls \ --htmldir=%{_docdir}/manual \ %if %{with guile} --enable-guile \ @@ -256,25 +291,30 @@ export FIPS_MODULE_NAME="$OS_NAME $OS_VERSION_ID %name" %else --disable-libdane \ %endif +%if %{with certificate_compression} + --with-zlib --with-brotli --with-zstd \ +%else + --without-zlib --without-brotli --without-zstd \ +%endif --disable-rpath \ --with-default-priority-string="@SYSTEM" -make %{?_smp_mflags} V=1 - -%if %{with fips} -%define __spec_install_post \ - %{?__debug_package:%{__debug_install_post}} \ - %{__arch_install_post} \ - %{__os_install_post} \ - rm -f $RPM_BUILD_ROOT%{_libdir}/.libgnutls.so.*.hmac \ - fipshmac -d $RPM_BUILD_ROOT%{_libdir} $RPM_BUILD_ROOT%{_libdir}/libgnutls.so.30.*.* \ - file=`basename $RPM_BUILD_ROOT%{_libdir}/libgnutls.so.30.*.hmac` && mv $RPM_BUILD_ROOT%{_libdir}/$file $RPM_BUILD_ROOT%{_libdir}/.$file && ln -s .$file $RPM_BUILD_ROOT%{_libdir}/.libgnutls.so.30.hmac \ -%{nil} -%endif +# build libgnutlsxx.so with older SONAME +make %{?_smp_mflags} V=1 CXX_LT_CURRENT=29 CXX_LT_REVISION=0 CXX_LT_AGE=1 %install make install DESTDIR=$RPM_BUILD_ROOT + +# build libgnutlsxx.so with newer SONAME +pushd lib +rm -f libgnutlsxx.la +make %{?_smp_mflags} V=1 +make install DESTDIR=$RPM_BUILD_ROOT +popd +touch doc/examples/ex-cxx + make -C doc install-html DESTDIR=$RPM_BUILD_ROOT + rm -f $RPM_BUILD_ROOT%{_infodir}/dir rm -f $RPM_BUILD_ROOT%{_libdir}/*.la rm -f $RPM_BUILD_ROOT%{_libdir}/guile/2.2/guile-gnutls*.a @@ -283,15 +323,33 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/guile/2.2/guile-gnutls*.la rm -f $RPM_BUILD_ROOT%{_libdir}/pkgconfig/gnutls-dane.pc %endif +%if %{with fips} +# doing it twice should be a no-op the second time, +# and this way we avoid redefining it and missing a future change +%{__spec_install_post} +./lib/fipshmac "$RPM_BUILD_ROOT%{_libdir}/libgnutls.so.30" > $RPM_BUILD_ROOT%{_libdir}/.gnutls.hmac +sed -i "s^$RPM_BUILD_ROOT/usr^^" $RPM_BUILD_ROOT%{_libdir}/.gnutls.hmac +%endif + +%if %{with fips} +%define __spec_install_post \ + %{?__debug_package:%{__debug_install_post}} \ + %{__arch_install_post} \ + %{__os_install_post} \ +%{nil} +%endif + %find_lang gnutls %check +%if %{with tests} make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null +%endif %files -f gnutls.lang %{_libdir}/libgnutls.so.30* %if %{with fips} -%{_libdir}/.libgnutls.so.30*.hmac +%{_libdir}/.gnutls.hmac %endif %doc README.md AUTHORS NEWS THANKS %license LICENSE doc/COPYING doc/COPYING.LESSER @@ -302,10 +360,6 @@ make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null %files devel %{_includedir}/* %{_libdir}/libgnutls*.so -%if %{with fips} -%{_libdir}/.libgnutls.so.*.hmac -%endif - %{_libdir}/pkgconfig/*.pc %{_mandir}/man3/* %{_infodir}/gnutls* @@ -343,6 +397,56 @@ make check %{?_smp_mflags} GNUTLS_SYSTEM_PRIORITY_FILE=/dev/null %endif %changelog +* Tue Sep 27 2022 Daiki Ueno - 3.7.6-12 +- fips: mark PBKDF2 with short key and output sizes non-approved +- fips: only mark HMAC as approved in PBKDF2 +- fips: mark gnutls_key_generate with short key sizes non-approved +- fips: fix checking on hash algorithm used in ECDSA +- fips: preserve operation context around FIPS selftests API + +* Fri Aug 26 2022 Daiki Ueno - 3.7.6-11 +- Supply --with{,out}-{zlib,brotli,zstd} explicitly + +* Thu Aug 25 2022 Daiki Ueno - 3.7.6-10 +- Revert nettle version pinning as it doesn't work well in side-tag + +* Thu Aug 25 2022 Daiki Ueno - 3.7.6-9 +- Pin nettle version in Requires when compiled with FIPS + +* Tue Aug 23 2022 Daiki Ueno - 3.7.6-8 +- Bundle GMP to privatize memory functions +- Disable certificate compression support by default + +* Tue Aug 23 2022 Daiki Ueno - 3.7.6-7 +- Update gnutls-3.7.6-cpuid-fixes.patch + +* Sat Aug 20 2022 Daiki Ueno - 3.7.6-6 +- Mark RSA SigVer operation approved for known modulus sizes (#2119770) +- accelerated: clear AVX bits if it cannot be queried through XSAVE + +* Thu Aug 4 2022 Daiki Ueno - 3.7.6-5 +- Block DES-CBC usage in decrypting PKCS#12 bag under FIPS (#2115314) +- sysrng: reseed source DRBG for prediction resistance + +* Fri Jul 29 2022 Daiki Ueno - 3.7.6-4 +- Make gnutls-cli work with KTLS for testing +- Fix double-free in gnutls_pkcs7_verify (#2109789) + +* Mon Jul 25 2022 Daiki Ueno - 3.7.6-3 +- Limit input size for AES-GCM according to SP800-38D (#2108635) +- Do not treat GPG verification errors as fatal +- Remove gnutls-3.7.6-libgnutlsxx-const.patch + +* Tue Jul 19 2022 Daiki Ueno - 3.7.6-2 +- Allow enabling KTLS with config file (#2108532) + +* Fri Jul 1 2022 Daiki Ueno - 3.7.6-1 +- Update to gnutls 3.7.6 (#2102591) + +* Thu Mar 31 2022 Daiki Ueno - 3.7.3-10 +- Use only the first component of VERSION from /etc/os-release (#2076626) +- Don't run power-on self-tests on DSA (#2076627) + * Fri Feb 25 2022 Daiki Ueno - 3.7.3-9 - Stop using typeof keyword for tss2 function prototypes (#2057490) - Ensure allowlist API is called before priority string construction (#1975421)