From 8889b85855996ba45112d353f94eefe62d5a187b1373471daead57cb7b06e5fc Mon Sep 17 00:00:00 2001
From: Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
Date: Mon, 15 Jul 2024 06:38:50 +0000
Subject: [PATCH] Add reproducible.patch to fix bsc#1223336  
 aes-gcm-avx512.pl: fix non-reproducibility issue

OBS-URL: https://build.opensuse.org/package/show/security:tls/openssl-3?expand=0&rev=104
---
 .gitattributes                                |   23 +
 .gitignore                                    |    1 +
 baselibs.conf                                 |   12 +
 openssl-3-use-include-directive.patch         |   35 +
 openssl-3.1.4.tar.gz                          |    3 +
 openssl-3.1.4.tar.gz.asc                      |   16 +
 openssl-3.changes                             | 1469 +++++++++++
 openssl-3.spec                                |  408 ++++
 ...sl-Add-FIPS_mode-compatibility-macro.patch |   83 +
 ...sl-Add-Kernel-FIPS-mode-flag-support.patch |   86 +
 ...PROFILE-SYSTEM-system-default-cipher.patch |  305 +++
 ...ort_for_Windows_CA_certificate_store.patch |  743 ++++++
 openssl-CVE-2023-5678.patch                   |  172 ++
 openssl-CVE-2023-6129.patch                   |  109 +
 openssl-CVE-2023-6237.patch                   |  122 +
 openssl-CVE-2024-0727.patch                   |  120 +
 openssl-CVE-2024-2511.patch                   |  116 +
 openssl-CVE-2024-4603.patch                   |  199 ++
 openssl-DEFAULT_SUSE_cipher.patch             |   64 +
 ...able-default-provider-for-test-suite.patch |   19 +
 ...nable-BTI-feature-for-md5-on-aarch64.patch |   28 +
 openssl-FIPS-embed-hmac.patch                 |  250 ++
 ...EVP_PKEY_CTX_add1_hkdf_info-behavior.patch |  309 +++
 openssl-Force-FIPS.patch                      |   68 +
 ...param-in-EVP_PKEY_CTX_add1_hkdf_info.patch |   94 +
 ...nce-for-6x-unrolling-with-vpermxor-i.patch |  495 ++++
 openssl-crypto-policies-support.patch         |   35 +
 openssl-disable-fipsinstall.patch             |  470 ++++
 ...-Limb-Solinas-Strategy-for-secp384r1.patch | 2159 +++++++++++++++++
 ...nkage-on-nistp521-felem_-square-mul-.patch |   65 +
 ...dd-asm-implementation-of-felem_-squa.patch |  428 ++++
 ...-extraneous-parentheses-in-secp384r1.patch |   76 +
 openssl-load-legacy-provider.patch            |   90 +
 openssl-no-date.patch                         |   13 +
 openssl-no-html-docs.patch                    |   13 +
 openssl-pkgconfig.patch                       |   22 +
 ...c-Fix-stack-allocation-secp384r1-asm.patch |   96 +
 openssl-ppc64-config.patch                    |   32 +
 openssl-truststore.patch                      |   17 +
 openssl.keyring                               |  305 +++
 reproducible.patch                            |  929 +++++++
 showciphers.c                                 |   27 +
 42 files changed, 10126 insertions(+)
 create mode 100644 .gitattributes
 create mode 100644 .gitignore
 create mode 100644 baselibs.conf
 create mode 100644 openssl-3-use-include-directive.patch
 create mode 100644 openssl-3.1.4.tar.gz
 create mode 100644 openssl-3.1.4.tar.gz.asc
 create mode 100644 openssl-3.changes
 create mode 100644 openssl-3.spec
 create mode 100644 openssl-Add-FIPS_mode-compatibility-macro.patch
 create mode 100644 openssl-Add-Kernel-FIPS-mode-flag-support.patch
 create mode 100644 openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
 create mode 100644 openssl-Add_support_for_Windows_CA_certificate_store.patch
 create mode 100644 openssl-CVE-2023-5678.patch
 create mode 100644 openssl-CVE-2023-6129.patch
 create mode 100644 openssl-CVE-2023-6237.patch
 create mode 100644 openssl-CVE-2024-0727.patch
 create mode 100644 openssl-CVE-2024-2511.patch
 create mode 100644 openssl-CVE-2024-4603.patch
 create mode 100644 openssl-DEFAULT_SUSE_cipher.patch
 create mode 100644 openssl-Disable-default-provider-for-test-suite.patch
 create mode 100644 openssl-Enable-BTI-feature-for-md5-on-aarch64.patch
 create mode 100644 openssl-FIPS-embed-hmac.patch
 create mode 100644 openssl-Fix-EVP_PKEY_CTX_add1_hkdf_info-behavior.patch
 create mode 100644 openssl-Force-FIPS.patch
 create mode 100644 openssl-Handle-empty-param-in-EVP_PKEY_CTX_add1_hkdf_info.patch
 create mode 100644 openssl-Improve-performance-for-6x-unrolling-with-vpermxor-i.patch
 create mode 100644 openssl-crypto-policies-support.patch
 create mode 100644 openssl-disable-fipsinstall.patch
 create mode 100644 openssl-ec-56-bit-Limb-Solinas-Strategy-for-secp384r1.patch
 create mode 100644 openssl-ec-Use-static-linkage-on-nistp521-felem_-square-mul-.patch
 create mode 100644 openssl-ec-powerpc64le-Add-asm-implementation-of-felem_-squa.patch
 create mode 100644 openssl-ecc-Remove-extraneous-parentheses-in-secp384r1.patch
 create mode 100644 openssl-load-legacy-provider.patch
 create mode 100644 openssl-no-date.patch
 create mode 100644 openssl-no-html-docs.patch
 create mode 100644 openssl-pkgconfig.patch
 create mode 100644 openssl-powerpc-ecc-Fix-stack-allocation-secp384r1-asm.patch
 create mode 100644 openssl-ppc64-config.patch
 create mode 100644 openssl-truststore.patch
 create mode 100644 openssl.keyring
 create mode 100644 reproducible.patch
 create mode 100644 showciphers.c

diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..9b03811
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,23 @@
+## Default LFS
+*.7z filter=lfs diff=lfs merge=lfs -text
+*.bsp filter=lfs diff=lfs merge=lfs -text
+*.bz2 filter=lfs diff=lfs merge=lfs -text
+*.gem filter=lfs diff=lfs merge=lfs -text
+*.gz filter=lfs diff=lfs merge=lfs -text
+*.jar filter=lfs diff=lfs merge=lfs -text
+*.lz filter=lfs diff=lfs merge=lfs -text
+*.lzma filter=lfs diff=lfs merge=lfs -text
+*.obscpio filter=lfs diff=lfs merge=lfs -text
+*.oxt filter=lfs diff=lfs merge=lfs -text
+*.pdf filter=lfs diff=lfs merge=lfs -text
+*.png filter=lfs diff=lfs merge=lfs -text
+*.rpm filter=lfs diff=lfs merge=lfs -text
+*.tbz filter=lfs diff=lfs merge=lfs -text
+*.tbz2 filter=lfs diff=lfs merge=lfs -text
+*.tgz filter=lfs diff=lfs merge=lfs -text
+*.ttf filter=lfs diff=lfs merge=lfs -text
+*.txz filter=lfs diff=lfs merge=lfs -text
+*.whl filter=lfs diff=lfs merge=lfs -text
+*.xz filter=lfs diff=lfs merge=lfs -text
+*.zip filter=lfs diff=lfs merge=lfs -text
+*.zst filter=lfs diff=lfs merge=lfs -text
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..57affb6
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+.osc
diff --git a/baselibs.conf b/baselibs.conf
new file mode 100644
index 0000000..0c211d7
--- /dev/null
+++ b/baselibs.conf
@@ -0,0 +1,12 @@
+libopenssl3
+  obsoletes "libopenssl1_1_0-<targettype>"
+  provides "libopenssl3-hmac-<targettype> = <version>-%release"
+  obsoletes "libopenssl3-hmac-<targettype> < <version>-%release"
+libopenssl-3-devel
+  provides "libopenssl-devel-<targettype> = <version>"
+  conflicts "otherproviders(libopenssl-devel-<targettype>)"
+  conflicts "libopenssl-1_1-devel-<targettype>"
+  requires -"openssl-3-<targettype>"
+  requires "libopenssl3-<targettype> = <version>"
+libopenssl-3-fips-provider
+  requires "libopenssl3-<targettype> >= <version>"
diff --git a/openssl-3-use-include-directive.patch b/openssl-3-use-include-directive.patch
new file mode 100644
index 0000000..d3ed451
--- /dev/null
+++ b/openssl-3-use-include-directive.patch
@@ -0,0 +1,35 @@
+---
+ apps/openssl.cnf |   13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+Index: openssl-3.1.4/apps/openssl.cnf
+===================================================================
+--- openssl-3.1.4.orig/apps/openssl.cnf
++++ openssl-3.1.4/apps/openssl.cnf
+@@ -19,6 +19,7 @@ openssl_conf = openssl_init
+ # Comment out the next line to ignore configuration errors
+ config_diagnostics = 1
+ 
++[ oid_section ]
+ # Extra OBJECT IDENTIFIER info:
+ # oid_file       = $ENV::HOME/.oid
+ oid_section = new_oids
+@@ -47,6 +48,18 @@ providers = provider_sect
+ # Load default TLS policy configuration
+ ssl_conf = ssl_module
+ 
++engines = engine_section
++
++[ engine_section ]
++
++# This include will look through the directory that will contain the
++# engine declarations for any engines provided by other packages.
++.include /etc/ssl/engines3.d
++
++# This include will look through the directory that will contain the
++# definitions of the engines declared in the engine section.
++.include /etc/ssl/engdef3.d
++
+ # Uncomment the sections that start with ## below to enable the legacy provider.
+ # Loading the legacy provider enables support for the following algorithms:
+ # Hashing Algorithms / Message Digests: MD2, MD4, MDC2, WHIRLPOOL, RIPEMD160
diff --git a/openssl-3.1.4.tar.gz b/openssl-3.1.4.tar.gz
new file mode 100644
index 0000000..dde84fd
--- /dev/null
+++ b/openssl-3.1.4.tar.gz
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:840af5366ab9b522bde525826be3ef0fb0af81c6a9ebd84caa600fea1731eee3
+size 15569450
diff --git a/openssl-3.1.4.tar.gz.asc b/openssl-3.1.4.tar.gz.asc
new file mode 100644
index 0000000..d7c5025
--- /dev/null
+++ b/openssl-3.1.4.tar.gz.asc
@@ -0,0 +1,16 @@
+-----BEGIN PGP SIGNATURE-----
+
+iQIzBAABCAAdFiEE78CkZ9YTy4PH7W0w2JTizos9efUFAmU3yaoACgkQ2JTizos9
+efXt8BAAqcF9RBzduklMCXSfG4Rzs2KcWmR1+BB0izxG3KwPr+r54qBbSRCCImHA
+U22An//xsDsQZ0K4rrkkkumpJCxLV/4F3TlEBdoCS4wzDXz/LfONzTuZ8Z3QP/Si
+ElHTKdqPo2tp6LrDIUSGa9BmK1AsxkhOoC/uJlGpLP0mLJGI3PGo5ordyERAjL/C
+hTumE16ErrXY3kHVPAeD6tJlxtV3M9UxsZAOK6LVfnhXLzz8hWMu2H5ZigXZWCDx
+NG6ylV4xxfqO9eLxT2wUrJzg24w0VZzmbD+ZeZ24v9aAxGsbl3ZHLgMKkDehNNuP
+0ADh3aGq9FkIg5n53UQu0pbOc6aBPgWwVuaNfxOheG2GqBCoca42ikW20QZyJAec
+h3uLQ76vnWOjUIjeRCjpw0+OCUaWr0wx5WzzfdgYc813VwN6FaC9ZmB46oaLfIeD
+MBAyuUxdTif/7SXmGgUIQDIf4Vxr2H7I0NyyDxD+y+C2gwn+zVvuVcBBc2cNq4QN
+UINxZvm75CwaCsys+MDjSneDhpcSlAPqTJqM3DvKf/r3+27buz+sFw463fTHnv0F
+FpyBPgvvusY4Z4h/jqLcfkl2MBOxlo+lpZJdPpQoEvGz751GsKmmtb0YgZ7BjrYs
+5vFvo0EJ066J9bWLbp6VZd825B9P2Uy7u3sUz+E5nuavT4eHv7o=
+=EH33
+-----END PGP SIGNATURE-----
diff --git a/openssl-3.changes b/openssl-3.changes
new file mode 100644
index 0000000..79a2f49
--- /dev/null
+++ b/openssl-3.changes
@@ -0,0 +1,1469 @@
+-------------------------------------------------------------------
+Mon Jul 15 05:52:07 UTC 2024 - Bernhard Wiedemann <bwiedemann@suse.com>
+
+- Add reproducible.patch to fix bsc#1223336
+  aes-gcm-avx512.pl: fix non-reproducibility issue
+
+-------------------------------------------------------------------
+Wed May 29 13:30:21 UTC 2024 - Martin Wilck <mwilck@suse.com>
+
+- Fix HDKF key derivation (bsc#1225291, gh#openssl/openssl#23448,
+  gh#openssl/openssl#23456)
+  * Add openssl-Fix-EVP_PKEY_CTX_add1_hkdf_info-behavior.patch
+  * Add openssl-Handle-empty-param-in-EVP_PKEY_CTX_add1_hkdf_info.patch
+
+-------------------------------------------------------------------
+Mon May 20 12:24:03 UTC 2024 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Security fix: [bsc#1224388, CVE-2024-4603]
+  * Check DSA parameters for excessive sizes before validating
+  * Add openssl-CVE-2024-4603.patch
+
+-------------------------------------------------------------------
+Tue May  7 13:35:31 UTC 2024 - Giuliano Belinassi <giuliano.belinassi@suse.com>
+
+- Enable livepatching support (bsc#1223428)
+
+-------------------------------------------------------------------
+Tue May  7 11:51:38 UTC 2024 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Add ktls capability [bsc#1216950]
+  Already added in January, but not mentioned in this changelog.
+
+-------------------------------------------------------------------
+Mon May  6 12:11:02 UTC 2024 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Security fix: [bsc#1222548, CVE-2024-2511]
+  * Fix unconstrained session cache growth in TLSv1.3
+  * Add openssl-CVE-2024-2511.patch
+
+-------------------------------------------------------------------
+Fri Feb 23 11:31:44 UTC 2024 - Pedro Monreal <pmonreal@suse.com>
+
+- Build the 32bit flavor of libopenssl-3-fips-provider [bsc#1220232]
+  * Update baselibs.conf
+
+-------------------------------------------------------------------
+Mon Feb  5 16:29:26 UTC 2024 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Add migration script to move old files (bsc#1219562)
+  /etc/ssl/engines.d/* -> /etc/ssl/engines1.1.d.rpmsave
+  /etc/ssl/engdef.d/* -> /etc/ssl/engdef1.1.d.rpmsave
+  They will be later restored by openssl-1_1 package
+  to engines1.1.d and engdef1.1.d
+
+-------------------------------------------------------------------
+Tue Jan 30 14:15:25 UTC 2024 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Security fix: [bsc#1219243, CVE-2024-0727]
+  * Add NULL checks where ContentInfo data can be NULL
+  * Add openssl-CVE-2024-0727.patch
+
+-------------------------------------------------------------------
+Mon Jan 29 15:17:22 UTC 2024 - Pedro Monreal <pmonreal@suse.com>
+
+- Encapsulate the fips provider into a new package called
+  libopenssl-3-fips-provider.
+
+-------------------------------------------------------------------
+Mon Jan 22 09:34:28 UTC 2024 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Added openssl-3-use-include-directive.patch so that the default
+  /etc/ssl/openssl.cnf file will include any configuration files that
+  other packages might place into /etc/ssl/engines3.d/ and
+  /etc/ssl/engdef3.d/. Also create symbolic links /etc/ssl/engines.d/
+  and /etc/ssl/engdef.d/ to above versioned directories.
+- Updated spec file to create the two new necessary directores for
+  the above patch and two symbolic links to above directories.
+  [bsc#1194187, bsc#1207472, bsc#1218933]
+
+-------------------------------------------------------------------
+Tue Jan 16 09:45:24 UTC 2024 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Security fix: [bsc#1218810, CVE-2023-6237]
+  * Limit the execution time of RSA public key check
+  * Add openssl-CVE-2023-6237.patch
+
+-------------------------------------------------------------------
+Sun Jan 14 13:36:33 UTC 2024 - Pedro Monreal <pmonreal@suse.com>
+
+- Rename openssl-Override-default-paths-for-the-CA-directory-tree.patch
+  to openssl-crypto-policies-support.patch
+
+-------------------------------------------------------------------
+Sat Jan 13 23:59:27 UTC 2024 - Pedro Monreal <pmonreal@suse.com>
+
+- Embed the FIPS hmac. Add openssl-FIPS-embed-hmac.patch
+
+-------------------------------------------------------------------
+Sat Jan 13 22:31:15 UTC 2024 - Pedro Monreal <pmonreal@suse.com>
+
+- Load the FIPS provider and set FIPS properties implicitly.
+  * Add openssl-Force-FIPS.patch [bsc#1217934]
+- Disable the fipsinstall command-line utility.
+  * Add openssl-disable-fipsinstall.patch
+- Add instructions to load legacy provider in openssl.cnf.
+  * openssl-load-legacy-provider.patch
+- Disable the default provider for the test suite.
+  * openssl-Disable-default-provider-for-test-suite.patch
+
+-------------------------------------------------------------------
+Thu Jan 11 08:07:48 UTC 2024 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Security fix: [bsc#1218690, CVE-2023-6129]
+  * POLY1305: Fix vector register clobbering on PowerPC
+  * Add openssl-CVE-2023-6129.patch
+
+-------------------------------------------------------------------
+Thu Dec  7 09:54:17 UTC 2023 - Guillaume GARDET <guillaume.gardet@opensuse.org>
+
+- Add patch to fix BTI enablement on aarch64:
+  * openssl-Enable-BTI-feature-for-md5-on-aarch64.patch
+
+-------------------------------------------------------------------
+Mon Nov 13 09:29:26 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Security fix: [bsc#1216922, CVE-2023-5678]
+  * Fix excessive time spent in DH check / generation with large Q
+    parameter value.
+  * Applications that use the functions DH_generate_key() to generate
+    an X9.42 DH key may experience long delays. Likewise,
+    applications that use DH_check_pub_key(), DH_check_pub_key_ex
+    () or EVP_PKEY_public_check() to check an X9.42 DH key or X9.42
+    DH parameters may experience long delays. Where the key or
+    parameters that are being checked have been obtained from an
+    untrusted source this may lead to a Denial of Service.
+  * Add openssl-CVE-2023-5678.patch
+
+-------------------------------------------------------------------
+Tue Oct 24 14:53:41 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Update to 3.1.4:
+  * Fix incorrect key and IV resizing issues when calling
+    EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() or EVP_CipherInit_ex2()
+    with OSSL_PARAM parameters that alter the key or IV length
+    [bsc#1216163, CVE-2023-5363].
+
+-------------------------------------------------------------------
+Thu Oct 19 15:03:14 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Performance enhancements for cryptography from OpenSSL 3.2
+  [jsc#PED-5086, jsc#PED-3514]
+  * Add patches:
+    - openssl-ec-Use-static-linkage-on-nistp521-felem_-square-mul-.patch
+    - openssl-ec-56-bit-Limb-Solinas-Strategy-for-secp384r1.patch
+    - openssl-ec-powerpc64le-Add-asm-implementation-of-felem_-squa.patch
+    - openssl-ecc-Remove-extraneous-parentheses-in-secp384r1.patch
+    - openssl-powerpc-ecc-Fix-stack-allocation-secp384r1-asm.patch
+    - openssl-Improve-performance-for-6x-unrolling-with-vpermxor-i.patch
+
+-------------------------------------------------------------------
+Thu Oct 19 11:53:29 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- FIPS: Add the FIPS_mode() compatibility macro and flag support.
+  * Add patches:
+    - openssl-Add-FIPS_mode-compatibility-macro.patch
+    - openssl-Add-Kernel-FIPS-mode-flag-support.patch
+
+-------------------------------------------------------------------
+Thu Oct 12 09:44:19 UTC 2023 - <jengelh@inai.de>
+
+- As of openssl 3.1.3, the devel package installs at least 5200
+  manpage files and is the owner of the most files in the man3
+  directory (in second place after lapack-man); move these manpages
+  off to the -doc subpackage to reduce the walltime to install just
+  openssl-3-devel (because there is also an invocation of mandb
+  that runs at some point).
+
+-------------------------------------------------------------------
+Tue Sep 19 14:17:56 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Update to 3.1.3:
+  * Fix POLY1305 MAC implementation corrupting XMM registers on
+    Windows (CVE-2023-4807)
+
+-------------------------------------------------------------------
+Tue Aug  1 15:24:46 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.1.2:
+  * Fix excessive time spent checking DH q parameter value
+    (bsc#1213853, CVE-2023-3817). The function DH_check() performs
+    various checks on DH parameters. After fixing CVE-2023-3446 it
+    was discovered that a large q parameter value can also trigger
+    an overly long computation during some of these checks. A
+    correct q value, if present, cannot be larger than the modulus
+    p parameter, thus it is unnecessary to perform these checks if
+    q is larger than p. If DH_check() is called with such q parameter
+    value, DH_CHECK_INVALID_Q_VALUE return flag is set and the
+    computationally intensive checks are skipped.
+  * Fix DH_check() excessive time with over sized modulus
+    (bsc#1213487, CVE-2023-3446). The function DH_check() performs
+    various checks on DH parameters. One of those checks confirms
+    that the modulus ("p" parameter) is not too large. Trying to use
+    a very large modulus is slow and OpenSSL will not normally use
+    a modulus which is over 10,000 bits in length. However the
+    DH_check() function checks numerous aspects of the key or
+    parameters that have been supplied. Some of those checks use the
+    supplied modulus value even if it has already been found to be
+    too large. A new limit has been added to DH_check of 32,768 bits.
+    Supplying a key/parameters with a modulus over this size will
+    simply cause DH_check() to fail.
+  * Do not ignore empty associated data entries with AES-SIV
+    (bsc#1213383, CVE-2023-2975). The AES-SIV algorithm allows for
+    authentication of multiple associated data entries along with the
+    encryption. To authenticate empty data the application has to call
+    EVP_EncryptUpdate() (or EVP_CipherUpdate()) with NULL pointer as
+    the output buffer and 0 as the input buffer length. The AES-SIV
+    implementation in OpenSSL just returns success for such call
+    instead of performing the associated data authentication operation.
+    The empty data thus will not be authenticated. The fix changes the
+    authentication tag value and the ciphertext for applications that
+    use empty associated data entries with AES-SIV. To decrypt data
+    encrypted with previous versions of OpenSSL the application has to
+    skip calls to EVP_DecryptUpdate() for empty associated data entries.
+  * When building with the enable-fips option and using the resulting
+    FIPS provider, TLS 1.2 will, by default, mandate the use of an
+    extended master secret (FIPS 140-3 IG G.Q) and the Hash and HMAC
+    DRBGs will not operate with truncated digests (FIPS 140-3 IG G.R).
+  * Update openssl.keyring with the OTC members that sign releases
+  * Remove openssl-z16-s390x.patch fixed upstream in
+    https://github.com/openssl/openssl/pull/21284
+  * Remove security patches fixed upstream:
+    - openssl-CVE-2023-2975.patch
+    - openssl-CVE-2023-3446.patch
+    - openssl-CVE-2023-3446-test.patch
+
+-------------------------------------------------------------------
+Thu Jul 20 07:48:20 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- Security fix: [bsc#1213487, CVE-2023-3446]
+  * Fix DH_check() excessive time with over sized modulus.
+  * The function DH_check() performs various checks on DH parameters.
+    One of those checks confirms that the modulus ("p" parameter) is
+    not too large. Trying to use a very large modulus is slow and
+    OpenSSL will not normally use a modulus which is over 10,000 bits
+    in length.
+    However the DH_check() function checks numerous aspects of the
+    key or parameters that have been supplied. Some of those checks
+    use the supplied modulus value even if it has already been found
+    to be too large.
+    A new limit has been added to DH_check of 32,768 bits. Supplying
+    a key/parameters with a modulus over this size will simply cause
+    DH_check() to fail.
+  * Add openssl-CVE-2023-3446.patch openssl-CVE-2023-3446-test.patch
+
+-------------------------------------------------------------------
+Tue Jul 18 07:32:49 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- Security fix: [bsc#1213383, CVE-2023-2975]
+  * AES-SIV implementation ignores empty associated data entries
+  * Add openssl-CVE-2023-2975.patch
+
+-------------------------------------------------------------------
+Tue Jun 20 15:18:56 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Improve cross-package provides/conflicts [boo#1210313]
+  * Add Provides/Conflicts: ssl-devel
+  * Remove explicit conflicts with other devel-libraries
+  * Remove Provides: openssl(cli) - it's managed by meta package
+
+-------------------------------------------------------------------
+Tue May 30 15:14:51 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Update to 3.1.1:
+  * Restrict the size of OBJECT IDENTIFIERs that OBJ_obj2txt will translate
+    (CVE-2023-2650, bsc#1211430)
+  * Multiple algorithm implementation fixes for ARM BE platforms.
+  * Added a -pedantic option to fipsinstall that adjusts the various settings
+    to ensure strict FIPS compliance rather than backwards compatibility.
+  * Fixed buffer overread in AES-XTS decryption on ARM 64 bit platforms which
+    happens if the buffer size is 4 mod 5 in 16 byte AES blocks. This can
+    trigger a crash of an application using AES-XTS decryption if the memory
+    just after the buffer being decrypted is not mapped. Thanks to Anton
+    Romanov (Amazon) for discovering the issue. (CVE-2023-1255, bsc#1210714)
+  * Add FIPS provider configuration option to disallow the use of truncated
+    digests with Hash and HMAC DRBGs (q.v. FIPS 140-3 IG D.R.). The
+    option '-no_drbg_truncated_digests' can optionally be supplied
+    to 'openssl fipsinstall'.
+  * Corrected documentation of X509_VERIFY_PARAM_add0_policy() to mention that
+    it does not enable policy checking. Thanks to David Benjamin for
+    discovering this issue. (CVE-2023-0466, bsc#1209873)
+  * Fixed an issue where invalid certificate policies in leaf certificates are
+    silently ignored by OpenSSL and other certificate policy checks are
+    skipped for that certificate. A malicious CA could use this to
+    deliberately assert invalid certificate policies in order to circumvent
+    policy checking on the certificate altogether. (CVE-2023-0465, bsc#1209878)
+  * Limited the number of nodes created in a policy tree to mitigate against
+    CVE-2023-0464. The default limit is set to 1000 nodes, which should be
+    sufficient for most installations. If required, the limit can be adjusted
+    by setting the OPENSSL_POLICY_TREE_NODES_MAX build time define to a
+    desired maximum number of nodes or zero to allow unlimited growth.
+    (CVE-2023-0464, bsc#1209624)
+  * Update openssl.keyring with key
+    A21F AB74 B008 8AA3 6115 2586 B8EF 1A6B A9DA 2D5C (Tomas Mraz)
+  * Rebased patches:
+    - openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
+    - openssl-Add_support_for_Windows_CA_certificate_store.patch
+  * Removed patches:
+    - openssl-CVE-2023-0464.patch
+    - openssl-Fix-OBJ_nid2obj-regression.patch
+    - openssl-CVE-2023-0465.patch
+    - openssl-CVE-2023-0466.patch
+
+-------------------------------------------------------------------
+Mon May 29 07:31:07 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- FIPS: Merge libopenssl3-hmac package into the library [bsc#1185116]
+
+-------------------------------------------------------------------
+Mon May 15 09:00:04 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Add support for Windows CA certificate store [bsc#1209430]
+  https://github.com/openssl/openssl/pull/18070
+  * Add openssl-Add_support_for_Windows_CA_certificate_store.patch
+
+-------------------------------------------------------------------
+Wed Mar 29 12:11:10 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Security Fix: [CVE-2023-0465, bsc#1209878]
+  * Invalid certificate policies in leaf certificates are silently ignored
+  * Add openssl-CVE-2023-0465.patch
+- Security Fix: [CVE-2023-0466, bsc#1209873]
+  * Certificate policy check not enabled
+  * Add openssl-CVE-2023-0466.patch
+
+-------------------------------------------------------------------
+Tue Mar 28 12:19:06 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- Fix regression in the OBJ_nid2obj() function: [bsc#1209430]
+  * Upstream https://github.com/openssl/openssl/issues/20555
+  * Add openssl-Fix-OBJ_nid2obj-regression.patch
+
+-------------------------------------------------------------------
+Mon Mar 27 14:44:32 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Fix compiler error "initializer element is not constant" on s390
+  * Add openssl-z16-s390x.patch
+
+-------------------------------------------------------------------
+Fri Mar 24 13:55:25 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Security Fix: [CVE-2023-0464, bsc#1209624]
+  * Excessive Resource Usage Verifying X.509 Policy Constraints
+  * Add openssl-CVE-2023-0464.patch
+
+-------------------------------------------------------------------
+Wed Mar 15 14:55:29 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Pass over with spec-cleaner
+
+-------------------------------------------------------------------
+Tue Mar 14 13:34:13 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Update to 3.1.0:
+  * Add FIPS provider configuration option to enforce the Extended Master
+    Secret (EMS) check during the TLS1_PRF KDF. The option '-ems-check' can
+    optionally be supplied to 'openssl fipsinstall'.
+  * The FIPS provider includes a few non-approved algorithms for backward
+    compatibility purposes and the "fips=yes" property query must be used for
+    all algorithm fetches to ensure FIPS compliance. The algorithms that are
+    included but not approved are Triple DES ECB, Triple DES CBC and EdDSA.
+  * Added support for KMAC in KBKDF.
+  * RNDR and RNDRRS support in provider functions to provide random number
+    generation for Arm CPUs (aarch64).
+  * s_client and s_server apps now explicitly say when the TLS version does not
+    include the renegotiation mechanism. This avoids confusion between that
+    scenario versus when the TLS version includes secure renegotiation but the
+    peer lacks support for it.
+  * AES-GCM enabled with AVX512 vAES and vPCLMULQDQ.
+  * The various OBJ_* functions have been made thread safe.
+  * Parallel dual-prime 1536/2048-bit modular exponentiation for AVX512_IFMA
+    capable processors.
+  * The functions OPENSSL_LH_stats, OPENSSL_LH_node_stats,
+    OPENSSL_LH_node_usage_stats, OPENSSL_LH_stats_bio,
+    OPENSSL_LH_node_stats_bio and OPENSSL_LH_node_usage_stats_bio are now
+    marked deprecated from OpenSSL 3.1 onwards and can be disabled by defining
+    OPENSSL_NO_DEPRECATED_3_1. The macro DEFINE_LHASH_OF is now deprecated in
+    favour of the macro DEFINE_LHASH_OF_EX, which omits the corresponding
+    type-specific function definitions for these functions regardless of
+    whether OPENSSL_NO_DEPRECATED_3_1 is defined. Users of DEFINE_LHASH_OF may
+    start receiving deprecation warnings for these functions regardless of
+    whether they are using them. It is recommended that users transition to the
+    new macro, DEFINE_LHASH_OF_EX.
+  * When generating safe-prime DH parameters set the recommended private key
+    length equivalent to minimum key lengths as in RFC 7919.
+  * Change the default salt length for PKCS#1 RSASSA-PSS signatures to the
+    maximum size that is smaller or equal to the digest length to comply with
+    FIPS 186-4 section 5. This is implemented by a new option
+    OSSL_PKEY_RSA_PSS_SALT_LEN_AUTO_DIGEST_MAX ("auto-digestmax") for the
+    rsa_pss_saltlen parameter, which is now the default. Signature verification
+    is not affected by this change and continues to work as before.
+  * Update openssl.keyring with key
+    8657 ABB2 60F0 56B1 E519 0839 D9C4 D26D 0E60 4491 (Matt Caswell)
+
+-------------------------------------------------------------------
+Wed Mar  8 10:37:09 UTC 2023 - Martin Pluskal <mpluskal@suse.com>
+
+- Build AVX2 enabled hwcaps library for x86_64-v3
+
+-------------------------------------------------------------------
+Tue Feb  7 15:43:22 UTC 2023 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Update to 3.0.8:
+  * Fixed NULL dereference during PKCS7 data verification.
+    A NULL pointer can be dereferenced when signatures are being
+    verified on PKCS7 signed or signedAndEnveloped data. In case the hash
+    algorithm used for the signature is known to the OpenSSL library but
+    the implementation of the hash algorithm is not available the digest
+    initialization will fail. There is a missing check for the return
+    value from the initialization function which later leads to invalid
+    usage of the digest API most likely leading to a crash.
+    ([bsc#1207541, CVE-2023-0401])
+
+    PKCS7 data is processed by the SMIME library calls and also by the
+    time stamp (TS) library calls. The TLS implementation in OpenSSL does
+    not call these functions however third party applications would be
+    affected if they call these functions to verify signatures on untrusted
+    data.
+  * Fixed X.400 address type confusion in X.509 GeneralName.
+    There is a type confusion vulnerability relating to X.400 address processing
+    inside an X.509 GeneralName. X.400 addresses were parsed as an ASN1_STRING
+    but the public structure definition for GENERAL_NAME incorrectly specified
+    the type of the x400Address field as ASN1_TYPE. This field is subsequently
+    interpreted by the OpenSSL function GENERAL_NAME_cmp as an ASN1_TYPE rather
+    than an ASN1_STRING.
+
+    When CRL checking is enabled (i.e. the application sets the
+    X509_V_FLAG_CRL_CHECK flag), this vulnerability may allow an attacker to
+    pass arbitrary pointers to a memcmp call, enabling them to read memory
+    contents or enact a denial of service.
+    ([bsc#1207533, CVE-2023-0286])
+  * Fixed NULL dereference validating DSA public key.
+    An invalid pointer dereference on read can be triggered when an
+    application tries to check a malformed DSA public key by the
+    EVP_PKEY_public_check() function. This will most likely lead
+    to an application crash. This function can be called on public
+    keys supplied from untrusted sources which could allow an attacker
+    to cause a denial of service attack.
+
+    The TLS implementation in OpenSSL does not call this function
+    but applications might call the function if there are additional
+    security requirements imposed by standards such as FIPS 140-3.
+    ([bsc#1207540, CVE-2023-0217])
+  * Fixed Invalid pointer dereference in d2i_PKCS7 functions.
+    An invalid pointer dereference on read can be triggered when an
+    application tries to load malformed PKCS7 data with the
+    d2i_PKCS7(), d2i_PKCS7_bio() or d2i_PKCS7_fp() functions.
+
+    The result of the dereference is an application crash which could
+    lead to a denial of service attack. The TLS implementation in OpenSSL
+    does not call this function however third party applications might
+    call these functions on untrusted data.
+    ([bsc#1207539, CVE-2023-0216])
+  * Fixed Use-after-free following BIO_new_NDEF.
+    The public API function BIO_new_NDEF is a helper function used for
+    streaming ASN.1 data via a BIO. It is primarily used internally to OpenSSL
+    to support the SMIME, CMS and PKCS7 streaming capabilities, but may also
+    be called directly by end user applications.
+
+    The function receives a BIO from the caller, prepends a new BIO_f_asn1
+    filter BIO onto the front of it to form a BIO chain, and then returns
+    the new head of the BIO chain to the caller. Under certain conditions,
+    for example if a CMS recipient public key is invalid, the new filter BIO
+    is freed and the function returns a NULL result indicating a failure.
+    However, in this case, the BIO chain is not properly cleaned up and the
+    BIO passed by the caller still retains internal pointers to the previously
+    freed filter BIO. If the caller then goes on to call BIO_pop() on the BIO
+    then a use-after-free will occur. This will most likely result in a crash.
+    ([bsc#1207536, CVE-2023-0215])
+  * Fixed Double free after calling PEM_read_bio_ex.
+    The function PEM_read_bio_ex() reads a PEM file from a BIO and parses and
+    decodes the "name" (e.g. "CERTIFICATE"), any header data and the payload
+    data. If the function succeeds then the "name_out", "header" and "data"
+    arguments are populated with pointers to buffers containing the relevant
+    decoded data. The caller is responsible for freeing those buffers. It is
+    possible to construct a PEM file that results in 0 bytes of payload data.
+    In this case PEM_read_bio_ex() will return a failure code but will populate
+    the header argument with a pointer to a buffer that has already been freed.
+    If the caller also frees this buffer then a double free will occur. This
+    will most likely lead to a crash.
+
+    The functions PEM_read_bio() and PEM_read() are simple wrappers around
+    PEM_read_bio_ex() and therefore these functions are also directly affected.
+
+    These functions are also called indirectly by a number of other OpenSSL
+    functions including PEM_X509_INFO_read_bio_ex() and
+    SSL_CTX_use_serverinfo_file() which are also vulnerable. Some OpenSSL
+    internal uses of these functions are not vulnerable because the caller does
+    not free the header argument if PEM_read_bio_ex() returns a failure code.
+    ([bsc#1207538, CVE-2022-4450])
+  * Fixed Timing Oracle in RSA Decryption.
+    A timing based side channel exists in the OpenSSL RSA Decryption
+    implementation which could be sufficient to recover a plaintext across
+    a network in a Bleichenbacher style attack. To achieve a successful
+    decryption an attacker would have to be able to send a very large number
+    of trial messages for decryption. The vulnerability affects all RSA padding
+    modes: PKCS#1 v1.5, RSA-OEAP and RSASVE.
+    ([bsc#1207534, CVE-2022-4304])
+  * Fixed X.509 Name Constraints Read Buffer Overflow.
+    A read buffer overrun can be triggered in X.509 certificate verification,
+    specifically in name constraint checking. The read buffer overrun might
+    result in a crash which could lead to a denial of service attack.
+    In a TLS client, this can be triggered by connecting to a malicious
+    server. In a TLS server, this can be triggered if the server requests
+    client authentication and a malicious client connects.
+    ([bsc#1207535, CVE-2022-4203])
+  * Fixed X.509 Policy Constraints Double Locking security issue.
+    If an X.509 certificate contains a malformed policy constraint and
+    policy processing is enabled, then a write lock will be taken twice
+    recursively.  On some operating systems (most widely: Windows) this
+    results in a denial of service when the affected process hangs.  Policy
+    processing being enabled on a publicly facing server is not considered
+    to be a common setup.
+    ([CVE-2022-3996])
+  * Our provider implementations of `OSSL_FUNC_KEYMGMT_EXPORT` and
+    `OSSL_FUNC_KEYMGMT_GET_PARAMS` for EC and SM2 keys now honor
+    `OSSL_PKEY_PARAM_EC_POINT_CONVERSION_FORMAT` as set (and
+    default to `POINT_CONVERSION_UNCOMPRESSED`) when exporting
+    `OSSL_PKEY_PARAM_PUB_KEY`, instead of unconditionally using
+    `POINT_CONVERSION_COMPRESSED` as in previous 3.x releases.
+    For symmetry, our implementation of `EVP_PKEY_ASN1_METHOD->export_to`
+    for legacy EC and SM2 keys is also changed similarly to honor the
+    equivalent conversion format flag as specified in the underlying
+    `EC_KEY` object being exported to a provider, when this function is
+    called through `EVP_PKEY_export()`.
+  * Removed openssl-3-Fix-double-locking-problem.patch,
+    contained in upstream.
+  * Rebased openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
+  * Update openssl.keyring with key
+    7953 AC1F BC3D C8B3 B292 393E D5E9 E43F 7DF9 EE8C (Richard Levitte)
+
+-------------------------------------------------------------------
+Thu Jan 26 08:17:50 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- Relax the crypto-policies requirements for the regression tests
+
+-------------------------------------------------------------------
+Wed Jan 25 11:09:52 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- Set OpenSSL 3.0.7 as the default openssl [bsc#1205042]
+  * Rename openssl-1.1.0-no-html.patch to openssl-no-html-docs.patch
+  * Rebase openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
+  * Package a copy of the original default config file called
+    openssl.cnf and name it as openssl-orig.cnf and warn the user
+    if the files differ.
+  * Add openssl-3-devel as conflicting with libopenssl-1_1-devel
+  * Remove patches:
+    - fix-config-in-tests.patch
+    - openssl-use-versioned-config.patch
+
+-------------------------------------------------------------------
+Wed Jan 25 09:10:06 UTC 2023 - Pedro Monreal <pmonreal@suse.com>
+
+- Create the openssl ca-certificates directory in case the
+  ca-certificates package is not installed. This directory is
+  required by the nodejs regression tests. [bsc#1207484]
+
+-------------------------------------------------------------------
+Wed Dec 14 16:38:05 UTC 2022 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Fix X.509 Policy Constraints Double Locking [bsc#1206374, CVE-2022-3996]
+  * Add patch: openssl-3-Fix-double-locking-problem.patch
+
+-------------------------------------------------------------------
+Wed Dec 14 12:40:04 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Compute the hmac files for FIPS 140-3 integrity checking of the
+  openssl shared libraries using the brp-50-generate-fips-hmac
+  script. Also computed for the 32bit package.
+
+-------------------------------------------------------------------
+Tue Nov  1 18:29:41 UTC 2022 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Temporary disable tests test_ssl_new and test_sslapi because they are
+  failing in openSUSE_Tumbleweed
+
+-------------------------------------------------------------------
+Tue Nov  1 15:46:44 UTC 2022 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Update to 3.0.7: [bsc#1204714, CVE-2022-3602,CVE-2022-3786]
+  * Fixed two buffer overflows in punycode decoding functions.
+    A buffer overrun can be triggered in X.509 certificate verification,
+    specifically in name constraint checking. Note that this occurs after
+    certificate chain signature verification and requires either a CA to
+    have signed the malicious certificate or for the application to continue
+    certificate verification despite failure to construct a path to a trusted
+    issuer.
+
+    In a TLS client, this can be triggered by connecting to a malicious
+    server.  In a TLS server, this can be triggered if the server requests
+    client authentication and a malicious client connects.
+
+    An attacker can craft a malicious email address to overflow
+    an arbitrary number of bytes containing the `.`  character (decimal 46)
+    on the stack.  This buffer overflow could result in a crash (causing a
+    denial of service).
+    ([CVE-2022-3786])
+
+    An attacker can craft a malicious email address to overflow four
+    attacker-controlled bytes on the stack.  This buffer overflow could
+    result in a crash (causing a denial of service) or potentially remote code
+    execution depending on stack layout for any given platform/compiler.
+    ([CVE-2022-3602])
+  * Removed all references to invalid OSSL_PKEY_PARAM_RSA names for CRT
+    parameters in OpenSSL code.
+    Applications should not use the names OSSL_PKEY_PARAM_RSA_FACTOR,
+    OSSL_PKEY_PARAM_RSA_EXPONENT and OSSL_PKEY_PARAM_RSA_COEFFICIENT.
+    Use the numbered names such as OSSL_PKEY_PARAM_RSA_FACTOR1 instead.
+    Using these invalid names may cause algorithms to use slower methods
+    that ignore the CRT parameters.
+  * Fixed a regression introduced in 3.0.6 version raising errors on some stack
+    operations.
+  * Fixed a regression introduced in 3.0.6 version not refreshing the certificate
+    data to be signed before signing the certificate.
+  * Added RIPEMD160 to the default provider.
+  * Ensured that the key share group sent or accepted for the key exchange
+    is allowed for the protocol version.
+
+-------------------------------------------------------------------
+Tue Nov  1 10:42:00 UTC 2022 - Otto Hollmann <otto.hollmann@suse.com>
+
+- Update to 3.0.6: [bsc#1204226, CVE-2022-3358]
+  * OpenSSL supports creating a custom cipher via the legacy
+    EVP_CIPHER_meth_new() function and associated function calls. This function
+    was deprecated in OpenSSL 3.0 and application authors are instead encouraged
+    to use the new provider mechanism in order to implement custom ciphers.
+  * OpenSSL versions 3.0.0 to 3.0.5 incorrectly handle legacy custom ciphers
+    passed to the EVP_EncryptInit_ex2(), EVP_DecryptInit_ex2() and
+    EVP_CipherInit_ex2() functions (as well as other similarly named encryption
+    and decryption initialisation functions). Instead of using the custom cipher
+    directly it incorrectly tries to fetch an equivalent cipher from the
+    available providers. An equivalent cipher is found based on the NID passed
+    to EVP_CIPHER_meth_new(). This NID is supposed to represent the unique NID
+    for a given cipher. However it is possible for an application to incorrectly
+    pass NID_undef as this value in the call to EVP_CIPHER_meth_new(). When
+    NID_undef is used in this way the OpenSSL encryption/decryption
+    initialisation function will match the NULL cipher as being equivalent and
+    will fetch this from the available providers. This will succeed if the
+    default provider has been loaded (or if a third party provider has been
+    loaded that offers this cipher). Using the NULL cipher means that the
+    plaintext is emitted as the ciphertext.
+  * Applications are only affected by this issue if they call
+    EVP_CIPHER_meth_new() using NID_undef and subsequently use it in a call to
+    an encryption/decryption initialisation function. Applications that only use
+    SSL/TLS are not impacted by this issue. ([CVE-2022-3358])
+  * Fix LLVM vs Apple LLVM version numbering confusion that caused build
+    failures on MacOS 10.11
+  * Fixed the linux-mips64 Configure target which was missing the SIXTY_FOUR_BIT
+    bn_ops flag. This was causing heap corruption on that platform.
+  * Fix handling of a ticket key callback that returns 0 in TLSv1.3 to not send
+    a ticket
+  * Correctly handle a retransmitted ClientHello in DTLS
+  * Fixed detection of ktls support in cross-compile environment on Linux
+  * Fixed some regressions and test failures when running the 3.0.0 FIPS
+    provider against 3.0.x
+  * Fixed SSL_pending() and SSL_has_pending() with DTLS which were failing to
+    report correct results in some cases
+  * Fix UWP builds by defining VirtualLock
+  * For known safe primes use the minimum key length according to RFC 7919.
+    Longer private key sizes unnecessarily raise the cycles needed to compute
+    the shared secret without any increase of the real security. This fixes a
+    regression from 1.1.1 where these shorter keys were generated for the known
+    safe primes.
+  * Added the loongarch64 target
+  * Fixed EC ASM flag passing. Flags for ASM implementations of EC curves were
+    only passed to the FIPS provider and not to the default or legacy provider.
+  * Fixed reported performance degradation on aarch64. Restored the
+    implementation prior to commit 2621751 ("aes/asm/aesv8-armx.pl: avoid 32-bit
+    lane assignment in CTR mode") for 64bit targets only, since it is reportedly
+    2-17% slower and the silicon errata only affects 32bit targets. The new
+    algorithm is still used for 32 bit targets.
+  * Added a missing header for memcmp that caused compilation failure on some
+    platforms
+
+-------------------------------------------------------------------
+Wed Sep 14 09:22:14 UTC 2022 - Bruno Pitrus <brunopitrus@hotmail.com>
+
+- Do not make libopenssl3-32bit obsolete libopenssl1_1-32bit.
+  They are independent libraries and can be installed simultaneously.
+
+-------------------------------------------------------------------
+Thu Jul 21 09:09:07 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.5:
+  * The OpenSSL 3.0.4 release introduced a serious bug in the RSA
+    implementation for X86_64 CPUs supporting the AVX512IFMA instructions.
+    This issue makes the RSA implementation with 2048 bit private keys
+    incorrect on such machines and memory corruption will happen during
+    the computation. As a consequence of the memory corruption an attacker
+    may be able to trigger a remote code execution on the machine performing
+    the computation.
+    SSL/TLS servers or other servers using 2048 bit RSA private keys running
+    on machines supporting AVX512IFMA instructions of the X86_64 architecture
+    are affected by this issue. [bsc#1201148, CVE-2022-2274]
+  * AES OCB mode for 32-bit x86 platforms using the AES-NI assembly optimised
+    implementation would not encrypt the entirety of the data under some
+    circumstances.  This could reveal sixteen bytes of data that was
+    preexisting in the memory that wasn't written.  In the special case of
+    "in place" encryption, sixteen bytes of the plaintext would be revealed.
+    Since OpenSSL does not support OCB based cipher suites for TLS and DTLS,
+    they are both unaffected. [bsc#1201099, CVE-2022-2097]
+- Rebase patches:
+  * openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
+
+-------------------------------------------------------------------
+Mon Jul 18 12:03:55 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.4: [bsc#1199166, CVE-2022-1292]
+  * In addition to the c_rehash shell command injection identified in
+    CVE-2022-1292, further bugs where the c_rehash script does not
+    properly sanitise shell metacharacters to prevent command injection
+    have been fixed.
+    When the CVE-2022-1292 was fixed it was not discovered that there
+    are other places in the script where the file names of certificates
+    being hashed were possibly passed to a command executed through the shell.
+    This script is distributed by some operating systems in a manner where
+    it is automatically executed.  On such operating systems, an attacker
+    could execute arbitrary commands with the privileges of the script.
+    Use of the c_rehash script is considered obsolete and should be replaced
+    by the OpenSSL rehash command line tool.
+  * Case insensitive string comparison no longer uses locales.
+    It has instead been directly implemented.
+
+-------------------------------------------------------------------
+Mon Jul 18 12:03:21 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.3:
+  * Case insensitive string comparison is reimplemented via new locale-agnostic
+    comparison functions OPENSSL_str[n]casecmp always using the POSIX locale for
+    comparison. The previous implementation had problems when the Turkish locale
+    was used.
+  * Fixed a bug in the c_rehash script which was not properly sanitising shell
+    metacharacters to prevent command injection.  This script is distributed by
+    some operating systems in a manner where it is automatically executed.  On
+    such operating systems, an attacker could execute arbitrary commands with the
+    privileges of the script.
+    Use of the c_rehash script is considered obsolete and should be replaced
+    by the OpenSSL rehash command line tool. [bsc#1199166, CVE-2022-1292]
+  * Fixed a bug in the function 'OCSP_basic_verify' that verifies the signer
+    certificate on an OCSP response. The bug caused the function in the case
+    where the (non-default) flag OCSP_NOCHECKS is used to return a postivie
+    response (meaning a successful verification) even in the case where the
+    response signing certificate fails to verify.
+    It is anticipated that most users of 'OCSP_basic_verify' will not use the
+    OCSP_NOCHECKS flag. In this case the 'OCSP_basic_verify' function will return
+    a negative value (indicating a fatal error) in the case of a certificate
+    verification failure. The normal expected return value in this case would be 0.
+    This issue also impacts the command line OpenSSL "ocsp" application. When
+    verifying an ocsp response with the "-no_cert_checks" option the command line
+    application will report that the verification is successful even though it
+    has in fact failed. In this case the incorrect successful response will also
+    be accompanied by error messages showing the failure and contradicting the
+    apparently successful result. [bsc#1199167, CVE-2022-1343]
+  * Fixed a bug where the RC4-MD5 ciphersuite incorrectly used the
+    AAD data as the MAC key. This made the MAC key trivially predictable.
+    An attacker could exploit this issue by performing a man-in-the-middle attack
+    to modify data being sent from one endpoint to an OpenSSL 3.0 recipient such
+    that the modified data would still pass the MAC integrity check.
+    Note that data sent from an OpenSSL 3.0 endpoint to a non-OpenSSL 3.0
+    endpoint will always be rejected by the recipient and the connection will
+    fail at that point. Many application protocols require data to be sent from
+    the client to the server first. Therefore, in such a case, only an OpenSSL
+    3.0 server would be impacted when talking to a non-OpenSSL 3.0 client.
+    [bsc#1199168, CVE-2022-1434]
+  * Fix a bug in the OPENSSL_LH_flush() function that breaks reuse of the memory
+    occuppied by the removed hash table entries.
+    This function is used when decoding certificates or keys. If a long lived
+    process periodically decodes certificates or keys its memory usage will
+    expand without bounds and the process might be terminated by the operating
+    system causing a denial of service. Also traversing the empty hash table
+    entries will take increasingly more time. Typically such long lived processes
+    might be TLS clients or TLS servers configured to accept client certificate
+    authentication. [bsc#1199169, CVE-2022-1473]
+  * The functions 'OPENSSL_LH_stats' and 'OPENSSL_LH_stats_bio' now only report
+    the 'num_items', 'num_nodes' and 'num_alloc_nodes' statistics. All other
+    statistics are no longer supported. For compatibility, these statistics are
+    still listed in the output but are now always reported as zero.
+
+-------------------------------------------------------------------
+Sat Mar 19 10:05:22 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Enable zlib compression support [bsc#1195149]
+
+-------------------------------------------------------------------
+Fri Mar 18 22:27:34 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Add crypto-policies support.
+  * Fix some tests that couldn't find the openssl3.cnf location
+  * Rebase patch:
+    openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
+
+-------------------------------------------------------------------
+Tue Mar 15 17:41:47 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.2: [bsc#1196877, CVE-2022-0778]
+  * Security fix [CVE-2022-0778]: Infinite loop for non-prime moduli
+    in BN_mod_sqrt() reachable when parsing certificates.
+  * Add ciphersuites based on DHE_PSK (RFC 4279) and ECDHE_PSK
+    (RFC 5489) to the list of ciphersuites providing Perfect Forward
+    Secrecy as required by SECLEVEL >= 3.
+  * Made the AES constant time code for no-asm configurations
+    optional due to the resulting 95% performance degradation.
+    The AES constant time code can be enabled, for no assembly
+    builds, with: ./config no-asm -DOPENSSL_AES_CONST_TIME
+  * Fixed PEM_write_bio_PKCS8PrivateKey() to make it possible to
+    use empty passphrase strings.
+  * The negative return value handling of the certificate
+    verification callback was reverted. The replacement is to set
+    the verification retry state with the SSL_set_retry_verify()
+    function.
+  * Rebase openssl-use-versioned-config.patch
+
+-------------------------------------------------------------------
+Tue Feb 22 18:46:13 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Keep CA_default and tsa_config1 default paths in openssl3.cnf
+- Rebase patches:
+  * openssl-Override-default-paths-for-the-CA-directory-tree.patch
+  * openssl-use-versioned-config.patch
+
+-------------------------------------------------------------------
+Tue Feb  1 13:55:24 UTC 2022 - Danilo Spinella <danilo.spinella@suse.com>
+
+- Fix conflict with openssl and libressl
+
+-------------------------------------------------------------------
+Fri Jan 28 08:32:43 UTC 2022 - Simon Lees <simonf.lees@suse.com>
+
+- Remove /etc/pki/CA from the [jsc#SLE-17856, jsc#SLE-19044]
+  openssl-Override-default-paths-for-the-CA-directory-tree.patch
+- Remove unused patches
+
+-------------------------------------------------------------------
+Fri Jan 21 08:18:28 UTC 2022 - Simon Lees <simonf.lees@suse.com>
+
+- Ship openssl-3 as binary names [jsc#SLE-17856, jsc#SLE-19044]
+- Use openssl3.cnf
+  * openssl-use-versioned-config.patch
+  * fix-config-in-tests.patch
+- Support crypto policies
+  * openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
+  * openssl-Override-default-paths-for-the-CA-directory-tree.patch
+- Remove obsolets, not ready to force an upgrade yet
+
+-------------------------------------------------------------------
+Thu Jan 13 10:49:26 UTC 2022 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.1: [bsc#1193740, CVE-2021-4044]
+  * RNDR and RNDRRS support in provider functions to provide
+    random number generation for Arm CPUs (aarch64).
+  * s_client and s_server apps now explicitly say when the TLS
+    version does not include the renegotiation mechanism. This
+    avoids confusion between that scenario versus when the TLS
+    version includes secure renegotiation but the peer lacks
+    support for it.
+  * The default SSL/TLS security level has been changed from 1 to 2.
+    RSA, DSA and DH keys of 1024 bits and above and less than 2048
+    bits and ECC keys of 160 bits and above and less than 224 bits
+    were previously accepted by default but are now no longer
+    allowed. By default TLS compression was already disabled in
+    previous OpenSSL versions. At security level 2 it cannot be
+    enabled.
+  * The SSL_CTX_set_cipher_list family functions now accept
+    ciphers using their IANA standard names.
+  * The PVK key derivation function has been moved from
+    b2i_PVK_bio_ex() into the legacy crypto provider as an
+    EVP_KDF. Applications requiring this KDF will need to load
+    the legacy crypto provider.
+  * The various OBJ_* functions have been made thread safe.
+  * CCM8 cipher suites in TLS have been downgraded to security
+    level zero because they use a short authentication tag which
+    lowers their strength.
+  * Subject or issuer names in X.509 objects are now displayed
+    as UTF-8 strings by default.
+  * Parallel dual-prime 1536/2048-bit modular exponentiation
+    for AVX512_IFMA capable processors.
+
+-------------------------------------------------------------------
+Tue Sep  7 14:58:35 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0
+  * The full list of changes since version 1.1.1 can be found in:
+    https://github.com/openssl/openssl/blob/master/CHANGES.md#openssl-30
+  * OpenSSL 3.0 wiki: https://wiki.openssl.org/index.php/OpenSSL_3.0
+  * The Migration guide:
+    https://github.com/openssl/openssl/blob/master/doc/man7/migration_guide.pod
+
+-------------------------------------------------------------------
+Thu Jul 29 16:46:14 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Beta 2
+  * The ERR_GET_FUNC() function was removed. With the loss of
+    meaningful function codes, this function can only cause problems
+    for calling applications.
+  * While a callback function set via 'SSL_CTX_set_cert_verify_callback()'
+    is not allowed to return a value > 1, this is no more taken as
+    failure.
+  * Deprecated the obsolete X9.31 RSA key generation related
+    functions BN_X931_generate_Xpq(), BN_X931_derive_prime_ex(),
+    and BN_X931_generate_prime_ex().
+- Remove openssl-ppc64-fix-build.patch fixed upstream
+
+-------------------------------------------------------------------
+Mon Jul  5 14:29:05 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Beta 1
+  * Add a configurable flag to output date formats as ISO 8601.
+    Does not change the default date format.
+  * Version of MSVC earlier than 1300 could get link warnings, which
+    could be suppressed if the undocumented -DI_CAN_LIVE_WITH_LNK4049
+    was set. Support for this flag has been removed.
+  * Rework and make DEBUG macros consistent. Remove unused
+    -DCONF_DEBUG, -DBN_CTX_DEBUG, and REF_PRINT. Add a new tracing
+    category and use it for printing reference counts. Rename
+    -DDEBUG_UNUSED to -DUNUSED_RESULT_DEBUG. Fix BN_DEBUG_RAND so it
+    compiles and, when set, force DEBUG_RAND to be set also. Rename
+    engine_debug_ref to be ENGINE_REF_PRINT also for consistency.
+  * The public definitions of conf_method_st and conf_st have been
+    deprecated. They will be made opaque in a future release.
+  * Many functions in the EVP_ namespace that are getters of values
+    from implementations or contexts were renamed to include get or
+    get0 in their names. Old names are provided as macro aliases for
+    compatibility and are not deprecated.
+  * PKCS#5 PBKDF1 key derivation has been moved from PKCS5_PBE_keyivgen()
+    into the legacy crypto provider as an EVP_KDF. Applications requiring
+    this KDF will need to load the legacy crypto provider. This includes
+    these PBE algorithms which use this KDF:
+     - NID_pbeWithMD2AndDES_CBC     - NID_pbeWithMD5AndDES_CBC
+     - NID_pbeWithSHA1AndRC2_CBC    - NID_pbeWithMD2AndRC2_CBC
+     - NID_pbeWithMD5AndRC2_CBC     - NID_pbeWithSHA1AndDES_CBC
+  * Deprecated obsolete BIO_set_callback(), BIO_get_callback(), and
+    BIO_debug_callback() functions.
+- Fix build on ppc and ppc64
+  * Add openssl-ppc64-fix-build.patch
+  * See https://github.com/openssl/openssl/issues/15923
+
+-------------------------------------------------------------------
+Fri Jun 11 13:17:54 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 17
+  * Added migration guide to man7
+  * Implemented support for fully "pluggable" TLSv1.3 groups
+  * Added convenience functions for generating asymmetric key pairs.
+  * Added a proper HTTP client supporting GET with optional redirection,
+    POST, arbitrary request and response content types, TLS, persistent
+    connections, connections via HTTP(s) proxies, connections and
+    exchange via user-defined BIOs (allowing implicit connections), and
+    timeout checks.
+
+-------------------------------------------------------------------
+Mon May 10 02:13:06 UTC 2021 - Jason Sikes <jsikes@suse.com>
+
+- Update to 3.0.0. Alpha 16
+  * Mark pop/clear error stack in der2key_decode_p8
+
+-------------------------------------------------------------------
+Sat May  1 19:58:48 UTC 2021 - Jason Sikes <jsikes@suse.com>
+
+- Update to 3.0.0 Alpha 15
+  * The default manual page suffix ($MANSUFFIX) has been changed to "ossl"
+  * Added support for Kernel TLS (KTLS). In order to use KTLS, support for it
+    must be compiled in using the "enable-ktls" compile time option. It must
+    also be enabled at run time using the SSL_OP_ENABLE_KTLS option.
+  * The error return values from some control calls (ctrl) have changed.
+    One significant change is that controls which used to return -2 for
+    invalid inputs, now return -1 indicating a generic error condition instead.
+  * Removed EVP_PKEY_set_alias_type().
+  * All of these low level RSA functions have been deprecated without
+    replacement:
+    RSA_blinding_off, RSA_blinding_on, RSA_clear_flags, RSA_get_version,
+    RSAPrivateKey_dup, RSAPublicKey_dup, RSA_set_flags, RSA_setup_blinding and
+    RSA_test_flags.
+  * All of these RSA flags have been deprecated without replacement:
+    RSA_FLAG_BLINDING, RSA_FLAG_CACHE_PRIVATE, RSA_FLAG_CACHE_PUBLIC,
+    RSA_FLAG_EXT_PKEY, RSA_FLAG_NO_BLINDING, RSA_FLAG_THREAD_SAFE and
+    RSA_METHOD_FLAG_NO_CHECK.
+  * These low level DH functions have been deprecated without replacement:
+    DH_clear_flags, DH_get_1024_160, DH_get_2048_224, DH_get_2048_256,
+    DH_set_flags and DH_test_flags.
+    The DH_FLAG_CACHE_MONT_P flag has been deprecated without replacement.
+    The DH_FLAG_TYPE_DH and DH_FLAG_TYPE_DHX have been deprecated.  Use
+    EVP_PKEY_is_a() to determine the type of a key.  There is no replacement for
+    setting these flags.
+  * These low level DSA functions have been deprecated without replacement:
+    DSA_clear_flags, DSA_dup_DH, DSAparams_dup, DSA_set_flags and
+    DSA_test_flags.
+  * The DSA_FLAG_CACHE_MONT_P flag has been deprecated without replacement.
+  * Reworked the treatment of EC EVP_PKEYs with the SM2 curve to
+    automatically become EVP_PKEY_SM2 rather than EVP_PKEY_EC. This is a breaking
+    change from previous OpenSSL versions.
+    Unlike in previous OpenSSL versions, this means that applications must not
+    call 'EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)' to get SM2 computations.
+    The 'EVP_PKEY_set_alias_type' function has now been removed.
+  * Parameter and key generation is also reworked to make it possible
+    to generate EVP_PKEY_SM2 parameters and keys. Applications must now generate
+    SM2 keys directly and must not create an EVP_PKEY_EC key first.
+
+-------------------------------------------------------------------
+Mon Apr 19 12:35:57 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 14
+  * A public key check is now performed during EVP_PKEY_derive_set_peer().
+    Previously DH was internally doing this during EVP_PKEY_derive().
+  * The EVP_PKEY_CTRL_PKCS7_ENCRYPT, EVP_PKEY_CTRL_PKCS7_DECRYPT,
+    EVP_PKEY_CTRL_PKCS7_SIGN, EVP_PKEY_CTRL_CMS_ENCRYPT,
+    EVP_PKEY_CTRL_CMS_DECRYPT, and EVP_PKEY_CTRL_CMS_SIGN control operations
+    are deprecated. They are not invoked by the OpenSSL library anymore and
+    are replaced by direct checks of the key operation against the key type
+    when the operation is initialized.
+  * The EVP_PKEY_public_check() and EVP_PKEY_param_check() functions now work for
+    more key types including RSA, DSA, ED25519, X25519, ED448 and X448.
+    Previously (in 1.1.1) they would return -2. For key types that do not have
+    parameters then EVP_PKEY_param_check() will always return 1.
+  * The output from numerous "printing" functions such as X509_signature_print(),
+    X509_print_ex(), X509_CRL_print_ex(), and other similar functions has been
+    amended such that there may be cosmetic differences between the output
+    observed in 1.1.1 and 3.0. This also applies to the "-text" output from the
+    x509 and crl applications.
+  * Improved adherence to Enhanced Security Services (ESS, RFC 2634 and RFC 5035)
+    for the TSP and CMS Advanced Electronic Signatures (CAdES) implementations.
+    As required by RFC 5035 check both ESSCertID and ESSCertIDv2 if both present.
+    Correct the semantics of checking the validation chain in case ESSCertID{,v2}
+    contains more than one certificate identifier: This means that all
+    certificates referenced there MUST be part of the validation chain.
+  * Parallel dual-prime 1024-bit modular exponentiation for AVX512_IFMA
+    capable processors.
+  * Added the AuthEnvelopedData content type structure (RFC 5083) with AES-GCM
+    parameter (RFC 5084) for the Cryptographic Message Syntax (CMS). Its purpose
+    is to support encryption and decryption of a digital envelope that is both
+    authenticated and encrypted using AES GCM mode.
+
+-------------------------------------------------------------------
+Wed Apr 14 17:55:21 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 13
+  * A public key check is now performed during EVP_PKEY_derive_set_peer().
+    Previously DH was internally doing this during EVP_PKEY_derive().
+    To disable this check use EVP_PKEY_derive_set_peer_ex(dh, peer, 0). This
+    may mean that an error can occur in EVP_PKEY_derive_set_peer() rather than
+    during EVP_PKEY_derive().
+  * The EVP_PKEY_CTRL_PKCS7_ENCRYPT, EVP_PKEY_CTRL_PKCS7_DECRYPT,
+    EVP_PKEY_CTRL_PKCS7_SIGN, EVP_PKEY_CTRL_CMS_ENCRYPT,
+    EVP_PKEY_CTRL_CMS_DECRYPT, and EVP_PKEY_CTRL_CMS_SIGN control operations
+    are deprecated. They are not invoked by the OpenSSL library anymore and
+    are replaced by direct checks of the key operation against the key type
+    when the operation is initialized.
+  * The EVP_PKEY_public_check() and EVP_PKEY_param_check() functions now work for
+    more key types including RSA, DSA, ED25519, X25519, ED448 and X448.
+    Previously (in 1.1.1) they would return -2. For key types that do not have
+    parameters then EVP_PKEY_param_check() will always return 1.
+  * The output from numerous "printing" functions such as X509_signature_print(),
+    X509_print_ex(), X509_CRL_print_ex(), and other similar functions has been
+    amended such that there may be cosmetic differences between the output
+    observed in 1.1.1 and 3.0. This also applies to the "-text" output from the
+    x509 and crl applications.
+  * Improved adherence to Enhanced Security Services (ESS, RFC 2634 and RFC 5035)
+    for the TSP and CMS Advanced Electronic Signatures (CAdES) implementations.
+    As required by RFC 5035 check both ESSCertID and ESSCertIDv2 if both present.
+    Correct the semantics of checking the validation chain in case ESSCertID{,v2}
+    contains more than one certificate identifier: This means that all
+    certificates referenced there MUST be part of the validation chain.
+  * Parallel dual-prime 1024-bit modular exponentiation for AVX512_IFMA
+    capable processors.
+  * Added the AuthEnvelopedData content type structure (RFC 5083) with AES-GCM
+    parameter (RFC 5084) for the Cryptographic Message Syntax (CMS). Its purpose
+    is to support encryption and decryption of a digital envelope that is both
+    authenticated and encrypted using AES GCM mode.
+
+-------------------------------------------------------------------
+Fri Feb 19 08:58:35 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 12
+  * The SRP APIs have been deprecated. The old APIs do not work via
+    providers, and there is no EVP interface to them. Unfortunately
+    there is no replacement for these APIs at this time.
+  * Add a compile time option to prevent the caching of provider
+    fetched algorithms. This is enabled by including the
+    no-cached-fetch option at configuration time.
+  * Combining the Configure options no-ec and no-dh no longer
+    disables TLSv1.3. Typically if OpenSSL has no EC or DH algorithms
+    then it cannot support connections with TLSv1.3. However OpenSSL
+    now supports "pluggable" groups through providers.
+  * The undocumented function X509_certificate_type() has been
+    deprecated; applications can use X509_get0_pubkey() and
+    X509_get0_signature() to get the same information.
+  * Deprecated the obsolete BN_pseudo_rand() and BN_pseudo_rand_range()
+    functions. They are identical to BN_rand() and BN_rand_range()
+    respectively.
+  * The default key generation method for the regular 2-prime RSA keys
+    was changed to the FIPS 186-4 B.3.6 method (Generation of Probable
+    Primes with Conditions Based on Auxiliary Probable Primes). This
+    method is slower than the original method.
+  * Deprecated the BN_is_prime_ex() and BN_is_prime_fasttest_ex()
+    functions. They are replaced with the BN_check_prime() function
+    that avoids possible misuse and always uses at least 64 rounds of
+    the Miller-Rabin primality test.
+  * Deprecated EVP_MD_CTX_set_update_fn() and EVP_MD_CTX_update_fn()
+    as they are not useful with non-deprecated functions.
+
+-------------------------------------------------------------------
+Fri Feb 12 11:47:35 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 11
+  * Deprecated the obsolete X9.31 RSA key generation related
+    functions BN_X931_generate_Xpq(), BN_X931_derive_prime_ex(),
+    and BN_X931_generate_prime_ex().
+  * Deprecated the type OCSP_REQ_CTX and the functions OCSP_REQ_CTX_*().
+    These were used to collect all necessary data to form a HTTP
+    request, and to perform the HTTP transfer with that request.
+    With OpenSSL 3.0, the type is OSSL_HTTP_REQ_CTX, and the
+    deprecated functions are replaced with OSSL_HTTP_REQ_CTX_*().
+  * Validation of SM2 keys has been separated from the validation of
+    regular EC keys, allowing to improve the SM2 validation process
+    to reject loaded private keys that are not conforming to the SM2
+    ISO standard. In particular, a private scalar 'k' outside the
+    range '1 <= k < n-1' is now correctly rejected.
+  * Behavior of the 'pkey' app is changed, when using the '-check'
+    or '-pubcheck' switches: a validation failure triggers an early
+    exit, returning a failure exit status to the parent process.
+  * Changed behavior of SSL_CTX_set_ciphersuites() and
+    SSL_set_ciphersuites() to ignore unknown ciphers.
+  * All of the low level EC_KEY functions have been deprecated.
+  * Functions that read and write EC_KEY objects and that assign or
+    obtain EC_KEY objects from an EVP_PKEY are also deprecated.
+  * Added the '-copy_extensions' option to the 'x509' command for use
+    with '-req' and '-x509toreq'. When given with the 'copy' or
+    'copyall' argument, all extensions in the request are copied to
+    the certificate or vice versa.
+  * Added the '-copy_extensions' option to the 'req' command for use
+    with '-x509'. When given with the 'copy' or 'copyall' argument,
+    all extensions in the certification request are copied to the
+    certificate.
+  * The 'x509', 'req', and 'ca' commands now make sure that X.509v3
+    certificates they generate are by default RFC 5280 compliant in
+    the following sense: There is a subjectKeyIdentifier extension
+    with a hash value of the public key and for not self-signed certs
+    there is an authorityKeyIdentifier extension with a keyIdentifier
+    field or issuer information identifying the signing key. This is
+    done unless some configuration overrides the new default behavior,
+    such as 'subjectKeyIdentifier = none' and 'authorityKeyIdentifier
+    = none'.
+
+-------------------------------------------------------------------
+Sat Jan  9 10:05:06 UTC 2021 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 10 (CVE-2020-1971)
+  * See full changelog: www.openssl.org/news/changelog.html
+  * Fixed NULL pointer deref in the GENERAL_NAME_cmp function
+    This function could crash if both GENERAL_NAMEs contain an
+    EDIPARTYNAME. If an attacker can control both items being
+    compared then this could lead to a possible denial of service
+    attack. OpenSSL itself uses the GENERAL_NAME_cmp function for
+    two purposes:
+    1) Comparing CRL distribution point names between an available
+       CRL and a CRL distribution point embedded in an X509 certificate
+    2) When verifying that a timestamp response token signer matches
+       the timestamp authority name (exposed via the API functions
+       TS_RESP_verify_response and TS_RESP_verify_token)
+  * The -cipher-commands and -digest-commands options of the
+    command line utility list has been deprecated. Instead use
+    the -cipher-algorithms and -digest-algorithms options.
+  * Additionally functions that read and write DH objects such as
+    d2i_DHparams, i2d_DHparams, PEM_read_DHparam, PEM_write_DHparams
+    and other similar functions have also been deprecated.
+    Applications should instead use the OSSL_DECODER and OSSL_ENCODER
+    APIs to read and write DH files.
+
+-------------------------------------------------------------------
+Thu Dec 17 09:26:56 UTC 2020 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 9
+  * See also https://www.openssl.org/news/changelog.html
+  * Deprecated all the libcrypto and libssl error string loading
+    functions. Calling these functions is not necessary since
+    OpenSSL 1.1.0, as OpenSSL now loads error strings automatically.
+  * The functions SSL_CTX_set_tmp_dh_callback and SSL_set_tmp_dh_callback, as
+    well as the macros SSL_CTX_set_tmp_dh() and SSL_set_tmp_dh() have been
+    deprecated. These are used to set the Diffie-Hellman (DH) parameters that
+    are to be used by servers requiring ephemeral DH keys. Instead applications
+    should consider using the built-in DH parameters that are available by
+    calling SSL_CTX_set_dh_auto() or SSL_set_dh_auto().
+  * The -crypt option to the passwd command line tool has been removed.
+  * The -C option to the x509, dhparam, dsaparam, and ecparam commands
+    has been removed.
+  * Added several checks to X509_verify_cert() according to requirements in
+    RFC 5280 in case 'X509_V_FLAG_X509_STRICT' is set (which may be done by
+    using the CLI option '-x509_strict'):
+    - The basicConstraints of CA certificates must be marked critical.
+    - CA certificates must explicitly include the keyUsage extension.
+    - If a pathlenConstraint is given the key usage keyCertSign must be allowed.
+    - The issuer name of any certificate must not be empty.
+    - The subject name of CA certs, certs with keyUsage crlSign,
+      and certs without subjectAlternativeName must not be empty.
+    - If a subjectAlternativeName extension is given it must not be empty.
+    - The signatureAlgorithm field and the cert signature must be consistent.
+    - Any given authorityKeyIdentifier and any given subjectKeyIdentifier
+      must not be marked critical.
+    - The authorityKeyIdentifier must be given for X.509v3 certs
+      unless they are self-signed.
+    - The subjectKeyIdentifier must be given for all X.509v3 CA certs.
+  * Certificate verification using X509_verify_cert() meanwhile rejects EC keys
+    with explicit curve parameters (specifiedCurve) as required by RFC 5480.
+
+-------------------------------------------------------------------
+Thu Nov  5 18:36:23 UTC 2020 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 8
+  * Add support for AES Key Wrap inverse ciphers to the EVP layer.
+    The algorithms are: "AES-128-WRAP-INV", "AES-192-WRAP-INV",
+    "AES-256-WRAP-INV", "AES-128-WRAP-PAD-INV", "AES-192-WRAP-PAD-INV"
+    and "AES-256-WRAP-PAD-INV". The inverse ciphers use AES decryption
+    for wrapping, and AES encryption for unwrapping.
+  * Deprecated EVP_PKEY_set1_tls_encodedpoint() and
+    EVP_PKEY_get1_tls_encodedpoint(). These functions were previously
+    used by libssl to set or get an encoded public key in/from an
+    EVP_PKEY object. With OpenSSL 3.0 these are replaced by the more
+    generic functions EVP_PKEY_set1_encoded_public_key() and
+    EVP_PKEY_get1_encoded_public_key(). The old versions have been
+    converted to deprecated macros that just call the new functions.
+  * The security callback, which can be customised by application
+    code, supports the security operation SSL_SECOP_TMP_DH. This is
+    defined to take an EVP_PKEY in the "other" parameter. In most
+    places this is what is passed. All these places occur server side.
+    However there was one client side call of this security operation
+    and it passed a DH object instead. This is incorrect according to
+    the definition of SSL_SECOP_TMP_DH, and is inconsistent with all
+    of the other locations. Therefore this client side call has been
+    changed to pass an EVP_PKEY instead.
+  * Added new option for 'openssl list', '-providers', which will
+    display the list of loaded providers, their names, version and
+    status. It optionally displays their gettable parameters.
+  * Deprecated pthread fork support methods. These were unused so no
+    replacement is required. OPENSSL_fork_prepare(),
+    OPENSSL_fork_parent() and OPENSSL_fork_child().
+- Remove openssl-AES_XTS.patch fixed upstream
+
+-------------------------------------------------------------------
+Fri Oct 16 10:58:53 UTC 2020 - Pedro Monreal <pmonreal@suse.com>
+
+- Fix build on ppc* architectures
+  * Fix tests failing: 30-test_acvp.t and 30-test_evp.t
+  * https://github.com/openssl/openssl/pull/13133
+- Add openssl-AES_XTS.patch for ppc64, ppc64le and aarch64
+
+-------------------------------------------------------------------
+Fri Oct 16 08:43:10 UTC 2020 - Pedro Monreal <pmonreal@suse.com>
+
+- Re-enable test 81-test_cmp_cli.t fixed upstream
+
+-------------------------------------------------------------------
+Thu Oct 15 16:44:44 UTC 2020 - Pedro Monreal <pmonreal@suse.com>
+
+- Update to 3.0.0 Alpha 7
+  * Add PKCS7_get_octet_string() and PKCS7_type_is_other() to the public
+    interface. Their functionality remains unchanged.
+  * Deprecated EVP_PKEY_set_alias_type(). This function was previously
+    needed as a workaround to recognise SM2 keys. With OpenSSL 3.0, this key
+    type is internally recognised so the workaround is no longer needed.
+  * Deprecated EVP_PKEY_CTX_set_rsa_keygen_pubexp() & introduced
+    EVP_PKEY_CTX_set1_rsa_keygen_pubexp(), which is now preferred.
+  * Changed all "STACK" functions to be macros instead of inline functions.
+    Macro parameters are still checked for type safety at compile time via
+    helper inline functions.
+  * Remove the RAND_DRBG API:
+    The RAND_DRBG API did not fit well into the new provider concept as
+    implemented by EVP_RAND and EVP_RAND_CTX. The main reason is that the
+    RAND_DRBG API is a mixture of 'front end' and 'back end' API calls
+    and some of its API calls are rather low-level. This holds in particular
+    for the callback mechanism (RAND_DRBG_set_callbacks()).
+    Adding a compatibility layer to continue supporting the RAND_DRBG API as
+    a legacy API for a regular deprecation period turned out to come at the
+    price of complicating the new provider API unnecessarily. Since the
+    RAND_DRBG API exists only since version 1.1.1, it was decided by the OMC
+    to drop it entirely.
+  * Added the options '-crl_lastupdate' and '-crl_nextupdate' to 'openssl ca',
+    allowing the 'lastUpdate' and 'nextUpdate' fields in the generated CRL to
+    be set explicitly.
+  * 'PKCS12_parse' now maintains the order of the parsed certificates
+    when outputting them via '*ca' (rather than reversing it).
+- Update openssl-DEFAULT_SUSE_cipher.patch
+
+-------------------------------------------------------------------
+Fri Aug  7 14:42:42 UTC 2020 - Callum Farmer <callumjfarmer13@gmail.com>
+
+- Removed 0001-Fix-typo-for-SSL_get_peer_certificate.patch:
+  contained in upstream.
+- Update to 3.0.0 Alpha 6
+  * Added util/check-format.pl for checking adherence to the coding guidelines.
+  * Allow SSL_set1_host() and SSL_add1_host() to take IP literal addresses
+   as well as actual hostnames.
+  * The 'MinProtocol' and 'MaxProtocol' configuration commands now silently
+   ignore TLS protocol version bounds when configuring DTLS-based contexts, and
+   conversely, silently ignore DTLS protocol version bounds when configuring
+   TLS-based contexts.  The commands can be repeated to set bounds of both
+   types.  The same applies with the corresponding "min_protocol" and
+   "max_protocol" command-line switches, in case some application uses both TLS
+   and DTLS. SSL_CTX instances that are created for a fixed protocol version (e.g.
+   TLSv1_server_method()) also silently ignore version bounds.  Previously
+   attempts to apply bounds to these protocol versions would result in an
+   error.  Now only the "version-flexible" SSL_CTX instances are subject to
+   limits in configuration files in command-line options.
+
+-------------------------------------------------------------------
+Mon Jul 20 08:40:26 UTC 2020 - Vítězslav Čížek <vcizek@suse.com>
+
+- Fix linking when the deprecated SSL_get_per_certificate() is in use
+  * https://github.com/openssl/openssl/pull/12468
+  * add 0001-Fix-typo-for-SSL_get_peer_certificate.patch
+
+-------------------------------------------------------------------
+Fri Jul 17 08:34:45 UTC 2020 - Pedro Monreal Gonzalez <pmonrealgonzalez@suse.com>
+
+- Update to 3.0.0 Alpha 5
+  * Deprecated the 'ENGINE' API. Engines should be replaced with
+    providers going forward.
+  * Reworked the recorded ERR codes to make better space for system errors.
+    To distinguish them, the macro 'ERR_SYSTEM_ERROR()' indicates
+    if the given code is a system error (true) or an OpenSSL error (false).
+  * Reworked the test perl framework to better allow parallel testing.
+  * Added ciphertext stealing algorithms AES-128-CBC-CTS, AES-192-CBC-CTS and
+    AES-256-CBC-CTS to the providers. CS1, CS2 and CS3 variants are supported.
+  * 'Configure' has been changed to figure out the configuration target if
+    none is given on the command line. Consequently, the 'config' script is
+    now only a mere wrapper. All documentation is changed to only mention
+    'Configure'.
+  * Added a library context that applications as well as other libraries can use
+    to form a separate context within which libcrypto operations are performed.
+    - There are two ways this can be used:
+      1) Directly, by passing a library context to functions that take
+         such an argument, such as 'EVP_CIPHER_fetch' and similar algorithm
+         fetching functions.
+      2) Indirectly, by creating a new library context and then assigning
+         it as the new default, with 'OPENSSL_CTX_set0_default'.
+    - All public OpenSSL functions that take an 'OPENSSL_CTX' pointer,
+      apart from the functions directly related to 'OPENSSL_CTX', accept
+      NULL to indicate that the default library context should be used.
+    - Library code that changes the default library context using
+      'OPENSSL_CTX_set0_default' should take care to restore it with a
+      second call before returning to the caller.
+  * The security strength of SHA1 and MD5 based signatures in TLS has been
+    reduced. This results in SSL 3, TLS 1.0, TLS 1.1 and DTLS 1.0 no longer
+    working at the default security level of 1 and instead requires security
+    level 0. The security level can be changed either using the cipher string
+    with @SECLEVEL, or calling SSL_CTX_set_security_level().
+  * The SSL option SSL_OP_CLEANSE_PLAINTEXT is introduced. If that option is
+    set, openssl cleanses (zeroize) plaintext bytes from internal buffers
+    after delivering them to the application. Note, the application is still
+    responsible for cleansing other copies (e.g.: data received by SSL_read(3)).
+- Update openssl-ppc64-config.patch
+
+-------------------------------------------------------------------
+Fri Jun 26 07:20:40 UTC 2020 - Vítězslav Čížek <vcizek@suse.com>
+
+- Update to 3.0.0 Alpha 4
+  * general improvements to the built-in providers, the providers API and the internal plumbing and the provider-aware mechanisms for libssl
+  * general improvements and fixes in the CLI apps
+  * support for Automated Cryptographic Validation Protocol (ACVP) tests
+  * fully pluggable TLS key exchange capability from providers
+  * finalization of the Certificate Management Protocol (CMP) contribution, adding an impressive amount of tests for the new features
+  * default to the newer SP800-56B compliant algorithm for RSA keygen
+  * provider-rand: PRNG functionality backed by providers
+  * refactored naming scheme for dispatched functions (#12222)
+  * fixes for various issues
+  * extended and improved test coverage
+  * additions and improvements to the documentations
+- Fix license: Apache-2.0
+- temporarily disable broken 81-test_cmp_cli.t test
+  * https://github.com/openssl/openssl/issues/12324
+
+-------------------------------------------------------------------
+Thu Jun  4 20:24:04 UTC 2020 - Vítězslav Čížek <vcizek@suse.com>
+
+- Update to 3.0.0 Alpha 3
+  * general improvements to the built-in providers, the providers API and the internal plumbing and the provider-aware mechanisms for libssl;
+  * general improvements and fixes in the CLI apps;
+  * cleanup of the EC API:
+    EC_METHOD became an internal-only concept, and functions using or returning EC_METHOD arguments have been deprecated;
+    EC_POINT_make_affine() and EC_POINTs_make_affine() have been deprecated in favor of automatic internal handling of conversions when needed;
+    EC_GROUP_precompute_mult(), EC_GROUP_have_precompute_mult(), and EC_KEY_precompute_mult() have been deprecated, as such precomputation data is now rarely used;
+    EC_POINTs_mul() has been deprecated, as for cryptographic applications EC_POINT_mul() is enough.
+  * the CMS API got support for CAdES-BES signature verification;
+  * introduction of a new SSL_OP_IGNORE_UNEXPECTED_EOF option;
+  * improvements to the RSA OAEP support;
+  * FFDH support in the speed app;
+  * CI: added external testing through the GOST engine;
+  * fixes for various issues;
+  * extended and improved test coverage;
+  * additions and improvements to the documentations.
+
+-------------------------------------------------------------------
+Sat May 23 14:06:54 UTC 2020 - Jan Engelhardt <jengelh@inai.de>
+
+- Use find -exec +. Replace 'pwd' by simply $PWD.
+- Drop Obsoletes on libopenssl1*. libopenssl3 has a new SONAME and
+  does not conflict with anything previously.
+
+-------------------------------------------------------------------
+Wed May 20 12:46:24 UTC 2020 - Vítězslav Čížek <vcizek@suse.com>
+
+- Obsolete openssl 1.1
+- Update baselibs.conf
+- Set man page permissions to 644
+
+-------------------------------------------------------------------
+Fri May 15 15:29:05 UTC 2020 - Vítězslav Čížek <vcizek@suse.com>
+
+- Update to 3.0.0 Alpha 2
+  * general improvements to the built-in providers, the providers API and the internal plumbing;
+  * the removal of legacy API functions related to FIPS mode, replaced by new provider-based mechanisms;
+  * the addition of a new cmp app for RFC 4210;
+  * extended and improved test coverage;
+  * improvements to the documentations;
+  * fixes for various issues.
+- drop obsolete version.patch
+
+-------------------------------------------------------------------
+Thu Apr 23 19:49:05 UTC 2020 - Vítězslav Čížek <vcizek@suse.com>
+
+- Initial packaging 3.0.0 Alpha 1
+  * Major Release
+    OpenSSL 3.0 is a major release and consequently any application
+    that currently uses an older version of OpenSSL will at the
+    very least need to be recompiled in order to work with the new version.
+    It is the intention that the large majority of applications will
+    work unchanged with OpenSSL 3.0 if those applications previously
+    worked with OpenSSL 1.1.1. However this is not guaranteed and
+    some changes may be required in some cases.
+  * Providers and FIPS support
+    Providers collect together and make available algorithm implementations.
+    With OpenSSL 3.0 it is possible to specify, either programmatically
+    or via a config file, which providers you want to use for any given application
+  * Low Level APIs
+    Use of the low level APIs have been deprecated.
+  * Legacy Algorithms
+    Some cryptographic algorithms that were available via the EVP APIs
+    are now considered legacy and their use is strongly discouraged.
+    These legacy EVP algorithms are still available in OpenSSL 3.0 but not by default.
+    If you want to use them then you must load the legacy provider.
+  * Engines and "METHOD" APIs
+    The ENGINE API and any function that creates or modifies custom "METHODS"
+    are being deprecated in OpenSSL 3.0
+    Authors and maintainers of external engines are strongly encouraged to
+    refactor their code transforming engines into providers using
+    the new Provider API and avoiding deprecated methods.
+  * Versioning Scheme
+    The OpenSSL versioning scheme has changed with the 3.0 release.
+    The new versioning scheme has this format: MAJOR.MINOR.PATCH
+    The patch level is indicated by the third number instead of a letter
+    at the end of the release version number.
+    A change in the second (MINOR) number indicates that new features may have been added.
+    OpenSSL versions with the same major number are API and ABI compatible.
+    If the major number changes then API and ABI compatibility is not guaranteed.
+  * Other major new features
+    Implementation of the Certificate Management Protocol (CMP, RFC 4210)
+    also covering CRMF (RFC 4211) and HTTP transfer (RFC 6712).
+    A proper HTTP(S) client in libcrypto supporting GET and POST,
+    redirection, plain and ASN.1-encoded contents, proxies, and timeouts
+    EVP_KDF APIs have been introduced for working with Key Derivation Functions
+    EVP_MAC APIs have been introduced for working with MACs
+    Support for Linux Kernel TLS
diff --git a/openssl-3.spec b/openssl-3.spec
new file mode 100644
index 0000000..f9857d7
--- /dev/null
+++ b/openssl-3.spec
@@ -0,0 +1,408 @@
+#
+# spec file for package openssl-3
+#
+# Copyright (c) 2024 SUSE LLC
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
+
+
+%define ssletcdir %{_sysconfdir}/ssl
+%define sover 3
+%define _rname openssl
+%define man_suffix 3ssl
+%global sslengcnf %{ssletcdir}/engines%{sover}.d
+%global sslengdef %{ssletcdir}/engdef%{sover}.d
+
+# Enable userspace livepatching.
+%define livepatchable 1
+
+Name:           openssl-3
+# Don't forget to update the version in the "openssl" meta-package!
+Version:        3.1.4
+Release:        0
+Summary:        Secure Sockets and Transport Layer Security
+License:        Apache-2.0
+URL:            https://www.openssl.org/
+Source:         https://www.%{_rname}.org/source/%{_rname}-%{version}.tar.gz
+# to get mtime of file:
+Source1:        %{name}.changes
+Source2:        baselibs.conf
+Source3:        https://www.%{_rname}.org/source/%{_rname}-%{version}.tar.gz.asc
+# https://www.openssl.org/about/
+# http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xA2D29B7BF295C759#/openssl.keyring
+Source4:        %{_rname}.keyring
+Source5:        showciphers.c
+Source6:        openssl-Disable-default-provider-for-test-suite.patch
+# PATCH-FIX-OPENSUSE: Do not install html docs as it takes ages
+Patch1:         openssl-no-html-docs.patch
+Patch2:         openssl-truststore.patch
+Patch3:         openssl-pkgconfig.patch
+Patch4:         openssl-DEFAULT_SUSE_cipher.patch
+Patch5:         openssl-ppc64-config.patch
+Patch6:         openssl-no-date.patch
+# Add crypto-policies support
+Patch7:         openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
+Patch8:         openssl-crypto-policies-support.patch
+# PATCH-FIX-UPSTREAM: bsc#1209430 Upgrade OpenSSL from 3.0.8 to 3.1.0 in TW
+Patch9:         openssl-Add_support_for_Windows_CA_certificate_store.patch
+# PATCH-FIX-FEDORA Add FIPS_mode compatibility macro and flag support
+Patch10:        openssl-Add-FIPS_mode-compatibility-macro.patch
+Patch11:        openssl-Add-Kernel-FIPS-mode-flag-support.patch
+# PATCH-FIX-UPSTREAM jsc#PED-5086, jsc#PED-3514
+# POWER10 performance enhancements for cryptography
+Patch12:        openssl-ec-Use-static-linkage-on-nistp521-felem_-square-mul-.patch
+Patch13:        openssl-ec-56-bit-Limb-Solinas-Strategy-for-secp384r1.patch
+Patch14:        openssl-ec-powerpc64le-Add-asm-implementation-of-felem_-squa.patch
+Patch15:        openssl-ecc-Remove-extraneous-parentheses-in-secp384r1.patch
+Patch16:        openssl-powerpc-ecc-Fix-stack-allocation-secp384r1-asm.patch
+Patch17:        openssl-Improve-performance-for-6x-unrolling-with-vpermxor-i.patch
+# PATCH-FIX-UPSTREAM: bsc#1216922 CVE-2023-5678 Generating excessively long X9.42 DH keys or
+# checking excessively long X9.42 DH keys or parameters may be very slow
+Patch18:        openssl-CVE-2023-5678.patch
+# PATCH-FIX-UPSTREAM https://github.com/openssl/openssl/pull/22971
+Patch19:        openssl-Enable-BTI-feature-for-md5-on-aarch64.patch
+# PATCH-FIX-UPSTREAM: bsc#1218690 CVE-2023-6129 - POLY1305 MAC implementation corrupts vector registers on PowerPC
+Patch20:        openssl-CVE-2023-6129.patch
+# PATCH-FIX-FEDORA Load FIPS the provider and set FIPS properties implicitly
+Patch21:        openssl-Force-FIPS.patch
+# PATCH-FIX-FEDORA Disable the fipsinstall command-line utility
+Patch22:        openssl-disable-fipsinstall.patch
+# PATCH-FIX-FEDORA Instructions to load legacy provider in openssl.cnf
+Patch23:        openssl-load-legacy-provider.patch
+# PATCH-FIX-FEDORA Embed the FIPS hmac
+Patch24:        openssl-FIPS-embed-hmac.patch
+# PATCH-FIX-UPSTREAM: bsc#1218810 CVE-2023-6237: Excessive time spent checking invalid RSA public keys
+Patch25:        openssl-CVE-2023-6237.patch
+# PATCH-FIX-SUSE bsc#1194187, bsc#1207472, bsc#1218933 - Add engines section in openssl.cnf
+Patch26:        openssl-3-use-include-directive.patch
+# PATCH-FIX-UPSTREAM: bsc#1219243 CVE-2024-0727: denial of service via null dereference
+Patch27:        openssl-CVE-2024-0727.patch
+# PATCH-FIX-UPSTREAM: bsc#1222548 CVE-2024-2511: Unbounded memory growth with session handling in TLSv1.3
+Patch28:        openssl-CVE-2024-2511.patch
+# PATCH-FIX-UPSTREAM: bsc#1224388 CVE-2024-4603: excessive time spent checking DSA keys and parameters
+Patch29:        openssl-CVE-2024-4603.patch
+# PATCH-FIX-UPSTREAM: bsc#1225291 NVMe/TCP TLS connection fails due to handshake failure
+Patch30:        openssl-Fix-EVP_PKEY_CTX_add1_hkdf_info-behavior.patch
+Patch31:        openssl-Handle-empty-param-in-EVP_PKEY_CTX_add1_hkdf_info.patch
+# PATCH-FIX-UPSTREAM: bsc#1223336 aes-gcm-avx512.pl: fix non-reproducibility issue
+Patch32:        reproducible.patch
+BuildRequires:  pkgconfig
+%if 0%{?sle_version} >= 150400 || 0%{?suse_version} >= 1550
+BuildRequires:  ulp-macros
+%else
+# Define ulp-macros macros as empty
+%define cflags_livepatching ""
+%define pack_ipa_dumps      echo "Livepatching is disabled in this build"
+%endif
+BuildRequires:  pkgconfig(zlib)
+Requires:       libopenssl3 = %{version}-%{release}
+Requires:       openssl
+Provides:       ssl
+# Needed for clean upgrade path, boo#1070003
+Obsoletes:      openssl-1_0_0
+# Needed for clean upgrade from former openssl-1_1_0, boo#1081335
+Obsoletes:      openssl-1_1_0
+%{?suse_build_hwcaps_libs}
+%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150400
+Requires:       crypto-policies
+%endif
+
+%description
+OpenSSL is a software library to be used in applications that need to
+secure communications over computer networks against eavesdropping or
+need to ascertain the identity of the party at the other end.
+OpenSSL contains an implementation of the SSL and TLS protocols.
+
+%package -n libopenssl3
+Summary:        Secure Sockets and Transport Layer Security
+Recommends:     ca-certificates-mozilla
+Conflicts:      %{name} < %{version}-%{release}
+# Needed for clean upgrade from former openssl-1_1_0, boo#1081335
+Obsoletes:      libopenssl1_1_0
+%if 0%{?suse_version} >= 1550 || 0%{?sle_version} >= 150400
+Requires:       crypto-policies
+%endif
+# Merge back the hmac files bsc#1185116
+Provides:       libopenssl3-hmac = %{version}-%{release}
+Obsoletes:      libopenssl3-hmac < %{version}-%{release}
+# Needed for clean upgrade from former openssl-1_1_0, boo#1081335
+Obsoletes:      libopenssl1_1_0-hmac
+# Needed for clean upgrade from SLE-12 openssl-1_0_0, bsc#1158499
+Obsoletes:      libopenssl-1_0_0-hmac
+
+%description -n libopenssl3
+OpenSSL is a software library to be used in applications that need to
+secure communications over computer networks against eavesdropping or
+need to ascertain the identity of the party at the other end.
+OpenSSL contains an implementation of the SSL and TLS protocols.
+
+%package -n libopenssl-3-devel
+Summary:        Development files for OpenSSL
+Requires:       libopenssl3 = %{version}
+Requires:       pkgconfig(zlib)
+Recommends:     %{name} = %{version}
+Provides:       ssl-devel
+Conflicts:      ssl-devel
+# Needed for clean upgrade from former openssl-1_1_0, boo#1081335
+Obsoletes:      libopenssl-1_1_0-devel
+# Needed for clean upgrade from SLE-12 openssl-1_0_0, bsc#1158499
+Obsoletes:      libopenssl-1_0_0-devel
+
+%description -n libopenssl-3-devel
+This subpackage contains header files for developing applications
+that want to make use of the OpenSSL C API.
+
+%package -n libopenssl-3-fips-provider
+Summary:        OpenSSL FIPS provider
+Requires:       libopenssl3 >= %{version}
+BuildRequires:  fipscheck
+
+%description -n libopenssl-3-fips-provider
+This package contains the OpenSSL FIPS provider.
+
+%package doc
+Summary:        Manpages and additional documentation for openssl
+Conflicts:      libopenssl-3-devel < %{version}-%{release}
+Conflicts:      openssl-doc
+Provides:       openssl-doc = %{version}
+Obsoletes:      openssl-doc < %{version}
+BuildArch:      noarch
+
+%description doc
+This package contains optional documentation provided in addition to
+this package's base documentation.
+
+%prep
+%autosetup -p1 -n %{_rname}-%{version}
+
+%build
+%ifarch armv5el armv5tel
+export MACHINE=armv5el
+%endif
+%ifarch armv6l armv6hl
+export MACHINE=armv6l
+%endif
+
+./Configure \
+    no-mdc2 no-ec2m no-sm2 no-sm4 \
+    enable-rfc3779 enable-camellia enable-seed \
+%ifarch x86_64 aarch64 ppc64le
+    enable-ec_nistp_64_gcc_128 \
+%endif
+    enable-fips \
+    enable-ktls \
+    zlib \
+    --prefix=%{_prefix} \
+    --libdir=%{_lib} \
+    --openssldir=%{ssletcdir} \
+    %{optflags} \
+    %{cflags_livepatching} \
+    -Wa,--noexecstack \
+    -Wl,-z,relro,-z,now \
+    -fno-common \
+    -DTERMIO \
+    -DPURIFY \
+    -D_GNU_SOURCE \
+    -DOPENSSL_NO_BUF_FREELISTS \
+    $(getconf LFS_CFLAGS) \
+    -Wall \
+    --with-rand-seed=getrandom \
+    --system-ciphers-file=%{_sysconfdir}/crypto-policies/back-ends/openssl.config
+
+# Show build configuration
+perl configdata.pm --dump
+
+# Do not run this in a production package the FIPS symbols must be patched-in
+# util/mkdef.pl crypto update
+
+%make_build depend
+%make_build all
+
+%check
+# Relax the crypto-policies requirements for the regression tests
+# Revert patch8 before running tests
+patch -p1 -R < %{PATCH8}
+# Revert openssl-3-use-include-directive.patch because these directories
+# exists only in buildroot but not in build system and some tests are failing
+# because of it.
+patch -p1 -R < %{PATCH26}
+# Disable the default provider for the test suite.
+patch -p1 < %{SOURCE6}
+export OPENSSL_SYSTEM_CIPHERS_OVERRIDE=xyz_nonexistent_file
+export MALLOC_CHECK_=3
+export MALLOC_PERTURB_=$(($RANDOM % 255 + 1))
+# export HARNESS_VERBOSE=yes
+# Embed HMAC into fips provider for test run
+OPENSSL_CONF=/dev/null LD_LIBRARY_PATH=. apps/openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813 < providers/fips.so > providers/fips.so.hmac
+objcopy --update-section .rodata1=providers/fips.so.hmac providers/fips.so providers/fips.so.mac
+mv providers/fips.so.mac providers/fips.so
+
+# Run the tests in non FIPS mode
+LD_LIBRARY_PATH="$PWD" make test -j16
+
+# Run the tests also in FIPS mode
+# OPENSSL_FORCE_FIPS_MODE=1 LD_LIBRARY_PATH="$PWD" make TESTS='-test_evp_fetch_prov -test_tsa' test -j16 || :
+
+# Add generation of HMAC checksum of the final stripped library
+# We manually copy standard definition of __spec_install_post
+# and add hmac calculation/embedding to fips.so
+%define __spec_install_post \
+    %{?__debug_package:%{__debug_install_post}} \
+    %{__arch_install_post} \
+    %{__os_install_post} \
+    OPENSSL_CONF=/dev/null LD_LIBRARY_PATH=. apps/openssl dgst -binary -sha256 -mac HMAC -macopt hexkey:f4556650ac31d35461610bac4ed81b1a181b2d8a43ea2854cbae22ca74560813 < $RPM_BUILD_ROOT%{_libdir}/ossl-modules/fips.so > $RPM_BUILD_ROOT%{_libdir}/ossl-modules/fips.so.hmac \
+    objcopy --update-section .rodata1=$RPM_BUILD_ROOT%{_libdir}/ossl-modules/fips.so.hmac $RPM_BUILD_ROOT%{_libdir}/ossl-modules/fips.so $RPM_BUILD_ROOT%{_libdir}/ossl-modules/fips.so.mac \
+    mv $RPM_BUILD_ROOT%{_libdir}/ossl-modules/fips.so.mac $RPM_BUILD_ROOT%{_libdir}/ossl-modules/fips.so \
+    rm $RPM_BUILD_ROOT%{_libdir}/ossl-modules/fips.so.hmac \
+%{nil}
+
+# show ciphers
+gcc -o showciphers %{optflags} -I%{buildroot}%{_includedir} %{SOURCE5} -L%{buildroot}%{_libdir} -lssl -lcrypto
+LD_LIBRARY_PATH=%{buildroot}%{_libdir} ./showciphers
+
+%install
+%{pack_ipa_dumps}
+%make_install %{?_smp_mflags} MANSUFFIX=%{man_suffix}
+
+rename so.%{sover} so.%{version} %{buildroot}%{_libdir}/*.so.%{sover}
+for lib in %{buildroot}%{_libdir}/*.so.%{version} ; do
+    chmod 755 ${lib}
+    ln -sf $(basename ${lib}) %{buildroot}%{_libdir}/$(basename ${lib} .%{version})
+    ln -sf $(basename ${lib}) %{buildroot}%{_libdir}/$(basename ${lib} .%{version}).%{sover}
+done
+
+# Remove static libraries
+rm -f %{buildroot}%{_libdir}/lib*.a
+
+# Remove the cnf.dist
+rm -f %{buildroot}%{ssletcdir}/openssl.cnf.dist
+rm -f %{buildroot}%{ssletcdir}/ct_log_list.cnf.dist
+
+# Make a copy of the default openssl.cnf file
+cp %{buildroot}%{ssletcdir}/openssl.cnf %{buildroot}%{ssletcdir}/openssl-orig.cnf
+
+# Create openssl ca-certificates dir required by nodejs regression tests [bsc#1207484]
+mkdir -p %{buildroot}%{_localstatedir}/lib/ca-certificates/openssl
+install -d -m 555 %{buildroot}%{_localstatedir}/lib/ca-certificates/openssl
+
+# Remove the fipsmodule.cnf because FIPS module is loaded automatically
+rm -f %{buildroot}%{ssletcdir}/fipsmodule.cnf
+
+ln -sf ./%{_rname} %{buildroot}/%{_includedir}/ssl
+mkdir %{buildroot}/%{_datadir}/ssl
+mv %{buildroot}/%{ssletcdir}/misc %{buildroot}/%{_datadir}/ssl/
+
+# Create the two directories into which packages will drop their configuration
+# files.
+mkdir %{buildroot}/%{sslengcnf}
+mkdir %{buildroot}/%{sslengdef}
+# Create unversioned symbolic links to above directories
+ln -s %{sslengcnf} %{buildroot}/%{ssletcdir}/engines.d
+ln -s %{sslengdef} %{buildroot}/%{ssletcdir}/engdef.d
+
+# Avoid file conflicts with man pages from other packages
+pushd %{buildroot}/%{_mandir}
+find . -type f -exec chmod 644 {} +
+mv man5/config.5%{man_suffix} man5/openssl.cnf.5
+popd
+
+# Do not install demo scripts executable under /usr/share/doc
+find demos -type f -perm /111 -exec chmod 644 {} +
+
+# Place showciphers.c for %%doc macro
+cp %{SOURCE5} .
+
+# Compute the FIPS hmac using the brp-50-generate-fips-hmac script
+export BRP_FIPSHMAC_FILES="%{buildroot}%{_libdir}/libssl.so.%{sover} %{buildroot}%{_libdir}/libcrypto.so.%{sover}"
+
+%post -p "/bin/bash"
+if [ "$1" -gt 1 ] ; then
+    # Check if the packaged default config file for openssl-3, called openssl.cnf,
+    # is the original or if it has been modified and alert the user in that case
+    # that a copy of the original file openssl-orig.cnf can be used if needed.
+    cmp --silent %{ssletcdir}/openssl.cnf %{ssletcdir}/openssl-orig.cnf 2>/dev/null
+    if [ "$?" -eq 1 ] ; then
+        echo -e " The openssl-3 default config file openssl.cnf is different from" ;
+        echo -e " the original one shipped by the package. A copy of the original" ;
+        echo -e " file is packaged and named as openssl-orig.cnf if needed."
+    fi
+fi
+
+%pre
+# Migrate old engines.d to engines1.1.d.rpmsave
+if [ ! -L %{ssletcdir}/engines.d ] && [ -d %{ssletcdir}/engines.d ]; then
+   mkdir %{ssletcdir}/engines1.1.d.rpmsave ||:
+   mv %{ssletcdir}/engines.d %{ssletcdir}/engines1.1.d.rpmsave ||:
+fi
+
+# Migrate old engdef.d to engdef1.1.d.rpmsave
+if [ ! -L %{ssletcdir}/engdef.d ] && [ -d %{ssletcdir}/engdef.d ]; then
+   mkdir %{ssletcdir}/engdef1.1.d.rpmsave ||:
+   mv %{ssletcdir}/engdef.d %{ssletcdir}/engdef1.1.d.rpmsave ||:
+fi
+
+%post -n libopenssl3 -p /sbin/ldconfig
+%postun -n libopenssl3 -p /sbin/ldconfig
+
+%files -n libopenssl3
+%license LICENSE.txt
+%attr(0755,root,root) %{_libdir}/libssl.so.%{version}
+%{_libdir}/libssl.so.%{sover}
+%attr(0755,root,root) %{_libdir}/libcrypto.so.%{version}
+%{_libdir}/libcrypto.so.%{sover}
+%{_libdir}/engines-%{sover}
+%dir %{_libdir}/ossl-modules
+%{_libdir}/ossl-modules/legacy.so
+%{_libdir}/.libssl.so.%{sover}.hmac
+%{_libdir}/.libcrypto.so.%{sover}.hmac
+
+%files -n libopenssl-3-fips-provider
+%{_libdir}/ossl-modules/fips.so
+
+%files -n libopenssl-3-devel
+%doc NOTES*.md CONTRIBUTING.md HACKING.md AUTHORS.md ACKNOWLEDGEMENTS.md
+%{_includedir}/%{_rname}/
+%{_includedir}/ssl
+%{_libdir}/*.so
+%{_libdir}/pkgconfig/*.pc
+
+%files doc
+%doc README.md
+%doc doc/html/* doc/HOWTO/* demos
+%doc showciphers.c
+%{_mandir}/man3/*
+
+%files
+%license LICENSE.txt
+%doc CHANGES.md NEWS.md FAQ.md README.md
+%dir %{ssletcdir}
+%config %{ssletcdir}/openssl-orig.cnf
+%config (noreplace) %{ssletcdir}/openssl.cnf
+%config (noreplace) %{ssletcdir}/ct_log_list.cnf
+%attr(700,root,root) %{ssletcdir}/private
+%dir %{sslengcnf}
+%dir %{sslengdef}
+# symbolic link to above directories
+%{ssletcdir}/engines.d
+%{ssletcdir}/engdef.d
+%dir %{_datadir}/ssl
+%{_datadir}/ssl/misc
+%dir %{_localstatedir}/lib/ca-certificates/
+%dir %{_localstatedir}/lib/ca-certificates/openssl
+%{_bindir}/%{_rname}
+%{_bindir}/c_rehash
+%{_mandir}/man1/*
+%{_mandir}/man5/*
+%{_mandir}/man7/*
+
+%changelog
diff --git a/openssl-Add-FIPS_mode-compatibility-macro.patch b/openssl-Add-FIPS_mode-compatibility-macro.patch
new file mode 100644
index 0000000..76abdf2
--- /dev/null
+++ b/openssl-Add-FIPS_mode-compatibility-macro.patch
@@ -0,0 +1,83 @@
+From 8e29a10b39a649d751870eb1fd1b8c388e66acc3 Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Mon, 31 Jul 2023 09:41:27 +0200
+Subject: [PATCH 08/35] 0008-Add-FIPS_mode-compatibility-macro.patch
+
+Patch-name: 0008-Add-FIPS_mode-compatibility-macro.patch
+Patch-id: 8
+Patch-status: |
+    # Add FIPS_mode() compatibility macro
+From-dist-git-commit: 9409bc7044cf4b5773639cce20f51399888c45fd
+---
+ include/openssl/fips.h | 26 ++++++++++++++++++++++++++
+ test/property_test.c   | 14 ++++++++++++++
+ 2 files changed, 40 insertions(+)
+ create mode 100644 include/openssl/fips.h
+
+diff --git a/include/openssl/fips.h b/include/openssl/fips.h
+new file mode 100644
+index 0000000000..4162cbf88e
+--- /dev/null
++++ b/include/openssl/fips.h
+@@ -0,0 +1,26 @@
++/*
++ * Copyright 2016-2020 The OpenSSL Project Authors. All Rights Reserved.
++ *
++ * Licensed under the Apache License 2.0 (the "License").  You may not use
++ * this file except in compliance with the License.  You can obtain a copy
++ * in the file LICENSE in the source distribution or at
++ * https://www.openssl.org/source/license.html
++ */
++
++#ifndef OPENSSL_FIPS_H
++# define OPENSSL_FIPS_H
++# pragma once
++
++# include <openssl/evp.h>
++# include <openssl/macros.h>
++
++# ifdef __cplusplus
++extern "C" {
++# endif
++
++# define FIPS_mode() EVP_default_properties_is_fips_enabled(NULL)
++
++# ifdef __cplusplus
++}
++# endif
++#endif
+diff --git a/test/property_test.c b/test/property_test.c
+index 45b1db3e85..8894c1c1cb 100644
+--- a/test/property_test.c
++++ b/test/property_test.c
+@@ -677,6 +677,19 @@ static int test_property_list_to_string(int i)
+     return ret;
+ }
+ 
++#include <openssl/fips.h>
++static int test_downstream_FIPS_mode(void)
++{
++    int ret = 0;
++
++    ret = TEST_true(EVP_set_default_properties(NULL, "fips=yes"))
++          && TEST_true(FIPS_mode())
++          && TEST_true(EVP_set_default_properties(NULL, "fips=no"))
++          && TEST_false(FIPS_mode());
++
++    return ret;
++}
++
+ int setup_tests(void)
+ {
+     ADD_TEST(test_property_string);
+@@ -690,6 +703,7 @@ int setup_tests(void)
+     ADD_TEST(test_property);
+     ADD_TEST(test_query_cache_stochastic);
+     ADD_TEST(test_fips_mode);
++    ADD_TEST(test_downstream_FIPS_mode);
+     ADD_ALL_TESTS(test_property_list_to_string, OSSL_NELEM(to_string_tests));
+     return 1;
+ }
+-- 
+2.41.0
+
diff --git a/openssl-Add-Kernel-FIPS-mode-flag-support.patch b/openssl-Add-Kernel-FIPS-mode-flag-support.patch
new file mode 100644
index 0000000..94a80cf
--- /dev/null
+++ b/openssl-Add-Kernel-FIPS-mode-flag-support.patch
@@ -0,0 +1,86 @@
+From aa3aebf132959e7e44876042efaf9ff24ffe0f2b Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Mon, 31 Jul 2023 09:41:27 +0200
+Subject: [PATCH 09/35] 0009-Add-Kernel-FIPS-mode-flag-support.patch
+
+Patch-name: 0009-Add-Kernel-FIPS-mode-flag-support.patch
+Patch-id: 9
+Patch-status: |
+    # Add check to see if fips flag is enabled in kernel
+From-dist-git-commit: 9409bc7044cf4b5773639cce20f51399888c45fd
+---
+ crypto/context.c            | 36 ++++++++++++++++++++++++++++++++++++
+ include/internal/provider.h |  3 +++
+ 2 files changed, 39 insertions(+)
+
+diff --git a/crypto/context.c b/crypto/context.c
+index e294ea1512..51002ba79a 100644
+--- a/crypto/context.c
++++ b/crypto/context.c
+@@ -16,6 +16,41 @@
+ #include "internal/provider.h"
+ #include "crypto/context.h"
+ 
++# include <sys/types.h>
++# include <sys/stat.h>
++# include <fcntl.h>
++# include <unistd.h>
++# include <openssl/evp.h>
++
++# define FIPS_MODE_SWITCH_FILE "/proc/sys/crypto/fips_enabled"
++
++static int kernel_fips_flag;
++
++static void read_kernel_fips_flag(void)
++{
++	char buf[2] = "0";
++	int fd;
++
++	if (ossl_safe_getenv("OPENSSL_FORCE_FIPS_MODE") != NULL) {
++		buf[0] = '1';
++	} else if ((fd = open(FIPS_MODE_SWITCH_FILE, O_RDONLY)) >= 0) {
++		while (read(fd, buf, sizeof(buf)) < 0 && errno == EINTR) ;
++		close(fd);
++	}
++
++	if (buf[0] == '1') {
++		kernel_fips_flag = 1;
++	}
++
++		return;
++}
++
++int ossl_get_kernel_fips_flag()
++{
++	return kernel_fips_flag;
++}
++
++
+ struct ossl_lib_ctx_st {
+     CRYPTO_RWLOCK *lock, *rand_crngt_lock;
+     OSSL_EX_DATA_GLOBAL global;
+@@ -336,6 +371,7 @@ static int default_context_inited = 0;
+ 
+ DEFINE_RUN_ONCE_STATIC(default_context_do_init)
+ {
++    read_kernel_fips_flag();
+     if (!CRYPTO_THREAD_init_local(&default_context_thread_local, NULL))
+         goto err;
+ 
+diff --git a/include/internal/provider.h b/include/internal/provider.h
+index 18937f84c7..1446bf7afb 100644
+--- a/include/internal/provider.h
++++ b/include/internal/provider.h
+@@ -112,6 +112,9 @@ int ossl_provider_init_as_child(OSSL_LIB_CTX *ctx,
+                                 const OSSL_DISPATCH *in);
+ void ossl_provider_deinit_child(OSSL_LIB_CTX *ctx);
+ 
++/* FIPS flag access */
++int ossl_get_kernel_fips_flag(void);
++
+ # ifdef __cplusplus
+ }
+ # endif
+-- 
+2.41.0
+
diff --git a/openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch b/openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
new file mode 100644
index 0000000..1bb6aee
--- /dev/null
+++ b/openssl-Add-support-for-PROFILE-SYSTEM-system-default-cipher.patch
@@ -0,0 +1,305 @@
+From 736d709ec194b3a763e004696df22792c62a11fc Mon Sep 17 00:00:00 2001
+From: Tomas Mraz <tmraz@fedoraproject.org>
+Date: Thu, 24 Sep 2020 10:16:46 +0200
+Subject: Add support for PROFILE=SYSTEM system default cipherlist
+
+(was openssl-1.1.1-system-cipherlist.patch)
+---
+ Configurations/unix-Makefile.tmpl |    5 ++
+ Configure                         |   11 ++++
+ doc/man1/openssl-ciphers.pod.in   |    9 +++
+ include/openssl/ssl.h.in          |    5 ++
+ ssl/ssl_ciph.c                    |   87 +++++++++++++++++++++++++++++++++-----
+ ssl/ssl_lib.c                     |    4 -
+ test/cipherlist_test.c            |    2 
+ util/libcrypto.num                |    1 
+ 8 files changed, 110 insertions(+), 14 deletions(-)
+
+--- a/Configurations/unix-Makefile.tmpl
++++ b/Configurations/unix-Makefile.tmpl
+@@ -315,6 +315,10 @@ MANDIR=$(INSTALLTOP)/share/man
+ DOCDIR=$(INSTALLTOP)/share/doc/$(BASENAME)
+ HTMLDIR=$(DOCDIR)/html
+ 
++{- output_off() if $config{system_ciphers_file} eq ""; "" -}
++SYSTEM_CIPHERS_FILE_DEFINE=-DSYSTEM_CIPHERS_FILE="\"{- $config{system_ciphers_file} -}\""
++{- output_on() if $config{system_ciphers_file} eq ""; "" -}
++
+ # MANSUFFIX is for the benefit of anyone who may want to have a suffix
+ # appended after the manpage file section number.  "ssl" is popular,
+ # resulting in files such as config.5ssl rather than config.5.
+@@ -338,6 +342,7 @@ CC=$(CROSS_COMPILE){- $config{CC} -}
+ CXX={- $config{CXX} ? "\$(CROSS_COMPILE)$config{CXX}" : '' -}
+ CPPFLAGS={- our $cppflags1 = join(" ",
+                                   (map { "-D".$_} @{$config{CPPDEFINES}}),
++                                  "\$(SYSTEM_CIPHERS_FILE_DEFINE)",
+                                   (map { "-I".$_} @{$config{CPPINCLUDES}}),
+                                   @{$config{CPPFLAGS}}) -}
+ CFLAGS={- join(' ', @{$config{CFLAGS}}) -}
+--- a/Configure
++++ b/Configure
+@@ -27,7 +27,7 @@ use OpenSSL::config;
+ my $orig_death_handler = $SIG{__DIE__};
+ $SIG{__DIE__} = \&death_handler;
+ 
+-my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
++my $usage="Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--system-ciphers-file=SYSTEMCIPHERFILE] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]\n";
+ 
+ my $banner = <<"EOF";
+ 
+@@ -61,6 +61,10 @@ EOF
+ #               given with --prefix.
+ #               This becomes the value of OPENSSLDIR in Makefile and in C.
+ #               (Default: PREFIX/ssl)
++#
++# --system-ciphers-file  A file to read cipher string from when the PROFILE=SYSTEM
++#		cipher is specified (default).
++#
+ # --banner=".." Output specified text instead of default completion banner
+ #
+ # -w            Don't wait after showing a Configure warning
+@@ -387,6 +391,7 @@ $config{prefix}="";
+ $config{openssldir}="";
+ $config{processor}="";
+ $config{libdir}="";
++$config{system_ciphers_file}="";
+ my $auto_threads=1;    # enable threads automatically? true by default
+ my $default_ranlib;
+ 
+@@ -989,6 +994,10 @@ while (@argvcopy)
+                         die "FIPS key too long (64 bytes max)\n"
+                            if length $1 > 64;
+                         }
++                elsif (/^--system-ciphers-file=(.*)$/)
++                        {
++                        $config{system_ciphers_file}=$1;
++                        }
+                 elsif (/^--banner=(.*)$/)
+                         {
+                         $banner = $1 . "\n";
+--- a/doc/man1/openssl-ciphers.pod.in
++++ b/doc/man1/openssl-ciphers.pod.in
+@@ -186,6 +186,15 @@ As of OpenSSL 1.0.0, the B<ALL> cipher s
+ 
+ The cipher suites not enabled by B<ALL>, currently B<eNULL>.
+ 
++=item B<PROFILE=SYSTEM>
++
++The list of enabled cipher suites will be loaded from the system crypto policy
++configuration file B</etc/crypto-policies/back-ends/openssl.config>.
++See also L<update-crypto-policies(8)>.
++This is the default behavior unless an application explicitly sets a cipher
++list. If used in a cipher list configuration value this string must be at the
++beginning of the cipher list, otherwise it will not be recognized.
++
+ =item B<HIGH>
+ 
+ "High" encryption cipher suites. This currently means those with key lengths
+--- a/include/openssl/ssl.h.in
++++ b/include/openssl/ssl.h.in
+@@ -213,6 +213,11 @@ extern "C" {
+  * throwing out anonymous and unencrypted ciphersuites! (The latter are not
+  * actually enabled by ALL, but "ALL:RSA" would enable some of them.)
+  */
++# ifdef SYSTEM_CIPHERS_FILE
++#  define SSL_SYSTEM_DEFAULT_CIPHER_LIST "PROFILE=SYSTEM"
++# else
++#  define SSL_SYSTEM_DEFAULT_CIPHER_LIST OSSL_default_cipher_list()
++# endif
+ 
+ /* Used in SSL_set_shutdown()/SSL_get_shutdown(); */
+ # define SSL_SENT_SHUTDOWN       1
+--- a/ssl/ssl_ciph.c
++++ b/ssl/ssl_ciph.c
+@@ -1443,6 +1443,53 @@ int SSL_set_ciphersuites(SSL *s, const c
+     return ret;
+ }
+ 
++#ifdef SYSTEM_CIPHERS_FILE
++static char *load_system_str(const char *suffix)
++{
++    FILE *fp;
++    char buf[1024];
++    char *new_rules;
++    const char *ciphers_path;
++    unsigned len, slen;
++
++    if ((ciphers_path = ossl_safe_getenv("OPENSSL_SYSTEM_CIPHERS_OVERRIDE")) == NULL)
++        ciphers_path = SYSTEM_CIPHERS_FILE;
++    fp = fopen(ciphers_path, "r");
++    if (fp == NULL || fgets(buf, sizeof(buf), fp) == NULL) {
++        /* cannot open or file is empty */
++        snprintf(buf, sizeof(buf), "%s", SSL_DEFAULT_CIPHER_LIST);
++    }
++
++    if (fp)
++        fclose(fp);
++
++    slen = strlen(suffix);
++    len = strlen(buf);
++
++    if (buf[len - 1] == '\n') {
++        len--;
++        buf[len] = 0;
++    }
++    if (buf[len - 1] == '\r') {
++        len--;
++        buf[len] = 0;
++    }
++
++    new_rules = OPENSSL_malloc(len + slen + 1);
++    if (new_rules == 0)
++        return NULL;
++
++    memcpy(new_rules, buf, len);
++    if (slen > 0) {
++        memcpy(&new_rules[len], suffix, slen);
++        len += slen;
++    }
++    new_rules[len] = 0;
++
++    return new_rules;
++}
++#endif
++
+ STACK_OF(SSL_CIPHER) *ssl_create_cipher_list(SSL_CTX *ctx,
+                                              STACK_OF(SSL_CIPHER) *tls13_ciphersuites,
+                                              STACK_OF(SSL_CIPHER) **cipher_list,
+@@ -1457,15 +1504,25 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+     CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr;
+     const SSL_CIPHER **ca_list = NULL;
+     const SSL_METHOD *ssl_method = ctx->method;
++#ifdef SYSTEM_CIPHERS_FILE
++    char *new_rules = NULL;
++
++    if (rule_str != NULL && strncmp(rule_str, "PROFILE=SYSTEM", 14) == 0) {
++        char *p = rule_str + 14;
++
++        new_rules = load_system_str(p);
++        rule_str = new_rules;
++    }
++#endif
+ 
+     /*
+      * Return with error if nothing to do.
+      */
+     if (rule_str == NULL || cipher_list == NULL || cipher_list_by_id == NULL)
+-        return NULL;
++        goto err;
+ 
+     if (!check_suiteb_cipher_list(ssl_method, c, &rule_str))
+-        return NULL;
++        goto err;
+ 
+     /*
+      * To reduce the work to do we only want to process the compiled
+@@ -1487,7 +1544,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+     co_list = OPENSSL_malloc(sizeof(*co_list) * num_of_ciphers);
+     if (co_list == NULL) {
+         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
+-        return NULL;          /* Failure */
++        goto err;
+     }
+ 
+     ssl_cipher_collect_ciphers(ssl_method, num_of_ciphers,
+@@ -1553,8 +1610,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+      * in force within each class
+      */
+     if (!ssl_cipher_strength_sort(&head, &tail)) {
+-        OPENSSL_free(co_list);
+-        return NULL;
++        goto err;
+     }
+ 
+     /*
+@@ -1598,9 +1654,8 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+     num_of_alias_max = num_of_ciphers + num_of_group_aliases + 1;
+     ca_list = OPENSSL_malloc(sizeof(*ca_list) * num_of_alias_max);
+     if (ca_list == NULL) {
+-        OPENSSL_free(co_list);
+         ERR_raise(ERR_LIB_SSL, ERR_R_MALLOC_FAILURE);
+-        return NULL;          /* Failure */
++        goto err;
+     }
+     ssl_cipher_collect_aliases(ca_list, num_of_group_aliases,
+                                disabled_mkey, disabled_auth, disabled_enc,
+@@ -1633,8 +1688,7 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+     OPENSSL_free(ca_list);      /* Not needed anymore */
+ 
+     if (!ok) {                  /* Rule processing failure */
+-        OPENSSL_free(co_list);
+-        return NULL;
++        goto err;
+     }
+ 
+     /*
+@@ -1642,10 +1696,13 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+      * if we cannot get one.
+      */
+     if ((cipherstack = sk_SSL_CIPHER_new_null()) == NULL) {
+-        OPENSSL_free(co_list);
+-        return NULL;
++        goto err;
+     }
+ 
++#ifdef SYSTEM_CIPHERS_FILE
++    OPENSSL_free(new_rules);    /* Not needed anymore */
++#endif
++
+     /* Add TLSv1.3 ciphers first - we always prefer those if possible */
+     for (i = 0; i < sk_SSL_CIPHER_num(tls13_ciphersuites); i++) {
+         const SSL_CIPHER *sslc = sk_SSL_CIPHER_value(tls13_ciphersuites, i);
+@@ -1697,6 +1754,14 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+     *cipher_list = cipherstack;
+ 
+     return cipherstack;
++
++err:
++    OPENSSL_free(co_list);
++#ifdef SYSTEM_CIPHERS_FILE
++    OPENSSL_free(new_rules);
++#endif
++    return NULL;
++
+ }
+ 
+ char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, int len)
+--- a/ssl/ssl_lib.c
++++ b/ssl/ssl_lib.c
+@@ -661,7 +661,7 @@ int SSL_CTX_set_ssl_version(SSL_CTX *ctx
+                                 ctx->tls13_ciphersuites,
+                                 &(ctx->cipher_list),
+                                 &(ctx->cipher_list_by_id),
+-                                OSSL_default_cipher_list(), ctx->cert);
++                                SSL_SYSTEM_DEFAULT_CIPHER_LIST, ctx->cert);
+     if ((sk == NULL) || (sk_SSL_CIPHER_num(sk) <= 0)) {
+         ERR_raise(ERR_LIB_SSL, SSL_R_SSL_LIBRARY_HAS_NO_CIPHERS);
+         return 0;
+@@ -3286,7 +3286,7 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *li
+     if (!ssl_create_cipher_list(ret,
+                                 ret->tls13_ciphersuites,
+                                 &ret->cipher_list, &ret->cipher_list_by_id,
+-                                OSSL_default_cipher_list(), ret->cert)
++                                SSL_SYSTEM_DEFAULT_CIPHER_LIST, ret->cert)
+         || sk_SSL_CIPHER_num(ret->cipher_list) <= 0) {
+         ERR_raise(ERR_LIB_SSL, SSL_R_LIBRARY_HAS_NO_CIPHERS);
+         goto err2;
+--- a/test/cipherlist_test.c
++++ b/test/cipherlist_test.c
+@@ -246,7 +246,9 @@ end:
+ 
+ int setup_tests(void)
+ {
++#ifndef SYSTEM_CIPHERS_FILE
+     ADD_TEST(test_default_cipherlist_implicit);
++#endif
+     ADD_TEST(test_default_cipherlist_explicit);
+     ADD_TEST(test_default_cipherlist_clear);
+     return 1;
+--- a/util/libcrypto.num
++++ b/util/libcrypto.num
+@@ -5435,3 +5435,4 @@ EVP_MD_CTX_dup
+ EVP_CIPHER_CTX_dup                      5563	3_1_0	EXIST::FUNCTION:
+ BN_are_coprime                          5564	3_1_0	EXIST::FUNCTION:
+ OSSL_CMP_MSG_update_recipNonce          5565	3_0_9	EXIST::FUNCTION:CMP
++ossl_safe_getenv                        ?	3_0_0	EXIST::FUNCTION:
diff --git a/openssl-Add_support_for_Windows_CA_certificate_store.patch b/openssl-Add_support_for_Windows_CA_certificate_store.patch
new file mode 100644
index 0000000..cd143e0
--- /dev/null
+++ b/openssl-Add_support_for_Windows_CA_certificate_store.patch
@@ -0,0 +1,743 @@
+From 2a071544f7d2e963a1f68f266f4e375568909d38 Mon Sep 17 00:00:00 2001
+From: Hugo Landau <hlandau@openssl.org>
+Date: Fri, 8 Apr 2022 13:10:52 +0100
+Subject: [PATCH 1/8] Fix URI handling in SSL_CERT_DIR/introduce SSL_CERT_URI
+ env
+
+Fixes #18068.
+---
+ CHANGES.md                                               |   21 
+ Configure                                                |    7 
+ crypto/x509/by_dir.c                                     |   17 
+ crypto/x509/by_store.c                                   |   14 
+ crypto/x509/x509_def.c                                   |   15 
+ doc/build.info                                           |    6 
+ doc/man3/X509_get_default_cert_file.pod                  |  113 +++++
+ include/internal/cryptlib.h                              |   11 
+ include/internal/e_os.h                                  |    2 
+ include/openssl/x509.h.in                                |    3 
+ providers/implementations/include/prov/implementations.h |    1 
+ providers/implementations/storemgmt/build.info           |    3 
+ providers/implementations/storemgmt/winstore_store.c     |  327 +++++++++++++++
+ providers/stores.inc                                     |    3 
+ util/libcrypto.num                                       |    3 
+ util/missingcrypto.txt                                   |    4 
+ 16 files changed, 536 insertions(+), 14 deletions(-)
+
+--- a/CHANGES.md
++++ b/CHANGES.md
+@@ -24,6 +24,27 @@ OpenSSL 3.1
+ 
+ ### Changes between 3.1.0 and 3.1.1 [30 May 2023]
+ 
++ * The `SSL_CERT_PATH` and `SSL_CERT_URI` environment variables are introduced.
++   `SSL_CERT_URI` can be used to specify a URI for a root certificate store. The
++   `SSL_CERT_PATH` environment variable specifies a delimiter-separated list of
++   paths which are searched for root certificates.
++
++   The existing `SSL_CERT_DIR` environment variable is deprecated.
++   `SSL_CERT_DIR` was previously used to specify either a delimiter-separated
++   list of paths or an URI, which is ambiguous. Setting `SSL_CERT_PATH` causes
++   `SSL_CERT_DIR` to be ignored for the purposes of determining root certificate
++   directories, and setting `SSL_CERT_URI` causes `SSL_CERT_DIR` to be ignored
++   for the purposes of determining root certificate stores.
++
++   *Hugo Landau*
++
++ * Support for loading root certificates from the Windows certificate store
++   has been added. The support is in the form of a store which recognises the
++   URI string of `org.openssl.winstore://`. This store is enabled by default and
++   can be disabled using the new compile-time option `no-winstore`.
++
++   *Hugo Landau*
++
+  * Mitigate for the time it takes for `OBJ_obj2txt` to translate gigantic
+    OBJECT IDENTIFIER sub-identifiers to canonical numeric text form.
+ 
+--- a/Configure
++++ b/Configure
+@@ -420,6 +420,7 @@ my @disablables = (
+     "cached-fetch",
+     "camellia",
+     "capieng",
++    "winstore",
+     "cast",
+     "chacha",
+     "cmac",
+@@ -1726,6 +1727,12 @@ unless ($disabled{ktls}) {
+     }
+ }
+ 
++unless ($disabled{winstore}) {
++    unless ($target =~ /^(?:Cygwin|mingw|VC-|BC-)/) {
++        disable('not-windows', 'winstore');
++    }
++}
++
+ push @{$config{openssl_other_defines}}, "OPENSSL_NO_KTLS" if ($disabled{ktls});
+ 
+ # Get the extra flags used when building shared libraries and modules.  We
+--- a/crypto/x509/by_dir.c
++++ b/crypto/x509/by_dir.c
+@@ -88,13 +88,18 @@ static int dir_ctrl(X509_LOOKUP *ctx, in
+     switch (cmd) {
+     case X509_L_ADD_DIR:
+         if (argl == X509_FILETYPE_DEFAULT) {
+-            const char *dir = ossl_safe_getenv(X509_get_default_cert_dir_env());
++            /* If SSL_CERT_PATH is provided and non-empty, use that. */
++            const char *dir = ossl_safe_getenv(X509_get_default_cert_path_env());
+ 
+-            if (dir)
+-                ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
+-            else
+-                ret = add_cert_dir(ld, X509_get_default_cert_dir(),
+-                                   X509_FILETYPE_PEM);
++            /* Fallback to SSL_CERT_DIR. */
++            if (dir == NULL)
++                dir = ossl_safe_getenv(X509_get_default_cert_dir_env());
++
++            /* Fallback to built-in default. */
++            if (dir == NULL)
++                dir = X509_get_default_cert_dir();
++
++            ret = add_cert_dir(ld, dir, X509_FILETYPE_PEM);
+             if (!ret) {
+                 ERR_raise(ERR_LIB_X509, X509_R_LOADING_CERT_DIR);
+             }
+--- a/crypto/x509/by_store.c
++++ b/crypto/x509/by_store.c
+@@ -111,11 +111,21 @@ static int by_store_ctrl_ex(X509_LOOKUP
+ {
+     switch (cmd) {
+     case X509_L_ADD_STORE:
+-        /* If no URI is given, use the default cert dir as default URI */
++        /* First try the newer default cert URI envvar. */
++        if (argp == NULL)
++            argp = ossl_safe_getenv(X509_get_default_cert_uri_env());
++
++        /* If not set, see if we have a URI in the older cert dir envvar. */
+         if (argp == NULL)
+             argp = ossl_safe_getenv(X509_get_default_cert_dir_env());
++
++        /* Fallback to default store URI. */
+         if (argp == NULL)
+-            argp = X509_get_default_cert_dir();
++            argp = X509_get_default_cert_uri();
++
++        /* No point adding an empty URI. */
++        if (!*argp)
++            return 1;
+ 
+         {
+             STACK_OF(OPENSSL_STRING) *uris = X509_LOOKUP_get_method_data(ctx);
+--- a/crypto/x509/x509_def.c
++++ b/crypto/x509/x509_def.c
+@@ -22,6 +22,11 @@ const char *X509_get_default_cert_area(v
+     return X509_CERT_AREA;
+ }
+ 
++const char *X509_get_default_cert_uri(void)
++{
++    return X509_CERT_URI;
++}
++
+ const char *X509_get_default_cert_dir(void)
+ {
+     return X509_CERT_DIR;
+@@ -32,6 +37,16 @@ const char *X509_get_default_cert_file(v
+     return X509_CERT_FILE;
+ }
+ 
++const char *X509_get_default_cert_uri_env(void)
++{
++    return X509_CERT_URI_EVP;
++}
++
++const char *X509_get_default_cert_path_env(void)
++{
++    return X509_CERT_PATH_EVP;
++}
++
+ const char *X509_get_default_cert_dir_env(void)
+ {
+     return X509_CERT_DIR_EVP;
+--- a/doc/build.info
++++ b/doc/build.info
+@@ -2791,6 +2791,10 @@ DEPEND[html/man3/X509_get0_uids.html]=ma
+ GENERATE[html/man3/X509_get0_uids.html]=man3/X509_get0_uids.pod
+ DEPEND[man/man3/X509_get0_uids.3]=man3/X509_get0_uids.pod
+ GENERATE[man/man3/X509_get0_uids.3]=man3/X509_get0_uids.pod
++DEPEND[html/man3/X509_get_default_cert_file.html]=man3/X509_get_default_cert_file.pod
++GENERATE[html/man3/X509_get_default_cert_file.html]=man3/X509_get_default_cert_file.pod
++DEPEND[man/man3/X509_get_default_cert_file.3]=man3/X509_get_default_cert_file.pod
++GENERATE[man/man3/X509_get_default_cert_file.3]=man3/X509_get_default_cert_file.pod
+ DEPEND[html/man3/X509_get_extension_flags.html]=man3/X509_get_extension_flags.pod
+ GENERATE[html/man3/X509_get_extension_flags.html]=man3/X509_get_extension_flags.pod
+ DEPEND[man/man3/X509_get_extension_flags.3]=man3/X509_get_extension_flags.pod
+@@ -3461,6 +3465,7 @@ html/man3/X509_get0_distinguishing_id.ht
+ html/man3/X509_get0_notBefore.html \
+ html/man3/X509_get0_signature.html \
+ html/man3/X509_get0_uids.html \
++html/man3/X509_get_default_cert_file.html \
+ html/man3/X509_get_extension_flags.html \
+ html/man3/X509_get_pubkey.html \
+ html/man3/X509_get_serialNumber.html \
+@@ -4064,6 +4069,7 @@ man/man3/X509_get0_distinguishing_id.3 \
+ man/man3/X509_get0_notBefore.3 \
+ man/man3/X509_get0_signature.3 \
+ man/man3/X509_get0_uids.3 \
++man/man3/X509_get_default_cert_file.3 \
+ man/man3/X509_get_extension_flags.3 \
+ man/man3/X509_get_pubkey.3 \
+ man/man3/X509_get_serialNumber.3 \
+--- /dev/null
++++ b/doc/man3/X509_get_default_cert_file.pod
+@@ -0,0 +1,113 @@
++=pod
++
++=head1 NAME
++
++X509_get_default_cert_file, X509_get_default_cert_file_env,
++X509_get_default_cert_path_env,
++X509_get_default_cert_dir, X509_get_default_cert_dir_env,
++X509_get_default_cert_uri, X509_get_default_cert_uri_env -
++retrieve default locations for trusted CA certificates
++
++=head1 SYNOPSIS
++
++ #include <openssl/x509.h>
++
++ const char *X509_get_default_cert_file(void);
++ const char *X509_get_default_cert_dir(void);
++ const char *X509_get_default_cert_uri(void);
++
++ const char *X509_get_default_cert_file_env(void);
++ const char *X509_get_default_cert_path_env(void);
++ const char *X509_get_default_cert_dir_env(void);
++ const char *X509_get_default_cert_uri_env(void);
++
++=head1 DESCRIPTION
++
++The X509_get_default_cert_file() function returns the default path
++to a file containing trusted CA certificates. OpenSSL will use this as
++the default path when it is asked to load trusted CA certificates
++from a file and no other path is specified. If the file exists, CA certificates
++are loaded from the file.
++
++The X509_get_default_cert_dir() function returns a default delimeter-separated
++list of paths to a directories containing trusted CA certificates named in the
++hashed format. OpenSSL will use this as the default list of paths when it is
++asked to load trusted CA certificates from a directory and no other path is
++specified. If a given directory in the list exists, OpenSSL attempts to lookup
++CA certificates in this directory by calculating a filename based on a hash of
++the certificate's subject name.
++
++The X509_get_default_cert_uri() function returns the default URI for a
++certificate store accessed programmatically via an OpenSSL provider. If there is
++no default store applicable to the system for which OpenSSL was compiled, this
++returns an empty string.
++
++X509_get_default_cert_file_env() and X509_get_default_cert_uri_env() return
++environment variable names which are recommended to specify nondefault values to
++be used instead of the values returned by X509_get_default_cert_file() and
++X509_get_default_cert_uri() respectively. The values returned by the latter
++functions are not affected by these environment variables; you must check for
++these environment variables yourself, using these functions to retrieve the
++correct environment variable names. If an environment variable is not set, the
++value returned by the corresponding function above should be used.
++
++X509_get_default_cert_path_env() returns the environment variable name which is
++recommended to specify a nondefault value to be used instead of the value
++returned by X509_get_default_cert_dir(). This environment variable supercedes
++the deprecated environment variable whose name is returned by
++X509_get_default_cert_dir_env(). This environment variable was deprecated as its
++contents can be interpreted ambiguously; see NOTES.
++
++By default, OpenSSL uses the path list specified in the environment variable
++whose name is returned by X509_get_default_cert_path_env() if it is set;
++otherwise, it uses the path list specified in the environment variable whose
++name is returned by X509_get_default_cert_dir_env() if it is set; otherwise, it
++uses the value returned by X509_get_default_cert_dir()).
++
++=head1 NOTES
++
++X509_get_default_cert_uri(), X509_get_default_cert_uri_env() and
++X509_get_default_cert_path_env() were introduced in OpenSSL 3.1. Prior to this
++release, store URIs were expressed via the environment variable returned by
++X509_get_default_cert_dir_env(); this environment variable could be used to
++specify either a list of directories or a store URI. This creates an ambiguity
++in which the environment variable returned by X509_get_default_cert_dir_env() is
++interpreted both as a list of directories and as a store URI.
++
++This usage and the environment variable returned by
++X509_get_default_cert_dir_env() are now deprecated; to specify a store URI, use
++the environment variable returned by X509_get_default_cert_uri_env(), and to
++specify a list of directories, use the environment variable returned by
++X509_get_default_cert_path_env().
++
++=head1 RETURN VALUES
++
++These functions return pointers to constant strings with static storage
++duration.
++
++=head1 SEE ALSO
++
++L<X509_LOOKUP(3)>,
++L<SSL_CTX_set_default_verify_file(3)>,
++L<SSL_CTX_set_default_verify_dir(3)>,
++L<SSL_CTX_set_default_verify_store(3)>,
++L<SSL_CTX_load_verify_file(3)>,
++L<SSL_CTX_load_verify_dir(3)>,
++L<SSL_CTX_load_verify_store(3)>,
++L<SSL_CTX_load_verify_locations(3)>
++
++=head1 HISTORY
++
++X509_get_default_cert_uri(), X509_get_default_cert_path_env() and
++X509_get_default_cert_uri_env() were introduced in OpenSSL 3.1.
++
++=head1 COPYRIGHT
++
++Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
++
++Licensed under the Apache License 2.0 (the "License").  You may not use
++this file except in compliance with the License.  You can obtain a copy
++in the file LICENSE in the source distribution or at
++L<https://www.openssl.org/source/license.html>.
++
++=cut
+--- a/include/internal/cryptlib.h
++++ b/include/internal/cryptlib.h
+@@ -13,6 +13,8 @@
+ 
+ # include <stdlib.h>
+ # include <string.h>
++# include "openssl/configuration.h"
++# include "internal/e_os.h" /* ossl_inline in many files */
+ 
+ # ifdef OPENSSL_USE_APPLINK
+ #  define BIO_FLAGS_UPLINK_INTERNAL 0x8000
+@@ -77,6 +79,14 @@ DEFINE_LHASH_OF_EX(MEM);
+ #  define CTLOG_FILE              "OSSL$DATAROOT:[000000]ct_log_list.cnf"
+ # endif
+ 
++#ifndef OPENSSL_NO_WINSTORE
++# define X509_CERT_URI            "org.openssl.winstore://"
++#else
++# define X509_CERT_URI            ""
++#endif
++
++# define X509_CERT_URI_EVP        "SSL_CERT_URI"
++# define X509_CERT_PATH_EVP       "SSL_CERT_PATH"
+ # define X509_CERT_DIR_EVP        "SSL_CERT_DIR"
+ # define X509_CERT_FILE_EVP       "SSL_CERT_FILE"
+ # define CTLOG_FILE_EVP           "CTLOG_FILE"
+@@ -240,5 +250,4 @@ static ossl_inline int ossl_is_absolute_
+ # endif
+     return path[0] == '/';
+ }
+-
+ #endif
+--- a/include/internal/e_os.h
++++ b/include/internal/e_os.h
+@@ -249,7 +249,7 @@ FILE *__iob_func();
+ /***********************************************/
+ 
+ # if defined(OPENSSL_SYS_WINDOWS)
+-#  if (_MSC_VER >= 1310) && !defined(_WIN32_WCE)
++#  if defined(_MSC_VER) && (_MSC_VER >= 1310) && !defined(_WIN32_WCE)
+ #   define open _open
+ #   define fdopen _fdopen
+ #   define close _close
+--- a/include/openssl/x509.h.in
++++ b/include/openssl/x509.h.in
+@@ -491,8 +491,11 @@ ASN1_TIME *X509_time_adj_ex(ASN1_TIME *s
+ ASN1_TIME *X509_gmtime_adj(ASN1_TIME *s, long adj);
+ 
+ const char *X509_get_default_cert_area(void);
++const char *X509_get_default_cert_uri(void);
+ const char *X509_get_default_cert_dir(void);
+ const char *X509_get_default_cert_file(void);
++const char *X509_get_default_cert_uri_env(void);
++const char *X509_get_default_cert_path_env(void);
+ const char *X509_get_default_cert_dir_env(void);
+ const char *X509_get_default_cert_file_env(void);
+ const char *X509_get_default_private_dir(void);
+--- a/providers/implementations/include/prov/implementations.h
++++ b/providers/implementations/include/prov/implementations.h
+@@ -517,3 +517,4 @@ extern const OSSL_DISPATCH ossl_SubjectP
+ extern const OSSL_DISPATCH ossl_pem_to_der_decoder_functions[];
+ 
+ extern const OSSL_DISPATCH ossl_file_store_functions[];
++extern const OSSL_DISPATCH ossl_winstore_store_functions[];
+--- a/providers/implementations/storemgmt/build.info
++++ b/providers/implementations/storemgmt/build.info
+@@ -4,3 +4,6 @@
+ $STORE_GOAL=../../libdefault.a
+ 
+ SOURCE[$STORE_GOAL]=file_store.c file_store_any2obj.c
++IF[{- !$disabled{winstore} -}]
++    SOURCE[$STORE_GOAL]=winstore_store.c
++ENDIF
+--- /dev/null
++++ b/providers/implementations/storemgmt/winstore_store.c
+@@ -0,0 +1,327 @@
++/*
++ * Copyright 2022 The OpenSSL Project Authors. All Rights Reserved.
++ *
++ * Licensed under the Apache License 2.0 (the "License").  You may not use
++ * this file except in compliance with the License.  You can obtain a copy
++ * in the file LICENSE in the source distribution or at
++ * https://www.openssl.org/source/license.html
++ */
++#include <openssl/store.h>
++#include <openssl/core_dispatch.h>
++#include <openssl/core_names.h>
++#include <openssl/core_object.h>
++#include <openssl/bio.h>
++#include <openssl/err.h>
++#include <openssl/params.h>
++#include <openssl/decoder.h>
++#include <openssl/proverr.h>
++#include <openssl/store.h>       /* The OSSL_STORE_INFO type numbers */
++#include "internal/cryptlib.h"
++#include "internal/o_dir.h"
++#include "crypto/decoder.h"
++#include "crypto/ctype.h"        /* ossl_isdigit() */
++#include "prov/implementations.h"
++#include "prov/bio.h"
++#include "file_store_local.h"
++
++#include <wincrypt.h>
++
++enum {
++    STATE_IDLE,
++    STATE_READ,
++    STATE_EOF,
++};
++
++struct winstore_ctx_st {
++    void                   *provctx;
++    char                   *propq;
++    unsigned char          *subject;
++    size_t                  subject_len;
++
++    HCERTSTORE              win_store;
++    const CERT_CONTEXT     *win_ctx;
++    int                     state;
++
++    OSSL_DECODER_CTX       *dctx;
++};
++
++static void winstore_win_reset(struct winstore_ctx_st *ctx)
++{
++    if (ctx->win_ctx != NULL) {
++        CertFreeCertificateContext(ctx->win_ctx);
++        ctx->win_ctx = NULL;
++    }
++
++    ctx->state = STATE_IDLE;
++}
++
++static void winstore_win_advance(struct winstore_ctx_st *ctx)
++{
++    CERT_NAME_BLOB name = {0};
++
++    if (ctx->state == STATE_EOF)
++        return;
++
++    name.cbData = ctx->subject_len;
++    name.pbData = ctx->subject;
++
++    ctx->win_ctx = (name.cbData == 0 ? NULL :
++        CertFindCertificateInStore(ctx->win_store,
++                                   X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
++                                   0, CERT_FIND_SUBJECT_NAME,
++                                   &name, ctx->win_ctx));
++
++    ctx->state = (ctx->win_ctx == NULL) ? STATE_EOF : STATE_READ;
++}
++
++static void *winstore_open(void *provctx, const char *uri)
++{
++    struct winstore_ctx_st *ctx = NULL;
++
++    if (!HAS_CASE_PREFIX(uri, "org.openssl.winstore:"))
++        return NULL;
++
++    ctx = OPENSSL_zalloc(sizeof(*ctx));
++    if (ctx == NULL)
++        return NULL;
++
++    ctx->provctx    = provctx;
++    ctx->win_store  = CertOpenSystemStoreW(0, L"ROOT");
++    if (ctx->win_store == NULL) {
++        OPENSSL_free(ctx);
++        return NULL;
++    }
++
++    winstore_win_reset(ctx);
++    return ctx;
++}
++
++static void *winstore_attach(void *provctx, OSSL_CORE_BIO *cin)
++{
++    return NULL; /* not supported */
++}
++
++static const OSSL_PARAM *winstore_settable_ctx_params(void *loaderctx, const OSSL_PARAM params[])
++{
++    static const OSSL_PARAM known_settable_ctx_params[] = {
++        OSSL_PARAM_octet_string(OSSL_STORE_PARAM_SUBJECT, NULL, 0),
++        OSSL_PARAM_utf8_string(OSSL_STORE_PARAM_PROPERTIES, NULL, 0),
++        OSSL_PARAM_END
++    };
++    return known_settable_ctx_params;
++}
++
++static int winstore_set_ctx_params(void *loaderctx, const OSSL_PARAM params[])
++{
++    struct winstore_ctx_st *ctx = loaderctx;
++    const OSSL_PARAM *p;
++    int do_reset = 0;
++
++    if (params == NULL)
++        return 1;
++
++    p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_PROPERTIES);
++    if (p != NULL) {
++        do_reset = 1;
++        OPENSSL_free(ctx->propq);
++        ctx->propq = NULL;
++        if (!OSSL_PARAM_get_utf8_string(p, &ctx->propq, 0))
++            return 0;
++    }
++
++    p = OSSL_PARAM_locate_const(params, OSSL_STORE_PARAM_SUBJECT);
++    if (p != NULL) {
++        const unsigned char *der = NULL;
++        size_t der_len = 0;
++
++        if (!OSSL_PARAM_get_octet_string_ptr(p, (const void **)&der, &der_len))
++            return 0;
++
++        do_reset = 1;
++
++        OPENSSL_free(ctx->subject);
++
++        ctx->subject = OPENSSL_malloc(der_len);
++        if (ctx->subject == NULL) {
++            ctx->subject_len = 0;
++            return 0;
++        }
++
++        ctx->subject_len = der_len;
++        memcpy(ctx->subject, der, der_len);
++    }
++
++    if (do_reset) {
++        winstore_win_reset(ctx);
++        winstore_win_advance(ctx);
++    }
++
++    return 1;
++}
++
++struct load_data_st {
++    OSSL_CALLBACK  *object_cb;
++    void           *object_cbarg;
++};
++
++static int load_construct(OSSL_DECODER_INSTANCE *decoder_inst,
++                           const OSSL_PARAM *params, void *construct_data)
++{
++    struct load_data_st *data = construct_data;
++    return data->object_cb(params, data->object_cbarg);
++}
++
++static void load_cleanup(void *construct_data)
++{
++    /* No-op. */
++}
++
++static int setup_decoder(struct winstore_ctx_st *ctx)
++{
++    OSSL_LIB_CTX *libctx = ossl_prov_ctx_get0_libctx(ctx->provctx);
++    const OSSL_ALGORITHM *to_algo = NULL;
++
++    if (ctx->dctx != NULL)
++        return 1;
++
++    ctx->dctx = OSSL_DECODER_CTX_new();
++    if (ctx->dctx == NULL) {
++        ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
++        return 0;
++    }
++
++    if (!OSSL_DECODER_CTX_set_input_type(ctx->dctx, "DER")) {
++        ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
++        goto err;
++    }
++
++    if (!OSSL_DECODER_CTX_set_input_structure(ctx->dctx, "Certificate")) {
++        ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
++        goto err;
++    }
++
++    for (to_algo = ossl_any_to_obj_algorithm;
++         to_algo->algorithm_names != NULL;
++         to_algo++) {
++        OSSL_DECODER *to_obj = NULL;
++        OSSL_DECODER_INSTANCE *to_obj_inst = NULL;
++
++        /*
++         * Create the internal last resort decoder implementation
++         * together with a "decoder instance".
++         * The decoder doesn't need any identification or to be
++         * attached to any provider, since it's only used locally.
++         */
++        to_obj = ossl_decoder_from_algorithm(0, to_algo, NULL);
++        if (to_obj != NULL)
++            to_obj_inst = ossl_decoder_instance_new(to_obj, ctx->provctx);
++
++        OSSL_DECODER_free(to_obj);
++        if (to_obj_inst == NULL)
++            goto err;
++
++        if (!ossl_decoder_ctx_add_decoder_inst(ctx->dctx,
++                                               to_obj_inst)) {
++            ossl_decoder_instance_free(to_obj_inst);
++            ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
++            goto err;
++        }
++    }
++
++    if (!OSSL_DECODER_CTX_add_extra(ctx->dctx, libctx, ctx->propq)) {
++        ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
++        goto err;
++    }
++
++    if (!OSSL_DECODER_CTX_set_construct(ctx->dctx, load_construct)) {
++        ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
++        goto err;
++    }
++
++    if (!OSSL_DECODER_CTX_set_cleanup(ctx->dctx, load_cleanup)) {
++        ERR_raise(ERR_LIB_PROV, ERR_R_OSSL_DECODER_LIB);
++        goto err;
++    }
++
++    return 1;
++
++err:
++    OSSL_DECODER_CTX_free(ctx->dctx);
++    ctx->dctx = NULL;
++    return 0;
++}
++
++static int winstore_load_using(struct winstore_ctx_st *ctx,
++                               OSSL_CALLBACK *object_cb, void *object_cbarg,
++                               OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg,
++                               const void *der, size_t der_len)
++{
++    struct load_data_st data;
++    const unsigned char *der_ = der;
++    size_t der_len_ = der_len;
++
++    if (setup_decoder(ctx) == 0)
++        return 0;
++
++    data.object_cb      = object_cb;
++    data.object_cbarg   = object_cbarg;
++
++    OSSL_DECODER_CTX_set_construct_data(ctx->dctx, &data);
++    OSSL_DECODER_CTX_set_passphrase_cb(ctx->dctx, pw_cb, pw_cbarg);
++
++    if (OSSL_DECODER_from_data(ctx->dctx, &der_, &der_len_) == 0)
++        return 0;
++
++    return 1;
++}
++
++static int winstore_load(void *loaderctx,
++                         OSSL_CALLBACK *object_cb, void *object_cbarg,
++                         OSSL_PASSPHRASE_CALLBACK *pw_cb, void *pw_cbarg)
++{
++    int ret = 0;
++    struct winstore_ctx_st *ctx = loaderctx;
++
++    if (ctx->state != STATE_READ)
++        return 0;
++
++    ret = winstore_load_using(ctx, object_cb, object_cbarg, pw_cb, pw_cbarg,
++                              ctx->win_ctx->pbCertEncoded,
++                              ctx->win_ctx->cbCertEncoded);
++
++    if (ret == 1)
++        winstore_win_advance(ctx);
++
++    return ret;
++}
++
++static int winstore_eof(void *loaderctx)
++{
++    struct winstore_ctx_st *ctx = loaderctx;
++
++    return ctx->state != STATE_READ;
++}
++
++static int winstore_close(void *loaderctx)
++{
++    struct winstore_ctx_st *ctx = loaderctx;
++
++    winstore_win_reset(ctx);
++    CertCloseStore(ctx->win_store, 0);
++    OSSL_DECODER_CTX_free(ctx->dctx);
++    OPENSSL_free(ctx->propq);
++    OPENSSL_free(ctx->subject);
++    OPENSSL_free(ctx);
++    return 1;
++}
++
++const OSSL_DISPATCH ossl_winstore_store_functions[] = {
++    { OSSL_FUNC_STORE_OPEN, (void (*)(void))winstore_open },
++    { OSSL_FUNC_STORE_ATTACH, (void (*)(void))winstore_attach },
++    { OSSL_FUNC_STORE_SETTABLE_CTX_PARAMS, (void (*)(void))winstore_settable_ctx_params },
++    { OSSL_FUNC_STORE_SET_CTX_PARAMS, (void (*)(void))winstore_set_ctx_params },
++    { OSSL_FUNC_STORE_LOAD, (void (*)(void))winstore_load },
++    { OSSL_FUNC_STORE_EOF, (void (*)(void))winstore_eof },
++    { OSSL_FUNC_STORE_CLOSE, (void (*)(void))winstore_close },
++    { 0, NULL },
++};
+--- a/providers/stores.inc
++++ b/providers/stores.inc
+@@ -12,3 +12,6 @@
+ #endif
+ 
+ STORE("file", "yes", ossl_file_store_functions)
++#ifndef OPENSSL_NO_WINSTORE
++STORE("org.openssl.winstore", "yes", ossl_winstore_store_functions)
++#endif
+--- a/util/libcrypto.num
++++ b/util/libcrypto.num
+@@ -5435,4 +5435,7 @@ EVP_MD_CTX_dup
+ EVP_CIPHER_CTX_dup                      5563	3_1_0	EXIST::FUNCTION:
+ BN_are_coprime                          5564	3_1_0	EXIST::FUNCTION:
+ OSSL_CMP_MSG_update_recipNonce          5565	3_0_9	EXIST::FUNCTION:CMP
++X509_get_default_cert_uri               ?	3_1_0	EXIST::FUNCTION:
++X509_get_default_cert_uri_env           ?	3_1_0	EXIST::FUNCTION:
++X509_get_default_cert_path_env          ?	3_1_0	EXIST::FUNCTION:
+ ossl_safe_getenv                        ?	3_0_0	EXIST::FUNCTION:
+--- a/util/missingcrypto.txt
++++ b/util/missingcrypto.txt
+@@ -1273,10 +1273,6 @@ X509_get0_trust_objects(3)
+ X509_get1_email(3)
+ X509_get1_ocsp(3)
+ X509_get_default_cert_area(3)
+-X509_get_default_cert_dir(3)
+-X509_get_default_cert_dir_env(3)
+-X509_get_default_cert_file(3)
+-X509_get_default_cert_file_env(3)
+ X509_get_default_private_dir(3)
+ X509_get_pubkey_parameters(3)
+ X509_get_signature_type(3)
diff --git a/openssl-CVE-2023-5678.patch b/openssl-CVE-2023-5678.patch
new file mode 100644
index 0000000..f4cd8eb
--- /dev/null
+++ b/openssl-CVE-2023-5678.patch
@@ -0,0 +1,172 @@
+From ddeb4b6c6d527e54ce9a99cba785c0f7776e54b6 Mon Sep 17 00:00:00 2001
+From: Richard Levitte <levitte@openssl.org>
+Date: Fri, 20 Oct 2023 09:18:19 +0200
+Subject: [PATCH] Make DH_check_pub_key() and DH_generate_key() safer yet
+
+We already check for an excessively large P in DH_generate_key(), but not in
+DH_check_pub_key(), and none of them check for an excessively large Q.
+
+This change adds all the missing excessive size checks of P and Q.
+
+It's to be noted that behaviours surrounding excessively sized P and Q
+differ.  DH_check() raises an error on the excessively sized P, but only
+sets a flag for the excessively sized Q.  This behaviour is mimicked in
+DH_check_pub_key().
+
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+Reviewed-by: Matt Caswell <matt@openssl.org>
+Reviewed-by: Hugo Landau <hlandau@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/22518)
+---
+ crypto/dh/dh_check.c    | 12 ++++++++++++
+ crypto/dh/dh_err.c      |  3 ++-
+ crypto/dh/dh_key.c      | 12 ++++++++++++
+ crypto/err/openssl.txt  |  1 +
+ include/crypto/dherr.h  |  2 +-
+ include/openssl/dh.h    |  6 +++---
+ include/openssl/dherr.h |  3 ++-
+ 7 files changed, 33 insertions(+), 6 deletions(-)
+
+diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
+index 7ba2beae7fd6b..e20eb62081c5e 100644
+--- a/crypto/dh/dh_check.c
++++ b/crypto/dh/dh_check.c
+@@ -249,6 +249,18 @@ int DH_check_pub_key_ex(const DH *dh, const BIGNUM *pub_key)
+  */
+ int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *ret)
+ {
++    /* Don't do any checks at all with an excessively large modulus */
++    if (BN_num_bits(dh->params.p) > OPENSSL_DH_CHECK_MAX_MODULUS_BITS) {
++        ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
++        *ret = DH_MODULUS_TOO_LARGE | DH_CHECK_PUBKEY_INVALID;
++        return 0;
++    }
++
++    if (dh->params.q != NULL && BN_ucmp(dh->params.p, dh->params.q) < 0) {
++        *ret |= DH_CHECK_INVALID_Q_VALUE | DH_CHECK_PUBKEY_INVALID;
++        return 1;
++    }
++
+     return ossl_ffc_validate_public_key(&dh->params, pub_key, ret);
+ }
+ 
+diff --git a/crypto/dh/dh_err.c b/crypto/dh/dh_err.c
+index 4152397426cc9..f76ac0dd1463f 100644
+--- a/crypto/dh/dh_err.c
++++ b/crypto/dh/dh_err.c
+@@ -1,6 +1,6 @@
+ /*
+  * Generated by util/mkerr.pl DO NOT EDIT
+- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
++ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+  *
+  * Licensed under the Apache License 2.0 (the "License").  You may not use
+  * this file except in compliance with the License.  You can obtain a copy
+@@ -54,6 +54,7 @@ static const ERR_STRING_DATA DH_str_reasons[] = {
+     {ERR_PACK(ERR_LIB_DH, 0, DH_R_PARAMETER_ENCODING_ERROR),
+     "parameter encoding error"},
+     {ERR_PACK(ERR_LIB_DH, 0, DH_R_PEER_KEY_ERROR), "peer key error"},
++    {ERR_PACK(ERR_LIB_DH, 0, DH_R_Q_TOO_LARGE), "q too large"},
+     {ERR_PACK(ERR_LIB_DH, 0, DH_R_SHARED_INFO_ERROR), "shared info error"},
+     {ERR_PACK(ERR_LIB_DH, 0, DH_R_UNABLE_TO_CHECK_GENERATOR),
+     "unable to check generator"},
+diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
+index d84ea99241b9e..afc49f5cdc87d 100644
+--- a/crypto/dh/dh_key.c
++++ b/crypto/dh/dh_key.c
+@@ -49,6 +49,12 @@ int ossl_dh_compute_key(unsigned char *key, const BIGNUM *pub_key, DH *dh)
+         goto err;
+     }
+ 
++    if (dh->params.q != NULL
++        && BN_num_bits(dh->params.q) > OPENSSL_DH_MAX_MODULUS_BITS) {
++        ERR_raise(ERR_LIB_DH, DH_R_Q_TOO_LARGE);
++        goto err;
++    }
++
+     if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) {
+         ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL);
+         return 0;
+@@ -267,6 +273,12 @@ static int generate_key(DH *dh)
+         return 0;
+     }
+ 
++    if (dh->params.q != NULL
++        && BN_num_bits(dh->params.q) > OPENSSL_DH_MAX_MODULUS_BITS) {
++        ERR_raise(ERR_LIB_DH, DH_R_Q_TOO_LARGE);
++        return 0;
++    }
++
+     if (BN_num_bits(dh->params.p) < DH_MIN_MODULUS_BITS) {
+         ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_SMALL);
+         return 0;
+diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
+index a1e6bbb617fcb..69e4f61aa1801 100644
+--- a/crypto/err/openssl.txt
++++ b/crypto/err/openssl.txt
+@@ -513,6 +513,7 @@ DH_R_NO_PARAMETERS_SET:107:no parameters set
+ DH_R_NO_PRIVATE_VALUE:100:no private value
+ DH_R_PARAMETER_ENCODING_ERROR:105:parameter encoding error
+ DH_R_PEER_KEY_ERROR:111:peer key error
++DH_R_Q_TOO_LARGE:130:q too large
+ DH_R_SHARED_INFO_ERROR:113:shared info error
+ DH_R_UNABLE_TO_CHECK_GENERATOR:121:unable to check generator
+ DSA_R_BAD_FFC_PARAMETERS:114:bad ffc parameters
+diff --git a/include/crypto/dherr.h b/include/crypto/dherr.h
+index bb24d131eb887..519327f795742 100644
+--- a/include/crypto/dherr.h
++++ b/include/crypto/dherr.h
+@@ -1,6 +1,6 @@
+ /*
+  * Generated by util/mkerr.pl DO NOT EDIT
+- * Copyright 2020-2021 The OpenSSL Project Authors. All Rights Reserved.
++ * Copyright 2020-2023 The OpenSSL Project Authors. All Rights Reserved.
+  *
+  * Licensed under the Apache License 2.0 (the "License").  You may not use
+  * this file except in compliance with the License.  You can obtain a copy
+diff --git a/include/openssl/dh.h b/include/openssl/dh.h
+index 8bc17448a0817..f1c0ed06b375a 100644
+--- a/include/openssl/dh.h
++++ b/include/openssl/dh.h
+@@ -144,7 +144,7 @@ DECLARE_ASN1_ITEM(DHparams)
+ #   define DH_GENERATOR_3          3
+ #   define DH_GENERATOR_5          5
+ 
+-/* DH_check error codes */
++/* DH_check error codes, some of them shared with DH_check_pub_key */
+ /*
+  * NB: These values must align with the equivalently named macros in
+  * internal/ffc.h.
+@@ -154,10 +154,10 @@ DECLARE_ASN1_ITEM(DHparams)
+ #   define DH_UNABLE_TO_CHECK_GENERATOR    0x04
+ #   define DH_NOT_SUITABLE_GENERATOR       0x08
+ #   define DH_CHECK_Q_NOT_PRIME            0x10
+-#   define DH_CHECK_INVALID_Q_VALUE        0x20
++#   define DH_CHECK_INVALID_Q_VALUE        0x20 /* +DH_check_pub_key */
+ #   define DH_CHECK_INVALID_J_VALUE        0x40
+ #   define DH_MODULUS_TOO_SMALL            0x80
+-#   define DH_MODULUS_TOO_LARGE            0x100
++#   define DH_MODULUS_TOO_LARGE            0x100 /* +DH_check_pub_key */
+ 
+ /* DH_check_pub_key error codes */
+ #   define DH_CHECK_PUBKEY_TOO_SMALL       0x01
+diff --git a/include/openssl/dherr.h b/include/openssl/dherr.h
+index 5d2a762a96f8c..074a70145f9f5 100644
+--- a/include/openssl/dherr.h
++++ b/include/openssl/dherr.h
+@@ -1,6 +1,6 @@
+ /*
+  * Generated by util/mkerr.pl DO NOT EDIT
+- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
++ * Copyright 1995-2023 The OpenSSL Project Authors. All Rights Reserved.
+  *
+  * Licensed under the Apache License 2.0 (the "License").  You may not use
+  * this file except in compliance with the License.  You can obtain a copy
+@@ -50,6 +50,7 @@
+ #  define DH_R_NO_PRIVATE_VALUE                            100
+ #  define DH_R_PARAMETER_ENCODING_ERROR                    105
+ #  define DH_R_PEER_KEY_ERROR                              111
++#  define DH_R_Q_TOO_LARGE                                 130
+ #  define DH_R_SHARED_INFO_ERROR                           113
+ #  define DH_R_UNABLE_TO_CHECK_GENERATOR                   121
+ 
diff --git a/openssl-CVE-2023-6129.patch b/openssl-CVE-2023-6129.patch
new file mode 100644
index 0000000..84cdec0
--- /dev/null
+++ b/openssl-CVE-2023-6129.patch
@@ -0,0 +1,109 @@
+From 050d26383d4e264966fb83428e72d5d48f402d35 Mon Sep 17 00:00:00 2001
+From: Rohan McLure <rmclure@linux.ibm.com>
+Date: Thu, 4 Jan 2024 10:25:50 +0100
+Subject: [PATCH] poly1305-ppc.pl: Fix vector register clobbering
+
+Fixes CVE-2023-6129
+
+The POLY1305 MAC (message authentication code) implementation in OpenSSL for
+PowerPC CPUs saves the the contents of vector registers in different order
+than they are restored. Thus the contents of some of these vector registers
+is corrupted when returning to the caller. The vulnerable code is used only
+on newer PowerPC processors supporting the PowerISA 2.07 instructions.
+
+Reviewed-by: Matt Caswell <matt@openssl.org>
+Reviewed-by: Richard Levitte <levitte@openssl.org>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/23200)
+
+(cherry picked from commit 8d847a3ffd4f0b17ee33962cf69c36224925b34f)
+---
+ crypto/poly1305/asm/poly1305-ppc.pl | 42 ++++++++++++++---------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/crypto/poly1305/asm/poly1305-ppc.pl b/crypto/poly1305/asm/poly1305-ppc.pl
+index 9f86134d923fb..2e601bb9c24be 100755
+--- a/crypto/poly1305/asm/poly1305-ppc.pl
++++ b/crypto/poly1305/asm/poly1305-ppc.pl
+@@ -744,7 +744,7 @@
+ my $LOCALS= 6*$SIZE_T;
+ my $VSXFRAME = $LOCALS + 6*$SIZE_T;
+    $VSXFRAME += 128;	# local variables
+-   $VSXFRAME += 13*16;	# v20-v31 offload
++   $VSXFRAME += 12*16;	# v20-v31 offload
+ 
+ my $BIG_ENDIAN = ($flavour !~ /le/) ? 4 : 0;
+ 
+@@ -919,12 +919,12 @@
+ 	addi	r11,r11,32
+ 	stvx	v22,r10,$sp
+ 	addi	r10,r10,32
+-	stvx	v23,r10,$sp
+-	addi	r10,r10,32
+-	stvx	v24,r11,$sp
++	stvx	v23,r11,$sp
+ 	addi	r11,r11,32
+-	stvx	v25,r10,$sp
++	stvx	v24,r10,$sp
+ 	addi	r10,r10,32
++	stvx	v25,r11,$sp
++	addi	r11,r11,32
+ 	stvx	v26,r10,$sp
+ 	addi	r10,r10,32
+ 	stvx	v27,r11,$sp
+@@ -1153,12 +1153,12 @@
+ 	addi	r11,r11,32
+ 	stvx	v22,r10,$sp
+ 	addi	r10,r10,32
+-	stvx	v23,r10,$sp
+-	addi	r10,r10,32
+-	stvx	v24,r11,$sp
++	stvx	v23,r11,$sp
+ 	addi	r11,r11,32
+-	stvx	v25,r10,$sp
++	stvx	v24,r10,$sp
+ 	addi	r10,r10,32
++	stvx	v25,r11,$sp
++	addi	r11,r11,32
+ 	stvx	v26,r10,$sp
+ 	addi	r10,r10,32
+ 	stvx	v27,r11,$sp
+@@ -1899,26 +1899,26 @@
+ 	mtspr	256,r12				# restore vrsave
+ 	lvx	v20,r10,$sp
+ 	addi	r10,r10,32
+-	lvx	v21,r10,$sp
+-	addi	r10,r10,32
+-	lvx	v22,r11,$sp
++	lvx	v21,r11,$sp
+ 	addi	r11,r11,32
+-	lvx	v23,r10,$sp
++	lvx	v22,r10,$sp
+ 	addi	r10,r10,32
+-	lvx	v24,r11,$sp
++	lvx	v23,r11,$sp
+ 	addi	r11,r11,32
+-	lvx	v25,r10,$sp
++	lvx	v24,r10,$sp
+ 	addi	r10,r10,32
+-	lvx	v26,r11,$sp
++	lvx	v25,r11,$sp
+ 	addi	r11,r11,32
+-	lvx	v27,r10,$sp
++	lvx	v26,r10,$sp
+ 	addi	r10,r10,32
+-	lvx	v28,r11,$sp
++	lvx	v27,r11,$sp
+ 	addi	r11,r11,32
+-	lvx	v29,r10,$sp
++	lvx	v28,r10,$sp
+ 	addi	r10,r10,32
+-	lvx	v30,r11,$sp
+-	lvx	v31,r10,$sp
++	lvx	v29,r11,$sp
++	addi	r11,r11,32
++	lvx	v30,r10,$sp
++	lvx	v31,r11,$sp
+ 	$POP	r27,`$VSXFRAME-$SIZE_T*5`($sp)
+ 	$POP	r28,`$VSXFRAME-$SIZE_T*4`($sp)
+ 	$POP	r29,`$VSXFRAME-$SIZE_T*3`($sp)
diff --git a/openssl-CVE-2023-6237.patch b/openssl-CVE-2023-6237.patch
new file mode 100644
index 0000000..17459be
--- /dev/null
+++ b/openssl-CVE-2023-6237.patch
@@ -0,0 +1,122 @@
+From 18c02492138d1eb8b6548cb26e7b625fb2414a2a Mon Sep 17 00:00:00 2001
+From: Tomas Mraz <tomas@openssl.org>
+Date: Fri, 22 Dec 2023 16:25:56 +0100
+Subject: [PATCH] Limit the execution time of RSA public key check
+
+Fixes CVE-2023-6237
+
+If a large and incorrect RSA public key is checked with
+EVP_PKEY_public_check() the computation could take very long time
+due to no limit being applied to the RSA public key size and
+unnecessarily high number of Miller-Rabin algorithm rounds
+used for non-primality check of the modulus.
+
+Now the keys larger than 16384 bits (OPENSSL_RSA_MAX_MODULUS_BITS)
+will fail the check with RSA_R_MODULUS_TOO_LARGE error reason.
+Also the number of Miller-Rabin rounds was set to 5.
+
+Reviewed-by: Neil Horman <nhorman@openssl.org>
+Reviewed-by: Matt Caswell <matt@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/23243)
+
+(cherry picked from commit e09fc1d746a4fd15bb5c3d7bbbab950aadd005db)
+---
+ crypto/rsa/rsa_sp800_56b_check.c              |  8 +++-
+ test/recipes/91-test_pkey_check.t             |  2 +-
+ .../91-test_pkey_check_data/rsapub_17k.pem    | 48 +++++++++++++++++++
+ 3 files changed, 56 insertions(+), 2 deletions(-)
+ create mode 100644 test/recipes/91-test_pkey_check_data/rsapub_17k.pem
+
+diff --git a/crypto/rsa/rsa_sp800_56b_check.c b/crypto/rsa/rsa_sp800_56b_check.c
+index fc8f19b48770b..bcbdd24fb8199 100644
+--- a/crypto/rsa/rsa_sp800_56b_check.c
++++ b/crypto/rsa/rsa_sp800_56b_check.c
+@@ -289,6 +289,11 @@ int ossl_rsa_sp800_56b_check_public(const RSA *rsa)
+         return 0;
+ 
+     nbits = BN_num_bits(rsa->n);
++    if (nbits > OPENSSL_RSA_MAX_MODULUS_BITS) {
++        ERR_raise(ERR_LIB_RSA, RSA_R_MODULUS_TOO_LARGE);
++        return 0;
++    }
++
+ #ifdef FIPS_MODULE
+     /*
+      * (Step a): modulus must be 2048 or 3072 (caveat from SP800-56Br1)
+@@ -324,7 +329,8 @@ int ossl_rsa_sp800_56b_check_public(const RSA *rsa)
+         goto err;
+     }
+ 
+-    ret = ossl_bn_miller_rabin_is_prime(rsa->n, 0, ctx, NULL, 1, &status);
++    /* Highest number of MR rounds from FIPS 186-5 Section B.3 Table B.1 */
++    ret = ossl_bn_miller_rabin_is_prime(rsa->n, 5, ctx, NULL, 1, &status);
+ #ifdef FIPS_MODULE
+     if (ret != 1 || status != BN_PRIMETEST_COMPOSITE_NOT_POWER_OF_PRIME) {
+ #else
+diff --git a/test/recipes/91-test_pkey_check.t b/test/recipes/91-test_pkey_check.t
+index dc7cc64533af2..f8088df14d36c 100644
+--- a/test/recipes/91-test_pkey_check.t
++++ b/test/recipes/91-test_pkey_check.t
+@@ -70,7 +70,7 @@ push(@positive_tests, (
+     "dhpkey.pem"
+     )) unless disabled("dh");
+ 
+-my @negative_pubtests = ();
++my @negative_pubtests = ("rsapub_17k.pem");  # Too big RSA public key
+ 
+ push(@negative_pubtests, (
+     "dsapub_noparam.der"
+diff --git a/test/recipes/91-test_pkey_check_data/rsapub_17k.pem b/test/recipes/91-test_pkey_check_data/rsapub_17k.pem
+new file mode 100644
+index 0000000000000..9a2eaedaf1b22
+--- /dev/null
++++ b/test/recipes/91-test_pkey_check_data/rsapub_17k.pem
+@@ -0,0 +1,48 @@
++-----BEGIN PUBLIC KEY-----
++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
++AQAB
++-----END PUBLIC KEY-----
diff --git a/openssl-CVE-2024-0727.patch b/openssl-CVE-2024-0727.patch
new file mode 100644
index 0000000..6e1eb5b
--- /dev/null
+++ b/openssl-CVE-2024-0727.patch
@@ -0,0 +1,120 @@
+From 09df4395b5071217b76dc7d3d2e630eb8c5a79c2 Mon Sep 17 00:00:00 2001
+From: Matt Caswell <matt@openssl.org>
+Date: Fri, 19 Jan 2024 11:28:58 +0000
+Subject: [PATCH] Add NULL checks where ContentInfo data can be NULL
+
+PKCS12 structures contain PKCS7 ContentInfo fields. These fields are
+optional and can be NULL even if the "type" is a valid value. OpenSSL
+was not properly accounting for this and a NULL dereference can occur
+causing a crash.
+
+CVE-2024-0727
+
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+Reviewed-by: Hugo Landau <hlandau@openssl.org>
+Reviewed-by: Neil Horman <nhorman@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/23362)
+
+(cherry picked from commit d135eeab8a5dbf72b3da5240bab9ddb7678dbd2c)
+---
+ crypto/pkcs12/p12_add.c  | 18 ++++++++++++++++++
+ crypto/pkcs12/p12_mutl.c |  5 +++++
+ crypto/pkcs12/p12_npas.c |  5 +++--
+ crypto/pkcs7/pk7_mime.c  |  7 +++++--
+ 4 files changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c
+index 6fd4184af5a52..80ce31b3bca66 100644
+--- a/crypto/pkcs12/p12_add.c
++++ b/crypto/pkcs12/p12_add.c
+@@ -78,6 +78,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7data(PKCS7 *p7)
+         ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA);
+         return NULL;
+     }
++
++    if (p7->d.data == NULL) {
++        ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR);
++        return NULL;
++    }
++
+     return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
+ }
+ 
+@@ -150,6 +156,12 @@ STACK_OF(PKCS12_SAFEBAG) *PKCS12_unpack_p7encdata(PKCS7 *p7, const char *pass,
+ {
+     if (!PKCS7_type_is_encrypted(p7))
+         return NULL;
++
++    if (p7->d.encrypted == NULL) {
++        ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR);
++        return NULL;
++    }
++
+     return PKCS12_item_decrypt_d2i_ex(p7->d.encrypted->enc_data->algorithm,
+                                    ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
+                                    pass, passlen,
+@@ -188,6 +200,12 @@ STACK_OF(PKCS7) *PKCS12_unpack_authsafes(const PKCS12 *p12)
+         ERR_raise(ERR_LIB_PKCS12, PKCS12_R_CONTENT_TYPE_NOT_DATA);
+         return NULL;
+     }
++
++    if (p12->authsafes->d.data == NULL) {
++        ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR);
++        return NULL;
++    }
++
+     p7s = ASN1_item_unpack(p12->authsafes->d.data,
+                            ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
+     if (p7s != NULL) {
+diff --git a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c
+index 67a885a45f89e..68ff54d0e90ee 100644
+--- a/crypto/pkcs12/p12_mutl.c
++++ b/crypto/pkcs12/p12_mutl.c
+@@ -98,6 +98,11 @@ static int pkcs12_gen_mac(PKCS12 *p12, const char *pass, int passlen,
+         return 0;
+     }
+ 
++    if (p12->authsafes->d.data == NULL) {
++        ERR_raise(ERR_LIB_PKCS12, PKCS12_R_DECODE_ERROR);
++        return 0;
++    }
++
+     salt = p12->mac->salt->data;
+     saltlen = p12->mac->salt->length;
+     if (p12->mac->iter == NULL)
+diff --git a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c
+index 62230bc6187ff..1e5b5495991a4 100644
+--- a/crypto/pkcs12/p12_npas.c
++++ b/crypto/pkcs12/p12_npas.c
+@@ -77,8 +77,9 @@ static int newpass_p12(PKCS12 *p12, const char *oldpass, const char *newpass)
+             bags = PKCS12_unpack_p7data(p7);
+         } else if (bagnid == NID_pkcs7_encrypted) {
+             bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
+-            if (!alg_get(p7->d.encrypted->enc_data->algorithm,
+-                         &pbe_nid, &pbe_iter, &pbe_saltlen))
++            if (p7->d.encrypted == NULL
++                    || !alg_get(p7->d.encrypted->enc_data->algorithm,
++                                &pbe_nid, &pbe_iter, &pbe_saltlen))
+                 goto err;
+         } else {
+             continue;
+diff --git a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c
+index 49a0da5f819c4..8228315eeaa3a 100644
+--- a/crypto/pkcs7/pk7_mime.c
++++ b/crypto/pkcs7/pk7_mime.c
+@@ -33,10 +33,13 @@ int SMIME_write_PKCS7(BIO *bio, PKCS7 *p7, BIO *data, int flags)
+     int ctype_nid = OBJ_obj2nid(p7->type);
+     const PKCS7_CTX *ctx = ossl_pkcs7_get0_ctx(p7);
+ 
+-    if (ctype_nid == NID_pkcs7_signed)
++    if (ctype_nid == NID_pkcs7_signed) {
++        if (p7->d.sign == NULL)
++            return 0;
+         mdalgs = p7->d.sign->md_algs;
+-    else
++    } else {
+         mdalgs = NULL;
++    }
+ 
+     flags ^= SMIME_OLDMIME;
+ 
diff --git a/openssl-CVE-2024-2511.patch b/openssl-CVE-2024-2511.patch
new file mode 100644
index 0000000..0ffdd7f
--- /dev/null
+++ b/openssl-CVE-2024-2511.patch
@@ -0,0 +1,116 @@
+From 7e4d731b1c07201ad9374c1cd9ac5263bdf35bce Mon Sep 17 00:00:00 2001
+From: Matt Caswell <matt@openssl.org>
+Date: Tue, 5 Mar 2024 15:43:53 +0000
+Subject: [PATCH] Fix unconstrained session cache growth in TLSv1.3
+
+In TLSv1.3 we create a new session object for each ticket that we send.
+We do this by duplicating the original session. If SSL_OP_NO_TICKET is in
+use then the new session will be added to the session cache. However, if
+early data is not in use (and therefore anti-replay protection is being
+used), then multiple threads could be resuming from the same session
+simultaneously. If this happens and a problem occurs on one of the threads,
+then the original session object could be marked as not_resumable. When we
+duplicate the session object this not_resumable status gets copied into the
+new session object. The new session object is then added to the session
+cache even though it is not_resumable.
+
+Subsequently, another bug means that the session_id_length is set to 0 for
+sessions that are marked as not_resumable - even though that session is
+still in the cache. Once this happens the session can never be removed from
+the cache. When that object gets to be the session cache tail object the
+cache never shrinks again and grows indefinitely.
+
+CVE-2024-2511
+
+Reviewed-by: Neil Horman <nhorman@openssl.org>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/24044)
+---
+ ssl/ssl_lib.c            |  5 +++--
+ ssl/ssl_sess.c           | 28 ++++++++++++++++++++++------
+ ssl/statem/statem_srvr.c |  5 ++---
+ 3 files changed, 27 insertions(+), 11 deletions(-)
+
+diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
+index b5cc4af2f0302..e747b7f90aa71 100644
+--- a/ssl/ssl_lib.c
++++ b/ssl/ssl_lib.c
+@@ -3737,9 +3737,10 @@ void ssl_update_cache(SSL *s, int mode)
+ 
+     /*
+      * If the session_id_length is 0, we are not supposed to cache it, and it
+-     * would be rather hard to do anyway :-)
++     * would be rather hard to do anyway :-). Also if the session has already
++     * been marked as not_resumable we should not cache it for later reuse.
+      */
+-    if (s->session->session_id_length == 0)
++    if (s->session->session_id_length == 0 || s->session->not_resumable)
+         return;
+ 
+     /*
+diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c
+index bf84e792251b8..241cf43c46296 100644
+--- a/ssl/ssl_sess.c
++++ b/ssl/ssl_sess.c
+@@ -154,16 +154,11 @@ SSL_SESSION *SSL_SESSION_new(void)
+     return ss;
+ }
+ 
+-SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
+-{
+-    return ssl_session_dup(src, 1);
+-}
+-
+ /*
+  * Create a new SSL_SESSION and duplicate the contents of |src| into it. If
+  * ticket == 0 then no ticket information is duplicated, otherwise it is.
+  */
+-SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
++static SSL_SESSION *ssl_session_dup_intern(const SSL_SESSION *src, int ticket)
+ {
+     SSL_SESSION *dest;
+ 
+@@ -287,6 +282,27 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
+     return NULL;
+ }
+ 
++SSL_SESSION *SSL_SESSION_dup(const SSL_SESSION *src)
++{
++    return ssl_session_dup_intern(src, 1);
++}
++
++/*
++ * Used internally when duplicating a session which might be already shared.
++ * We will have resumed the original session. Subsequently we might have marked
++ * it as non-resumable (e.g. in another thread) - but this copy should be ok to
++ * resume from.
++ */
++SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket)
++{
++    SSL_SESSION *sess = ssl_session_dup_intern(src, ticket);
++
++    if (sess != NULL)
++        sess->not_resumable = 0;
++
++    return sess;
++}
++
+ const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *s, unsigned int *len)
+ {
+     if (len)
+diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
+index 5d59d53563ed8..8e493176f658e 100644
+--- a/ssl/statem/statem_srvr.c
++++ b/ssl/statem/statem_srvr.c
+@@ -2338,9 +2338,8 @@ int tls_construct_server_hello(SSL *s, WPACKET *pkt)
+      * so the following won't overwrite an ID that we're supposed
+      * to send back.
+      */
+-    if (s->session->not_resumable ||
+-        (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
+-         && !s->hit))
++    if (!(s->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)
++            && !s->hit)
+         s->session->session_id_length = 0;
+ 
+     if (usetls13) {
diff --git a/openssl-CVE-2024-4603.patch b/openssl-CVE-2024-4603.patch
new file mode 100644
index 0000000..23fa5d3
--- /dev/null
+++ b/openssl-CVE-2024-4603.patch
@@ -0,0 +1,199 @@
+From 9c39b3858091c152f52513c066ff2c5a47969f0d Mon Sep 17 00:00:00 2001
+From: Tomas Mraz <tomas@openssl.org>
+Date: Wed, 8 May 2024 15:23:45 +0200
+Subject: [PATCH] Check DSA parameters for excessive sizes before validating
+
+This avoids overly long computation of various validation
+checks.
+
+Fixes CVE-2024-4603
+
+Reviewed-by: Paul Dale <ppzgs1@gmail.com>
+Reviewed-by: Matt Caswell <matt@openssl.org>
+Reviewed-by: Neil Horman <nhorman@openssl.org>
+Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
+(Merged from https://github.com/openssl/openssl/pull/24346)
+
+(cherry picked from commit 85ccbab216da245cf9a6503dd327072f21950d9b)
+---
+ CHANGES.md                                    | 17 ++++++
+ crypto/dsa/dsa_check.c                        | 44 ++++++++++++--
+ .../invalid/p10240_q256_too_big.pem           | 57 +++++++++++++++++++
+ 3 files changed, 114 insertions(+), 4 deletions(-)
+ create mode 100644 test/recipes/15-test_dsaparam_data/invalid/p10240_q256_too_big.pem
+
+Index: openssl-3.1.4/crypto/dsa/dsa_check.c
+===================================================================
+--- openssl-3.1.4.orig/crypto/dsa/dsa_check.c
++++ openssl-3.1.4/crypto/dsa/dsa_check.c
+@@ -19,8 +19,34 @@
+ #include "dsa_local.h"
+ #include "crypto/dsa.h"
+ 
++static int dsa_precheck_params(const DSA *dsa, int *ret)
++{
++    if (dsa->params.p == NULL || dsa->params.q == NULL) {
++        ERR_raise(ERR_LIB_DSA, DSA_R_BAD_FFC_PARAMETERS);
++        *ret = FFC_CHECK_INVALID_PQ;
++        return 0;
++    }
++
++    if (BN_num_bits(dsa->params.p) > OPENSSL_DSA_MAX_MODULUS_BITS) {
++        ERR_raise(ERR_LIB_DSA, DSA_R_MODULUS_TOO_LARGE);
++        *ret = FFC_CHECK_INVALID_PQ;
++        return 0;
++    }
++
++    if (BN_num_bits(dsa->params.q) >= BN_num_bits(dsa->params.p)) {
++        ERR_raise(ERR_LIB_DSA, DSA_R_BAD_Q_VALUE);
++        *ret = FFC_CHECK_INVALID_PQ;
++        return 0;
++    }
++
++    return 1;
++}
++
+ int ossl_dsa_check_params(const DSA *dsa, int checktype, int *ret)
+ {
++    if (!dsa_precheck_params(dsa, ret))
++        return 0;
++
+     if (checktype == OSSL_KEYMGMT_VALIDATE_QUICK_CHECK)
+         return ossl_ffc_params_simple_validate(dsa->libctx, &dsa->params,
+                                                FFC_PARAM_TYPE_DSA, ret);
+@@ -39,6 +65,9 @@ int ossl_dsa_check_params(const DSA *dsa
+  */
+ int ossl_dsa_check_pub_key(const DSA *dsa, const BIGNUM *pub_key, int *ret)
+ {
++    if (!dsa_precheck_params(dsa, ret))
++        return 0;
++
+     return ossl_ffc_validate_public_key(&dsa->params, pub_key, ret)
+            && *ret == 0;
+ }
+@@ -50,6 +79,9 @@ int ossl_dsa_check_pub_key(const DSA *ds
+  */
+ int ossl_dsa_check_pub_key_partial(const DSA *dsa, const BIGNUM *pub_key, int *ret)
+ {
++    if (!dsa_precheck_params(dsa, ret))
++        return 0;
++
+     return ossl_ffc_validate_public_key_partial(&dsa->params, pub_key, ret)
+            && *ret == 0;
+ }
+@@ -58,8 +90,10 @@ int ossl_dsa_check_priv_key(const DSA *d
+ {
+     *ret = 0;
+ 
+-    return (dsa->params.q != NULL
+-            && ossl_ffc_validate_private_key(dsa->params.q, priv_key, ret));
++    if (!dsa_precheck_params(dsa, ret))
++        return 0;
++
++    return ossl_ffc_validate_private_key(dsa->params.q, priv_key, ret);
+ }
+ 
+ /*
+@@ -72,8 +106,10 @@ int ossl_dsa_check_pairwise(const DSA *d
+     BN_CTX *ctx = NULL;
+     BIGNUM *pub_key = NULL;
+ 
+-    if (dsa->params.p == NULL
+-        || dsa->params.g == NULL
++    if (!dsa_precheck_params(dsa, &ret))
++        return 0;
++
++    if (dsa->params.g == NULL
+         || dsa->priv_key == NULL
+         || dsa->pub_key == NULL)
+         return 0;
+Index: openssl-3.1.4/test/recipes/15-test_dsaparam_data/invalid/p10240_q256_too_big.pem
+===================================================================
+--- /dev/null
++++ openssl-3.1.4/test/recipes/15-test_dsaparam_data/invalid/p10240_q256_too_big.pem
+@@ -0,0 +1,57 @@
++-----BEGIN DSA PARAMETERS-----
++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
++vKuje86bePD6kD/LH3wmkA==
++-----END DSA PARAMETERS-----
+Index: openssl-3.1.4/CHANGES.md
+===================================================================
+--- openssl-3.1.4.orig/CHANGES.md
++++ openssl-3.1.4/CHANGES.md
+@@ -22,6 +22,23 @@ OpenSSL Releases
+ OpenSSL 3.1
+ -----------
+ 
++ * Fixed an issue where checking excessively long DSA keys or parameters may
++   be very slow.
++
++   Applications that use the functions EVP_PKEY_param_check() or
++   EVP_PKEY_public_check() to check a DSA public key or DSA parameters may
++   experience long delays. Where the key or parameters that are being checked
++   have been obtained from an untrusted source this may lead to a Denial of
++   Service.
++
++   To resolve this issue DSA keys larger than OPENSSL_DSA_MAX_MODULUS_BITS
++   will now fail the check immediately with a DSA_R_MODULUS_TOO_LARGE error
++   reason.
++
++   ([CVE-2024-4603])
++
++   *Tomáš Mráz*
++
+ ### Changes between 3.1.3 and 3.1.4 [24 Oct 2023]
+ 
+  * Fix incorrect key and IV resizing issues when calling EVP_EncryptInit_ex2(),
diff --git a/openssl-DEFAULT_SUSE_cipher.patch b/openssl-DEFAULT_SUSE_cipher.patch
new file mode 100644
index 0000000..b8d8688
--- /dev/null
+++ b/openssl-DEFAULT_SUSE_cipher.patch
@@ -0,0 +1,64 @@
+Index: openssl-3.0.0-alpha7/ssl/ssl_ciph.c
+===================================================================
+--- openssl-3.0.0-alpha7.orig/ssl/ssl_ciph.c
++++ openssl-3.0.0-alpha7/ssl/ssl_ciph.c
+@@ -1592,7 +1592,14 @@ STACK_OF(SSL_CIPHER) *ssl_create_cipher_
+      */
+     ok = 1;
+     rule_p = rule_str;
+-    if (strncmp(rule_str, "DEFAULT", 7) == 0) {
++    if (strncmp(rule_str,"DEFAULT_SUSE", 12) == 0) {
++        ok = ssl_cipher_process_rulestr(SSL_DEFAULT_SUSE_CIPHER_LIST,
++                                        &head, &tail, ca_list, c);
++        rule_p += 12;
++        if (*rule_p == ':')
++            rule_p++;
++    }
++    else if (strncmp(rule_str, "DEFAULT", 7) == 0) {
+         ok = ssl_cipher_process_rulestr(OSSL_default_cipher_list(),
+                                         &head, &tail, ca_list, c);
+         rule_p += 7;
+Index: openssl-3.0.0-alpha7/test/recipes/99-test_suse_default_ciphers.t
+===================================================================
+--- /dev/null
++++ openssl-3.0.0-alpha7/test/recipes/99-test_suse_default_ciphers.t
+@@ -0,0 +1,23 @@
++#! /usr/bin/env perl
++
++use strict;
++use warnings;
++
++use OpenSSL::Test qw/:DEFAULT/;
++use OpenSSL::Test::Utils;
++
++setup("test_default_ciphersuites");
++
++plan tests => 6;
++
++my @cipher_suites = ("DEFAULT_SUSE", "DEFAULT");
++
++foreach my $cipherlist (@cipher_suites) {
++  ok(run(app(["openssl", "ciphers", "-s", $cipherlist])),
++     "openssl ciphers works with ciphersuite $cipherlist");
++  ok(!grep(/(MD5|RC4|DES)/, run(app(["openssl", "ciphers", "-s", $cipherlist]), capture => 1)),
++         "$cipherlist shouldn't contain MD5, DES or RC4\n");
++  ok(grep(/(TLSv1.3)/, run(app(["openssl", "ciphers", "-tls1_3", "-s", "-v", $cipherlist]), capture => 1)),
++         "$cipherlist should contain TLSv1.3 ciphers\n");
++}
++
+Index: openssl-3.0.0-alpha7/include/openssl/ssl.h.in
+===================================================================
+--- openssl-3.0.0-alpha7.orig/include/openssl/ssl.h.in
++++ openssl-3.0.0-alpha7/include/openssl/ssl.h.in
+@@ -189,6 +189,11 @@ extern "C" {
+  */
+ # ifndef OPENSSL_NO_DEPRECATED_3_0
+ #  define SSL_DEFAULT_CIPHER_LIST "ALL:!COMPLEMENTOFDEFAULT:!eNULL"
++#  define SSL_DEFAULT_SUSE_CIPHER_LIST "ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:"\
++    "ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-SHA256:"\
++    "ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:"\
++    "DHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:DHE-RSA-CAMELLIA256-SHA:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-CAMELLIA128-SHA:"\
++    "AES256-GCM-SHA384:AES256-SHA256:AES256-SHA:CAMELLIA256-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:CAMELLIA128-SHA"
+ /*
+  * This is the default set of TLSv1.3 ciphersuites
+  * DEPRECATED IN 3.0.0, in favor of OSSL_default_ciphersuites()
diff --git a/openssl-Disable-default-provider-for-test-suite.patch b/openssl-Disable-default-provider-for-test-suite.patch
new file mode 100644
index 0000000..719a289
--- /dev/null
+++ b/openssl-Disable-default-provider-for-test-suite.patch
@@ -0,0 +1,19 @@
+Index: openssl-3.1.4/apps/openssl.cnf
+===================================================================
+--- openssl-3.1.4.orig/apps/openssl.cnf
++++ openssl-3.1.4/apps/openssl.cnf
+@@ -70,11 +70,11 @@ engines = engine_section
+ # to side-channel attacks and as such have been deprecated.
+ 
+ [provider_sect]
+-default = default_sect
++##default = default_sect
+ ##legacy = legacy_sect
+ 
+-[default_sect]
+-activate = 1
++##[default_sect]
++##activate = 1
+ 
+ ##[legacy_sect]
+ ##activate = 1
diff --git a/openssl-Enable-BTI-feature-for-md5-on-aarch64.patch b/openssl-Enable-BTI-feature-for-md5-on-aarch64.patch
new file mode 100644
index 0000000..031bef4
--- /dev/null
+++ b/openssl-Enable-BTI-feature-for-md5-on-aarch64.patch
@@ -0,0 +1,28 @@
+From d2bfec6e464aeb247a2d6853668d4e473f19e15f Mon Sep 17 00:00:00 2001
+From: "fangming.fang" <fangming.fang@arm.com>
+Date: Thu, 7 Dec 2023 06:17:51 +0000
+Subject: [PATCH] Enable BTI feature for md5 on aarch64
+
+Fixes: #22959
+---
+ crypto/md5/asm/md5-aarch64.pl | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/crypto/md5/asm/md5-aarch64.pl b/crypto/md5/asm/md5-aarch64.pl
+index 3200a0fa9bff0..5a8608069691d 100755
+--- a/crypto/md5/asm/md5-aarch64.pl
++++ b/crypto/md5/asm/md5-aarch64.pl
+@@ -28,10 +28,13 @@
+ *STDOUT=*OUT;
+ 
+ $code .= <<EOF;
++#include "arm_arch.h"
++
+ .text
+ .globl  ossl_md5_block_asm_data_order
+ .type   ossl_md5_block_asm_data_order,\@function
+ ossl_md5_block_asm_data_order:
++        AARCH64_VALID_CALL_TARGET
+         // Save all callee-saved registers
+         stp     x19,x20,[sp,#-80]!
+         stp     x21,x22,[sp,#16]
diff --git a/openssl-FIPS-embed-hmac.patch b/openssl-FIPS-embed-hmac.patch
new file mode 100644
index 0000000..288361b
--- /dev/null
+++ b/openssl-FIPS-embed-hmac.patch
@@ -0,0 +1,250 @@
+From e364a858262c8f563954544cc81e66f1b3b8db8c Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Thu, 19 Oct 2023 13:12:40 +0200
+Subject: [PATCH 16/46] 0033-FIPS-embed-hmac.patch
+
+Patch-name: 0033-FIPS-embed-hmac.patch
+Patch-id: 33
+Patch-status: |
+    # # Embed HMAC into the fips.so
+From-dist-git-commit: 5c67b5adc311af297f425c09e3e1ac7ca8483911
+---
+ providers/fips/self_test.c            | 70 ++++++++++++++++++++++++---
+ test/fipsmodule.cnf                   |  2 +
+ test/recipes/00-prep_fipsmodule_cnf.t |  2 +-
+ test/recipes/01-test_fipsmodule_cnf.t |  2 +-
+ test/recipes/03-test_fipsinstall.t    |  2 +-
+ test/recipes/30-test_defltfips.t      |  2 +-
+ test/recipes/80-test_ssl_new.t        |  2 +-
+ test/recipes/90-test_sslapi.t         |  2 +-
+ 8 files changed, 71 insertions(+), 13 deletions(-)
+ create mode 100644 test/fipsmodule.cnf
+
+diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c
+index b8dc9817b2..e3a629018a 100644
+--- a/providers/fips/self_test.c
++++ b/providers/fips/self_test.c
+@@ -230,11 +230,27 @@ err:
+     return ok;
+ }
+ 
++#define HMAC_LEN 32
++/*
++ * The __attribute__ ensures we've created the .rodata1 section
++ * static ensures it's zero filled
++*/
++static const unsigned char __attribute__ ((section (".rodata1"))) fips_hmac_container[HMAC_LEN] = {0};
++
+ /*
+  * Calculate the HMAC SHA256 of data read using a BIO and read_cb, and verify
+  * the result matches the expected value.
+  * Return 1 if verified, or 0 if it fails.
+  */
++#ifndef __USE_GNU
++#define __USE_GNU
++#include <dlfcn.h>
++#undef __USE_GNU
++#else
++#include <dlfcn.h>
++#endif
++#include <link.h>
++
+ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex_cb,
+                             unsigned char *expected, size_t expected_len,
+                             OSSL_LIB_CTX *libctx, OSSL_SELF_TEST *ev,
+@@ -247,12 +263,23 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex
+     EVP_MAC *mac = NULL;
+     EVP_MAC_CTX *ctx = NULL;
+     OSSL_PARAM params[2], *p = params;
++    Dl_info info;
++    void *extra_info = NULL;
++    struct link_map *lm = NULL;
++    unsigned long paddr;
++    unsigned long off = 0;
+ 
+     if (!integrity_self_test(ev, libctx))
+         goto err;
+ 
+     OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
+ 
++    if (!dladdr1 ((const void *)fips_hmac_container,
++                &info, &extra_info, RTLD_DL_LINKMAP))
++        goto err;
++    lm = extra_info;
++    paddr = (unsigned long)fips_hmac_container - lm->l_addr;
++
+     mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
+     if (mac == NULL)
+         goto err;
+@@ -266,13 +293,42 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex
+     if (!EVP_MAC_init(ctx, fixed_key, sizeof(fixed_key), params))
+         goto err;
+ 
+-    while (1) {
+-        status = read_ex_cb(bio, buf, sizeof(buf), &bytes_read);
++    while ((off + INTEGRITY_BUF_SIZE) <= paddr) {
++        status = read_ex_cb(bio, buf, INTEGRITY_BUF_SIZE, &bytes_read);
++        if (status != 1)
++            break;
++        if (!EVP_MAC_update(ctx, buf, bytes_read))
++            goto err;
++	off += bytes_read;
++    }
++
++    if (off + INTEGRITY_BUF_SIZE > paddr) {
++        int delta = paddr - off;
++        status = read_ex_cb(bio, buf, delta, &bytes_read);
++        if (status != 1)
++            goto err;
++        if (!EVP_MAC_update(ctx, buf, bytes_read))
++            goto err;
++	off += bytes_read;
++
++        status = read_ex_cb(bio, buf, HMAC_LEN, &bytes_read);
++        memset(buf, 0, HMAC_LEN);
++        if (status != 1)
++            goto err;
++        if (!EVP_MAC_update(ctx, buf, bytes_read))
++            goto err;
++	off += bytes_read;
++    }
++
++    while (bytes_read > 0) {
++        status = read_ex_cb(bio, buf, INTEGRITY_BUF_SIZE, &bytes_read);
+         if (status != 1)
+             break;
+         if (!EVP_MAC_update(ctx, buf, bytes_read))
+             goto err;
++	off += bytes_read;
+     }
++
+     if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
+         goto err;
+ 
+@@ -282,6 +338,7 @@ static int verify_integrity(OSSL_CORE_BIO *bio, OSSL_FUNC_BIO_read_ex_fn read_ex
+         goto err;
+     ret = 1;
+ err:
++    OPENSSL_cleanse(out, sizeof(out));
+     OSSL_SELF_TEST_onend(ev, ret);
+     EVP_MAC_CTX_free(ctx);
+     EVP_MAC_free(mac);
+@@ -335,8 +392,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
+         return 0;
+     }
+ 
+-    if (st == NULL
+-            || st->module_checksum_data == NULL) {
++    if (st == NULL) {
+         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_CONFIG_DATA);
+         goto end;
+     }
+@@ -345,8 +401,9 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
+     if (ev == NULL)
+         goto end;
+ 
+-    module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
+-                                         &checksum_len);
++    module_checksum = fips_hmac_container;
++    checksum_len = sizeof(fips_hmac_container);
++
+     if (module_checksum == NULL) {
+         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CONFIG_DATA);
+         goto end;
+@@ -420,7 +477,6 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
+ end:
+     EVP_RAND_free(testrand);
+     OSSL_SELF_TEST_free(ev);
+-    OPENSSL_free(module_checksum);
+     OPENSSL_free(indicator_checksum);
+ 
+     if (st != NULL) {
+diff --git a/test/fipsmodule.cnf b/test/fipsmodule.cnf
+new file mode 100644
+index 0000000000..f05d0dedbe
+--- /dev/null
++++ b/test/fipsmodule.cnf
+@@ -0,0 +1,2 @@
++[fips_sect]
++activate = 1
+diff --git a/test/recipes/00-prep_fipsmodule_cnf.t b/test/recipes/00-prep_fipsmodule_cnf.t
+index 4e3a6d85e8..e8255ba974 100644
+--- a/test/recipes/00-prep_fipsmodule_cnf.t
++++ b/test/recipes/00-prep_fipsmodule_cnf.t
+@@ -20,7 +20,7 @@ use lib srctop_dir('Configurations');
+ use lib bldtop_dir('.');
+ use platform;
+ 
+-my $no_check = disabled("fips");
++my $no_check = 1;
+ plan skip_all => "FIPS module config file only supported in a fips build"
+     if $no_check;
+ 
+diff --git a/test/recipes/01-test_fipsmodule_cnf.t b/test/recipes/01-test_fipsmodule_cnf.t
+index ce594817d5..00cebacff8 100644
+--- a/test/recipes/01-test_fipsmodule_cnf.t
++++ b/test/recipes/01-test_fipsmodule_cnf.t
+@@ -23,7 +23,7 @@ use lib srctop_dir('Configurations');
+ use lib bldtop_dir('.');
+ use platform;
+ 
+-my $no_check = disabled("fips");
++my $no_check = 1;
+ plan skip_all => "Test only supported in a fips build"
+     if $no_check;
+ plan tests => 1;
+diff --git a/test/recipes/03-test_fipsinstall.t b/test/recipes/03-test_fipsinstall.t
+index b8b136d110..8242f4ebc3 100644
+--- a/test/recipes/03-test_fipsinstall.t
++++ b/test/recipes/03-test_fipsinstall.t
+@@ -22,7 +22,7 @@ use lib srctop_dir('Configurations');
+ use lib bldtop_dir('.');
+ use platform;
+ 
+-plan skip_all => "Test only supported in a fips build" if disabled("fips");
++plan skip_all => "Test only supported in a fips build" if 1;
+ 
+ # Compatible options for pedantic FIPS compliance
+ my @pedantic_okay =
+diff --git a/test/recipes/30-test_defltfips.t b/test/recipes/30-test_defltfips.t
+index c8f145405b..56a2ec5dc4 100644
+--- a/test/recipes/30-test_defltfips.t
++++ b/test/recipes/30-test_defltfips.t
+@@ -24,7 +24,7 @@ use lib bldtop_dir('.');
+ plan skip_all => "Configuration loading is turned off"
+     if disabled("autoload-config");
+ 
+-my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
++my $no_fips = 1; #disabled('fips') || ($ENV{NO_FIPS} // 0);
+ 
+ plan tests =>
+     ($no_fips ? 1 : 5);
+diff --git a/test/recipes/80-test_ssl_new.t b/test/recipes/80-test_ssl_new.t
+index 0c6d6402d9..e45f9cb560 100644
+--- a/test/recipes/80-test_ssl_new.t
++++ b/test/recipes/80-test_ssl_new.t
+@@ -27,7 +27,7 @@ setup("test_ssl_new");
+ use lib srctop_dir('Configurations');
+ use lib bldtop_dir('.');
+ 
+-my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
++my $no_fips = 1; #disabled('fips') || ($ENV{NO_FIPS} // 0);
+ 
+ $ENV{TEST_CERTS_DIR} = srctop_dir("test", "certs");
+ 
+diff --git a/test/recipes/90-test_sslapi.t b/test/recipes/90-test_sslapi.t
+index 9e9e32b51e..1a1a7159b5 100644
+--- a/test/recipes/90-test_sslapi.t
++++ b/test/recipes/90-test_sslapi.t
+@@ -17,7 +17,7 @@ setup("test_sslapi");
+ use lib srctop_dir('Configurations');
+ use lib bldtop_dir('.');
+ 
+-my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
++my $no_fips = 1; #disabled('fips') || ($ENV{NO_FIPS} // 0);
+ my $fipsmodcfg_filename = "fipsmodule.cnf";
+ my $fipsmodcfg = bldtop_file("test", $fipsmodcfg_filename);
+ 
+-- 
+2.41.0
+
diff --git a/openssl-Fix-EVP_PKEY_CTX_add1_hkdf_info-behavior.patch b/openssl-Fix-EVP_PKEY_CTX_add1_hkdf_info-behavior.patch
new file mode 100644
index 0000000..e79c626
--- /dev/null
+++ b/openssl-Fix-EVP_PKEY_CTX_add1_hkdf_info-behavior.patch
@@ -0,0 +1,309 @@
+From 4580c303fa88f77a98461fee5fe26b5db725967c Mon Sep 17 00:00:00 2001
+From: Todd Short <todd.short@me.com>
+Date: Thu, 1 Feb 2024 23:09:38 -0500
+Subject: [PATCH 1/2] Fix EVP_PKEY_CTX_add1_hkdf_info() behavior
+
+Fix #23448
+
+`EVP_PKEY_CTX_add1_hkdf_info()` behaves like a `set1` function.
+
+Fix the setting of the parameter in the params code.
+Update the TLS_PRF code to also use the params code.
+Add tests.
+
+Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/23456)
+
+(cherry picked from commit 6b566687b58fde08b28e3331377f050768fad89b)
+---
+ crypto/evp/pmeth_lib.c                        | 65 ++++++++++++++++++-
+ providers/implementations/exchange/kdf_exch.c | 42 ++++++++++++
+ providers/implementations/kdfs/hkdf.c         |  8 +++
+ test/pkey_meth_kdf_test.c                     | 53 +++++++++++----
+ 4 files changed, 156 insertions(+), 12 deletions(-)
+
+diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
+index ba1971c..d0eeaf7 100644
+--- a/crypto/evp/pmeth_lib.c
++++ b/crypto/evp/pmeth_lib.c
+@@ -1028,6 +1028,69 @@ static int evp_pkey_ctx_set1_octet_string(EVP_PKEY_CTX *ctx, int fallback,
+     return EVP_PKEY_CTX_set_params(ctx, octet_string_params);
+ }
+ 
++static int evp_pkey_ctx_add1_octet_string(EVP_PKEY_CTX *ctx, int fallback,
++                                          const char *param, int op, int ctrl,
++                                          const unsigned char *data,
++                                          int datalen)
++{
++    OSSL_PARAM os_params[2];
++    unsigned char *info = NULL;
++    size_t info_len = 0;
++    size_t info_alloc = 0;
++    int ret = 0;
++
++    if (ctx == NULL || (ctx->operation & op) == 0) {
++        ERR_raise(ERR_LIB_EVP, EVP_R_COMMAND_NOT_SUPPORTED);
++        /* Uses the same return values as EVP_PKEY_CTX_ctrl */
++        return -2;
++    }
++
++    /* Code below to be removed when legacy support is dropped. */
++    if (fallback)
++        return EVP_PKEY_CTX_ctrl(ctx, -1, op, ctrl, datalen, (void *)(data));
++    /* end of legacy support */
++
++    if (datalen < 0) {
++        ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
++        return 0;
++    }
++
++    /* Get the original value length */
++    os_params[0] = OSSL_PARAM_construct_octet_string(param, NULL, 0);
++    os_params[1] = OSSL_PARAM_construct_end();
++
++    if (!EVP_PKEY_CTX_get_params(ctx, os_params))
++        return 0;
++
++    /* Older provider that doesn't support getting this parameter */
++    if (os_params[0].return_size == OSSL_PARAM_UNMODIFIED)
++        return evp_pkey_ctx_set1_octet_string(ctx, fallback, param, op, ctrl, data, datalen);
++
++    info_alloc = os_params[0].return_size + datalen;
++    if (info_alloc == 0)
++        return 0;
++    info = OPENSSL_zalloc(info_alloc);
++    if (info == NULL)
++        return 0;
++    info_len = os_params[0].return_size;
++
++    os_params[0] = OSSL_PARAM_construct_octet_string(param, info, info_alloc);
++
++    /* if we have data, then go get it */
++    if (info_len > 0) {
++        if (!EVP_PKEY_CTX_get_params(ctx, os_params))
++            goto error;
++    }
++
++    /* Copy the input data */
++    memcpy(&info[info_len], data, datalen);
++    ret = EVP_PKEY_CTX_set_params(ctx, os_params);
++
++ error:
++    OPENSSL_clear_free(info, info_alloc);
++    return ret;
++}
++
+ int EVP_PKEY_CTX_set1_tls1_prf_secret(EVP_PKEY_CTX *ctx,
+                                       const unsigned char *sec, int seclen)
+ {
+@@ -1078,7 +1141,7 @@ int EVP_PKEY_CTX_set1_hkdf_key(EVP_PKEY_CTX *ctx,
+ int EVP_PKEY_CTX_add1_hkdf_info(EVP_PKEY_CTX *ctx,
+                                       const unsigned char *info, int infolen)
+ {
+-    return evp_pkey_ctx_set1_octet_string(ctx, ctx->op.kex.algctx == NULL,
++    return evp_pkey_ctx_add1_octet_string(ctx, ctx->op.kex.algctx == NULL,
+                                           OSSL_KDF_PARAM_INFO,
+                                           EVP_PKEY_OP_DERIVE,
+                                           EVP_PKEY_CTRL_HKDF_INFO,
+diff --git a/providers/implementations/exchange/kdf_exch.c b/providers/implementations/exchange/kdf_exch.c
+index 527a866..4bc8102 100644
+--- a/providers/implementations/exchange/kdf_exch.c
++++ b/providers/implementations/exchange/kdf_exch.c
+@@ -28,9 +28,13 @@ static OSSL_FUNC_keyexch_derive_fn kdf_derive;
+ static OSSL_FUNC_keyexch_freectx_fn kdf_freectx;
+ static OSSL_FUNC_keyexch_dupctx_fn kdf_dupctx;
+ static OSSL_FUNC_keyexch_set_ctx_params_fn kdf_set_ctx_params;
++static OSSL_FUNC_keyexch_get_ctx_params_fn kdf_get_ctx_params;
+ static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_tls1_prf_settable_ctx_params;
+ static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_hkdf_settable_ctx_params;
+ static OSSL_FUNC_keyexch_settable_ctx_params_fn kdf_scrypt_settable_ctx_params;
++static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_tls1_prf_gettable_ctx_params;
++static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_hkdf_gettable_ctx_params;
++static OSSL_FUNC_keyexch_gettable_ctx_params_fn kdf_scrypt_gettable_ctx_params;
+ 
+ typedef struct {
+     void *provctx;
+@@ -169,6 +173,13 @@ static int kdf_set_ctx_params(void *vpkdfctx, const OSSL_PARAM params[])
+     return EVP_KDF_CTX_set_params(pkdfctx->kdfctx, params);
+ }
+ 
++static int kdf_get_ctx_params(void *vpkdfctx, OSSL_PARAM params[])
++{
++    PROV_KDF_CTX *pkdfctx = (PROV_KDF_CTX *)vpkdfctx;
++
++    return EVP_KDF_CTX_get_params(pkdfctx->kdfctx, params);
++}
++
+ static const OSSL_PARAM *kdf_settable_ctx_params(ossl_unused void *vpkdfctx,
+                                                  void *provctx,
+                                                  const char *kdfname)
+@@ -197,6 +208,34 @@ KDF_SETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF")
+ KDF_SETTABLE_CTX_PARAMS(hkdf, "HKDF")
+ KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT")
+ 
++static const OSSL_PARAM *kdf_gettable_ctx_params(ossl_unused void *vpkdfctx,
++                                                 void *provctx,
++                                                 const char *kdfname)
++{
++    EVP_KDF *kdf = EVP_KDF_fetch(PROV_LIBCTX_OF(provctx), kdfname,
++                                 NULL);
++    const OSSL_PARAM *params;
++
++    if (kdf == NULL)
++        return NULL;
++
++    params = EVP_KDF_gettable_ctx_params(kdf);
++    EVP_KDF_free(kdf);
++
++    return params;
++}
++
++#define KDF_GETTABLE_CTX_PARAMS(funcname, kdfname) \
++    static const OSSL_PARAM *kdf_##funcname##_gettable_ctx_params(void *vpkdfctx, \
++                                                                  void *provctx) \
++    { \
++        return kdf_gettable_ctx_params(vpkdfctx, provctx, kdfname); \
++    }
++
++KDF_GETTABLE_CTX_PARAMS(tls1_prf, "TLS1-PRF")
++KDF_GETTABLE_CTX_PARAMS(hkdf, "HKDF")
++KDF_GETTABLE_CTX_PARAMS(scrypt, "SCRYPT")
++
+ #define KDF_KEYEXCH_FUNCTIONS(funcname) \
+     const OSSL_DISPATCH ossl_kdf_##funcname##_keyexch_functions[] = { \
+         { OSSL_FUNC_KEYEXCH_NEWCTX, (void (*)(void))kdf_##funcname##_newctx }, \
+@@ -205,8 +244,11 @@ KDF_SETTABLE_CTX_PARAMS(scrypt, "SCRYPT")
+         { OSSL_FUNC_KEYEXCH_FREECTX, (void (*)(void))kdf_freectx }, \
+         { OSSL_FUNC_KEYEXCH_DUPCTX, (void (*)(void))kdf_dupctx }, \
+         { OSSL_FUNC_KEYEXCH_SET_CTX_PARAMS, (void (*)(void))kdf_set_ctx_params }, \
++        { OSSL_FUNC_KEYEXCH_GET_CTX_PARAMS, (void (*)(void))kdf_get_ctx_params }, \
+         { OSSL_FUNC_KEYEXCH_SETTABLE_CTX_PARAMS, \
+         (void (*)(void))kdf_##funcname##_settable_ctx_params }, \
++        { OSSL_FUNC_KEYEXCH_GETTABLE_CTX_PARAMS, \
++        (void (*)(void))kdf_##funcname##_gettable_ctx_params }, \
+         { 0, NULL } \
+     };
+ 
+diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
+index daa619b..dd65a2a 100644
+--- a/providers/implementations/kdfs/hkdf.c
++++ b/providers/implementations/kdfs/hkdf.c
+@@ -371,6 +371,13 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+             return 0;
+         return OSSL_PARAM_set_size_t(p, sz);
+     }
++    if ((p = OSSL_PARAM_locate(params, OSSL_KDF_PARAM_INFO)) != NULL) {
++        if (ctx->info == NULL || ctx->info_len == 0) {
++            p->return_size = 0;
++            return 1;
++        }
++        return OSSL_PARAM_set_octet_string(p, ctx->info, ctx->info_len);
++    }
+     return -2;
+ }
+ 
+@@ -379,6 +386,7 @@ static const OSSL_PARAM *kdf_hkdf_gettable_ctx_params(ossl_unused void *ctx,
+ {
+     static const OSSL_PARAM known_gettable_ctx_params[] = {
+         OSSL_PARAM_size_t(OSSL_KDF_PARAM_SIZE, NULL),
++        OSSL_PARAM_octet_string(OSSL_KDF_PARAM_INFO, NULL, 0),
+         OSSL_PARAM_END
+     };
+     return known_gettable_ctx_params;
+diff --git a/test/pkey_meth_kdf_test.c b/test/pkey_meth_kdf_test.c
+index f816d24..c09e2f3 100644
+--- a/test/pkey_meth_kdf_test.c
++++ b/test/pkey_meth_kdf_test.c
+@@ -16,7 +16,7 @@
+ #include <openssl/kdf.h>
+ #include "testutil.h"
+ 
+-static int test_kdf_tls1_prf(void)
++static int test_kdf_tls1_prf(int index)
+ {
+     int ret = 0;
+     EVP_PKEY_CTX *pctx;
+@@ -40,10 +40,23 @@ static int test_kdf_tls1_prf(void)
+         TEST_error("EVP_PKEY_CTX_set1_tls1_prf_secret");
+         goto err;
+     }
+-    if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx,
+-                                        (unsigned char *)"seed", 4) <= 0) {
+-        TEST_error("EVP_PKEY_CTX_add1_tls1_prf_seed");
+-        goto err;
++    if (index == 0) {
++        if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx,
++                                            (unsigned char *)"seed", 4) <= 0) {
++            TEST_error("EVP_PKEY_CTX_add1_tls1_prf_seed");
++            goto err;
++        }
++    } else {
++        if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx,
++                                            (unsigned char *)"se", 2) <= 0) {
++            TEST_error("EVP_PKEY_CTX_add1_tls1_prf_seed");
++            goto err;
++        }
++        if (EVP_PKEY_CTX_add1_tls1_prf_seed(pctx,
++                                            (unsigned char *)"ed", 2) <= 0) {
++            TEST_error("EVP_PKEY_CTX_add1_tls1_prf_seed");
++            goto err;
++        }
+     }
+     if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) {
+         TEST_error("EVP_PKEY_derive");
+@@ -65,7 +78,7 @@ err:
+     return ret;
+ }
+ 
+-static int test_kdf_hkdf(void)
++static int test_kdf_hkdf(int index)
+ {
+     int ret = 0;
+     EVP_PKEY_CTX *pctx;
+@@ -94,10 +107,23 @@ static int test_kdf_hkdf(void)
+         TEST_error("EVP_PKEY_CTX_set1_hkdf_key");
+         goto err;
+     }
+-    if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (const unsigned char *)"label", 5)
++    if (index == 0) {
++        if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (const unsigned char *)"label", 5)
+             <= 0) {
+-        TEST_error("EVP_PKEY_CTX_set1_hkdf_info");
+-        goto err;
++            TEST_error("EVP_PKEY_CTX_add1_hkdf_info");
++            goto err;
++        }
++    } else {
++        if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (const unsigned char *)"lab", 3)
++            <= 0) {
++            TEST_error("EVP_PKEY_CTX_add1_hkdf_info");
++            goto err;
++        }
++        if (EVP_PKEY_CTX_add1_hkdf_info(pctx, (const unsigned char *)"el", 2)
++            <= 0) {
++            TEST_error("EVP_PKEY_CTX_add1_hkdf_info");
++            goto err;
++        }
+     }
+     if (EVP_PKEY_derive(pctx, out, &outlen) <= 0) {
+         TEST_error("EVP_PKEY_derive");
+@@ -195,8 +221,13 @@ err:
+ 
+ int setup_tests(void)
+ {
+-    ADD_TEST(test_kdf_tls1_prf);
+-    ADD_TEST(test_kdf_hkdf);
++    int tests = 1;
++
++    if (fips_provider_version_ge(NULL, 3, 3, 1))
++        tests = 2;
++
++    ADD_ALL_TESTS(test_kdf_tls1_prf, tests);
++    ADD_ALL_TESTS(test_kdf_hkdf, tests);
+ #ifndef OPENSSL_NO_SCRYPT
+     ADD_TEST(test_kdf_scrypt);
+ #endif
+-- 
+2.45.1
+
diff --git a/openssl-Force-FIPS.patch b/openssl-Force-FIPS.patch
new file mode 100644
index 0000000..8596ef9
--- /dev/null
+++ b/openssl-Force-FIPS.patch
@@ -0,0 +1,68 @@
+From 2c110cf5551a3869514e697d8dc06682b62ca57d Mon Sep 17 00:00:00 2001
+From: Dmitry Belyavskiy <dbelyavs@redhat.com>
+Date: Mon, 21 Aug 2023 11:59:02 +0200
+Subject: [PATCH 16/48] 0032-Force-fips.patch
+
+Patch-name: 0032-Force-fips.patch
+Patch-id: 32
+Patch-status: |
+    # We load FIPS provider and set FIPS properties implicitly
+---
+ crypto/provider_conf.c | 28 +++++++++++++++++++++++++++-
+ 1 file changed, 27 insertions(+), 1 deletion(-)
+
+diff --git a/crypto/provider_conf.c b/crypto/provider_conf.c
+index 058fb58837..5274265a70 100644
+--- a/crypto/provider_conf.c
++++ b/crypto/provider_conf.c
+@@ -10,6 +10,8 @@
+ #include <string.h>
+ #include <openssl/trace.h>
+ #include <openssl/err.h>
++#include <openssl/evp.h>
++#include <unistd.h>
+ #include <openssl/conf.h>
+ #include <openssl/safestack.h>
+ #include <openssl/provider.h>
+@@ -169,7 +171,7 @@ static int provider_conf_activate(OSSL_LIB_CTX *libctx, const char *name,
+         if (path != NULL)
+             ossl_provider_set_module_path(prov, path);
+ 
+-        ok = provider_conf_params(prov, NULL, NULL, value, cnf);
++        ok = cnf ? provider_conf_params(prov, NULL, NULL, value, cnf) : 1;
+ 
+         if (ok) {
+             if (!ossl_provider_activate(prov, 1, 0)) {
+@@ -309,6 +311,30 @@ static int provider_conf_init(CONF_IMODULE *md, const CONF *cnf)
+             return 0;
+     }
+ 
++    if (ossl_get_kernel_fips_flag() != 0) { /* XXX from provider_conf_load */
++        OSSL_LIB_CTX *libctx = NCONF_get0_libctx((CONF *)cnf);
++#  define FIPS_LOCAL_CONF           OPENSSLDIR "/fips_local.cnf"
++
++        if (access(FIPS_LOCAL_CONF, R_OK) == 0) {
++            CONF *fips_conf = NCONF_new_ex(libctx, NCONF_default());
++            if (NCONF_load(fips_conf, FIPS_LOCAL_CONF, NULL) <= 0)
++                return 0;
++
++            if (provider_conf_load(libctx, "fips", "fips_sect", fips_conf) != 1) {
++                NCONF_free(fips_conf);
++                return 0;
++            }
++            NCONF_free(fips_conf);
++        } else {
++            if (provider_conf_activate(libctx, "fips", NULL, NULL, 0, NULL) != 1)
++                return 0;
++        }
++        if (provider_conf_activate(libctx, "base", NULL, NULL, 0, NULL) != 1)
++            return 0;
++        if (EVP_default_properties_enable_fips(libctx, 1) != 1)
++            return 0;
++    }
++
+     return 1;
+ }
+ 
+-- 
+2.41.0
diff --git a/openssl-Handle-empty-param-in-EVP_PKEY_CTX_add1_hkdf_info.patch b/openssl-Handle-empty-param-in-EVP_PKEY_CTX_add1_hkdf_info.patch
new file mode 100644
index 0000000..0ad7660
--- /dev/null
+++ b/openssl-Handle-empty-param-in-EVP_PKEY_CTX_add1_hkdf_info.patch
@@ -0,0 +1,94 @@
+From d6a9c21302e01c33a9a919e7ba380ba3b0ed65b0 Mon Sep 17 00:00:00 2001
+From: trinity-1686a <trinity@deuxfleurs.fr>
+Date: Mon, 15 Apr 2024 11:13:14 +0200
+Subject: [PATCH 2/2] Handle empty param in EVP_PKEY_CTX_add1_hkdf_info
+
+Fixes #24130
+The regression was introduced in PR #23456.
+
+Reviewed-by: Paul Dale <ppzgs1@gmail.com>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/24141)
+
+(cherry picked from commit 299996fb1fcd76eeadfd547958de2a1b822f37f5)
+---
+ crypto/evp/pmeth_lib.c |  2 ++
+ test/evp_extra_test.c  | 42 ++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 44 insertions(+)
+
+diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
+index d0eeaf7..bce1ebc 100644
+--- a/crypto/evp/pmeth_lib.c
++++ b/crypto/evp/pmeth_lib.c
+@@ -1053,6 +1053,8 @@ static int evp_pkey_ctx_add1_octet_string(EVP_PKEY_CTX *ctx, int fallback,
+     if (datalen < 0) {
+         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_LENGTH);
+         return 0;
++    } else if (datalen == 0) {
++        return 1;
+     }
+ 
+     /* Get the original value length */
+diff --git a/test/evp_extra_test.c b/test/evp_extra_test.c
+index 9b3bee7..22121ce 100644
+--- a/test/evp_extra_test.c
++++ b/test/evp_extra_test.c
+@@ -2565,6 +2565,47 @@ static int test_emptyikm_HKDF(void)
+     return ret;
+ }
+ 
++static int test_empty_salt_info_HKDF(void)
++{
++    EVP_PKEY_CTX *pctx;
++    unsigned char out[20];
++    size_t outlen;
++    int ret = 0;
++    unsigned char salt[] = "";
++    unsigned char key[] = "012345678901234567890123456789";
++    unsigned char info[] = "";
++    const unsigned char expected[] = {
++	0x67, 0x12, 0xf9, 0x27, 0x8a, 0x8a, 0x3a, 0x8f, 0x7d, 0x2c, 0xa3, 0x6a,
++	0xaa, 0xe9, 0xb3, 0xb9, 0x52, 0x5f, 0xe0, 0x06,
++    };
++    size_t expectedlen = sizeof(expected);
++
++    if (!TEST_ptr(pctx = EVP_PKEY_CTX_new_from_name(testctx, "HKDF", testpropq)))
++        goto done;
++
++    outlen = sizeof(out);
++    memset(out, 0, outlen);
++
++    if (!TEST_int_gt(EVP_PKEY_derive_init(pctx), 0)
++            || !TEST_int_gt(EVP_PKEY_CTX_set_hkdf_md(pctx, EVP_sha256()), 0)
++            || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_salt(pctx, salt,
++                                                        sizeof(salt) - 1), 0)
++            || !TEST_int_gt(EVP_PKEY_CTX_set1_hkdf_key(pctx, key,
++                                                       sizeof(key) - 1), 0)
++            || !TEST_int_gt(EVP_PKEY_CTX_add1_hkdf_info(pctx, info,
++                                                        sizeof(info) - 1), 0)
++            || !TEST_int_gt(EVP_PKEY_derive(pctx, out, &outlen), 0)
++            || !TEST_mem_eq(out, outlen, expected, expectedlen))
++        goto done;
++
++    ret = 1;
++
++ done:
++    EVP_PKEY_CTX_free(pctx);
++
++    return ret;
++}
++
+ #ifndef OPENSSL_NO_EC
+ static int test_X509_PUBKEY_inplace(void)
+ {
+@@ -5166,6 +5207,7 @@ int setup_tests(void)
+ #endif
+     ADD_TEST(test_HKDF);
+     ADD_TEST(test_emptyikm_HKDF);
++    ADD_TEST(test_empty_salt_info_HKDF);
+ #ifndef OPENSSL_NO_EC
+     ADD_TEST(test_X509_PUBKEY_inplace);
+     ADD_TEST(test_X509_PUBKEY_dup);
+-- 
+2.45.1
+
diff --git a/openssl-Improve-performance-for-6x-unrolling-with-vpermxor-i.patch b/openssl-Improve-performance-for-6x-unrolling-with-vpermxor-i.patch
new file mode 100644
index 0000000..7c57d6b
--- /dev/null
+++ b/openssl-Improve-performance-for-6x-unrolling-with-vpermxor-i.patch
@@ -0,0 +1,495 @@
+From 3d3a7ecd1ae5ab08d22041f7b3b035c34f12fa02 Mon Sep 17 00:00:00 2001
+From: Danny Tsen <dtsen@linux.ibm.com>
+Date: Tue, 22 Aug 2023 15:58:53 -0400
+Subject: [PATCH] Improve performance for 6x unrolling with vpermxor
+ instruction
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/21812)
+---
+ crypto/aes/asm/aesp8-ppc.pl | 145 +++++++++++++++++++++++-------------
+ 1 file changed, 95 insertions(+), 50 deletions(-)
+
+diff --git a/crypto/aes/asm/aesp8-ppc.pl b/crypto/aes/asm/aesp8-ppc.pl
+index 60cf86f52aed2..38b9405a283b7 100755
+--- a/crypto/aes/asm/aesp8-ppc.pl
++++ b/crypto/aes/asm/aesp8-ppc.pl
+@@ -99,11 +99,12 @@
+ .long	0x1b000000, 0x1b000000, 0x1b000000, 0x1b000000	?rev
+ .long	0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c, 0x0d0e0f0c	?rev
+ .long	0,0,0,0						?asis
++.long	0x0f102132, 0x43546576, 0x8798a9ba, 0xcbdcedfe
+ Lconsts:
+ 	mflr	r0
+ 	bcl	20,31,\$+4
+ 	mflr	$ptr	 #vvvvv "distance between . and rcon
+-	addi	$ptr,$ptr,-0x48
++	addi	$ptr,$ptr,-0x58
+ 	mtlr	r0
+ 	blr
+ 	.long	0
+@@ -2405,7 +2406,7 @@ ()
+ my $key_=$key2;
+ my ($x00,$x10,$x20,$x30,$x40,$x50,$x60,$x70)=map("r$_",(0,3,26..31));
+     $x00=0 if ($flavour =~ /osx/);
+-my ($in0,  $in1,  $in2,  $in3,  $in4,  $in5 )=map("v$_",(0..5));
++my ($in0,  $in1,  $in2,  $in3,  $in4,  $in5)=map("v$_",(0..5));
+ my ($out0, $out1, $out2, $out3, $out4, $out5)=map("v$_",(7,12..16));
+ my ($twk0, $twk1, $twk2, $twk3, $twk4, $twk5)=map("v$_",(17..22));
+ my $rndkey0="v23";	# v24-v25 rotating buffer for first found keys
+@@ -2460,6 +2461,18 @@ ()
+ 	li		$x70,0x70
+ 	mtspr		256,r0
+ 
++	# Reverse eighty7 to 0x010101..87
++	xxlor		2, 32+$eighty7, 32+$eighty7
++	vsldoi		$eighty7,$tmp,$eighty7,1	# 0x010101..87
++	xxlor		1, 32+$eighty7, 32+$eighty7
++
++	# Load XOR contents. 0xf102132435465768798a9bacbdcedfe
++	mr		$x70, r6
++	bl		Lconsts
++	lxvw4x		0, $x40, r6		# load XOR contents
++	mr		r6, $x70
++	li		$x70,0x70
++
+ 	subi		$rounds,$rounds,3	# -4 in total
+ 
+ 	lvx		$rndkey0,$x00,$key1	# load key schedule
+@@ -2502,69 +2515,77 @@ ()
+ 	?vperm		v31,v31,$twk5,$keyperm
+ 	lvx		v25,$x10,$key_		# pre-load round[2]
+ 
++	# Switch to use the following codes with 0x010101..87 to generate tweak.
++	#     eighty7 = 0x010101..87
++	# vsrab		tmp, tweak, seven	# next tweak value, right shift 7 bits
++	# vand		tmp, tmp, eighty7	# last byte with carry
++	# vaddubm	tweak, tweak, tweak	# left shift 1 bit (x2)
++	# xxlor		vsx, 0, 0
++	# vpermxor	tweak, tweak, tmp, vsx
++
+ 	 vperm		$in0,$inout,$inptail,$inpperm
+ 	 subi		$inp,$inp,31		# undo "caller"
+ 	vxor		$twk0,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out0,$in0,$twk0
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in1, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in1
+ 
+ 	 lvx_u		$in1,$x10,$inp
+ 	vxor		$twk1,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in1,$in1,$in1,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out1,$in1,$twk1
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in2, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in2
+ 
+ 	 lvx_u		$in2,$x20,$inp
+ 	 andi.		$taillen,$len,15
+ 	vxor		$twk2,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in2,$in2,$in2,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out2,$in2,$twk2
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in3, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in3
+ 
+ 	 lvx_u		$in3,$x30,$inp
+ 	 sub		$len,$len,$taillen
+ 	vxor		$twk3,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in3,$in3,$in3,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out3,$in3,$twk3
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in4, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in4
+ 
+ 	 lvx_u		$in4,$x40,$inp
+ 	 subi		$len,$len,0x60
+ 	vxor		$twk4,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in4,$in4,$in4,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out4,$in4,$twk4
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in5, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in5
+ 
+ 	 lvx_u		$in5,$x50,$inp
+ 	 addi		$inp,$inp,0x60
+ 	vxor		$twk5,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in5,$in5,$in5,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out5,$in5,$twk5
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in0, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in0
+ 
+ 	vxor		v31,v31,$rndkey0
+ 	mtctr		$rounds
+@@ -2590,6 +2611,8 @@ ()
+ 	lvx		v25,$x10,$key_		# round[4]
+ 	bdnz		Loop_xts_enc6x
+ 
++	xxlor		32+$eighty7, 1, 1		# 0x010101..87
++
+ 	subic		$len,$len,96		# $len-=96
+ 	 vxor		$in0,$twk0,v31		# xor with last round key
+ 	vcipher		$out0,$out0,v24
+@@ -2599,7 +2622,6 @@ ()
+ 	 vaddubm	$tweak,$tweak,$tweak
+ 	vcipher		$out2,$out2,v24
+ 	vcipher		$out3,$out3,v24
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vcipher		$out4,$out4,v24
+ 	vcipher		$out5,$out5,v24
+ 
+@@ -2607,7 +2629,8 @@ ()
+ 	 vand		$tmp,$tmp,$eighty7
+ 	vcipher		$out0,$out0,v25
+ 	vcipher		$out1,$out1,v25
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in1, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in1
+ 	vcipher		$out2,$out2,v25
+ 	vcipher		$out3,$out3,v25
+ 	 vxor		$in1,$twk1,v31
+@@ -2618,13 +2641,13 @@ ()
+ 
+ 	and		r0,r0,$len
+ 	 vaddubm	$tweak,$tweak,$tweak
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vcipher		$out0,$out0,v26
+ 	vcipher		$out1,$out1,v26
+ 	 vand		$tmp,$tmp,$eighty7
+ 	vcipher		$out2,$out2,v26
+ 	vcipher		$out3,$out3,v26
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in2, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in2
+ 	vcipher		$out4,$out4,v26
+ 	vcipher		$out5,$out5,v26
+ 
+@@ -2638,7 +2661,6 @@ ()
+ 	 vaddubm	$tweak,$tweak,$tweak
+ 	vcipher		$out0,$out0,v27
+ 	vcipher		$out1,$out1,v27
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vcipher		$out2,$out2,v27
+ 	vcipher		$out3,$out3,v27
+ 	 vand		$tmp,$tmp,$eighty7
+@@ -2646,7 +2668,8 @@ ()
+ 	vcipher		$out5,$out5,v27
+ 
+ 	addi		$key_,$sp,$FRAME+15	# rewind $key_
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in3, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in3
+ 	vcipher		$out0,$out0,v28
+ 	vcipher		$out1,$out1,v28
+ 	 vxor		$in3,$twk3,v31
+@@ -2655,7 +2678,6 @@ ()
+ 	vcipher		$out2,$out2,v28
+ 	vcipher		$out3,$out3,v28
+ 	 vaddubm	$tweak,$tweak,$tweak
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vcipher		$out4,$out4,v28
+ 	vcipher		$out5,$out5,v28
+ 	lvx		v24,$x00,$key_		# re-pre-load round[1]
+@@ -2663,7 +2685,8 @@ ()
+ 
+ 	vcipher		$out0,$out0,v29
+ 	vcipher		$out1,$out1,v29
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in4, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in4
+ 	vcipher		$out2,$out2,v29
+ 	vcipher		$out3,$out3,v29
+ 	 vxor		$in4,$twk4,v31
+@@ -2673,14 +2696,14 @@ ()
+ 	vcipher		$out5,$out5,v29
+ 	lvx		v25,$x10,$key_		# re-pre-load round[2]
+ 	 vaddubm	$tweak,$tweak,$tweak
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 
+ 	vcipher		$out0,$out0,v30
+ 	vcipher		$out1,$out1,v30
+ 	 vand		$tmp,$tmp,$eighty7
+ 	vcipher		$out2,$out2,v30
+ 	vcipher		$out3,$out3,v30
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in5, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in5
+ 	vcipher		$out4,$out4,v30
+ 	vcipher		$out5,$out5,v30
+ 	 vxor		$in5,$twk5,v31
+@@ -2690,7 +2713,6 @@ ()
+ 	vcipherlast	$out0,$out0,$in0
+ 	 lvx_u		$in0,$x00,$inp		# load next input block
+ 	 vaddubm	$tweak,$tweak,$tweak
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vcipherlast	$out1,$out1,$in1
+ 	 lvx_u		$in1,$x10,$inp
+ 	vcipherlast	$out2,$out2,$in2
+@@ -2703,7 +2725,10 @@ ()
+ 	vcipherlast	$out4,$out4,$in4
+ 	 le?vperm	$in2,$in2,$in2,$leperm
+ 	 lvx_u		$in4,$x40,$inp
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		10, 32+$in0, 32+$in0
++	 xxlor		32+$in0, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in0
++	 xxlor		32+$in0, 10, 10
+ 	vcipherlast	$tmp,$out5,$in5		# last block might be needed
+ 						# in stealing mode
+ 	 le?vperm	$in3,$in3,$in3,$leperm
+@@ -2736,6 +2761,8 @@ ()
+ 	mtctr		$rounds
+ 	beq		Loop_xts_enc6x		# did $len-=96 borrow?
+ 
++	xxlor		32+$eighty7, 2, 2		# 0x870101..01
++
+ 	addic.		$len,$len,0x60
+ 	beq		Lxts_enc6x_zero
+ 	cmpwi		$len,0x20
+@@ -3112,6 +3139,18 @@ ()
+ 	li		$x70,0x70
+ 	mtspr		256,r0
+ 
++	# Reverse eighty7 to 0x010101..87
++	xxlor		2, 32+$eighty7, 32+$eighty7
++	vsldoi		$eighty7,$tmp,$eighty7,1	# 0x010101..87
++	xxlor		1, 32+$eighty7, 32+$eighty7
++
++	# Load XOR contents. 0xf102132435465768798a9bacbdcedfe
++	mr		$x70, r6
++	bl		Lconsts
++	lxvw4x		0, $x40, r6		# load XOR contents
++	mr		r6, $x70
++	li		$x70,0x70
++
+ 	subi		$rounds,$rounds,3	# -4 in total
+ 
+ 	lvx		$rndkey0,$x00,$key1	# load key schedule
+@@ -3159,64 +3198,64 @@ ()
+ 	vxor		$twk0,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out0,$in0,$twk0
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in1, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in1
+ 
+ 	 lvx_u		$in1,$x10,$inp
+ 	vxor		$twk1,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in1,$in1,$in1,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out1,$in1,$twk1
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in2, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in2
+ 
+ 	 lvx_u		$in2,$x20,$inp
+ 	 andi.		$taillen,$len,15
+ 	vxor		$twk2,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in2,$in2,$in2,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out2,$in2,$twk2
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in3, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in3
+ 
+ 	 lvx_u		$in3,$x30,$inp
+ 	 sub		$len,$len,$taillen
+ 	vxor		$twk3,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in3,$in3,$in3,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out3,$in3,$twk3
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in4, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in4
+ 
+ 	 lvx_u		$in4,$x40,$inp
+ 	 subi		$len,$len,0x60
+ 	vxor		$twk4,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in4,$in4,$in4,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out4,$in4,$twk4
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in5, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in5
+ 
+ 	 lvx_u		$in5,$x50,$inp
+ 	 addi		$inp,$inp,0x60
+ 	vxor		$twk5,$tweak,$rndkey0
+ 	vsrab		$tmp,$tweak,$seven	# next tweak value
+ 	vaddubm		$tweak,$tweak,$tweak
+-	vsldoi		$tmp,$tmp,$tmp,15
+ 	 le?vperm	$in5,$in5,$in5,$leperm
+ 	vand		$tmp,$tmp,$eighty7
+ 	 vxor		$out5,$in5,$twk5
+-	vxor		$tweak,$tweak,$tmp
++	xxlor		32+$in0, 0, 0
++	vpermxor	$tweak, $tweak, $tmp, $in0
+ 
+ 	vxor		v31,v31,$rndkey0
+ 	mtctr		$rounds
+@@ -3242,6 +3281,8 @@ ()
+ 	lvx		v25,$x10,$key_		# round[4]
+ 	bdnz		Loop_xts_dec6x
+ 
++	xxlor		32+$eighty7, 1, 1
++
+ 	subic		$len,$len,96		# $len-=96
+ 	 vxor		$in0,$twk0,v31		# xor with last round key
+ 	vncipher	$out0,$out0,v24
+@@ -3251,7 +3292,6 @@ ()
+ 	 vaddubm	$tweak,$tweak,$tweak
+ 	vncipher	$out2,$out2,v24
+ 	vncipher	$out3,$out3,v24
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vncipher	$out4,$out4,v24
+ 	vncipher	$out5,$out5,v24
+ 
+@@ -3259,7 +3299,8 @@ ()
+ 	 vand		$tmp,$tmp,$eighty7
+ 	vncipher	$out0,$out0,v25
+ 	vncipher	$out1,$out1,v25
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in1, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in1
+ 	vncipher	$out2,$out2,v25
+ 	vncipher	$out3,$out3,v25
+ 	 vxor		$in1,$twk1,v31
+@@ -3270,13 +3311,13 @@ ()
+ 
+ 	and		r0,r0,$len
+ 	 vaddubm	$tweak,$tweak,$tweak
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vncipher	$out0,$out0,v26
+ 	vncipher	$out1,$out1,v26
+ 	 vand		$tmp,$tmp,$eighty7
+ 	vncipher	$out2,$out2,v26
+ 	vncipher	$out3,$out3,v26
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in2, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in2
+ 	vncipher	$out4,$out4,v26
+ 	vncipher	$out5,$out5,v26
+ 
+@@ -3290,7 +3331,6 @@ ()
+ 	 vaddubm	$tweak,$tweak,$tweak
+ 	vncipher	$out0,$out0,v27
+ 	vncipher	$out1,$out1,v27
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vncipher	$out2,$out2,v27
+ 	vncipher	$out3,$out3,v27
+ 	 vand		$tmp,$tmp,$eighty7
+@@ -3298,7 +3338,8 @@ ()
+ 	vncipher	$out5,$out5,v27
+ 
+ 	addi		$key_,$sp,$FRAME+15	# rewind $key_
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in3, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in3
+ 	vncipher	$out0,$out0,v28
+ 	vncipher	$out1,$out1,v28
+ 	 vxor		$in3,$twk3,v31
+@@ -3307,7 +3348,6 @@ ()
+ 	vncipher	$out2,$out2,v28
+ 	vncipher	$out3,$out3,v28
+ 	 vaddubm	$tweak,$tweak,$tweak
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vncipher	$out4,$out4,v28
+ 	vncipher	$out5,$out5,v28
+ 	lvx		v24,$x00,$key_		# re-pre-load round[1]
+@@ -3315,7 +3355,8 @@ ()
+ 
+ 	vncipher	$out0,$out0,v29
+ 	vncipher	$out1,$out1,v29
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in4, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in4
+ 	vncipher	$out2,$out2,v29
+ 	vncipher	$out3,$out3,v29
+ 	 vxor		$in4,$twk4,v31
+@@ -3325,14 +3366,14 @@ ()
+ 	vncipher	$out5,$out5,v29
+ 	lvx		v25,$x10,$key_		# re-pre-load round[2]
+ 	 vaddubm	$tweak,$tweak,$tweak
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 
+ 	vncipher	$out0,$out0,v30
+ 	vncipher	$out1,$out1,v30
+ 	 vand		$tmp,$tmp,$eighty7
+ 	vncipher	$out2,$out2,v30
+ 	vncipher	$out3,$out3,v30
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		32+$in5, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in5
+ 	vncipher	$out4,$out4,v30
+ 	vncipher	$out5,$out5,v30
+ 	 vxor		$in5,$twk5,v31
+@@ -3342,7 +3383,6 @@ ()
+ 	vncipherlast	$out0,$out0,$in0
+ 	 lvx_u		$in0,$x00,$inp		# load next input block
+ 	 vaddubm	$tweak,$tweak,$tweak
+-	 vsldoi		$tmp,$tmp,$tmp,15
+ 	vncipherlast	$out1,$out1,$in1
+ 	 lvx_u		$in1,$x10,$inp
+ 	vncipherlast	$out2,$out2,$in2
+@@ -3355,7 +3395,10 @@ ()
+ 	vncipherlast	$out4,$out4,$in4
+ 	 le?vperm	$in2,$in2,$in2,$leperm
+ 	 lvx_u		$in4,$x40,$inp
+-	 vxor		$tweak,$tweak,$tmp
++	 xxlor		10, 32+$in0, 32+$in0
++	 xxlor		32+$in0, 0, 0
++	 vpermxor	$tweak, $tweak, $tmp, $in0
++	 xxlor		32+$in0, 10, 10
+ 	vncipherlast	$out5,$out5,$in5
+ 	 le?vperm	$in3,$in3,$in3,$leperm
+ 	 lvx_u		$in5,$x50,$inp
+@@ -3386,6 +3429,8 @@ ()
+ 	mtctr		$rounds
+ 	beq		Loop_xts_dec6x		# did $len-=96 borrow?
+ 
++	xxlor		32+$eighty7, 2, 2
++
+ 	addic.		$len,$len,0x60
+ 	beq		Lxts_dec6x_zero
+ 	cmpwi		$len,0x20
diff --git a/openssl-crypto-policies-support.patch b/openssl-crypto-policies-support.patch
new file mode 100644
index 0000000..c7f3f16
--- /dev/null
+++ b/openssl-crypto-policies-support.patch
@@ -0,0 +1,35 @@
+Add default section to load crypto-policies configuration for TLS.
+
+It needs to be reverted before running tests.
+
+---
+ apps/openssl.cnf | 20 ++++++++++++++++++--
+ 2 files changed, 19 insertions(+), 3 deletions(-)
+
+Index: openssl-3.2.0/apps/openssl.cnf
+===================================================================
+--- openssl-3.2.0.orig/apps/openssl.cnf
++++ openssl-3.2.0/apps/openssl.cnf
+@@ -52,6 +52,8 @@ tsa_policy3 = 1.2.3.4.5.7
+ 
+ [openssl_init]
+ providers = provider_sect
++# Load default TLS policy configuration
++ssl_conf = ssl_module
+ 
+ # List of providers to load
+ [provider_sect]
+@@ -71,6 +73,13 @@ default = default_sect
+ [default_sect]
+ # activate = 1
+ 
++[ ssl_module ]
++
++system_default = crypto_policy
++
++[ crypto_policy ]
++
++.include = /etc/crypto-policies/back-ends/opensslcnf.config
+ 
+ ####################################################################
+ [ ca ]
diff --git a/openssl-disable-fipsinstall.patch b/openssl-disable-fipsinstall.patch
new file mode 100644
index 0000000..b5f0593
--- /dev/null
+++ b/openssl-disable-fipsinstall.patch
@@ -0,0 +1,470 @@
+From a9825123e7ab3474d2794a5706d9bed047959c9c Mon Sep 17 00:00:00 2001
+From: rpm-build <rpm-build>
+Date: Mon, 31 Jul 2023 09:41:28 +0200
+Subject: [PATCH 18/35] 0034.fipsinstall_disable.patch
+
+Patch-name: 0034.fipsinstall_disable.patch
+Patch-id: 34
+Patch-status: |
+    # Comment out fipsinstall command-line utility
+From-dist-git-commit: 9409bc7044cf4b5773639cce20f51399888c45fd
+---
+ apps/fipsinstall.c                  |   3 +
+ doc/man1/openssl-fipsinstall.pod.in | 272 +---------------------------
+ doc/man1/openssl.pod                |   4 -
+ doc/man5/config.pod                 |   1 -
+ doc/man5/fips_config.pod            | 104 +----------
+ doc/man7/OSSL_PROVIDER-FIPS.pod     |   1 -
+ 6 files changed, 10 insertions(+), 375 deletions(-)
+
+Index: openssl-3.1.4/apps/fipsinstall.c
+===================================================================
+--- openssl-3.1.4.orig/apps/fipsinstall.c
++++ openssl-3.1.4/apps/fipsinstall.c
+@@ -375,6 +375,9 @@ int fipsinstall_main(int argc, char **ar
+     EVP_MAC *mac = NULL;
+     CONF *conf = NULL;
+ 
++    BIO_printf(bio_err, "This command is not enabled in SUSE/openSUSE OpenSSL build, please see 'man 8 fips-mode-setup' to learn how to enable FIPS mode\n");
++    return 1;
++
+     if ((opts = sk_OPENSSL_STRING_new_null()) == NULL)
+         goto end;
+ 
+Index: openssl-3.1.4/doc/man1/openssl-fipsinstall.pod.in
+===================================================================
+--- openssl-3.1.4.orig/doc/man1/openssl-fipsinstall.pod.in
++++ openssl-3.1.4/doc/man1/openssl-fipsinstall.pod.in
+@@ -8,275 +8,9 @@ openssl-fipsinstall - perform FIPS confi
+ =head1 SYNOPSIS
+ 
+ B<openssl fipsinstall>
+-[B<-help>]
+-[B<-in> I<configfilename>]
+-[B<-out> I<configfilename>]
+-[B<-module> I<modulefilename>]
+-[B<-provider_name> I<providername>]
+-[B<-section_name> I<sectionname>]
+-[B<-verify>]
+-[B<-mac_name> I<macname>]
+-[B<-macopt> I<nm>:I<v>]
+-[B<-noout>]
+-[B<-quiet>]
+-[B<-pedantic>]
+-[B<-no_conditional_errors>]
+-[B<-no_security_checks>]
+-[B<-ems_check>]
+-[B<-no_drbg_truncated_digests>]
+-[B<-self_test_onload>]
+-[B<-self_test_oninstall>]
+-[B<-corrupt_desc> I<selftest_description>]
+-[B<-corrupt_type> I<selftest_type>]
+-[B<-config> I<parent_config>]
+-
+-=head1 DESCRIPTION
+-
+-This command is used to generate a FIPS module configuration file.
+-This configuration file can be used each time a FIPS module is loaded
+-in order to pass data to the FIPS module self tests. The FIPS module always
+-verifies its MAC, but optionally only needs to run the KAT's once,
+-at installation.
+-
+-The generated configuration file consists of:
+-
+-=over 4
+-
+-=item - A MAC of the FIPS module file.
+-
+-=item - A test status indicator.
+-
+-This indicates if the Known Answer Self Tests (KAT's) have successfully run.
+-
+-=item - A MAC of the status indicator.
+-
+-=item - A control for conditional self tests errors.
+-
+-By default if a continuous test (e.g a key pair test) fails then the FIPS module
+-will enter an error state, and no services or cryptographic algorithms will be
+-able to be accessed after this point.
+-The default value of '1' will cause the fips module error state to be entered.
+-If the value is '0' then the module error state will not be entered.
+-Regardless of whether the error state is entered or not, the current operation
+-(e.g. key generation) will return an error. The user is responsible for retrying
+-the operation if the module error state is not entered.
+-
+-=item - A control to indicate whether run-time security checks are done.
+-
+-This indicates if run-time checks related to enforcement of security parameters
+-such as minimum security strength of keys and approved curve names are used.
+-The default value of '1' will perform the checks.
+-If the value is '0' the checks are not performed and FIPS compliance must
+-be done by procedures documented in the relevant Security Policy.
+-
+-=back
+-
+-This file is described in L<fips_config(5)>.
+-
+-=head1 OPTIONS
+-
+-=over 4
+-
+-=item B<-help>
+-
+-Print a usage message.
+-
+-=item B<-module> I<filename>
+-
+-Filename of the FIPS module to perform an integrity check on.
+-The path provided in the filename is used to load the module when it is
+-activated, and this overrides the environment variable B<OPENSSL_MODULES>.
+-
+-=item B<-out> I<configfilename>
+-
+-Filename to output the configuration data to; the default is standard output.
+-
+-=item B<-in> I<configfilename>
+-
+-Input filename to load configuration data from.
+-Must be used if the B<-verify> option is specified.
+-
+-=item B<-verify>
+-
+-Verify that the input configuration file contains the correct information.
+-
+-=item B<-provider_name> I<providername>
+-
+-Name of the provider inside the configuration file.
+-The default value is C<fips>.
+-
+-=item B<-section_name> I<sectionname>
+-
+-Name of the section inside the configuration file.
+-The default value is C<fips_sect>.
+-
+-=item B<-mac_name> I<name>
+-
+-Specifies the name of a supported MAC algorithm which will be used.
+-The MAC mechanisms that are available will depend on the options
+-used when building OpenSSL.
+-To see the list of supported MAC's use the command
+-C<openssl list -mac-algorithms>.  The default is B<HMAC>.
+-
+-=item B<-macopt> I<nm>:I<v>
+-
+-Passes options to the MAC algorithm.
+-A comprehensive list of controls can be found in the EVP_MAC implementation
+-documentation.
+-Common control strings used for this command are:
+-
+-=over 4
+-
+-=item B<key>:I<string>
+-
+-Specifies the MAC key as an alphanumeric string (use if the key contains
+-printable characters only).
+-The string length must conform to any restrictions of the MAC algorithm.
+-A key must be specified for every MAC algorithm.
+-If no key is provided, the default that was specified when OpenSSL was
+-configured is used.
+-
+-=item B<hexkey>:I<string>
+-
+-Specifies the MAC key in hexadecimal form (two hex digits per byte).
+-The key length must conform to any restrictions of the MAC algorithm.
+-A key must be specified for every MAC algorithm.
+-If no key is provided, the default that was specified when OpenSSL was
+-configured is used.
+-
+-=item B<digest>:I<string>
+-
+-Used by HMAC as an alphanumeric string (use if the key contains printable
+-characters only).
+-The string length must conform to any restrictions of the MAC algorithm.
+-To see the list of supported digests, use the command
+-C<openssl list -digest-commands>.
+-The default digest is SHA-256.
+-
+-=back
+-
+-=item B<-noout>
+-
+-Disable logging of the self tests.
+-
+-=item B<-pedantic>
+-
+-Configure the module so that it is strictly FIPS compliant rather
+-than being backwards compatible.  This enables conditional errors,
+-security checks etc.  Note that any previous configuration options will
+-be overwritten and any subsequent configuration options that violate
+-FIPS compliance will result in an error.
+-
+-=item B<-no_conditional_errors>
+-
+-Configure the module to not enter an error state if a conditional self test
+-fails as described above.
+-
+-=item B<-no_security_checks>
+-
+-Configure the module to not perform run-time security checks as described above.
+-
+-Enabling the configuration option "no-fips-securitychecks" provides another way to
+-turn off the check at compile time.
+-
+-=item B<-ems_check>
+-
+-Configure the module to enable a run-time Extended Master Secret (EMS) check
+-when using the TLS1_PRF KDF algorithm. This check is disabled by default.
+-See RFC 7627 for information related to EMS.
+-
+-=item B<-no_drbg_truncated_digests>
+-
+-Configure the module to not allow truncated digests to be used with Hash and
+-HMAC DRBGs.  See FIPS 140-3 IG D.R for details.
+-
+-=item B<-self_test_onload>
+-
+-Do not write the two fields related to the "test status indicator" and
+-"MAC status indicator" to the output configuration file. Without these fields
+-the self tests KATS will run each time the module is loaded. This option could be
+-used for cross compiling, since the self tests need to run at least once on each
+-target machine. Once the self tests have run on the target machine the user
+-could possibly then add the 2 fields into the configuration using some other
+-mechanism.
+-
+-This is the default.
+-
+-=item B<-self_test_oninstall>
+-
+-The converse of B<-self_test_oninstall>.  The two fields related to the
+-"test status indicator" and "MAC status indicator" are written to the
+-output configuration file.
+-
+-=item B<-quiet>
+-
+-Do not output pass/fail messages. Implies B<-noout>.
+-
+-=item B<-corrupt_desc> I<selftest_description>,
+-B<-corrupt_type> I<selftest_type>
+-
+-The corrupt options can be used to test failure of one or more self tests by
+-name.
+-Either option or both may be used to select the tests to corrupt.
+-Refer to the entries for B<st-desc> and B<st-type> in L<OSSL_PROVIDER-FIPS(7)> for
+-values that can be used.
+-
+-=item B<-config> I<parent_config>
+-
+-Test that a FIPS provider can be loaded from the specified configuration file.
+-A previous call to this application needs to generate the extra configuration
+-data that is included by the base C<parent_config> configuration file.
+-See L<config(5)> for further information on how to set up a provider section.
+-All other options are ignored if '-config' is used.
+-
+-=back
+-
+-=head1 NOTES
+-
+-Self tests results are logged by default if the options B<-quiet> and B<-noout>
+-are not specified, or if either of the options B<-corrupt_desc> or
+-B<-corrupt_type> are used.
+-If the base configuration file is set up to autoload the fips module, then the
+-fips module will be loaded and self tested BEFORE the fipsinstall application
+-has a chance to set up its own self test callback. As a result of this the self
+-test output and the options B<-corrupt_desc> and B<-corrupt_type> will be ignored.
+-For normal usage the base configuration file should use the default provider
+-when generating the fips configuration file.
+-
+-The B<-self_test_oninstall> option was added and the
+-B<-self_test_onload> option was made the default in OpenSSL 3.1.
+-
+-The command and all remaining options were added in OpenSSL 3.0.
+-
+-=head1 EXAMPLES
+-
+-Calculate the mac of a FIPS module F<fips.so> and run a FIPS self test
+-for the module, and save the F<fips.cnf> configuration file:
+-
+- openssl fipsinstall -module ./fips.so -out fips.cnf -provider_name fips
+-
+-Verify that the configuration file F<fips.cnf> contains the correct info:
+-
+- openssl fipsinstall -module ./fips.so -in fips.cnf  -provider_name fips -verify
+-
+-Corrupt any self tests which have the description C<SHA1>:
+-
+- openssl fipsinstall -module ./fips.so -out fips.cnf -provider_name fips \
+-         -corrupt_desc 'SHA1'
+-
+-Validate that the fips module can be loaded from a base configuration file:
+-
+- export OPENSSL_CONF_INCLUDE=<path of configuration files>
+- export OPENSSL_MODULES=<provider-path>
+- openssl fipsinstall -config' 'default.cnf'
+-
+-
+-=head1 SEE ALSO
+-
+-L<config(5)>,
+-L<fips_config(5)>,
+-L<OSSL_PROVIDER-FIPS(7)>,
+-L<EVP_MAC(3)>
++This command is disabled.
++Please consult the SUSE/openSUSE documentation to learn how to correctly
++enable FIPS mode.
+ 
+ =head1 COPYRIGHT
+ 
+Index: openssl-3.1.4/doc/man1/openssl.pod
+===================================================================
+--- openssl-3.1.4.orig/doc/man1/openssl.pod
++++ openssl-3.1.4/doc/man1/openssl.pod
+@@ -135,10 +135,6 @@ Engine (loadable module) information and
+ 
+ Error Number to Error String Conversion.
+ 
+-=item B<fipsinstall>
+-
+-FIPS configuration installation.
+-
+ =item B<gendsa>
+ 
+ Generation of DSA Private Key from Parameters. Superseded by
+Index: openssl-3.1.4/doc/man5/config.pod
+===================================================================
+--- openssl-3.1.4.orig/doc/man5/config.pod
++++ openssl-3.1.4/doc/man5/config.pod
+@@ -565,7 +565,6 @@ configuration files using that syntax wi
+ =head1 SEE ALSO
+ 
+ L<openssl-x509(1)>, L<openssl-req(1)>, L<openssl-ca(1)>,
+-L<openssl-fipsinstall(1)>,
+ L<ASN1_generate_nconf(3)>,
+ L<EVP_set_default_properties(3)>,
+ L<CONF_modules_load(3)>,
+Index: openssl-3.1.4/doc/man5/fips_config.pod
+===================================================================
+--- openssl-3.1.4.orig/doc/man5/fips_config.pod
++++ openssl-3.1.4/doc/man5/fips_config.pod
+@@ -6,106 +6,10 @@ fips_config - OpenSSL FIPS configuration
+ 
+ =head1 DESCRIPTION
+ 
+-A separate configuration file, using the OpenSSL L<config(5)> syntax,
+-is used to hold information about the FIPS module. This includes a digest
+-of the shared library file, and status about the self-testing.
+-This data is used automatically by the module itself for two
+-purposes:
+-
+-=over 4
+-
+-=item - Run the startup FIPS self-test known answer tests (KATS).
+-
+-This is normally done once, at installation time, but may also be set up to
+-run each time the module is used.
+-
+-=item - Verify the module's checksum.
+-
+-This is done each time the module is used.
+-
+-=back
+-
+-This file is generated by the L<openssl-fipsinstall(1)> program, and
+-used internally by the FIPS module during its initialization.
+-
+-The following options are supported. They should all appear in a section
+-whose name is identified by the B<fips> option in the B<providers>
+-section, as described in L<config(5)/Provider Configuration Module>.
+-
+-=over 4
+-
+-=item B<activate>
+-
+-If present, the module is activated. The value assigned to this name is not
+-significant.
+-
+-=item B<install-version>
+-
+-A version number for the fips install process. Should be 1.
+-
+-=item B<conditional-errors>
+-
+-The FIPS module normally enters an internal error mode if any self test fails.
+-Once this error mode is active, no services or cryptographic algorithms are
+-accessible from this point on.
+-Continuous tests are a subset of the self tests (e.g., a key pair test during key
+-generation, or the CRNG output test).
+-Setting this value to C<0> allows the error mode to not be triggered if any
+-continuous test fails. The default value of C<1> will trigger the error mode.
+-Regardless of the value, the operation (e.g., key generation) that called the
+-continuous test will return an error code if its continuous test fails. The
+-operation may then be retried if the error mode has not been triggered.
+-
+-=item B<security-checks>
+-
+-This indicates if run-time checks related to enforcement of security parameters
+-such as minimum security strength of keys and approved curve names are used.
+-A value of '1' will perform the checks, otherwise if the value is '0' the checks
+-are not performed and FIPS compliance must be done by procedures documented in
+-the relevant Security Policy.
+-
+-=item B<module-mac>
+-
+-The calculated MAC of the FIPS provider file.
+-
+-=item B<install-status>
+-
+-An indicator that the self-tests were successfully run.
+-This should only be written after the module has
+-successfully passed its self tests during installation.
+-If this field is not present, then the self tests will run when the module
+-loads.
+-
+-=item B<install-mac>
+-
+-A MAC of the value of the B<install-status> option, to prevent accidental
+-changes to that value.
+-It is written-to at the same time as B<install-status> is updated.
+-
+-=back
+-
+-For example:
+-
+- [fips_sect]
+- activate = 1
+- install-version = 1
+- conditional-errors = 1
+- security-checks = 1
+- module-mac = 41:D0:FA:C2:5D:41:75:CD:7D:C3:90:55:6F:A4:DC
+- install-mac = FE:10:13:5A:D3:B4:C7:82:1B:1E:17:4C:AC:84:0C
+- install-status = INSTALL_SELF_TEST_KATS_RUN
+-
+-=head1 NOTES
+-
+-When using the FIPS provider, it is recommended that the
+-B<config_diagnostics> option is enabled to prevent accidental use of
+-non-FIPS validated algorithms via broken or mistaken configuration.
+-See L<config(5)>.
+-
+-=head1 SEE ALSO
+-
+-L<config(5)>
+-L<openssl-fipsinstall(1)>
++This command is disabled in SUSE/openSUSE. The FIPS provider is
++automatically loaded when the system is booted in FIPS mode, or when the
++environment variable B<OPENSSL_FORCE_FIPS_MODE> is set.
++See the documentation for more information.
+ 
+ =head1 HISTORY
+ 
+Index: openssl-3.1.4/doc/man7/OSSL_PROVIDER-FIPS.pod
+===================================================================
+--- openssl-3.1.4.orig/doc/man7/OSSL_PROVIDER-FIPS.pod
++++ openssl-3.1.4/doc/man7/OSSL_PROVIDER-FIPS.pod
+@@ -455,7 +455,6 @@ want to operate in a FIPS approved manne
+ 
+ =head1 SEE ALSO
+ 
+-L<openssl-fipsinstall(1)>,
+ L<fips_config(5)>,
+ L<OSSL_SELF_TEST_set_callback(3)>,
+ L<OSSL_SELF_TEST_new(3)>,
diff --git a/openssl-ec-56-bit-Limb-Solinas-Strategy-for-secp384r1.patch b/openssl-ec-56-bit-Limb-Solinas-Strategy-for-secp384r1.patch
new file mode 100644
index 0000000..3bb9496
--- /dev/null
+++ b/openssl-ec-56-bit-Limb-Solinas-Strategy-for-secp384r1.patch
@@ -0,0 +1,2159 @@
+From 01d901e470d9e035a3bd78e77b9438a4cc0da785 Mon Sep 17 00:00:00 2001
+From: Rohan McLure <rohanmclure@linux.ibm.com>
+Date: Wed, 12 Jul 2023 12:25:22 +1000
+Subject: [PATCH] ec: 56-bit Limb Solinas' Strategy for secp384r1
+
+Adopt a 56-bit redundant-limb Solinas' reduction approach for efficient
+modular multiplication in P384. This has the affect of accelerating
+digital signing by 446% and verification by 106%. The implementation
+strategy and names of methods are the same as that provided in
+ecp_nistp224 and ecp_nistp521.
+
+As in Commit 1036749883cc ("ec: Add run time code selection for p521
+field operations"), allow for run time selection of implementation for
+felem_{square,mul}, where an assembly implementation is proclaimed to
+be present when ECP_NISTP384_ASM is present.
+
+Signed-off-by: Rohan McLure <rohanmclure@linux.ibm.com>
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
+Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
+Reviewed-by: Todd Short <todd.short@me.com>
+(Merged from https://github.com/openssl/openssl/pull/21471)
+---
+ crypto/ec/build.info     |    2 
+ crypto/ec/ec_curve.c     |    4 
+ crypto/ec/ec_lib.c       |    8 
+ crypto/ec/ec_local.h     |   27 
+ crypto/ec/ecp_nistp384.c | 1988 +++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 2027 insertions(+), 2 deletions(-)
+ create mode 100644 crypto/ec/ecp_nistp384.c
+
+--- a/crypto/ec/build.info
++++ b/crypto/ec/build.info
+@@ -59,7 +59,7 @@ $COMMON=ec_lib.c ecp_smpl.c ecp_mont.c e
+         curve448/arch_32/f_impl32.c
+ 
+ IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}]
+-  $COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp521.c ecp_nistputil.c
++  $COMMON=$COMMON ecp_nistp224.c ecp_nistp256.c ecp_nistp384.c ecp_nistp521.c ecp_nistputil.c
+ ENDIF
+ 
+ SOURCE[../../libcrypto]=$COMMON ec_ameth.c ec_pmeth.c ecx_meth.c \
+--- a/crypto/ec/ec_curve.c
++++ b/crypto/ec/ec_curve.c
+@@ -2838,6 +2838,8 @@ static const ec_list_element curve_list[
+     {NID_secp384r1, &_EC_NIST_PRIME_384.h,
+ # if defined(S390X_EC_ASM)
+      EC_GFp_s390x_nistp384_method,
++# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
++     ossl_ec_GFp_nistp384_method,
+ # else
+      0,
+ # endif
+@@ -2931,6 +2933,8 @@ static const ec_list_element curve_list[
+     {NID_secp384r1, &_EC_NIST_PRIME_384.h,
+ # if defined(S390X_EC_ASM)
+      EC_GFp_s390x_nistp384_method,
++# elif !defined(OPENSSL_NO_EC_NISTP_64_GCC_128)
++     ossl_ec_GFp_nistp384_method,
+ # else
+      0,
+ # endif
+--- a/crypto/ec/ec_lib.c
++++ b/crypto/ec/ec_lib.c
+@@ -102,12 +102,16 @@ void EC_pre_comp_free(EC_GROUP *group)
+     case PCT_nistp256:
+         EC_nistp256_pre_comp_free(group->pre_comp.nistp256);
+         break;
++    case PCT_nistp384:
++        ossl_ec_nistp384_pre_comp_free(group->pre_comp.nistp384);
++        break;
+     case PCT_nistp521:
+         EC_nistp521_pre_comp_free(group->pre_comp.nistp521);
+         break;
+ #else
+     case PCT_nistp224:
+     case PCT_nistp256:
++    case PCT_nistp384:
+     case PCT_nistp521:
+         break;
+ #endif
+@@ -191,12 +195,16 @@ int EC_GROUP_copy(EC_GROUP *dest, const
+     case PCT_nistp256:
+         dest->pre_comp.nistp256 = EC_nistp256_pre_comp_dup(src->pre_comp.nistp256);
+         break;
++    case PCT_nistp384:
++        dest->pre_comp.nistp384 = ossl_ec_nistp384_pre_comp_dup(src->pre_comp.nistp384);
++        break;
+     case PCT_nistp521:
+         dest->pre_comp.nistp521 = EC_nistp521_pre_comp_dup(src->pre_comp.nistp521);
+         break;
+ #else
+     case PCT_nistp224:
+     case PCT_nistp256:
++    case PCT_nistp384:
+     case PCT_nistp521:
+         break;
+ #endif
+--- a/crypto/ec/ec_local.h
++++ b/crypto/ec/ec_local.h
+@@ -203,6 +203,7 @@ struct ec_method_st {
+  */
+ typedef struct nistp224_pre_comp_st NISTP224_PRE_COMP;
+ typedef struct nistp256_pre_comp_st NISTP256_PRE_COMP;
++typedef struct nistp384_pre_comp_st NISTP384_PRE_COMP;
+ typedef struct nistp521_pre_comp_st NISTP521_PRE_COMP;
+ typedef struct nistz256_pre_comp_st NISTZ256_PRE_COMP;
+ typedef struct ec_pre_comp_st EC_PRE_COMP;
+@@ -264,12 +265,13 @@ struct ec_group_st {
+      */
+     enum {
+         PCT_none,
+-        PCT_nistp224, PCT_nistp256, PCT_nistp521, PCT_nistz256,
++        PCT_nistp224, PCT_nistp256, PCT_nistp384, PCT_nistp521, PCT_nistz256,
+         PCT_ec
+     } pre_comp_type;
+     union {
+         NISTP224_PRE_COMP *nistp224;
+         NISTP256_PRE_COMP *nistp256;
++        NISTP384_PRE_COMP *nistp384;
+         NISTP521_PRE_COMP *nistp521;
+         NISTZ256_PRE_COMP *nistz256;
+         EC_PRE_COMP *ec;
+@@ -333,6 +335,7 @@ static ossl_inline int ec_point_is_compa
+ 
+ NISTP224_PRE_COMP *EC_nistp224_pre_comp_dup(NISTP224_PRE_COMP *);
+ NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
++NISTP384_PRE_COMP *ossl_ec_nistp384_pre_comp_dup(NISTP384_PRE_COMP *);
+ NISTP521_PRE_COMP *EC_nistp521_pre_comp_dup(NISTP521_PRE_COMP *);
+ NISTZ256_PRE_COMP *EC_nistz256_pre_comp_dup(NISTZ256_PRE_COMP *);
+ NISTP256_PRE_COMP *EC_nistp256_pre_comp_dup(NISTP256_PRE_COMP *);
+@@ -341,6 +344,7 @@ EC_PRE_COMP *EC_ec_pre_comp_dup(EC_PRE_C
+ void EC_pre_comp_free(EC_GROUP *group);
+ void EC_nistp224_pre_comp_free(NISTP224_PRE_COMP *);
+ void EC_nistp256_pre_comp_free(NISTP256_PRE_COMP *);
++void ossl_ec_nistp384_pre_comp_free(NISTP384_PRE_COMP *);
+ void EC_nistp521_pre_comp_free(NISTP521_PRE_COMP *);
+ void EC_nistz256_pre_comp_free(NISTZ256_PRE_COMP *);
+ void EC_ec_pre_comp_free(EC_PRE_COMP *);
+@@ -552,6 +556,27 @@ int ossl_ec_GFp_nistp256_points_mul(cons
+ int ossl_ec_GFp_nistp256_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
+ int ossl_ec_GFp_nistp256_have_precompute_mult(const EC_GROUP *group);
+ 
++/* method functions in ecp_nistp384.c */
++int ossl_ec_GFp_nistp384_group_init(EC_GROUP *group);
++int ossl_ec_GFp_nistp384_group_set_curve(EC_GROUP *group, const BIGNUM *p,
++                                         const BIGNUM *a, const BIGNUM *n,
++                                         BN_CTX *);
++int ossl_ec_GFp_nistp384_point_get_affine_coordinates(const EC_GROUP *group,
++                                                      const EC_POINT *point,
++                                                      BIGNUM *x, BIGNUM *y,
++                                                      BN_CTX *ctx);
++int ossl_ec_GFp_nistp384_mul(const EC_GROUP *group, EC_POINT *r,
++                             const BIGNUM *scalar, size_t num,
++                             const EC_POINT *points[], const BIGNUM *scalars[],
++                             BN_CTX *);
++int ossl_ec_GFp_nistp384_points_mul(const EC_GROUP *group, EC_POINT *r,
++                                    const BIGNUM *scalar, size_t num,
++                                    const EC_POINT *points[],
++                                    const BIGNUM *scalars[], BN_CTX *ctx);
++int ossl_ec_GFp_nistp384_precompute_mult(EC_GROUP *group, BN_CTX *ctx);
++int ossl_ec_GFp_nistp384_have_precompute_mult(const EC_GROUP *group);
++const EC_METHOD *ossl_ec_GFp_nistp384_method(void);
++
+ /* method functions in ecp_nistp521.c */
+ int ossl_ec_GFp_nistp521_group_init(EC_GROUP *group);
+ int ossl_ec_GFp_nistp521_group_set_curve(EC_GROUP *group, const BIGNUM *p,
+--- /dev/null
++++ b/crypto/ec/ecp_nistp384.c
+@@ -0,0 +1,1988 @@
++/*
++ * Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
++ *
++ * Licensed under the Apache License 2.0 (the "License").  You may not use
++ * this file except in compliance with the License.  You can obtain a copy
++ * in the file LICENSE in the source distribution or at
++ * https://www.openssl.org/source/license.html
++ */
++
++/* Copyright 2023 IBM Corp.
++ *
++ * Licensed under the Apache License, Version 2.0 (the "License");
++ *
++ * you may not use this file except in compliance with the License.
++ * You may obtain a copy of the License at
++ *
++ *     http://www.apache.org/licenses/LICENSE-2.0
++ *
++ *  Unless required by applicable law or agreed to in writing, software
++ *  distributed under the License is distributed on an "AS IS" BASIS,
++ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++ *  See the License for the specific language governing permissions and
++ *  limitations under the License.
++ */
++
++/*
++ * Designed for 56-bit limbs by Rohan McLure <rohan.mclure@linux.ibm.com>.
++ * The layout is based on that of ecp_nistp{224,521}.c, allowing even for asm
++ * acceleration of felem_{square,mul} as supported in these files.
++ */
++
++#include <openssl/e_os2.h>
++
++#include <string.h>
++#include <openssl/err.h>
++#include "ec_local.h"
++
++#include "internal/numbers.h"
++
++#ifndef INT128_MAX
++# error "Your compiler doesn't appear to support 128-bit integer types"
++#endif
++
++typedef uint8_t u8;
++typedef uint64_t u64;
++
++/*
++ * The underlying field. P384 operates over GF(2^384-2^128-2^96+2^32-1). We
++ * can serialize an element of this field into 48 bytes. We call this an
++ * felem_bytearray.
++ */
++
++typedef u8 felem_bytearray[48];
++
++/*
++ * These are the parameters of P384, taken from FIPS 186-3, section D.1.2.4.
++ * These values are big-endian.
++ */
++static const felem_bytearray nistp384_curve_params[5] = {
++  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* p */
++   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
++   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF},
++  {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /* a = -3 */
++   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
++   0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF,
++   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFC},
++  {0xB3, 0x31, 0x2F, 0xA7, 0xE2, 0x3E, 0xE7, 0xE4, 0x98, 0x8E, 0x05, 0x6B, /* b */
++   0xE3, 0xF8, 0x2D, 0x19, 0x18, 0x1D, 0x9C, 0x6E, 0xFE, 0x81, 0x41, 0x12,
++   0x03, 0x14, 0x08, 0x8F, 0x50, 0x13, 0x87, 0x5A, 0xC6, 0x56, 0x39, 0x8D,
++   0x8A, 0x2E, 0xD1, 0x9D, 0x2A, 0x85, 0xC8, 0xED, 0xD3, 0xEC, 0x2A, 0xEF},
++  {0xAA, 0x87, 0xCA, 0x22, 0xBE, 0x8B, 0x05, 0x37, 0x8E, 0xB1, 0xC7, 0x1E, /* x */
++   0xF3, 0x20, 0xAD, 0x74, 0x6E, 0x1D, 0x3B, 0x62, 0x8B, 0xA7, 0x9B, 0x98,
++   0x59, 0xF7, 0x41, 0xE0, 0x82, 0x54, 0x2A, 0x38, 0x55, 0x02, 0xF2, 0x5D,
++   0xBF, 0x55, 0x29, 0x6C, 0x3A, 0x54, 0x5E, 0x38, 0x72, 0x76, 0x0A, 0xB7},
++  {0x36, 0x17, 0xDE, 0x4A, 0x96, 0x26, 0x2C, 0x6F, 0x5D, 0x9E, 0x98, 0xBF, /* y */
++   0x92, 0x92, 0xDC, 0x29, 0xF8, 0xF4, 0x1D, 0xBD, 0x28, 0x9A, 0x14, 0x7C,
++   0xE9, 0xDA, 0x31, 0x13, 0xB5, 0xF0, 0xB8, 0xC0, 0x0A, 0x60, 0xB1, 0xCE,
++   0x1D, 0x7E, 0x81, 0x9D, 0x7A, 0x43, 0x1D, 0x7C, 0x90, 0xEA, 0x0E, 0x5F},
++};
++
++/*-
++ * The representation of field elements.
++ * ------------------------------------
++ *
++ * We represent field elements with seven values. These values are either 64 or
++ * 128 bits and the field element represented is:
++ *   v[0]*2^0 + v[1]*2^56 + v[2]*2^112 + ... + v[6]*2^336  (mod p)
++ * Each of the seven values is called a 'limb'. Since the limbs are spaced only
++ * 56 bits apart, but are greater than 56 bits in length, the most significant
++ * bits of each limb overlap with the least significant bits of the next
++ *
++ * This representation is considered to be 'redundant' in the sense that
++ * intermediate values can each contain more than a 56-bit value in each limb.
++ * Reduction causes all but the final limb to be reduced to contain a value less
++ * than 2^56, with the final value represented allowed to be larger than 2^384,
++ * inasmuch as we can be sure that arithmetic overflow remains impossible. The
++ * reduced value must of course be congruent to the unreduced value.
++ *
++ * A field element with 64-bit limbs is an 'felem'. One with 128-bit limbs is a
++ * 'widefelem', featuring enough bits to store the result of a multiplication
++ * and even some further arithmetic without need for immediate reduction.
++ */
++
++#define NLIMBS 7
++
++typedef uint64_t limb;
++typedef uint128_t widelimb;
++typedef limb limb_aX __attribute((__aligned__(1)));
++typedef limb felem[NLIMBS];
++typedef widelimb widefelem[2*NLIMBS-1];
++
++static const limb bottom56bits = 0xffffffffffffff;
++
++/* Helper functions (de)serialising reduced field elements in little endian */
++static void bin48_to_felem(felem out, const u8 in[48])
++{
++    memset(out, 0, 56);
++    out[0] = (*((limb *) & in[0])) & bottom56bits;
++    out[1] = (*((limb_aX *) & in[7])) & bottom56bits;
++    out[2] = (*((limb_aX *) & in[14])) & bottom56bits;
++    out[3] = (*((limb_aX *) & in[21])) & bottom56bits;
++    out[4] = (*((limb_aX *) & in[28])) & bottom56bits;
++    out[5] = (*((limb_aX *) & in[35])) & bottom56bits;
++    memmove(&out[6], &in[42], 6);
++}
++
++static void felem_to_bin48(u8 out[48], const felem in)
++{
++    memset(out, 0, 48);
++    (*((limb *) & out[0]))     |= (in[0] & bottom56bits);
++    (*((limb_aX *) & out[7]))  |= (in[1] & bottom56bits);
++    (*((limb_aX *) & out[14])) |= (in[2] & bottom56bits);
++    (*((limb_aX *) & out[21])) |= (in[3] & bottom56bits);
++    (*((limb_aX *) & out[28])) |= (in[4] & bottom56bits);
++    (*((limb_aX *) & out[35])) |= (in[5] & bottom56bits);
++    memmove(&out[42], &in[6], 6);
++}
++
++/* BN_to_felem converts an OpenSSL BIGNUM into an felem */
++static int BN_to_felem(felem out, const BIGNUM *bn)
++{
++    felem_bytearray b_out;
++    int num_bytes;
++
++    if (BN_is_negative(bn)) {
++        ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
++        return 0;
++    }
++    num_bytes = BN_bn2lebinpad(bn, b_out, sizeof(b_out));
++    if (num_bytes < 0) {
++        ERR_raise(ERR_LIB_EC, EC_R_BIGNUM_OUT_OF_RANGE);
++        return 0;
++    }
++    bin48_to_felem(out, b_out);
++    return 1;
++}
++
++/* felem_to_BN converts an felem into an OpenSSL BIGNUM */
++static BIGNUM *felem_to_BN(BIGNUM *out, const felem in)
++{
++    felem_bytearray b_out;
++
++    felem_to_bin48(b_out, in);
++    return BN_lebin2bn(b_out, sizeof(b_out), out);
++}
++
++/*-
++ * Field operations
++ * ----------------
++ */
++
++static void felem_one(felem out)
++{
++    out[0] = 1;
++    memset(&out[1], 0, sizeof(limb) * (NLIMBS-1));
++}
++
++static void felem_assign(felem out, const felem in)
++{
++    memcpy(out, in, sizeof(felem));
++}
++
++/* felem_sum64 sets out = out + in. */
++static void felem_sum64(felem out, const felem in)
++{
++    unsigned int i;
++
++    for (i = 0; i < NLIMBS; i++)
++        out[i] += in[i];
++}
++
++/* felem_scalar sets out = in * scalar */
++static void felem_scalar(felem out, const felem in, limb scalar)
++{
++    unsigned int i;
++
++    for (i = 0; i < NLIMBS; i++)
++        out[i] = in[i] * scalar;
++}
++
++/* felem_scalar64 sets out = out * scalar */
++static void felem_scalar64(felem out, limb scalar)
++{
++    unsigned int i;
++
++    for (i = 0; i < NLIMBS; i++)
++        out[i] *= scalar;
++}
++
++/* felem_scalar128 sets out = out * scalar */
++static void felem_scalar128(widefelem out, limb scalar)
++{
++    unsigned int i;
++
++    for (i = 0; i < 2*NLIMBS-1; i++)
++        out[i] *= scalar;
++}
++
++/*-
++ * felem_neg sets |out| to |-in|
++ * On entry:
++ *   in[i] < 2^60 - 2^29
++ * On exit:
++ *   out[i] < 2^60
++ */
++static void felem_neg(felem out, const felem in)
++{
++    /*
++     * In order to prevent underflow, we add a multiple of p before subtracting.
++     * Use telescopic sums to represent 2^12 * p redundantly with each limb
++     * of the form 2^60 + ...
++     */
++    static const limb two60m52m4 = (((limb) 1) << 60)
++                                 - (((limb) 1) << 52)
++                                 - (((limb) 1) << 4);
++    static const limb two60p44m12 = (((limb) 1) << 60)
++                                  + (((limb) 1) << 44)
++                                  - (((limb) 1) << 12);
++    static const limb two60m28m4 = (((limb) 1) << 60)
++                                 - (((limb) 1) << 28)
++                                 - (((limb) 1) << 4);
++    static const limb two60m4 = (((limb) 1) << 60)
++                              - (((limb) 1) << 4);
++
++    out[0] = two60p44m12 - in[0];
++    out[1] = two60m52m4 - in[1];
++    out[2] = two60m28m4 - in[2];
++    out[3] = two60m4 - in[3];
++    out[4] = two60m4 - in[4];
++    out[5] = two60m4 - in[5];
++    out[6] = two60m4 - in[6];
++}
++
++/*-
++ * felem_diff64 subtracts |in| from |out|
++ * On entry:
++ *   in[i] < 2^60 - 2^52 - 2^4
++ * On exit:
++ *   out[i] < out_orig[i] + 2^60 + 2^44
++ */
++static void felem_diff64(felem out, const felem in)
++{
++    /*
++     * In order to prevent underflow, we add a multiple of p before subtracting.
++     * Use telescopic sums to represent 2^12 * p redundantly with each limb
++     * of the form 2^60 + ...
++     */
++
++    static const limb two60m52m4 = (((limb) 1) << 60)
++                                 - (((limb) 1) << 52)
++                                 - (((limb) 1) << 4);
++    static const limb two60p44m12 = (((limb) 1) << 60)
++                                  + (((limb) 1) << 44)
++                                  - (((limb) 1) << 12);
++    static const limb two60m28m4 = (((limb) 1) << 60)
++                                 - (((limb) 1) << 28)
++                                 - (((limb) 1) << 4);
++    static const limb two60m4 = (((limb) 1) << 60)
++                              - (((limb) 1) << 4);
++
++    out[0] += two60p44m12 - in[0];
++    out[1] += two60m52m4 - in[1];
++    out[2] += two60m28m4 - in[2];
++    out[3] += two60m4 - in[3];
++    out[4] += two60m4 - in[4];
++    out[5] += two60m4 - in[5];
++    out[6] += two60m4 - in[6];
++}
++
++/*
++ * in[i] < 2^63
++ * out[i] < out_orig[i] + 2^64 + 2^48
++ */
++static void felem_diff_128_64(widefelem out, const felem in)
++{
++    /*
++     * In order to prevent underflow, we add a multiple of p before subtracting.
++     * Use telescopic sums to represent 2^16 * p redundantly with each limb
++     * of the form 2^64 + ...
++     */
++
++    static const widelimb two64m56m8 = (((widelimb) 1) << 64)
++                                     - (((widelimb) 1) << 56)
++                                     - (((widelimb) 1) << 8);
++    static const widelimb two64m32m8 = (((widelimb) 1) << 64)
++                                     - (((widelimb) 1) << 32)
++                                     - (((widelimb) 1) << 8);
++    static const widelimb two64m8 = (((widelimb) 1) << 64)
++                                  - (((widelimb) 1) << 8);
++    static const widelimb two64p48m16 = (((widelimb) 1) << 64)
++                                      + (((widelimb) 1) << 48)
++                                      - (((widelimb) 1) << 16);
++    unsigned int i;
++
++    out[0] += two64p48m16;
++    out[1] += two64m56m8;
++    out[2] += two64m32m8;
++    out[3] += two64m8;
++    out[4] += two64m8;
++    out[5] += two64m8;
++    out[6] += two64m8;
++
++    for (i = 0; i < NLIMBS; i++)
++        out[i] -= in[i];
++}
++
++/*
++ * in[i] < 2^127 - 2^119 - 2^71
++ * out[i] < out_orig[i] + 2^127 + 2^111
++ */
++static void felem_diff128(widefelem out, const widefelem in)
++{
++    /*
++     * In order to prevent underflow, we add a multiple of p before subtracting.
++     * Use telescopic sums to represent 2^415 * p redundantly with each limb
++     * of the form 2^127 + ...
++     */
++
++    static const widelimb two127 = ((widelimb) 1) << 127;
++    static const widelimb two127m71 = (((widelimb) 1) << 127)
++                                    - (((widelimb) 1) << 71);
++    static const widelimb two127p111m79m71 = (((widelimb) 1) << 127)
++                                           + (((widelimb) 1) << 111)
++                                           - (((widelimb) 1) << 79)
++                                           - (((widelimb) 1) << 71);
++    static const widelimb two127m119m71 = (((widelimb) 1) << 127)
++                                        - (((widelimb) 1) << 119)
++                                        - (((widelimb) 1) << 71);
++    static const widelimb two127m95m71 = (((widelimb) 1) << 127)
++                                       - (((widelimb) 1) << 95)
++                                       - (((widelimb) 1) << 71);
++    unsigned int i;
++
++    out[0]  += two127;
++    out[1]  += two127m71;
++    out[2]  += two127m71;
++    out[3]  += two127m71;
++    out[4]  += two127m71;
++    out[5]  += two127m71;
++    out[6]  += two127p111m79m71;
++    out[7]  += two127m119m71;
++    out[8]  += two127m95m71;
++    out[9]  += two127m71;
++    out[10] += two127m71;
++    out[11] += two127m71;
++    out[12] += two127m71;
++
++    for (i = 0; i < 2*NLIMBS-1; i++)
++        out[i] -= in[i];
++}
++
++static void felem_square_ref(widefelem out, const felem in)
++{
++    felem inx2;
++    felem_scalar(inx2, in, 2);
++
++    out[0] = ((uint128_t) in[0]) * in[0];
++
++    out[1] = ((uint128_t) in[0]) * inx2[1];
++
++    out[2] = ((uint128_t) in[0]) * inx2[2]
++           + ((uint128_t) in[1]) * in[1];
++
++    out[3] = ((uint128_t) in[0]) * inx2[3]
++           + ((uint128_t) in[1]) * inx2[2];
++
++    out[4] = ((uint128_t) in[0]) * inx2[4]
++           + ((uint128_t) in[1]) * inx2[3]
++           + ((uint128_t) in[2]) * in[2];
++
++    out[5] = ((uint128_t) in[0]) * inx2[5]
++           + ((uint128_t) in[1]) * inx2[4]
++           + ((uint128_t) in[2]) * inx2[3];
++
++    out[6] = ((uint128_t) in[0]) * inx2[6]
++           + ((uint128_t) in[1]) * inx2[5]
++           + ((uint128_t) in[2]) * inx2[4]
++           + ((uint128_t) in[3]) * in[3];
++
++    out[7] = ((uint128_t) in[1]) * inx2[6]
++           + ((uint128_t) in[2]) * inx2[5]
++           + ((uint128_t) in[3]) * inx2[4];
++
++    out[8] = ((uint128_t) in[2]) * inx2[6]
++           + ((uint128_t) in[3]) * inx2[5]
++           + ((uint128_t) in[4]) * in[4];
++
++    out[9] = ((uint128_t) in[3]) * inx2[6]
++           + ((uint128_t) in[4]) * inx2[5];
++
++    out[10] = ((uint128_t) in[4]) * inx2[6]
++            + ((uint128_t) in[5]) * in[5];
++
++    out[11] = ((uint128_t) in[5]) * inx2[6];
++
++    out[12] = ((uint128_t) in[6]) * in[6];
++}
++
++static void felem_mul_ref(widefelem out, const felem in1, const felem in2)
++{
++    out[0] = ((uint128_t) in1[0]) * in2[0];
++
++    out[1] = ((uint128_t) in1[0]) * in2[1]
++           + ((uint128_t) in1[1]) * in2[0];
++
++    out[2] = ((uint128_t) in1[0]) * in2[2]
++           + ((uint128_t) in1[1]) * in2[1]
++           + ((uint128_t) in1[2]) * in2[0];
++
++    out[3] = ((uint128_t) in1[0]) * in2[3]
++           + ((uint128_t) in1[1]) * in2[2]
++           + ((uint128_t) in1[2]) * in2[1]
++           + ((uint128_t) in1[3]) * in2[0];
++
++    out[4] = ((uint128_t) in1[0]) * in2[4]
++           + ((uint128_t) in1[1]) * in2[3]
++           + ((uint128_t) in1[2]) * in2[2]
++           + ((uint128_t) in1[3]) * in2[1]
++           + ((uint128_t) in1[4]) * in2[0];
++
++    out[5] = ((uint128_t) in1[0]) * in2[5]
++           + ((uint128_t) in1[1]) * in2[4]
++           + ((uint128_t) in1[2]) * in2[3]
++           + ((uint128_t) in1[3]) * in2[2]
++           + ((uint128_t) in1[4]) * in2[1]
++           + ((uint128_t) in1[5]) * in2[0];
++
++    out[6] = ((uint128_t) in1[0]) * in2[6]
++           + ((uint128_t) in1[1]) * in2[5]
++           + ((uint128_t) in1[2]) * in2[4]
++           + ((uint128_t) in1[3]) * in2[3]
++           + ((uint128_t) in1[4]) * in2[2]
++           + ((uint128_t) in1[5]) * in2[1]
++           + ((uint128_t) in1[6]) * in2[0];
++
++    out[7] = ((uint128_t) in1[1]) * in2[6]
++           + ((uint128_t) in1[2]) * in2[5]
++           + ((uint128_t) in1[3]) * in2[4]
++           + ((uint128_t) in1[4]) * in2[3]
++           + ((uint128_t) in1[5]) * in2[2]
++           + ((uint128_t) in1[6]) * in2[1];
++
++    out[8] = ((uint128_t) in1[2]) * in2[6]
++           + ((uint128_t) in1[3]) * in2[5]
++           + ((uint128_t) in1[4]) * in2[4]
++           + ((uint128_t) in1[5]) * in2[3]
++           + ((uint128_t) in1[6]) * in2[2];
++
++    out[9] = ((uint128_t) in1[3]) * in2[6]
++           + ((uint128_t) in1[4]) * in2[5]
++           + ((uint128_t) in1[5]) * in2[4]
++           + ((uint128_t) in1[6]) * in2[3];
++
++    out[10] = ((uint128_t) in1[4]) * in2[6]
++            + ((uint128_t) in1[5]) * in2[5]
++            + ((uint128_t) in1[6]) * in2[4];
++
++    out[11] = ((uint128_t) in1[5]) * in2[6]
++            + ((uint128_t) in1[6]) * in2[5];
++
++    out[12] = ((uint128_t) in1[6]) * in2[6];
++}
++
++/*-
++ * Reduce thirteen 128-bit coefficients to seven 64-bit coefficients.
++ * in[i] < 2^128 - 2^125
++ * out[i] < 2^56 for i < 6,
++ * out[6] <= 2^48
++ *
++ * The technique in use here stems from the format of the prime modulus:
++ * P384 = 2^384 - delta
++ *
++ * Thus we can reduce numbers of the form (X + 2^384 * Y) by substituting
++ * them with (X + delta Y), with delta = 2^128 + 2^96 + (-2^32 + 1). These
++ * coefficients are still quite large, and so we repeatedly apply this
++ * technique on high-order bits in order to guarantee the desired bounds on
++ * the size of our output.
++ *
++ * The three phases of elimination are as follows:
++ * [1]: Y = 2^120 (in[12] | in[11] | in[10] | in[9])
++ * [2]: Y = 2^8 (acc[8] | acc[7])
++ * [3]: Y = 2^48 (acc[6] >> 48)
++ * (Where a | b | c | d = (2^56)^3 a + (2^56)^2 b + (2^56) c + d)
++ */
++static void felem_reduce(felem out, const widefelem in)
++{
++    /*
++     * In order to prevent underflow, we add a multiple of p before subtracting.
++     * Use telescopic sums to represent 2^76 * p redundantly with each limb
++     * of the form 2^124 + ...
++     */
++    static const widelimb two124m68 = (((widelimb) 1) << 124)
++                                    - (((widelimb) 1) << 68);
++    static const widelimb two124m116m68 = (((widelimb) 1) << 124)
++                                        - (((widelimb) 1) << 116)
++                                        - (((widelimb) 1) << 68);
++    static const widelimb two124p108m76 = (((widelimb) 1) << 124)
++                                        + (((widelimb) 1) << 108)
++                                        - (((widelimb) 1) << 76);
++    static const widelimb two124m92m68 = (((widelimb) 1) << 124)
++                                       - (((widelimb) 1) << 92)
++                                       - (((widelimb) 1) << 68);
++    widelimb temp, acc[9];
++    unsigned int i;
++
++    memcpy(acc, in, sizeof(widelimb) * 9);
++
++    acc[0] += two124p108m76;
++    acc[1] += two124m116m68;
++    acc[2] += two124m92m68;
++    acc[3] += two124m68;
++    acc[4] += two124m68;
++    acc[5] += two124m68;
++    acc[6] += two124m68;
++
++    /* [1]: Eliminate in[9], ..., in[12] */
++    acc[8] += in[12] >> 32;
++    acc[7] += (in[12] & 0xffffffff) << 24;
++    acc[7] += in[12] >> 8;
++    acc[6] += (in[12] & 0xff) << 48;
++    acc[6] -= in[12] >> 16;
++    acc[5] -= ((in[12] & 0xffff) << 40);
++    acc[6] += in[12] >> 48;
++    acc[5] += (in[12] & 0xffffffffffff) << 8;
++
++    acc[7] += in[11] >> 32;
++    acc[6] += (in[11] & 0xffffffff) << 24;
++    acc[6] += in[11] >> 8;
++    acc[5] += (in[11] & 0xff) << 48;
++    acc[5] -= in[11] >> 16;
++    acc[4] -= ((in[11] & 0xffff) << 40);
++    acc[5] += in[11] >> 48;
++    acc[4] += (in[11] & 0xffffffffffff) << 8;
++
++    acc[6] += in[10] >> 32;
++    acc[5] += (in[10] & 0xffffffff) << 24;
++    acc[5] += in[10] >> 8;
++    acc[4] += (in[10] & 0xff) << 48;
++    acc[4] -= in[10] >> 16;
++    acc[3] -= ((in[10] & 0xffff) << 40);
++    acc[4] += in[10] >> 48;
++    acc[3] += (in[10] & 0xffffffffffff) << 8;
++
++    acc[5] += in[9] >> 32;
++    acc[4] += (in[9] & 0xffffffff) << 24;
++    acc[4] += in[9] >> 8;
++    acc[3] += (in[9] & 0xff) << 48;
++    acc[3] -= in[9] >> 16;
++    acc[2] -= ((in[9] & 0xffff) << 40);
++    acc[3] += in[9] >> 48;
++    acc[2] += (in[9] & 0xffffffffffff) << 8;
++
++    /*
++     * [2]: Eliminate acc[7], acc[8], that is the 7 and eighth limbs, as
++     * well as the contributions made from eliminating higher limbs.
++     * acc[7] < in[7] + 2^120 + 2^56 < in[7] + 2^121
++     * acc[8] < in[8] + 2^96
++     */
++    acc[4] += acc[8] >> 32;
++    acc[3] += (acc[8] & 0xffffffff) << 24;
++    acc[3] += acc[8] >> 8;
++    acc[2] += (acc[8] & 0xff) << 48;
++    acc[2] -= acc[8] >> 16;
++    acc[1] -= ((acc[8] & 0xffff) << 40);
++    acc[2] += acc[8] >> 48;
++    acc[1] += (acc[8] & 0xffffffffffff) << 8;
++
++    acc[3] += acc[7] >> 32;
++    acc[2] += (acc[7] & 0xffffffff) << 24;
++    acc[2] += acc[7] >> 8;
++    acc[1] += (acc[7] & 0xff) << 48;
++    acc[1] -= acc[7] >> 16;
++    acc[0] -= ((acc[7] & 0xffff) << 40);
++    acc[1] += acc[7] >> 48;
++    acc[0] += (acc[7] & 0xffffffffffff) << 8;
++
++    /*-
++     * acc[k] < in[k] + 2^124 + 2^121 
++     *        < in[k] + 2^125
++     *        < 2^128, for k <= 6
++     */
++
++    /*
++     * Carry 4 -> 5 -> 6
++     * This has the effect of ensuring that these more significant limbs
++     * will be small in value after eliminating high bits from acc[6].
++     */
++    acc[5] += acc[4] >> 56;
++    acc[4] &= 0x00ffffffffffffff;
++
++    acc[6] += acc[5] >> 56;
++    acc[5] &= 0x00ffffffffffffff;
++
++    /*-
++     * acc[6] < in[6] + 2^124 + 2^121 + 2^72 + 2^16
++     *        < in[6] + 2^125
++     *        < 2^128
++     */
++
++    /* [3]: Eliminate high bits of acc[6] */
++    temp = acc[6] >> 48;
++    acc[6] &= 0x0000ffffffffffff;
++    
++    /* temp < 2^80 */
++
++    acc[3] += temp >> 40;
++    acc[2] += (temp & 0xffffffffff) << 16;
++    acc[2] += temp >> 16;
++    acc[1] += (temp & 0xffff) << 40;
++    acc[1] -= temp >> 24;
++    acc[0] -= (temp & 0xffffff) << 32;
++    acc[0] += temp;
++
++    /*-
++     * acc[k] < acc_old[k] + 2^64 + 2^56
++     *        < in[k] + 2^124 + 2^121 + 2^72 + 2^64 + 2^56 + 2^16 , k < 4
++     */
++
++    /* Carry 0 -> 1 -> 2 -> 3 -> 4 -> 5 -> 6 */
++    acc[1] += acc[0] >> 56;   /* acc[1] < acc_old[1] + 2^72 */
++    acc[0] &= 0x00ffffffffffffff;
++
++    acc[2] += acc[1] >> 56;   /* acc[2] < acc_old[2] + 2^72 + 2^16 */
++    acc[1] &= 0x00ffffffffffffff;
++
++    acc[3] += acc[2] >> 56;   /* acc[3] < acc_old[3] + 2^72 + 2^16 */
++    acc[2] &= 0x00ffffffffffffff;
++
++    /*-
++     * acc[k] < acc_old[k] + 2^72 + 2^16
++     *        < in[k] + 2^124 + 2^121 + 2^73 + 2^64 + 2^56 + 2^17
++     *        < in[k] + 2^125
++     *        < 2^128 , k < 4
++     */
++
++    acc[4] += acc[3] >> 56;   /*-
++                               * acc[4] < acc_old[4] + 2^72 + 2^16
++                               *        < 2^72 + 2^56 + 2^16
++                               */
++    acc[3] &= 0x00ffffffffffffff;
++
++    acc[5] += acc[4] >> 56;   /*-
++                               * acc[5] < acc_old[5] + 2^16 + 1
++                               *        < 2^56 + 2^16 + 1
++                               */
++    acc[4] &= 0x00ffffffffffffff;
++
++    acc[6] += acc[5] >> 56;   /* acc[6] < 2^48 + 1 <= 2^48 */
++    acc[5] &= 0x00ffffffffffffff;
++
++    for (i = 0; i < NLIMBS; i++)
++        out[i] = acc[i];
++}
++
++#if defined(ECP_NISTP384_ASM)
++static void felem_square_wrapper(widefelem out, const felem in);
++static void felem_mul_wrapper(widefelem out, const felem in1, const felem in2);
++
++static void (*felem_square_p)(widefelem out, const felem in) =
++    felem_square_wrapper;
++static void (*felem_mul_p)(widefelem out, const felem in1, const felem in2) =
++    felem_mul_wrapper;
++
++void p384_felem_square(widefelem out, const felem in);
++void p384_felem_mul(widefelem out, const felem in1, const felem in2);
++
++# if defined(_ARCH_PPC64)
++#  include "crypto/ppc_arch.h"
++# endif
++
++static void felem_select(void)
++{
++    /* Default */
++    felem_square_p = felem_square_ref;
++    felem_mul_p = felem_mul_ref;
++}
++
++static void felem_square_wrapper(widefelem out, const felem in)
++{
++    felem_select();
++    felem_square_p(out, in);
++}
++
++static void felem_mul_wrapper(widefelem out, const felem in1, const felem in2)
++{
++    felem_select();
++    felem_mul_p(out, in1, in2);
++}
++
++# define felem_square felem_square_p
++# define felem_mul felem_mul_p
++#else
++# define felem_square felem_square_ref
++# define felem_mul felem_mul_ref
++#endif
++
++static ossl_inline void felem_square_reduce(felem out, const felem in)
++{
++    widefelem tmp;
++
++    felem_square(tmp, in);
++    felem_reduce(out, tmp);
++}
++
++static ossl_inline void felem_mul_reduce(felem out, const felem in1, const felem in2)
++{
++    widefelem tmp;
++
++    felem_mul(tmp, in1, in2);
++    felem_reduce(out, tmp);
++}
++
++/*-
++ * felem_inv calculates |out| = |in|^{-1}
++ *
++ * Based on Fermat's Little Theorem:
++ *   a^p = a (mod p)
++ *   a^{p-1} = 1 (mod p)
++ *   a^{p-2} = a^{-1} (mod p)
++ */
++static void felem_inv(felem out, const felem in)
++{
++    felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6;
++    unsigned int i = 0;
++
++    felem_square_reduce(ftmp, in);      /* 2^1 */
++    felem_mul_reduce(ftmp, ftmp, in);   /* 2^1 + 2^0 */
++    felem_assign(ftmp2, ftmp);
++
++    felem_square_reduce(ftmp, ftmp);    /* 2^2 + 2^1 */
++    felem_mul_reduce(ftmp, ftmp, in);   /* 2^2 + 2^1 * 2^0 */
++    felem_assign(ftmp3, ftmp);
++
++    for (i = 0; i < 3; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^5 + 2^4 + 2^3 */
++    felem_mul_reduce(ftmp, ftmp3, ftmp); /* 2^5 + 2^4 + 2^3 + 2^2 + 2^1 + 2^0 */
++    felem_assign(ftmp4, ftmp);
++
++    for (i = 0; i < 6; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^11 + ... + 2^6 */
++    felem_mul_reduce(ftmp, ftmp4, ftmp); /* 2^11 + ... + 2^0 */
++
++    for (i = 0; i < 3; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^14 + ... + 2^3 */
++    felem_mul_reduce(ftmp, ftmp3, ftmp); /* 2^14 + ... + 2^0 */
++    felem_assign(ftmp5, ftmp);
++
++    for (i = 0; i < 15; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^29 + ... + 2^15 */
++    felem_mul_reduce(ftmp, ftmp5, ftmp); /* 2^29 + ... + 2^0 */
++    felem_assign(ftmp6, ftmp);
++
++    for (i = 0; i < 30; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^59 + ... + 2^30 */
++    felem_mul_reduce(ftmp, ftmp6, ftmp); /* 2^59 + ... + 2^0 */
++    felem_assign(ftmp4, ftmp);
++
++    for (i = 0; i < 60; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^119 + ... + 2^60 */
++    felem_mul_reduce(ftmp, ftmp4, ftmp); /* 2^119 + ... + 2^0 */
++    felem_assign(ftmp4, ftmp);
++
++    for (i = 0; i < 120; i++)
++      felem_square_reduce(ftmp, ftmp);   /* 2^239 + ... + 2^120 */
++    felem_mul_reduce(ftmp, ftmp4, ftmp); /* 2^239 + ... + 2^0 */
++
++    for (i = 0; i < 15; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^254 + ... + 2^15 */
++    felem_mul_reduce(ftmp, ftmp5, ftmp); /* 2^254 + ... + 2^0 */
++
++    for (i = 0; i < 31; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^285 + ... + 2^31 */
++    felem_mul_reduce(ftmp, ftmp6, ftmp); /* 2^285 + ... + 2^31 + 2^29 + ... + 2^0 */
++
++    for (i = 0; i < 2; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^287 + ... + 2^33 + 2^31 + ... + 2^2 */
++    felem_mul_reduce(ftmp, ftmp2, ftmp); /* 2^287 + ... + 2^33 + 2^31 + ... + 2^0 */
++
++    for (i = 0; i < 94; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^381 + ... + 2^127 + 2^125 + ... + 2^94 */
++    felem_mul_reduce(ftmp, ftmp6, ftmp); /* 2^381 + ... + 2^127 + 2^125 + ... + 2^94 + 2^29 + ... + 2^0 */
++
++    for (i = 0; i < 2; i++)
++        felem_square_reduce(ftmp, ftmp); /* 2^383 + ... + 2^129 + 2^127 + ... + 2^96 + 2^31 + ... + 2^2 */
++    felem_mul_reduce(ftmp, in, ftmp);    /* 2^383 + ... + 2^129 + 2^127 + ... + 2^96 + 2^31 + ... + 2^2 + 2^0 */
++
++    memcpy(out, ftmp, sizeof(felem));
++}
++
++/*
++ * Zero-check: returns a limb with all bits set if |in| == 0 (mod p)
++ * and 0 otherwise. We know that field elements are reduced to
++ * 0 < in < 2p, so we only need to check two cases:
++ * 0 and 2^384 - 2^128 - 2^96 + 2^32 - 1
++ *   in[k] < 2^56, k < 6
++ *   in[6] <= 2^48
++ */
++static limb felem_is_zero(const felem in)
++{
++    limb zero, p384;
++
++    zero = in[0] | in[1] | in[2] | in[3] | in[4] | in[5] | in[6];
++    zero = ((int64_t) (zero) - 1) >> 63;
++    p384 = (in[0] ^ 0x000000ffffffff) | (in[1] ^ 0xffff0000000000)
++         | (in[2] ^ 0xfffffffffeffff) | (in[3] ^ 0xffffffffffffff)
++         | (in[4] ^ 0xffffffffffffff) | (in[5] ^ 0xffffffffffffff)
++         | (in[6] ^ 0xffffffffffff);
++    p384 = ((int64_t) (p384) - 1) >> 63;
++
++    return (zero | p384);
++}
++
++static int felem_is_zero_int(const void *in)
++{
++    return (int)(felem_is_zero(in) & ((limb) 1));
++}
++
++/*-
++ * felem_contract converts |in| to its unique, minimal representation.
++ * Assume we've removed all redundant bits.
++ * On entry:
++ *   in[k] < 2^56, k < 6
++ *   in[6] <= 2^48
++ */
++static void felem_contract(felem out, const felem in)
++{
++    static const int64_t two56 = ((limb) 1) << 56;
++
++    /*
++     * We know for a fact that 0 <= |in| < 2*p, for p = 2^384 - 2^128 - 2^96 + 2^32 - 1
++     * Perform two successive, idempotent subtractions to reduce if |in| >= p.
++     */
++
++    int64_t tmp[NLIMBS], cond[5], a;
++    unsigned int i;
++
++    memcpy(tmp, in, sizeof(felem));
++ 
++    /* Case 1: a = 1 iff |in| >= 2^384 */
++    a = (in[6] >> 48);
++    tmp[0] += a;
++    tmp[0] -= a << 32;
++    tmp[1] += a << 40;
++    tmp[2] += a << 16;
++    tmp[6] &= 0x0000ffffffffffff;
++
++    /*
++     * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be
++     * non-zero, so we only need one step
++     */
++
++    a = tmp[0] >> 63;
++    tmp[0] += a & two56;
++    tmp[1] -= a & 1;
++
++    /* Carry 1 -> 2 -> 3 -> 4 -> 5 -> 6 */
++    tmp[2] += tmp[1] >> 56;
++    tmp[1] &= 0x00ffffffffffffff;
++
++    tmp[3] += tmp[2] >> 56;
++    tmp[2] &= 0x00ffffffffffffff;
++
++    tmp[4] += tmp[3] >> 56;
++    tmp[3] &= 0x00ffffffffffffff;
++
++    tmp[5] += tmp[4] >> 56;
++    tmp[4] &= 0x00ffffffffffffff;
++
++    tmp[6] += tmp[5] >> 56; /* tmp[6] < 2^48 */
++    tmp[5] &= 0x00ffffffffffffff;
++
++    /*
++     * Case 2: a = all ones if p <= |in| < 2^384, 0 otherwise
++     */
++
++    /* 0 iff (2^129..2^383) are all one */
++    cond[0] = ((tmp[6] | 0xff000000000000) & tmp[5] & tmp[4] & tmp[3] & (tmp[2] | 0x0000000001ffff)) + 1;
++    /* 0 iff 2^128 bit is one */
++    cond[1] = (tmp[2] | ~0x00000000010000) + 1;
++    /* 0 iff (2^96..2^127) bits are all one */
++    cond[2] = ((tmp[2] | 0xffffffffff0000) & (tmp[1] | 0x0000ffffffffff)) + 1;
++    /* 0 iff (2^32..2^95) bits are all zero */
++    cond[3] = (tmp[1] & ~0xffff0000000000) | (tmp[0] & ~((int64_t) 0x000000ffffffff));
++    /* 0 iff (2^0..2^31) bits are all one */
++    cond[4] = (tmp[0] | 0xffffff00000000) + 1;
++
++    /*
++     * In effect, invert our conditions, so that 0 values become all 1's,
++     * any non-zero value in the low-order 56 bits becomes all 0's
++     */
++    for (i = 0; i < 5; i++)
++       cond[i] = ((cond[i] & 0x00ffffffffffffff) - 1) >> 63;
++
++    /*
++     * The condition for determining whether in is greater than our
++     * prime is given by the following condition.
++     */
++
++    /* First subtract 2^384 - 2^129 cheaply */
++    a = cond[0] & (cond[1] | (cond[2] & (~cond[3] | cond[4])));
++    tmp[6] &= ~a;
++    tmp[5] &= ~a;
++    tmp[4] &= ~a;
++    tmp[3] &= ~a;
++    tmp[2] &= ~a | 0x0000000001ffff;
++
++    /*
++     * Subtract 2^128 - 2^96 by
++     * means of disjoint cases.
++     */
++
++    /* subtract 2^128 if that bit is present, and add 2^96 */
++    a = cond[0] & cond[1];
++    tmp[2] &= ~a | 0xfffffffffeffff;
++    tmp[1] += a & ((int64_t) 1 << 40);
++
++    /* otherwise, clear bits 2^127 .. 2^96  */
++    a = cond[0] & ~cond[1] & (cond[2] & (~cond[3] | cond[4]));
++    tmp[2] &= ~a | 0xffffffffff0000;
++    tmp[1] &= ~a | 0x0000ffffffffff;
++
++    /* finally, subtract the last 2^32 - 1 */
++    a = cond[0] & (cond[1] | (cond[2] & (~cond[3] | cond[4])));
++    tmp[0] += a & (-((int64_t) 1 << 32) + 1);
++
++    /*
++     * eliminate negative coefficients: if tmp[0] is negative, tmp[1] must be
++     * non-zero, so we only need one step
++     */
++    a = tmp[0] >> 63;
++    tmp[0] += a & two56;
++    tmp[1] -= a & 1;
++
++    /* Carry 1 -> 2 -> 3 -> 4 -> 5 -> 6 */
++    tmp[2] += tmp[1] >> 56;
++    tmp[1] &= 0x00ffffffffffffff;
++
++    tmp[3] += tmp[2] >> 56;
++    tmp[2] &= 0x00ffffffffffffff;
++
++    tmp[4] += tmp[3] >> 56;
++    tmp[3] &= 0x00ffffffffffffff;
++
++    tmp[5] += tmp[4] >> 56;
++    tmp[4] &= 0x00ffffffffffffff;
++
++    tmp[6] += tmp[5] >> 56;
++    tmp[5] &= 0x00ffffffffffffff;
++
++    memcpy(out, tmp, sizeof(felem));
++}
++
++/*-
++ * Group operations
++ * ----------------
++ *
++ * Building on top of the field operations we have the operations on the
++ * elliptic curve group itself. Points on the curve are represented in Jacobian
++ * coordinates
++ */
++
++/*-
++ * point_double calculates 2*(x_in, y_in, z_in)
++ *
++ * The method is taken from:
++ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#doubling-dbl-2001-b
++ *
++ * Outputs can equal corresponding inputs, i.e., x_out == x_in is allowed.
++ * while x_out == y_in is not (maybe this works, but it's not tested).
++ */
++static void
++point_double(felem x_out, felem y_out, felem z_out,
++             const felem x_in, const felem y_in, const felem z_in)
++{
++    widefelem tmp, tmp2;
++    felem delta, gamma, beta, alpha, ftmp, ftmp2;
++
++    felem_assign(ftmp, x_in);
++    felem_assign(ftmp2, x_in);
++
++    /* delta = z^2 */
++    felem_square_reduce(delta, z_in);     /* delta[i] < 2^56 */
++
++    /* gamma = y^2 */
++    felem_square_reduce(gamma, y_in);     /* gamma[i] < 2^56 */
++
++    /* beta = x*gamma */
++    felem_mul_reduce(beta, x_in, gamma);  /* beta[i] < 2^56 */
++
++    /* alpha = 3*(x-delta)*(x+delta) */
++    felem_diff64(ftmp, delta);            /* ftmp[i] < 2^60 + 2^58 + 2^44 */
++    felem_sum64(ftmp2, delta);            /* ftmp2[i] < 2^59 */
++    felem_scalar64(ftmp2, 3);             /* ftmp2[i] < 2^61 */
++    felem_mul_reduce(alpha, ftmp, ftmp2); /* alpha[i] < 2^56 */
++
++    /* x' = alpha^2 - 8*beta */
++    felem_square(tmp, alpha);             /* tmp[i] < 2^115 */
++    felem_assign(ftmp, beta);             /* ftmp[i] < 2^56 */
++    felem_scalar64(ftmp, 8);              /* ftmp[i] < 2^59 */
++    felem_diff_128_64(tmp, ftmp);         /* tmp[i] < 2^115 + 2^64 + 2^48 */
++    felem_reduce(x_out, tmp);             /* x_out[i] < 2^56 */
++
++    /* z' = (y + z)^2 - gamma - delta */
++    felem_sum64(delta, gamma);     /* delta[i] < 2^57 */
++    felem_assign(ftmp, y_in);      /* ftmp[i] < 2^56 */
++    felem_sum64(ftmp, z_in);       /* ftmp[i] < 2^56 */
++    felem_square(tmp, ftmp);       /* tmp[i] < 2^115 */
++    felem_diff_128_64(tmp, delta); /* tmp[i] < 2^115 + 2^64 + 2^48 */
++    felem_reduce(z_out, tmp);      /* z_out[i] < 2^56 */
++
++    /* y' = alpha*(4*beta - x') - 8*gamma^2 */
++    felem_scalar64(beta, 4);       /* beta[i] < 2^58 */
++    felem_diff64(beta, x_out);     /* beta[i] < 2^60 + 2^58 + 2^44 */
++    felem_mul(tmp, alpha, beta);   /* tmp[i] < 2^119 */
++    felem_square(tmp2, gamma);     /* tmp2[i] < 2^115 */
++    felem_scalar128(tmp2, 8);      /* tmp2[i] < 2^118 */
++    felem_diff128(tmp, tmp2);      /* tmp[i] < 2^127 + 2^119 + 2^111 */
++    felem_reduce(y_out, tmp);      /* tmp[i] < 2^56 */
++}
++
++/* copy_conditional copies in to out iff mask is all ones. */
++static void copy_conditional(felem out, const felem in, limb mask)
++{
++    unsigned int i;
++
++    for (i = 0; i < NLIMBS; i++)
++        out[i] ^= mask & (in[i] ^ out[i]);
++}
++
++/*-
++ * point_add calculates (x1, y1, z1) + (x2, y2, z2)
++ *
++ * The method is taken from
++ *   http://hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-3.html#addition-add-2007-bl,
++ * adapted for mixed addition (z2 = 1, or z2 = 0 for the point at infinity).
++ *
++ * This function includes a branch for checking whether the two input points
++ * are equal (while not equal to the point at infinity). See comment below
++ * on constant-time.
++ */
++static void point_add(felem x3, felem y3, felem z3,
++                      const felem x1, const felem y1, const felem z1,
++                      const int mixed, const felem x2, const felem y2,
++                      const felem z2)
++{
++    felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, ftmp6, x_out, y_out, z_out;
++    widefelem tmp, tmp2;
++    limb x_equal, y_equal, z1_is_zero, z2_is_zero;
++    limb points_equal;
++
++    z1_is_zero = felem_is_zero(z1);
++    z2_is_zero = felem_is_zero(z2);
++
++    /* ftmp = z1z1 = z1**2 */
++    felem_square_reduce(ftmp, z1);      /* ftmp[i] < 2^56 */
++
++    if (!mixed) {
++        /* ftmp2 = z2z2 = z2**2 */
++        felem_square_reduce(ftmp2, z2); /* ftmp2[i] < 2^56 */
++
++        /* u1 = ftmp3 = x1*z2z2 */
++        felem_mul_reduce(ftmp3, x1, ftmp2); /* ftmp3[i] < 2^56 */
++
++        /* ftmp5 = z1 + z2 */
++        felem_assign(ftmp5, z1);       /* ftmp5[i] < 2^56 */
++        felem_sum64(ftmp5, z2);        /* ftmp5[i] < 2^57 */
++
++        /* ftmp5 = (z1 + z2)**2 - z1z1 - z2z2 = 2*z1z2 */
++        felem_square(tmp, ftmp5);      /* tmp[i] < 2^117 */
++        felem_diff_128_64(tmp, ftmp);  /* tmp[i] < 2^117 + 2^64 + 2^48 */
++        felem_diff_128_64(tmp, ftmp2); /* tmp[i] < 2^117 + 2^65 + 2^49 */
++        felem_reduce(ftmp5, tmp);      /* ftmp5[i] < 2^56 */
++
++        /* ftmp2 = z2 * z2z2 */
++        felem_mul_reduce(ftmp2, ftmp2, z2); /* ftmp2[i] < 2^56 */
++
++        /* s1 = ftmp6 = y1 * z2**3 */
++        felem_mul_reduce(ftmp6, y1, ftmp2); /* ftmp6[i] < 2^56 */
++    } else {
++        /*
++         * We'll assume z2 = 1 (special case z2 = 0 is handled later)
++         */
++
++        /* u1 = ftmp3 = x1*z2z2 */
++        felem_assign(ftmp3, x1);     /* ftmp3[i] < 2^56 */
++
++        /* ftmp5 = 2*z1z2 */
++        felem_scalar(ftmp5, z1, 2);  /* ftmp5[i] < 2^57 */
++
++        /* s1 = ftmp6 = y1 * z2**3 */
++        felem_assign(ftmp6, y1);     /* ftmp6[i] < 2^56 */
++    }
++    /* ftmp3[i] < 2^56, ftmp5[i] < 2^57, ftmp6[i] < 2^56 */
++
++    /* u2 = x2*z1z1 */
++    felem_mul(tmp, x2, ftmp);        /* tmp[i] < 2^115 */
++
++    /* h = ftmp4 = u2 - u1 */
++    felem_diff_128_64(tmp, ftmp3);   /* tmp[i] < 2^115 + 2^64 + 2^48 */
++    felem_reduce(ftmp4, tmp);        /* ftmp[4] < 2^56 */
++
++    x_equal = felem_is_zero(ftmp4);
++
++    /* z_out = ftmp5 * h */
++    felem_mul_reduce(z_out, ftmp5, ftmp4);  /* z_out[i] < 2^56 */
++
++    /* ftmp = z1 * z1z1 */
++    felem_mul_reduce(ftmp, ftmp, z1);  /* ftmp[i] < 2^56 */
++
++    /* s2 = tmp = y2 * z1**3 */
++    felem_mul(tmp, y2, ftmp);      /* tmp[i] < 2^115 */
++
++    /* r = ftmp5 = (s2 - s1)*2 */
++    felem_diff_128_64(tmp, ftmp6); /* tmp[i] < 2^115 + 2^64 + 2^48 */
++    felem_reduce(ftmp5, tmp);      /* ftmp5[i] < 2^56 */
++    y_equal = felem_is_zero(ftmp5);
++    felem_scalar64(ftmp5, 2);      /* ftmp5[i] < 2^57 */
++
++    /*
++     * The formulae are incorrect if the points are equal, in affine coordinates
++     * (X_1, Y_1) == (X_2, Y_2), so we check for this and do doubling if this
++     * happens.
++     *
++     * We use bitwise operations to avoid potential side-channels introduced by
++     * the short-circuiting behaviour of boolean operators.
++     *
++     * The special case of either point being the point at infinity (z1 and/or
++     * z2 are zero), is handled separately later on in this function, so we
++     * avoid jumping to point_double here in those special cases.
++     *
++     * Notice the comment below on the implications of this branching for timing
++     * leaks and why it is considered practically irrelevant.
++     */
++    points_equal = (x_equal & y_equal & (~z1_is_zero) & (~z2_is_zero));
++
++    if (points_equal) {
++        /*
++         * This is obviously not constant-time but it will almost-never happen
++         * for ECDH / ECDSA.
++         */
++        point_double(x3, y3, z3, x1, y1, z1);
++        return;
++    }
++
++    /* I = ftmp = (2h)**2 */
++    felem_assign(ftmp, ftmp4);        /* ftmp[i] < 2^56 */
++    felem_scalar64(ftmp, 2);          /* ftmp[i] < 2^57 */
++    felem_square_reduce(ftmp, ftmp);  /* ftmp[i] < 2^56 */
++
++    /* J = ftmp2 = h * I */
++    felem_mul_reduce(ftmp2, ftmp4, ftmp); /* ftmp2[i] < 2^56 */
++
++    /* V = ftmp4 = U1 * I */
++    felem_mul_reduce(ftmp4, ftmp3, ftmp); /* ftmp4[i] < 2^56 */
++
++    /* x_out = r**2 - J - 2V */
++    felem_square(tmp, ftmp5);      /* tmp[i] < 2^117 */
++    felem_diff_128_64(tmp, ftmp2); /* tmp[i] < 2^117 + 2^64 + 2^48 */
++    felem_assign(ftmp3, ftmp4);    /* ftmp3[i] < 2^56 */
++    felem_scalar64(ftmp4, 2);      /* ftmp4[i] < 2^57 */
++    felem_diff_128_64(tmp, ftmp4); /* tmp[i] < 2^117 + 2^65 + 2^49 */
++    felem_reduce(x_out, tmp);      /* x_out[i] < 2^56 */
++
++    /* y_out = r(V-x_out) - 2 * s1 * J */
++    felem_diff64(ftmp3, x_out);    /* ftmp3[i] < 2^60 + 2^56 + 2^44 */
++    felem_mul(tmp, ftmp5, ftmp3);  /* tmp[i] < 2^116 */
++    felem_mul(tmp2, ftmp6, ftmp2); /* tmp2[i] < 2^115 */
++    felem_scalar128(tmp2, 2);      /* tmp2[i] < 2^116 */
++    felem_diff128(tmp, tmp2);      /* tmp[i] < 2^127 + 2^116 + 2^111 */
++    felem_reduce(y_out, tmp);      /* y_out[i] < 2^56 */
++
++    copy_conditional(x_out, x2, z1_is_zero);
++    copy_conditional(x_out, x1, z2_is_zero);
++    copy_conditional(y_out, y2, z1_is_zero);
++    copy_conditional(y_out, y1, z2_is_zero);
++    copy_conditional(z_out, z2, z1_is_zero);
++    copy_conditional(z_out, z1, z2_is_zero);
++    felem_assign(x3, x_out);
++    felem_assign(y3, y_out);
++    felem_assign(z3, z_out);
++}
++
++/*-
++ * Base point pre computation
++ * --------------------------
++ *
++ * Two different sorts of precomputed tables are used in the following code.
++ * Each contain various points on the curve, where each point is three field
++ * elements (x, y, z).
++ *
++ * For the base point table, z is usually 1 (0 for the point at infinity).
++ * This table has 16 elements:
++ * index | bits    | point
++ * ------+---------+------------------------------
++ *     0 | 0 0 0 0 | 0G
++ *     1 | 0 0 0 1 | 1G
++ *     2 | 0 0 1 0 | 2^95G
++ *     3 | 0 0 1 1 | (2^95 + 1)G
++ *     4 | 0 1 0 0 | 2^190G
++ *     5 | 0 1 0 1 | (2^190 + 1)G
++ *     6 | 0 1 1 0 | (2^190 + 2^95)G
++ *     7 | 0 1 1 1 | (2^190 + 2^95 + 1)G
++ *     8 | 1 0 0 0 | 2^285G
++ *     9 | 1 0 0 1 | (2^285 + 1)G
++ *    10 | 1 0 1 0 | (2^285 + 2^95)G
++ *    11 | 1 0 1 1 | (2^285 + 2^95 + 1)G
++ *    12 | 1 1 0 0 | (2^285 + 2^190)G
++ *    13 | 1 1 0 1 | (2^285 + 2^190 + 1)G
++ *    14 | 1 1 1 0 | (2^285 + 2^190 + 2^95)G
++ *    15 | 1 1 1 1 | (2^285 + 2^190 + 2^95 + 1)G
++ *
++ * The reason for this is so that we can clock bits into four different
++ * locations when doing simple scalar multiplies against the base point.
++ *
++ * Tables for other points have table[i] = iG for i in 0 .. 16.
++ */
++
++/* gmul is the table of precomputed base points */
++static const felem gmul[16][3] = {
++{{0, 0, 0, 0, 0, 0, 0},
++ {0, 0, 0, 0, 0, 0, 0},
++ {0, 0, 0, 0, 0, 0, 0}},
++{{0x00545e3872760ab7, 0x00f25dbf55296c3a, 0x00e082542a385502, 0x008ba79b9859f741,
++  0x0020ad746e1d3b62, 0x0005378eb1c71ef3, 0x0000aa87ca22be8b},
++ {0x00431d7c90ea0e5f, 0x00b1ce1d7e819d7a, 0x0013b5f0b8c00a60, 0x00289a147ce9da31,
++  0x0092dc29f8f41dbd, 0x002c6f5d9e98bf92, 0x00003617de4a9626},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x00024711cc902a90, 0x00acb2e579ab4fe1, 0x00af818a4b4d57b1, 0x00a17c7bec49c3de,
++  0x004280482d726a8b, 0x00128dd0f0a90f3b, 0x00004387c1c3fa3c},
++ {0x002ce76543cf5c3a, 0x00de6cee5ef58f0a, 0x00403e42fa561ca6, 0x00bc54d6f9cb9731,
++  0x007155f925fb4ff1, 0x004a9ce731b7b9bc, 0x00002609076bd7b2},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x00e74c9182f0251d, 0x0039bf54bb111974, 0x00b9d2f2eec511d2, 0x0036b1594eb3a6a4,
++  0x00ac3bb82d9d564b, 0x00f9313f4615a100, 0x00006716a9a91b10},
++ {0x0046698116e2f15c, 0x00f34347067d3d33, 0x008de4ccfdebd002, 0x00e838c6b8e8c97b,
++  0x006faf0798def346, 0x007349794a57563c, 0x00002629e7e6ad84},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x0075300e34fd163b, 0x0092e9db4e8d0ad3, 0x00254be9f625f760, 0x00512c518c72ae68,
++  0x009bfcf162bede5a, 0x00bf9341566ce311, 0x0000cd6175bd41cf},
++ {0x007dfe52af4ac70f, 0x0002159d2d5c4880, 0x00b504d16f0af8d0, 0x0014585e11f5e64c,
++  0x0089c6388e030967, 0x00ffb270cbfa5f71, 0x00009a15d92c3947},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x0033fc1278dc4fe5, 0x00d53088c2caa043, 0x0085558827e2db66, 0x00c192bef387b736,
++  0x00df6405a2225f2c, 0x0075205aa90fd91a, 0x0000137e3f12349d},
++ {0x00ce5b115efcb07e, 0x00abc3308410deeb, 0x005dc6fc1de39904, 0x00907c1c496f36b4,
++  0x0008e6ad3926cbe1, 0x00110747b787928c, 0x0000021b9162eb7e},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x008180042cfa26e1, 0x007b826a96254967, 0x0082473694d6b194, 0x007bd6880a45b589,
++  0x00c0a5097072d1a3, 0x0019186555e18b4e, 0x000020278190e5ca},
++ {0x00b4bef17de61ac0, 0x009535e3c38ed348, 0x002d4aa8e468ceab, 0x00ef40b431036ad3,
++  0x00defd52f4542857, 0x0086edbf98234266, 0x00002025b3a7814d},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x00b238aa97b886be, 0x00ef3192d6dd3a32, 0x0079f9e01fd62df8, 0x00742e890daba6c5,
++  0x008e5289144408ce, 0x0073bbcc8e0171a5, 0x0000c4fd329d3b52},
++ {0x00c6f64a15ee23e7, 0x00dcfb7b171cad8b, 0x00039f6cbd805867, 0x00de024e428d4562,
++  0x00be6a594d7c64c5, 0x0078467b70dbcd64, 0x0000251f2ed7079b},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x000e5cc25fc4b872, 0x005ebf10d31ef4e1, 0x0061e0ebd11e8256, 0x0076e026096f5a27,
++  0x0013e6fc44662e9a, 0x0042b00289d3597e, 0x000024f089170d88},
++ {0x001604d7e0effbe6, 0x0048d77cba64ec2c, 0x008166b16da19e36, 0x006b0d1a0f28c088,
++  0x000259fcd47754fd, 0x00cc643e4d725f9a, 0x00007b10f3c79c14},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x00430155e3b908af, 0x00b801e4fec25226, 0x00b0d4bcfe806d26, 0x009fc4014eb13d37,
++  0x0066c94e44ec07e8, 0x00d16adc03874ba2, 0x000030c917a0d2a7},
++ {0x00edac9e21eb891c, 0x00ef0fb768102eff, 0x00c088cef272a5f3, 0x00cbf782134e2964,
++  0x0001044a7ba9a0e3, 0x00e363f5b194cf3c, 0x00009ce85249e372},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x001dd492dda5a7eb, 0x008fd577be539fd1, 0x002ff4b25a5fc3f1, 0x0074a8a1b64df72f,
++  0x002ba3d8c204a76c, 0x009d5cff95c8235a, 0x0000e014b9406e0f},
++ {0x008c2e4dbfc98aba, 0x00f30bb89f1a1436, 0x00b46f7aea3e259c, 0x009224454ac02f54,
++  0x00906401f5645fa2, 0x003a1d1940eabc77, 0x00007c9351d680e6},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x005a35d872ef967c, 0x0049f1b7884e1987, 0x0059d46d7e31f552, 0x00ceb4869d2d0fb6,
++  0x00e8e89eee56802a, 0x0049d806a774aaf2, 0x0000147e2af0ae24},
++ {0x005fd1bd852c6e5e, 0x00b674b7b3de6885, 0x003b9ea5eb9b6c08, 0x005c9f03babf3ef7,
++  0x00605337fecab3c7, 0x009a3f85b11bbcc8, 0x0000455470f330ec},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x002197ff4d55498d, 0x00383e8916c2d8af, 0x00eb203f34d1c6d2, 0x0080367cbd11b542,
++  0x00769b3be864e4f5, 0x0081a8458521c7bb, 0x0000c531b34d3539},
++ {0x00e2a3d775fa2e13, 0x00534fc379573844, 0x00ff237d2a8db54a, 0x00d301b2335a8882,
++  0x000f75ea96103a80, 0x0018fecb3cdd96fa, 0x0000304bf61e94eb},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x00b2afc332a73dbd, 0x0029a0d5bb007bc5, 0x002d628eb210f577, 0x009f59a36dd05f50,
++  0x006d339de4eca613, 0x00c75a71addc86bc, 0x000060384c5ea93c},
++ {0x00aa9641c32a30b4, 0x00cc73ae8cce565d, 0x00ec911a4df07f61, 0x00aa4b762ea4b264,
++  0x0096d395bb393629, 0x004efacfb7632fe0, 0x00006f252f46fa3f},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x00567eec597c7af6, 0x0059ba6795204413, 0x00816d4e6f01196f, 0x004ae6b3eb57951d,
++  0x00420f5abdda2108, 0x003401d1f57ca9d9, 0x0000cf5837b0b67a},
++ {0x00eaa64b8aeeabf9, 0x00246ddf16bcb4de, 0x000e7e3c3aecd751, 0x0008449f04fed72e,
++  0x00307b67ccf09183, 0x0017108c3556b7b1, 0x0000229b2483b3bf},
++ {1, 0, 0, 0, 0, 0, 0}},
++{{0x00e7c491a7bb78a1, 0x00eafddd1d3049ab, 0x00352c05e2bc7c98, 0x003d6880c165fa5c,
++  0x00b6ac61cc11c97d, 0x00beeb54fcf90ce5, 0x0000dc1f0b455edc},
++ {0x002db2e7aee34d60, 0x0073b5f415a2d8c0, 0x00dd84e4193e9a0c, 0x00d02d873467c572,
++  0x0018baaeda60aee5, 0x0013fb11d697c61e, 0x000083aafcc3a973},
++ {1, 0, 0, 0, 0, 0, 0}}
++};
++
++/*
++ * select_point selects the |idx|th point from a precomputation table and
++ * copies it to out.
++ *
++ * pre_comp below is of the size provided in |size|.
++ */
++static void select_point(const limb idx, unsigned int size,
++                         const felem pre_comp[][3], felem out[3])
++{
++    unsigned int i, j;
++    limb *outlimbs = &out[0][0];
++
++    memset(out, 0, sizeof(*out) * 3);
++
++    for (i = 0; i < size; i++) {
++        const limb *inlimbs = &pre_comp[i][0][0];
++        limb mask = i ^ idx;
++
++        mask |= mask >> 4;
++        mask |= mask >> 2;
++        mask |= mask >> 1;
++        mask &= 1;
++        mask--;
++        for (j = 0; j < NLIMBS * 3; j++)
++            outlimbs[j] |= inlimbs[j] & mask;
++    }
++}
++
++/* get_bit returns the |i|th bit in |in| */
++static char get_bit(const felem_bytearray in, int i)
++{
++    if (i < 0 || i >= 384)
++        return 0;
++    return (in[i >> 3] >> (i & 7)) & 1;
++}
++
++/*
++ * Interleaved point multiplication using precomputed point multiples: The
++ * small point multiples 0*P, 1*P, ..., 16*P are in pre_comp[], the scalars
++ * in scalars[]. If g_scalar is non-NULL, we also add this multiple of the
++ * generator, using certain (large) precomputed multiples in g_pre_comp.
++ * Output point (X, Y, Z) is stored in x_out, y_out, z_out
++ */
++static void batch_mul(felem x_out, felem y_out, felem z_out,
++                      const felem_bytearray scalars[],
++                      const unsigned int num_points, const u8 *g_scalar,
++                      const int mixed, const felem pre_comp[][17][3],
++                      const felem g_pre_comp[16][3])
++{
++    int i, skip;
++    unsigned int num, gen_mul = (g_scalar != NULL);
++    felem nq[3], tmp[4];
++    limb bits;
++    u8 sign, digit;
++
++    /* set nq to the point at infinity */
++    memset(nq, 0, sizeof(nq));
++
++    /*
++     * Loop over all scalars msb-to-lsb, interleaving additions of multiples
++     * of the generator (last quarter of rounds) and additions of other
++     * points multiples (every 5th round).
++     */
++    skip = 1;                   /* save two point operations in the first
++                                 * round */
++    for (i = (num_points ? 380 : 98); i >= 0; --i) {
++        /* double */
++        if (!skip)
++            point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]);
++
++        /* add multiples of the generator */
++        if (gen_mul && (i <= 98)) {
++            bits = get_bit(g_scalar, i + 285) << 3;
++            if (i < 95) {
++                bits |= get_bit(g_scalar, i + 190) << 2;
++                bits |= get_bit(g_scalar, i + 95) << 1;
++                bits |= get_bit(g_scalar, i);
++            }
++            /* select the point to add, in constant time */
++            select_point(bits, 16, g_pre_comp, tmp);
++            if (!skip) {
++                /* The 1 argument below is for "mixed" */
++                point_add(nq[0],  nq[1],  nq[2],
++                          nq[0],  nq[1],  nq[2], 1,
++                          tmp[0], tmp[1], tmp[2]);
++            } else {
++                memcpy(nq, tmp, 3 * sizeof(felem));
++                skip = 0;
++            }
++        }
++
++        /* do other additions every 5 doublings */
++        if (num_points && (i % 5 == 0)) {
++            /* loop over all scalars */
++            for (num = 0; num < num_points; ++num) {
++                bits = get_bit(scalars[num], i + 4) << 5;
++                bits |= get_bit(scalars[num], i + 3) << 4;
++                bits |= get_bit(scalars[num], i + 2) << 3;
++                bits |= get_bit(scalars[num], i + 1) << 2;
++                bits |= get_bit(scalars[num], i) << 1;
++                bits |= get_bit(scalars[num], i - 1);
++                ossl_ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits);
++
++                /*
++                 * select the point to add or subtract, in constant time
++                 */
++                select_point(digit, 17, pre_comp[num], tmp);
++                felem_neg(tmp[3], tmp[1]); /* (X, -Y, Z) is the negative
++                                            * point */
++                copy_conditional(tmp[1], tmp[3], (-(limb) sign));
++
++                if (!skip) {
++                    point_add(nq[0],  nq[1],  nq[2],
++                              nq[0],  nq[1],  nq[2], mixed,
++                              tmp[0], tmp[1], tmp[2]);
++                } else {
++                    memcpy(nq, tmp, 3 * sizeof(felem));
++                    skip = 0;
++                }
++            }
++        }
++    }
++    felem_assign(x_out, nq[0]);
++    felem_assign(y_out, nq[1]);
++    felem_assign(z_out, nq[2]);
++}
++
++/* Precomputation for the group generator. */
++struct nistp384_pre_comp_st {
++    felem g_pre_comp[16][3];
++    CRYPTO_REF_COUNT refcnt;
++    CRYPTO_RWLOCK *refcnt_lock;
++};
++
++const EC_METHOD *ossl_ec_GFp_nistp384_method(void)
++{
++    static const EC_METHOD ret = {
++        EC_FLAGS_DEFAULT_OCT,
++        NID_X9_62_prime_field,
++        ossl_ec_GFp_nistp384_group_init,
++        ossl_ec_GFp_simple_group_finish,
++        ossl_ec_GFp_simple_group_clear_finish,
++        ossl_ec_GFp_nist_group_copy,
++        ossl_ec_GFp_nistp384_group_set_curve,
++        ossl_ec_GFp_simple_group_get_curve,
++        ossl_ec_GFp_simple_group_get_degree,
++        ossl_ec_group_simple_order_bits,
++        ossl_ec_GFp_simple_group_check_discriminant,
++        ossl_ec_GFp_simple_point_init,
++        ossl_ec_GFp_simple_point_finish,
++        ossl_ec_GFp_simple_point_clear_finish,
++        ossl_ec_GFp_simple_point_copy,
++        ossl_ec_GFp_simple_point_set_to_infinity,
++        ossl_ec_GFp_simple_point_set_affine_coordinates,
++        ossl_ec_GFp_nistp384_point_get_affine_coordinates,
++        0, /* point_set_compressed_coordinates */
++        0, /* point2oct */
++        0, /* oct2point */
++        ossl_ec_GFp_simple_add,
++        ossl_ec_GFp_simple_dbl,
++        ossl_ec_GFp_simple_invert,
++        ossl_ec_GFp_simple_is_at_infinity,
++        ossl_ec_GFp_simple_is_on_curve,
++        ossl_ec_GFp_simple_cmp,
++        ossl_ec_GFp_simple_make_affine,
++        ossl_ec_GFp_simple_points_make_affine,
++        ossl_ec_GFp_nistp384_points_mul,
++        ossl_ec_GFp_nistp384_precompute_mult,
++        ossl_ec_GFp_nistp384_have_precompute_mult,
++        ossl_ec_GFp_nist_field_mul,
++        ossl_ec_GFp_nist_field_sqr,
++        0, /* field_div */
++        ossl_ec_GFp_simple_field_inv,
++        0, /* field_encode */
++        0, /* field_decode */
++        0, /* field_set_to_one */
++        ossl_ec_key_simple_priv2oct,
++        ossl_ec_key_simple_oct2priv,
++        0, /* set private */
++        ossl_ec_key_simple_generate_key,
++        ossl_ec_key_simple_check_key,
++        ossl_ec_key_simple_generate_public_key,
++        0, /* keycopy */
++        0, /* keyfinish */
++        ossl_ecdh_simple_compute_key,
++        ossl_ecdsa_simple_sign_setup,
++        ossl_ecdsa_simple_sign_sig,
++        ossl_ecdsa_simple_verify_sig,
++        0, /* field_inverse_mod_ord */
++        0, /* blind_coordinates */
++        0, /* ladder_pre */
++        0, /* ladder_step */
++        0  /* ladder_post */
++    };
++
++    return &ret;
++}
++
++/******************************************************************************/
++/*
++ * FUNCTIONS TO MANAGE PRECOMPUTATION
++ */
++
++static NISTP384_PRE_COMP *nistp384_pre_comp_new(void)
++{
++    NISTP384_PRE_COMP *ret = OPENSSL_zalloc(sizeof(*ret));
++
++    if (ret == NULL || (ret->refcnt_lock = CRYPTO_THREAD_lock_new()) == NULL) {
++        OPENSSL_free(ret);
++        return NULL;
++    }
++
++    ret->refcnt = 1;
++    return ret;
++}
++
++NISTP384_PRE_COMP *ossl_ec_nistp384_pre_comp_dup(NISTP384_PRE_COMP *p)
++{
++    int i;
++
++    if (p != NULL)
++        CRYPTO_UP_REF(&p->refcnt, &i, p->refcnt_lock);
++    return p;
++}
++
++void ossl_ec_nistp384_pre_comp_free(NISTP384_PRE_COMP *p)
++{
++    int i;
++
++    if (p == NULL)
++        return;
++
++    CRYPTO_DOWN_REF(&p->refcnt, &i, p->refcnt_lock);
++    REF_PRINT_COUNT("ossl_ec_nistp384", p);
++    if (i > 0)
++        return;
++    REF_ASSERT_ISNT(i < 0);
++
++    CRYPTO_THREAD_lock_free(p->refcnt_lock);
++    OPENSSL_free(p);
++}
++
++/******************************************************************************/
++/*
++ * OPENSSL EC_METHOD FUNCTIONS
++ */
++
++int ossl_ec_GFp_nistp384_group_init(EC_GROUP *group)
++{
++    int ret;
++
++    ret = ossl_ec_GFp_simple_group_init(group);
++    group->a_is_minus3 = 1;
++    return ret;
++}
++
++int ossl_ec_GFp_nistp384_group_set_curve(EC_GROUP *group, const BIGNUM *p,
++                                         const BIGNUM *a, const BIGNUM *b,
++                                         BN_CTX *ctx)
++{
++    int ret = 0;
++    BIGNUM *curve_p, *curve_a, *curve_b;
++#ifndef FIPS_MODULE
++    BN_CTX *new_ctx = NULL;
++
++    if (ctx == NULL)
++        ctx = new_ctx = BN_CTX_new();
++#endif
++    if (ctx == NULL)
++        return 0;
++
++    BN_CTX_start(ctx);
++    curve_p = BN_CTX_get(ctx);
++    curve_a = BN_CTX_get(ctx);
++    curve_b = BN_CTX_get(ctx);
++    if (curve_b == NULL)
++        goto err;
++    BN_bin2bn(nistp384_curve_params[0], sizeof(felem_bytearray), curve_p);
++    BN_bin2bn(nistp384_curve_params[1], sizeof(felem_bytearray), curve_a);
++    BN_bin2bn(nistp384_curve_params[2], sizeof(felem_bytearray), curve_b);
++    if ((BN_cmp(curve_p, p)) || (BN_cmp(curve_a, a)) || (BN_cmp(curve_b, b))) {
++        ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS);
++        goto err;
++    }
++    group->field_mod_func = BN_nist_mod_384;
++    ret = ossl_ec_GFp_simple_group_set_curve(group, p, a, b, ctx);
++ err:
++    BN_CTX_end(ctx);
++#ifndef FIPS_MODULE
++    BN_CTX_free(new_ctx);
++#endif
++    return ret;
++}
++
++/*
++ * Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') =
++ * (X/Z^2, Y/Z^3)
++ */
++int ossl_ec_GFp_nistp384_point_get_affine_coordinates(const EC_GROUP *group,
++                                                      const EC_POINT *point,
++                                                      BIGNUM *x, BIGNUM *y,
++                                                      BN_CTX *ctx)
++{
++    felem z1, z2, x_in, y_in, x_out, y_out;
++    widefelem tmp;
++
++    if (EC_POINT_is_at_infinity(group, point)) {
++        ERR_raise(ERR_LIB_EC, EC_R_POINT_AT_INFINITY);
++        return 0;
++    }
++    if ((!BN_to_felem(x_in, point->X)) || (!BN_to_felem(y_in, point->Y)) ||
++        (!BN_to_felem(z1, point->Z)))
++        return 0;
++    felem_inv(z2, z1);
++    felem_square(tmp, z2);
++    felem_reduce(z1, tmp);
++    felem_mul(tmp, x_in, z1);
++    felem_reduce(x_in, tmp);
++    felem_contract(x_out, x_in);
++    if (x != NULL) {
++        if (!felem_to_BN(x, x_out)) {
++            ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
++            return 0;
++        }
++    }
++    felem_mul(tmp, z1, z2);
++    felem_reduce(z1, tmp);
++    felem_mul(tmp, y_in, z1);
++    felem_reduce(y_in, tmp);
++    felem_contract(y_out, y_in);
++    if (y != NULL) {
++        if (!felem_to_BN(y, y_out)) {
++            ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
++            return 0;
++        }
++    }
++    return 1;
++}
++
++/* points below is of size |num|, and tmp_felems is of size |num+1/ */
++static void make_points_affine(size_t num, felem points[][3],
++                               felem tmp_felems[])
++{
++    /*
++     * Runs in constant time, unless an input is the point at infinity (which
++     * normally shouldn't happen).
++     */
++    ossl_ec_GFp_nistp_points_make_affine_internal(num,
++                                                  points,
++                                                  sizeof(felem),
++                                                  tmp_felems,
++                                                  (void (*)(void *))felem_one,
++                                                  felem_is_zero_int,
++                                                  (void (*)(void *, const void *))
++                                                  felem_assign,
++                                                  (void (*)(void *, const void *))
++                                                  felem_square_reduce,
++                                                  (void (*)(void *, const void *, const void*))
++                                                  felem_mul_reduce,
++                                                  (void (*)(void *, const void *))
++                                                  felem_inv,
++                                                  (void (*)(void *, const void *))
++                                                  felem_contract);
++}
++
++/*
++ * Computes scalar*generator + \sum scalars[i]*points[i], ignoring NULL
++ * values Result is stored in r (r can equal one of the inputs).
++ */
++int ossl_ec_GFp_nistp384_points_mul(const EC_GROUP *group, EC_POINT *r,
++                                    const BIGNUM *scalar, size_t num,
++                                    const EC_POINT *points[],
++                                    const BIGNUM *scalars[], BN_CTX *ctx)
++{
++    int ret = 0;
++    int j;
++    int mixed = 0;
++    BIGNUM *x, *y, *z, *tmp_scalar;
++    felem_bytearray g_secret;
++    felem_bytearray *secrets = NULL;
++    felem (*pre_comp)[17][3] = NULL;
++    felem *tmp_felems = NULL;
++    unsigned int i;
++    int num_bytes;
++    int have_pre_comp = 0;
++    size_t num_points = num;
++    felem x_in, y_in, z_in, x_out, y_out, z_out;
++    NISTP384_PRE_COMP *pre = NULL;
++    felem(*g_pre_comp)[3] = NULL;
++    EC_POINT *generator = NULL;
++    const EC_POINT *p = NULL;
++    const BIGNUM *p_scalar = NULL;
++
++    BN_CTX_start(ctx);
++    x = BN_CTX_get(ctx);
++    y = BN_CTX_get(ctx);
++    z = BN_CTX_get(ctx);
++    tmp_scalar = BN_CTX_get(ctx);
++    if (tmp_scalar == NULL)
++        goto err;
++
++    if (scalar != NULL) {
++        pre = group->pre_comp.nistp384;
++        if (pre)
++            /* we have precomputation, try to use it */
++            g_pre_comp = &pre->g_pre_comp[0];
++        else
++            /* try to use the standard precomputation */
++            g_pre_comp = (felem(*)[3]) gmul;
++        generator = EC_POINT_new(group);
++        if (generator == NULL)
++            goto err;
++        /* get the generator from precomputation */
++        if (!felem_to_BN(x, g_pre_comp[1][0]) ||
++            !felem_to_BN(y, g_pre_comp[1][1]) ||
++            !felem_to_BN(z, g_pre_comp[1][2])) {
++            ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
++            goto err;
++        }
++        if (!ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group,
++                                                                generator,
++                                                                x, y, z, ctx))
++            goto err;
++        if (0 == EC_POINT_cmp(group, generator, group->generator, ctx))
++            /* precomputation matches generator */
++            have_pre_comp = 1;
++        else
++            /*
++             * we don't have valid precomputation: treat the generator as a
++             * random point
++             */
++            num_points++;
++    }
++
++    if (num_points > 0) {
++        if (num_points >= 2) {
++            /*
++             * unless we precompute multiples for just one point, converting
++             * those into affine form is time well spent
++             */
++            mixed = 1;
++        }
++        secrets = OPENSSL_zalloc(sizeof(*secrets) * num_points);
++        pre_comp = OPENSSL_zalloc(sizeof(*pre_comp) * num_points);
++        if (mixed)
++            tmp_felems =
++                OPENSSL_malloc(sizeof(*tmp_felems) * (num_points * 17 + 1));
++        if ((secrets == NULL) || (pre_comp == NULL)
++            || (mixed && (tmp_felems == NULL)))
++            goto err;
++
++        /*
++         * we treat NULL scalars as 0, and NULL points as points at infinity,
++         * i.e., they contribute nothing to the linear combination
++         */
++        for (i = 0; i < num_points; ++i) {
++            if (i == num) {
++                /*
++                 * we didn't have a valid precomputation, so we pick the
++                 * generator
++                 */
++                p = EC_GROUP_get0_generator(group);
++                p_scalar = scalar;
++            } else {
++                /* the i^th point */
++                p = points[i];
++                p_scalar = scalars[i];
++            }
++            if (p_scalar != NULL && p != NULL) {
++                /* reduce scalar to 0 <= scalar < 2^384 */
++                if ((BN_num_bits(p_scalar) > 384)
++                    || (BN_is_negative(p_scalar))) {
++                    /*
++                     * this is an unusual input, and we don't guarantee
++                     * constant-timeness
++                     */
++                    if (!BN_nnmod(tmp_scalar, p_scalar, group->order, ctx)) {
++                        ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
++                        goto err;
++                    }
++                    num_bytes = BN_bn2lebinpad(tmp_scalar,
++                                               secrets[i], sizeof(secrets[i]));
++                } else {
++                    num_bytes = BN_bn2lebinpad(p_scalar,
++                                               secrets[i], sizeof(secrets[i]));
++                }
++                if (num_bytes < 0) {
++                    ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
++                    goto err;
++                }
++                /* precompute multiples */
++                if ((!BN_to_felem(x_out, p->X)) ||
++                    (!BN_to_felem(y_out, p->Y)) ||
++                    (!BN_to_felem(z_out, p->Z)))
++                    goto err;
++                memcpy(pre_comp[i][1][0], x_out, sizeof(felem));
++                memcpy(pre_comp[i][1][1], y_out, sizeof(felem));
++                memcpy(pre_comp[i][1][2], z_out, sizeof(felem));
++                for (j = 2; j <= 16; ++j) {
++                    if (j & 1) {
++                        point_add(pre_comp[i][j][0],     pre_comp[i][j][1],     pre_comp[i][j][2],
++                                  pre_comp[i][1][0],     pre_comp[i][1][1],     pre_comp[i][1][2], 0,
++                                  pre_comp[i][j - 1][0], pre_comp[i][j - 1][1], pre_comp[i][j - 1][2]);
++                    } else {
++                        point_double(pre_comp[i][j][0],     pre_comp[i][j][1],     pre_comp[i][j][2],
++                                     pre_comp[i][j / 2][0], pre_comp[i][j / 2][1], pre_comp[i][j / 2][2]);
++                    }
++                }
++            }
++        }
++        if (mixed)
++            make_points_affine(num_points * 17, pre_comp[0], tmp_felems);
++    }
++
++    /* the scalar for the generator */
++    if (scalar != NULL && have_pre_comp) {
++        memset(g_secret, 0, sizeof(g_secret));
++        /* reduce scalar to 0 <= scalar < 2^384 */
++        if ((BN_num_bits(scalar) > 384) || (BN_is_negative(scalar))) {
++            /*
++             * this is an unusual input, and we don't guarantee
++             * constant-timeness
++             */
++            if (!BN_nnmod(tmp_scalar, scalar, group->order, ctx)) {
++                ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
++                goto err;
++            }
++            num_bytes = BN_bn2lebinpad(tmp_scalar, g_secret, sizeof(g_secret));
++        } else {
++            num_bytes = BN_bn2lebinpad(scalar, g_secret, sizeof(g_secret));
++        }
++        /* do the multiplication with generator precomputation */
++        batch_mul(x_out, y_out, z_out,
++                  (const felem_bytearray(*))secrets, num_points,
++                  g_secret,
++                  mixed, (const felem(*)[17][3])pre_comp,
++                  (const felem(*)[3])g_pre_comp);
++    } else {
++        /* do the multiplication without generator precomputation */
++        batch_mul(x_out, y_out, z_out,
++                  (const felem_bytearray(*))secrets, num_points,
++                  NULL, mixed, (const felem(*)[17][3])pre_comp, NULL);
++    }
++    /* reduce the output to its unique minimal representation */
++    felem_contract(x_in, x_out);
++    felem_contract(y_in, y_out);
++    felem_contract(z_in, z_out);
++    if ((!felem_to_BN(x, x_in)) || (!felem_to_BN(y, y_in)) ||
++        (!felem_to_BN(z, z_in))) {
++        ERR_raise(ERR_LIB_EC, ERR_R_BN_LIB);
++        goto err;
++    }
++    ret = ossl_ec_GFp_simple_set_Jprojective_coordinates_GFp(group, r, x, y, z,
++                                                             ctx);
++
++ err:
++    BN_CTX_end(ctx);
++    EC_POINT_free(generator);
++    OPENSSL_free(secrets);
++    OPENSSL_free(pre_comp);
++    OPENSSL_free(tmp_felems);
++    return ret;
++}
++
++int ossl_ec_GFp_nistp384_precompute_mult(EC_GROUP *group, BN_CTX *ctx)
++{
++    int ret = 0;
++    NISTP384_PRE_COMP *pre = NULL;
++    int i, j;
++    BIGNUM *x, *y;
++    EC_POINT *generator = NULL;
++    felem tmp_felems[16];
++#ifndef FIPS_MODULE
++    BN_CTX *new_ctx = NULL;
++#endif
++
++    /* throw away old precomputation */
++    EC_pre_comp_free(group);
++
++#ifndef FIPS_MODULE
++    if (ctx == NULL)
++        ctx = new_ctx = BN_CTX_new();
++#endif
++    if (ctx == NULL)
++        return 0;
++
++    BN_CTX_start(ctx);
++    x = BN_CTX_get(ctx);
++    y = BN_CTX_get(ctx);
++    if (y == NULL)
++        goto err;
++    /* get the generator */
++    if (group->generator == NULL)
++        goto err;
++    generator = EC_POINT_new(group);
++    if (generator == NULL)
++        goto err;
++    BN_bin2bn(nistp384_curve_params[3], sizeof(felem_bytearray), x);
++    BN_bin2bn(nistp384_curve_params[4], sizeof(felem_bytearray), y);
++    if (!EC_POINT_set_affine_coordinates(group, generator, x, y, ctx))
++        goto err;
++    if ((pre = nistp384_pre_comp_new()) == NULL)
++        goto err;
++    /*
++     * if the generator is the standard one, use built-in precomputation
++     */
++    if (0 == EC_POINT_cmp(group, generator, group->generator, ctx)) {
++        memcpy(pre->g_pre_comp, gmul, sizeof(pre->g_pre_comp));
++        goto done;
++    }
++    if ((!BN_to_felem(pre->g_pre_comp[1][0], group->generator->X)) ||
++        (!BN_to_felem(pre->g_pre_comp[1][1], group->generator->Y)) ||
++        (!BN_to_felem(pre->g_pre_comp[1][2], group->generator->Z)))
++        goto err;
++    /* compute 2^95*G, 2^190*G, 2^285*G */
++    for (i = 1; i <= 4; i <<= 1) {
++        point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2],
++                     pre->g_pre_comp[i][0],  pre->g_pre_comp[i][1],    pre->g_pre_comp[i][2]);
++        for (j = 0; j < 94; ++j) {
++            point_double(pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2],
++                         pre->g_pre_comp[2 * i][0], pre->g_pre_comp[2 * i][1], pre->g_pre_comp[2 * i][2]);
++        }
++    }
++    /* g_pre_comp[0] is the point at infinity */
++    memset(pre->g_pre_comp[0], 0, sizeof(pre->g_pre_comp[0]));
++    /* the remaining multiples */
++    /* 2^95*G + 2^190*G */
++    point_add(pre->g_pre_comp[6][0],  pre->g_pre_comp[6][1],  pre->g_pre_comp[6][2],
++              pre->g_pre_comp[4][0],  pre->g_pre_comp[4][1],  pre->g_pre_comp[4][2], 0,
++              pre->g_pre_comp[2][0],  pre->g_pre_comp[2][1],  pre->g_pre_comp[2][2]);
++    /* 2^95*G + 2^285*G */
++    point_add(pre->g_pre_comp[10][0], pre->g_pre_comp[10][1], pre->g_pre_comp[10][2],
++              pre->g_pre_comp[8][0],  pre->g_pre_comp[8][1],  pre->g_pre_comp[8][2], 0,
++              pre->g_pre_comp[2][0],  pre->g_pre_comp[2][1],  pre->g_pre_comp[2][2]);
++    /* 2^190*G + 2^285*G */
++    point_add(pre->g_pre_comp[12][0], pre->g_pre_comp[12][1], pre->g_pre_comp[12][2],
++              pre->g_pre_comp[8][0],  pre->g_pre_comp[8][1],  pre->g_pre_comp[8][2], 0,
++              pre->g_pre_comp[4][0],  pre->g_pre_comp[4][1],  pre->g_pre_comp[4][2]);
++    /* 2^95*G + 2^190*G + 2^285*G */
++    point_add(pre->g_pre_comp[14][0], pre->g_pre_comp[14][1], pre->g_pre_comp[14][2],
++              pre->g_pre_comp[12][0], pre->g_pre_comp[12][1], pre->g_pre_comp[12][2], 0,
++              pre->g_pre_comp[2][0],  pre->g_pre_comp[2][1],  pre->g_pre_comp[2][2]);
++    for (i = 1; i < 8; ++i) {
++        /* odd multiples: add G */
++        point_add(pre->g_pre_comp[2 * i + 1][0], pre->g_pre_comp[2 * i + 1][1], pre->g_pre_comp[2 * i + 1][2],
++                  pre->g_pre_comp[2 * i][0],     pre->g_pre_comp[2 * i][1],     pre->g_pre_comp[2 * i][2], 0,
++                  pre->g_pre_comp[1][0],         pre->g_pre_comp[1][1],         pre->g_pre_comp[1][2]);
++    }
++    make_points_affine(15, &(pre->g_pre_comp[1]), tmp_felems);
++
++ done:
++    SETPRECOMP(group, nistp384, pre);
++    ret = 1;
++    pre = NULL;
++ err:
++    BN_CTX_end(ctx);
++    EC_POINT_free(generator);
++#ifndef FIPS_MODULE
++    BN_CTX_free(new_ctx);
++#endif
++    ossl_ec_nistp384_pre_comp_free(pre);
++    return ret;
++}
++
++int ossl_ec_GFp_nistp384_have_precompute_mult(const EC_GROUP *group)
++{
++    return HAVEPRECOMP(group, nistp384);
++}
diff --git a/openssl-ec-Use-static-linkage-on-nistp521-felem_-square-mul-.patch b/openssl-ec-Use-static-linkage-on-nistp521-felem_-square-mul-.patch
new file mode 100644
index 0000000..90f12cd
--- /dev/null
+++ b/openssl-ec-Use-static-linkage-on-nistp521-felem_-square-mul-.patch
@@ -0,0 +1,65 @@
+From 3e47a286dc3274bda72a196c3a4030a1fc8302f1 Mon Sep 17 00:00:00 2001
+From: Rohan McLure <rohanmclure@linux.ibm.com>
+Date: Fri, 23 Jun 2023 16:41:48 +1000
+Subject: [PATCH] ec: Use static linkage on nistp521 felem_{square,mul}
+ wrappers
+
+Runtime selection of implementations for felem_{square,mul} depends on
+felem_{square,mul}_wrapper functions, which overwrite function points in
+a similar design to that of .plt.got sections used by program loaders
+during dynamic linking.
+
+There's no reason why these functions need to have external linkage.
+Mark static.
+
+Signed-off-by: Rohan McLure <rohanmclure@linux.ibm.com>
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
+Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
+Reviewed-by: Todd Short <todd.short@me.com>
+(Merged from https://github.com/openssl/openssl/pull/21471)
+---
+ crypto/ec/ecp_nistp521.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/crypto/ec/ecp_nistp521.c b/crypto/ec/ecp_nistp521.c
+index 97815cac1f13..32a9268ecf17 100644
+--- a/crypto/ec/ecp_nistp521.c
++++ b/crypto/ec/ecp_nistp521.c
+@@ -676,8 +676,8 @@ static void felem_reduce(felem out, const largefelem in)
+ }
+ 
+ #if defined(ECP_NISTP521_ASM)
+-void felem_square_wrapper(largefelem out, const felem in);
+-void felem_mul_wrapper(largefelem out, const felem in1, const felem in2);
++static void felem_square_wrapper(largefelem out, const felem in);
++static void felem_mul_wrapper(largefelem out, const felem in1, const felem in2);
+ 
+ static void (*felem_square_p)(largefelem out, const felem in) =
+     felem_square_wrapper;
+@@ -691,7 +691,7 @@ void p521_felem_mul(largefelem out, const felem in1, const felem in2);
+ #  include "crypto/ppc_arch.h"
+ # endif
+ 
+-void felem_select(void)
++static void felem_select(void)
+ {
+ # if defined(_ARCH_PPC64)
+     if ((OPENSSL_ppccap_P & PPC_MADD300) && (OPENSSL_ppccap_P & PPC_ALTIVEC)) {
+@@ -707,13 +707,13 @@ void felem_select(void)
+     felem_mul_p = felem_mul_ref;
+ }
+ 
+-void felem_square_wrapper(largefelem out, const felem in)
++static void felem_square_wrapper(largefelem out, const felem in)
+ {
+     felem_select();
+     felem_square_p(out, in);
+ }
+ 
+-void felem_mul_wrapper(largefelem out, const felem in1, const felem in2)
++static void felem_mul_wrapper(largefelem out, const felem in1, const felem in2)
+ {
+     felem_select();
+     felem_mul_p(out, in1, in2);
diff --git a/openssl-ec-powerpc64le-Add-asm-implementation-of-felem_-squa.patch b/openssl-ec-powerpc64le-Add-asm-implementation-of-felem_-squa.patch
new file mode 100644
index 0000000..91bb470
--- /dev/null
+++ b/openssl-ec-powerpc64le-Add-asm-implementation-of-felem_-squa.patch
@@ -0,0 +1,428 @@
+From 966047ee13188e8634af25af348940acceb9316d Mon Sep 17 00:00:00 2001
+From: Rohan McLure <rohanmclure@linux.ibm.com>
+Date: Wed, 31 May 2023 14:32:26 +1000
+Subject: [PATCH] ec: powerpc64le: Add asm implementation of felem_{square,mul}
+
+Add an assembly implementation of felem_{square,mul}, which will be
+implemented whenever Altivec support is present and the core implements
+ISA 3.0 (Power 9) or greater.
+
+Signed-off-by: Rohan McLure <rohanmclure@linux.ibm.com>
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
+Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
+Reviewed-by: Todd Short <todd.short@me.com>
+(Merged from https://github.com/openssl/openssl/pull/21471)
+---
+ crypto/ec/asm/ecp_nistp384-ppc64.pl | 355 ++++++++++++++++++++++++++++
+ crypto/ec/build.info                |   6 +-
+ crypto/ec/ecp_nistp384.c            |   9 +
+ 3 files changed, 368 insertions(+), 2 deletions(-)
+ create mode 100755 crypto/ec/asm/ecp_nistp384-ppc64.pl
+
+diff --git a/crypto/ec/asm/ecp_nistp384-ppc64.pl b/crypto/ec/asm/ecp_nistp384-ppc64.pl
+new file mode 100755
+index 000000000000..3f86b391af69
+--- /dev/null
++++ b/crypto/ec/asm/ecp_nistp384-ppc64.pl
+@@ -0,0 +1,355 @@
++#! /usr/bin/env perl
++# Copyright 2023 The OpenSSL Project Authors. All Rights Reserved.
++#
++# Licensed under the Apache License 2.0 (the "License").  You may not use
++# this file except in compliance with the License.  You can obtain a copy
++# in the file LICENSE in the source distribution or at
++# https://www.openssl.org/source/license.html
++#
++# ====================================================================
++# Written by Rohan McLure <rmclure@linux.ibm.com> for the OpenSSL
++# project.
++# ====================================================================
++#
++# p384 lower-level primitives for PPC64 using vector instructions.
++#
++
++use strict;
++use warnings;
++
++my $flavour = shift;
++my $output = "";
++while (($output=shift) && ($output!~/\w[\w\-]*\.\w+$/)) {}
++if (!$output) {
++    $output = "-";
++}
++
++my ($xlate, $dir);
++$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
++( $xlate="${dir}ppc-xlate.pl" and -f $xlate ) or
++( $xlate="${dir}../../perlasm/ppc-xlate.pl" and -f $xlate) or
++die "can't locate ppc-xlate.pl";
++
++open OUT,"| \"$^X\" $xlate $flavour $output";
++*STDOUT=*OUT;
++
++my $code = "";
++
++my ($sp, $outp, $savelr, $savesp) = ("r1", "r3", "r10", "r12");
++
++my $vzero = "v32";
++
++sub startproc($)
++{
++    my ($name) = @_;
++
++    $code.=<<___;
++    .globl ${name}
++    .align 5
++${name}:
++
++___
++}
++
++sub endproc($)
++{
++    my ($name) = @_;
++
++    $code.=<<___;
++    blr
++        .size ${name},.-${name}
++
++___
++}
++
++
++sub push_vrs($$)
++{
++    my ($min, $max) = @_;
++
++    my $count = $max - $min + 1;
++
++    $code.=<<___;
++    mr      $savesp,$sp
++    stdu        $sp,-16*`$count+1`($sp)
++
++___
++        for (my $i = $min; $i <= $max; $i++) {
++            my $mult = $max - $i + 1;
++            $code.=<<___;
++    stxv        $i,-16*$mult($savesp)
++___
++
++    }
++
++    $code.=<<___;
++
++___
++}
++
++sub pop_vrs($$)
++{
++    my ($min, $max) = @_;
++
++    $code.=<<___;
++    ld      $savesp,0($sp)
++___
++    for (my $i = $min; $i <= $max; $i++) {
++        my $mult = $max - $i + 1;
++        $code.=<<___;
++    lxv     $i,-16*$mult($savesp)
++___
++    }
++
++    $code.=<<___;
++    mr      $sp,$savesp
++
++___
++}
++
++sub load_vrs($$)
++{
++    my ($pointer, $reg_list) = @_;
++
++    for (my $i = 0; $i <= 6; $i++) {
++        my $offset = $i * 8;
++        $code.=<<___;
++    lxsd        $reg_list->[$i],$offset($pointer)
++___
++    }
++
++    $code.=<<___;
++
++___
++}
++
++sub store_vrs($$)
++{
++    my ($pointer, $reg_list) = @_;
++
++    for (my $i = 0; $i <= 12; $i++) {
++        my $offset = $i * 16;
++        $code.=<<___;
++    stxv        $reg_list->[$i],$offset($pointer)
++___
++    }
++
++    $code.=<<___;
++
++___
++}
++
++$code.=<<___;
++.machine    "any"
++.text
++
++___
++
++{
++    # mul/square common
++    my ($t1, $t2, $t3, $t4) = ("v33", "v34", "v42", "v43");
++    my ($zero, $one) = ("r8", "r9");
++    my $out = "v51";
++
++    {
++        #
++        # p384_felem_mul
++        #
++
++        my ($in1p, $in2p) = ("r4", "r5");
++        my @in1 = map("v$_",(44..50));
++        my @in2 = map("v$_",(35..41));
++
++        startproc("p384_felem_mul");
++
++        push_vrs(52, 63);
++
++        $code.=<<___;
++    vspltisw    $vzero,0
++
++___
++
++        load_vrs($in1p, \@in1);
++        load_vrs($in2p, \@in2);
++
++        $code.=<<___;
++    vmsumudm    $out,$in1[0],$in2[0],$vzero
++    stxv        $out,0($outp)
++
++    xxpermdi    $t1,$in1[0],$in1[1],0b00
++    xxpermdi    $t2,$in2[1],$in2[0],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    stxv        $out,16($outp)
++
++    xxpermdi    $t2,$in2[2],$in2[1],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$in1[2],$in2[0],$out
++    stxv        $out,32($outp)
++
++    xxpermdi    $t2,$in2[1],$in2[0],0b00
++    xxpermdi    $t3,$in1[2],$in1[3],0b00
++    xxpermdi    $t4,$in2[3],$in2[2],0b00
++    vmsumudm    $out,$t1,$t4,$vzero
++    vmsumudm    $out,$t3,$t2,$out
++    stxv        $out,48($outp)
++
++    xxpermdi    $t2,$in2[4],$in2[3],0b00
++    xxpermdi    $t4,$in2[2],$in2[1],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$t3,$t4,$out
++    vmsumudm    $out,$in1[4],$in2[0],$out
++    stxv        $out,64($outp)
++
++    xxpermdi    $t2,$in2[5],$in2[4],0b00
++    xxpermdi    $t4,$in2[3],$in2[2],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$t3,$t4,$out
++    xxpermdi    $t4,$in2[1],$in2[0],0b00
++    xxpermdi    $t1,$in1[4],$in1[5],0b00
++    vmsumudm    $out,$t1,$t4,$out
++    stxv        $out,80($outp)
++
++    xxpermdi    $t1,$in1[0],$in1[1],0b00
++    xxpermdi    $t2,$in2[6],$in2[5],0b00
++    xxpermdi    $t4,$in2[4],$in2[3],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$t3,$t4,$out
++    xxpermdi    $t2,$in2[2],$in2[1],0b00
++    xxpermdi    $t1,$in1[4],$in1[5],0b00
++    vmsumudm    $out,$t1,$t2,$out
++    vmsumudm    $out,$in1[6],$in2[0],$out
++    stxv        $out,96($outp)
++
++    xxpermdi    $t1,$in1[1],$in1[2],0b00
++    xxpermdi    $t2,$in2[6],$in2[5],0b00
++    xxpermdi    $t3,$in1[3],$in1[4],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$t3,$t4,$out
++    xxpermdi    $t3,$in2[2],$in2[1],0b00
++    xxpermdi    $t1,$in1[5],$in1[6],0b00
++    vmsumudm    $out,$t1,$t3,$out
++    stxv        $out,112($outp)
++
++    xxpermdi    $t1,$in1[2],$in1[3],0b00
++    xxpermdi    $t3,$in1[4],$in1[5],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$t3,$t4,$out
++    vmsumudm    $out,$in1[6],$in2[2],$out
++    stxv        $out,128($outp)
++
++    xxpermdi    $t1,$in1[3],$in1[4],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    xxpermdi    $t1,$in1[5],$in1[6],0b00
++    vmsumudm    $out,$t1,$t4,$out
++    stxv        $out,144($outp)
++
++    vmsumudm    $out,$t3,$t2,$vzero
++    vmsumudm    $out,$in1[6],$in2[4],$out
++    stxv        $out,160($outp)
++
++    vmsumudm    $out,$t1,$t2,$vzero
++    stxv        $out,176($outp)
++
++    vmsumudm    $out,$in1[6],$in2[6],$vzero
++    stxv        $out,192($outp)
++___
++
++        endproc("p384_felem_mul");
++    }
++
++    {
++        #
++        # p384_felem_square
++        #
++
++        my ($inp) = ("r4");
++        my @in = map("v$_",(44..50));
++        my @inx2 = map("v$_",(35..41));
++
++        startproc("p384_felem_square");
++
++        push_vrs(52, 63);
++
++        $code.=<<___;
++    vspltisw    $vzero,0
++
++___
++
++        load_vrs($inp, \@in);
++
++        $code.=<<___;
++    li        $zero,0
++    li        $one,1
++    mtvsrdd        $t1,$one,$zero
++___
++
++        for (my $i = 0; $i <= 6; $i++) {
++            $code.=<<___;
++    vsld        $inx2[$i],$in[$i],$t1
++___
++        }
++
++        $code.=<<___;
++    vmsumudm    $out,$in[0],$in[0],$vzero
++    stxv        $out,0($outp)
++
++    vmsumudm    $out,$in[0],$inx2[1],$vzero
++    stxv        $out,16($outp)
++
++    vmsumudm    $out,$in[0],$inx2[2],$vzero
++    vmsumudm    $out,$in[1],$in[1],$out
++    stxv        $out,32($outp)
++
++    xxpermdi    $t1,$in[0],$in[1],0b00
++    xxpermdi    $t2,$inx2[3],$inx2[2],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    stxv        $out,48($outp)
++
++    xxpermdi    $t4,$inx2[4],$inx2[3],0b00
++    vmsumudm    $out,$t1,$t4,$vzero
++    vmsumudm    $out,$in[2],$in[2],$out
++    stxv        $out,64($outp)
++
++    xxpermdi    $t2,$inx2[5],$inx2[4],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$in[2],$inx2[3],$out
++    stxv        $out,80($outp)
++
++    xxpermdi    $t2,$inx2[6],$inx2[5],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$in[2],$inx2[4],$out
++    vmsumudm    $out,$in[3],$in[3],$out
++    stxv        $out,96($outp)
++
++    xxpermdi    $t3,$in[1],$in[2],0b00
++    vmsumudm    $out,$t3,$t2,$vzero
++    vmsumudm    $out,$in[3],$inx2[4],$out
++    stxv        $out,112($outp)
++
++    xxpermdi    $t1,$in[2],$in[3],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    vmsumudm    $out,$in[4],$in[4],$out
++    stxv        $out,128($outp)
++
++    xxpermdi    $t1,$in[3],$in[4],0b00
++    vmsumudm    $out,$t1,$t2,$vzero
++    stxv        $out,144($outp)
++
++    vmsumudm    $out,$in[4],$inx2[6],$vzero
++    vmsumudm    $out,$in[5],$in[5],$out
++    stxv        $out,160($outp)
++
++    vmsumudm    $out,$in[5],$inx2[6],$vzero
++    stxv        $out,176($outp)
++
++    vmsumudm    $out,$in[6],$in[6],$vzero
++    stxv        $out,192($outp)
++___
++
++        endproc("p384_felem_square");
++    }
++}
++
++$code =~ s/\`([^\`]*)\`/eval $1/gem;
++print $code;
++close STDOUT or die "error closing STDOUT: $!";
+diff --git a/crypto/ec/build.info b/crypto/ec/build.info
+index 1fa60a1deddd..4077bead7bdb 100644
+--- a/crypto/ec/build.info
++++ b/crypto/ec/build.info
+@@ -39,8 +39,9 @@ IF[{- !$disabled{asm} -}]
+   $ECASM_ppc64=ecp_nistz256.c ecp_ppc.c ecp_nistz256-ppc64.s x25519-ppc64.s
+   $ECDEF_ppc64=ECP_NISTZ256_ASM X25519_ASM
+   IF[{- !$disabled{'ec_nistp_64_gcc_128'} -}]
+-    $ECASM_ppc64=$ECASM_ppc64 ecp_nistp521-ppc64.s
+-    $ECDEF_ppc64=$ECDEF_ppc64 ECP_NISTP521_ASM
++    $ECASM_ppc64=$ECASM_ppc64 ecp_nistp384-ppc64.s ecp_nistp521-ppc64.s
++    $ECDEF_ppc64=$ECDEF_ppc64 ECP_NISTP384_ASM ECP_NISTP521_ASM
++    INCLUDE[ecp_nistp384.o]=..
+     INCLUDE[ecp_nistp521.o]=..
+   ENDIF
+ 
+@@ -119,6 +120,7 @@ GENERATE[ecp_nistz256-armv8.S]=asm/ecp_nistz256-armv8.pl
+ INCLUDE[ecp_nistz256-armv8.o]=..
+ GENERATE[ecp_nistz256-ppc64.s]=asm/ecp_nistz256-ppc64.pl
+ 
++GENERATE[ecp_nistp384-ppc64.s]=asm/ecp_nistp384-ppc64.pl
+ GENERATE[ecp_nistp521-ppc64.s]=asm/ecp_nistp521-ppc64.pl
+ 
+ GENERATE[x25519-x86_64.s]=asm/x25519-x86_64.pl
+diff --git a/crypto/ec/ecp_nistp384.c b/crypto/ec/ecp_nistp384.c
+index a0559487ed4e..14f9530d07c6 100644
+--- a/crypto/ec/ecp_nistp384.c
++++ b/crypto/ec/ecp_nistp384.c
+@@ -691,6 +691,15 @@ void p384_felem_mul(widefelem out, const felem in1, const felem in2);
+ 
+ static void felem_select(void)
+ {
++# if defined(_ARCH_PPC64)
++    if ((OPENSSL_ppccap_P & PPC_MADD300) && (OPENSSL_ppccap_P & PPC_ALTIVEC)) {
++        felem_square_p = p384_felem_square;
++        felem_mul_p = p384_felem_mul;
++
++        return;
++    }
++# endif
++
+     /* Default */
+     felem_square_p = felem_square_ref;
+     felem_mul_p = felem_mul_ref;
diff --git a/openssl-ecc-Remove-extraneous-parentheses-in-secp384r1.patch b/openssl-ecc-Remove-extraneous-parentheses-in-secp384r1.patch
new file mode 100644
index 0000000..a2918d9
--- /dev/null
+++ b/openssl-ecc-Remove-extraneous-parentheses-in-secp384r1.patch
@@ -0,0 +1,76 @@
+From 670e73d9084465384b11ef24802ca4a313e1d2f4 Mon Sep 17 00:00:00 2001
+From: Rohan McLure <rohanmclure@linux.ibm.com>
+Date: Tue, 15 Aug 2023 15:20:20 +1000
+Subject: [PATCH] ecc: Remove extraneous parentheses in secp384r1
+
+Substitutions in the felem_reduce() method feature unecessary
+parentheses, remove them.
+
+Signed-off-by: Rohan McLure <rohan.mclure@linux.ibm.com>
+
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
+Reviewed-by: Hugo Landau <hlandau@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/21749)
+---
+ crypto/ec/ecp_nistp384.c | 12 ++++++------
+ 1 file changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/crypto/ec/ecp_nistp384.c b/crypto/ec/ecp_nistp384.c
+index 14f9530d07c6..ff68f9cc7ad0 100644
+--- a/crypto/ec/ecp_nistp384.c
++++ b/crypto/ec/ecp_nistp384.c
+@@ -540,7 +540,7 @@ static void felem_reduce(felem out, const widefelem in)
+     acc[7] += in[12] >> 8;
+     acc[6] += (in[12] & 0xff) << 48;
+     acc[6] -= in[12] >> 16;
+-    acc[5] -= ((in[12] & 0xffff) << 40);
++    acc[5] -= (in[12] & 0xffff) << 40;
+     acc[6] += in[12] >> 48;
+     acc[5] += (in[12] & 0xffffffffffff) << 8;
+ 
+@@ -549,7 +549,7 @@ static void felem_reduce(felem out, const widefelem in)
+     acc[6] += in[11] >> 8;
+     acc[5] += (in[11] & 0xff) << 48;
+     acc[5] -= in[11] >> 16;
+-    acc[4] -= ((in[11] & 0xffff) << 40);
++    acc[4] -= (in[11] & 0xffff) << 40;
+     acc[5] += in[11] >> 48;
+     acc[4] += (in[11] & 0xffffffffffff) << 8;
+ 
+@@ -558,7 +558,7 @@ static void felem_reduce(felem out, const widefelem in)
+     acc[5] += in[10] >> 8;
+     acc[4] += (in[10] & 0xff) << 48;
+     acc[4] -= in[10] >> 16;
+-    acc[3] -= ((in[10] & 0xffff) << 40);
++    acc[3] -= (in[10] & 0xffff) << 40;
+     acc[4] += in[10] >> 48;
+     acc[3] += (in[10] & 0xffffffffffff) << 8;
+ 
+@@ -567,7 +567,7 @@ static void felem_reduce(felem out, const widefelem in)
+     acc[4] += in[9] >> 8;
+     acc[3] += (in[9] & 0xff) << 48;
+     acc[3] -= in[9] >> 16;
+-    acc[2] -= ((in[9] & 0xffff) << 40);
++    acc[2] -= (in[9] & 0xffff) << 40;
+     acc[3] += in[9] >> 48;
+     acc[2] += (in[9] & 0xffffffffffff) << 8;
+ 
+@@ -582,7 +582,7 @@ static void felem_reduce(felem out, const widefelem in)
+     acc[3] += acc[8] >> 8;
+     acc[2] += (acc[8] & 0xff) << 48;
+     acc[2] -= acc[8] >> 16;
+-    acc[1] -= ((acc[8] & 0xffff) << 40);
++    acc[1] -= (acc[8] & 0xffff) << 40;
+     acc[2] += acc[8] >> 48;
+     acc[1] += (acc[8] & 0xffffffffffff) << 8;
+ 
+@@ -591,7 +591,7 @@ static void felem_reduce(felem out, const widefelem in)
+     acc[2] += acc[7] >> 8;
+     acc[1] += (acc[7] & 0xff) << 48;
+     acc[1] -= acc[7] >> 16;
+-    acc[0] -= ((acc[7] & 0xffff) << 40);
++    acc[0] -= (acc[7] & 0xffff) << 40;
+     acc[1] += acc[7] >> 48;
+     acc[0] += (acc[7] & 0xffffffffffff) << 8;
+ 
diff --git a/openssl-load-legacy-provider.patch b/openssl-load-legacy-provider.patch
new file mode 100644
index 0000000..217d8e1
--- /dev/null
+++ b/openssl-load-legacy-provider.patch
@@ -0,0 +1,90 @@
+287863366dcdd6548dee78c7a4 Mon Sep 17 00:00:00 2001
+From: rpm-build &lt;rpm-build&gt;
+Date: Mon, 31 Jul 2023 09:41:28 +0200
+Subject: [PATCH 14/35] 0024-load-legacy-prov.patch
+
+Patch-name: 0024-load-legacy-prov.patch
+Patch-id: 24
+Patch-status: |
+    # Instructions to load legacy provider in openssl.cnf
+From-dist-git-commit: 9409bc7044cf4b5773639cce20f51399888c45fd
+---
+ apps/openssl.cnf    | 37 +++++++++++++++----------------------
+ doc/man5/config.pod |  8 ++++++++
+ 2 files changed, 23 insertions(+), 22 deletions(-)
+
+Index: openssl-3.1.4/apps/openssl.cnf
+===================================================================
+--- openssl-3.1.4.orig/apps/openssl.cnf
++++ openssl-3.1.4/apps/openssl.cnf
+@@ -42,36 +42,29 @@ tsa_policy1 = 1.2.3.4.1
+ tsa_policy2 = 1.2.3.4.5.6
+ tsa_policy3 = 1.2.3.4.5.7
+ 
+-# For FIPS
+-# Optionally include a file that is generated by the OpenSSL fipsinstall
+-# application. This file contains configuration data required by the OpenSSL
+-# fips provider. It contains a named section e.g. [fips_sect] which is
+-# referenced from the [provider_sect] below.
+-# Refer to the OpenSSL security policy for more information.
+-# .include fipsmodule.cnf
+-
+ [openssl_init]
+ providers = provider_sect
+ # Load default TLS policy configuration
+ ssl_conf = ssl_module
+ 
+-# List of providers to load
++# Uncomment the sections that start with ## below to enable the legacy provider.
++# Loading the legacy provider enables support for the following algorithms:
++# Hashing Algorithms / Message Digests: MD2, MD4, MDC2, WHIRLPOOL, RIPEMD160
++# Symmetric Ciphers: Blowfish, CAST, DES, IDEA, RC2, RC4,RC5, SEED
++# Key Derivation Function (KDF): PBKDF1
++# In general it is not recommended to use the above mentioned algorithms for
++# security critical operations, as they are cryptographically weak or vulnerable
++# to side-channel attacks and as such have been deprecated.
++
+ [provider_sect]
+ default = default_sect
+-# The fips section name should match the section name inside the
+-# included fipsmodule.cnf.
+-# fips = fips_sect
+-
+-# If no providers are activated explicitly, the default one is activated implicitly.
+-# See man 7 OSSL_PROVIDER-default for more details.
+-#
+-# If you add a section explicitly activating any other provider(s), you most
+-# probably need to explicitly activate the default provider, otherwise it
+-# becomes unavailable in openssl.  As a consequence applications depending on
+-# OpenSSL may not work correctly which could lead to significant system
+-# problems including inability to remotely access the system.
++##legacy = legacy_sect
++
+ [default_sect]
+-# activate = 1
++activate = 1
++
++##[legacy_sect]
++##activate = 1
+ 
+ [ ssl_module ]
+ 
+Index: openssl-3.1.4/doc/man5/config.pod
+===================================================================
+--- openssl-3.1.4.orig/doc/man5/config.pod
++++ openssl-3.1.4/doc/man5/config.pod
+@@ -273,6 +273,14 @@ significant.
+ All parameters in the section as well as sub-sections are made
+ available to the provider.
+ 
++=head3 Loading the legacy provider
++
++Uncomment the sections that start with ## in openssl.cnf
++to enable the legacy provider.
++Note: In general it is not recommended to use the above mentioned algorithms for
++security critical operations, as they are cryptographically weak or vulnerable
++to side-channel attacks and as such have been deprecated.
++
+ =head3 Default provider and its activation
+ 
+ If no providers are activated explicitly, the default one is activated implicitly.
diff --git a/openssl-no-date.patch b/openssl-no-date.patch
new file mode 100644
index 0000000..c910674
--- /dev/null
+++ b/openssl-no-date.patch
@@ -0,0 +1,13 @@
+Index: openssl-1.1.1-pre1/util/mkbuildinf.pl
+===================================================================
+--- openssl-1.1.1-pre1.orig/util/mkbuildinf.pl	2018-02-13 16:31:28.011389734 +0100
++++ openssl-1.1.1-pre1/util/mkbuildinf.pl	2018-02-13 16:31:51.539764582 +0100
+@@ -28,7 +28,7 @@ print <<"END_OUTPUT";
+  */
+ 
+ #define PLATFORM "platform: $platform"
+-#define DATE "built on: $date"
++#define DATE ""
+ 
+ /*
+  * Generate compiler_flags as an array of individual characters. This is a
diff --git a/openssl-no-html-docs.patch b/openssl-no-html-docs.patch
new file mode 100644
index 0000000..efda996
--- /dev/null
+++ b/openssl-no-html-docs.patch
@@ -0,0 +1,13 @@
+Index: openssl-3.1.4/Configurations/unix-Makefile.tmpl
+===================================================================
+--- openssl-3.1.4.orig/Configurations/unix-Makefile.tmpl
++++ openssl-3.1.4/Configurations/unix-Makefile.tmpl
+@@ -611,7 +611,7 @@ install_sw: install_dev install_engines
+ 
+ uninstall_sw: uninstall_runtime uninstall_modules uninstall_engines uninstall_dev
+ 
+-install_docs: install_man_docs install_html_docs
++install_docs: install_man_docs
+ 
+ uninstall_docs: uninstall_man_docs uninstall_html_docs
+ 	$(RM) -r "$(DESTDIR)$(DOCDIR)"
diff --git a/openssl-pkgconfig.patch b/openssl-pkgconfig.patch
new file mode 100644
index 0000000..862be2c
--- /dev/null
+++ b/openssl-pkgconfig.patch
@@ -0,0 +1,22 @@
+Index: openssl-1.1.1-pre3/Configurations/unix-Makefile.tmpl
+===================================================================
+--- openssl-1.1.1-pre3.orig/Configurations/unix-Makefile.tmpl	2018-03-20 15:20:03.037124698 +0100
++++ openssl-1.1.1-pre3/Configurations/unix-Makefile.tmpl	2018-03-20 15:21:04.206084731 +0100
+@@ -843,7 +843,7 @@ libcrypto.pc:
+ 	    echo 'Version: '$(VERSION); \
+ 	    echo 'Libs: -L$${libdir} -lcrypto'; \
+ 	    echo 'Libs.private: $(LIB_EX_LIBS)'; \
+-	    echo 'Cflags: -I$${includedir}' ) > libcrypto.pc
++	    echo 'Cflags: -DOPENSSL_LOAD_CONF -I$${includedir}' ) > libcrypto.pc
+ 
+ libssl.pc:
+ 	@ ( echo 'prefix=$(INSTALLTOP)'; \
+@@ -860,7 +860,7 @@ libssl.pc:
+ 	    echo 'Version: '$(VERSION); \
+ 	    echo 'Requires.private: libcrypto'; \
+ 	    echo 'Libs: -L$${libdir} -lssl'; \
+-	    echo 'Cflags: -I$${includedir}' ) > libssl.pc
++	    echo 'Cflags: -DOPENSSL_LOAD_CONF -I$${includedir}' ) > libssl.pc
+ 
+ openssl.pc:
+ 	@ ( echo 'prefix=$(INSTALLTOP)'; \
diff --git a/openssl-powerpc-ecc-Fix-stack-allocation-secp384r1-asm.patch b/openssl-powerpc-ecc-Fix-stack-allocation-secp384r1-asm.patch
new file mode 100644
index 0000000..ecfecb5
--- /dev/null
+++ b/openssl-powerpc-ecc-Fix-stack-allocation-secp384r1-asm.patch
@@ -0,0 +1,96 @@
+From 50f8b936b00dc18ce1f622a7a6aa46daf03da48b Mon Sep 17 00:00:00 2001
+From: Rohan McLure <rohanmclure@linux.ibm.com>
+Date: Wed, 16 Aug 2023 16:52:47 +1000
+Subject: [PATCH] powerpc: ecc: Fix stack allocation secp384r1 asm
+
+Assembly acceleration secp384r1 opts to not use any callee-save VSRs, as
+VSX enabled systems make extensive use of renaming, and so writebacks in
+felem_{mul,square}() can be reordered for best cache effects.
+
+Remove stack allocations. This in turn fixes unmatched push/pops in
+felem_{mul,square}().
+
+Signed-off-by: Rohan McLure <rohan.mclure@linux.ibm.com>
+
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
+Reviewed-by: Hugo Landau <hlandau@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/21749)
+---
+ crypto/ec/asm/ecp_nistp384-ppc64.pl | 49 -----------------------------
+ 1 file changed, 49 deletions(-)
+
+diff --git a/crypto/ec/asm/ecp_nistp384-ppc64.pl b/crypto/ec/asm/ecp_nistp384-ppc64.pl
+index 3f86b391af69..28f4168e5218 100755
+--- a/crypto/ec/asm/ecp_nistp384-ppc64.pl
++++ b/crypto/ec/asm/ecp_nistp384-ppc64.pl
+@@ -62,51 +62,6 @@ ($)
+ ___
+ }
+ 
+-
+-sub push_vrs($$)
+-{
+-    my ($min, $max) = @_;
+-
+-    my $count = $max - $min + 1;
+-
+-    $code.=<<___;
+-    mr      $savesp,$sp
+-    stdu        $sp,-16*`$count+1`($sp)
+-
+-___
+-        for (my $i = $min; $i <= $max; $i++) {
+-            my $mult = $max - $i + 1;
+-            $code.=<<___;
+-    stxv        $i,-16*$mult($savesp)
+-___
+-
+-    }
+-
+-    $code.=<<___;
+-
+-___
+-}
+-
+-sub pop_vrs($$)
+-{
+-    my ($min, $max) = @_;
+-
+-    $code.=<<___;
+-    ld      $savesp,0($sp)
+-___
+-    for (my $i = $min; $i <= $max; $i++) {
+-        my $mult = $max - $i + 1;
+-        $code.=<<___;
+-    lxv     $i,-16*$mult($savesp)
+-___
+-    }
+-
+-    $code.=<<___;
+-    mr      $sp,$savesp
+-
+-___
+-}
+-
+ sub load_vrs($$)
+ {
+     my ($pointer, $reg_list) = @_;
+@@ -162,8 +117,6 @@ ($$)
+ 
+         startproc("p384_felem_mul");
+ 
+-        push_vrs(52, 63);
+-
+         $code.=<<___;
+     vspltisw    $vzero,0
+ 
+@@ -268,8 +221,6 @@ ($$)
+ 
+         startproc("p384_felem_square");
+ 
+-        push_vrs(52, 63);
+-
+         $code.=<<___;
+     vspltisw    $vzero,0
+ 
diff --git a/openssl-ppc64-config.patch b/openssl-ppc64-config.patch
new file mode 100644
index 0000000..1efc39d
--- /dev/null
+++ b/openssl-ppc64-config.patch
@@ -0,0 +1,32 @@
+Index: openssl-3.0.0-alpha5/util/perl/OpenSSL/config.pm
+===================================================================
+--- openssl-3.0.0-alpha5.orig/util/perl/OpenSSL/config.pm
++++ openssl-3.0.0-alpha5/util/perl/OpenSSL/config.pm
+@@ -525,14 +525,19 @@ EOF
+             return { target => "linux-ppc64" } if $KERNEL_BITS eq '64';
+ 
+             my %config = ();
+-            if (!okrun('echo __LP64__',
+-                       'gcc -E -x c - 2>/dev/null',
+-                       'grep "^__LP64__" 2>&1 >/dev/null') ) {
+-                %config = ( cflags => [ '-m32' ],
+-                            cxxflags =>  [ '-m32' ] );
+-            }
+-            return { target => "linux-ppc",
+-                     %config };
++	    # ##
++            # if (!okrun('echo __LP64__', 'gcc -E -x c - 2>/dev/null', 'grep "^__LP64__" 2>&1 >/dev/null') ) { %config = ( cflags => [ '-m32' ], cxxflags =>  [ '-m32' ] ); }
++            # return { target => "linux-ppc",
++            #          %config };
++	    # ##
++            if (okrun('echo __LP64__', 'gcc -E -x c - 2>/dev/null',
++                      'grep "^__LP64__" 2>&1 >/dev/null') )
++                {
++                    return { target => "linux-ppc", %config };
++                } else {
++                    return { target => "linux-ppc64", %config };
++                }
++            ##
+         }
+       ],
+       [ 'ppc64le-.*-linux2',      { target => "linux-ppc64le" } ],
diff --git a/openssl-truststore.patch b/openssl-truststore.patch
new file mode 100644
index 0000000..e43f30e
--- /dev/null
+++ b/openssl-truststore.patch
@@ -0,0 +1,17 @@
+Don't use the legacy /etc/ssl/certs directory anymore but rather the
+p11-kit generated /var/lib/ca-certificates/openssl one (fate#314991)
+Index: openssl-1.1.1-pre1/include/internal/cryptlib.h
+===================================================================
+--- openssl-1.1.1-pre1.orig/include/internal/cryptlib.h	2018-02-13 14:48:12.000000000 +0100
++++ openssl-1.1.1-pre1/include/internal/cryptlib.h	2018-02-13 16:30:11.738161984 +0100
+@@ -59,8 +59,8 @@ DEFINE_LHASH_OF(MEM);
+ 
+ # ifndef OPENSSL_SYS_VMS
+ #  define X509_CERT_AREA          OPENSSLDIR
+-#  define X509_CERT_DIR           OPENSSLDIR "/certs"
+-#  define X509_CERT_FILE          OPENSSLDIR "/cert.pem"
++#  define X509_CERT_DIR           "/var/lib/ca-certificates/openssl"
++#  define X509_CERT_FILE          "/var/lib/ca-certificates/ca-bundle.pem"
+ #  define X509_PRIVATE_DIR        OPENSSLDIR "/private"
+ #  define CTLOG_FILE              OPENSSLDIR "/ct_log_list.cnf"
+ # else
diff --git a/openssl.keyring b/openssl.keyring
new file mode 100644
index 0000000..d7ab2d7
--- /dev/null
+++ b/openssl.keyring
@@ -0,0 +1,305 @@
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: 8657 ABB2 60F0 56B1 E519 0839 D9C4 D26D 0E60 4491
+Comment: Matt Caswell <matt@openssl.org>
+Comment: Matt Caswell <frodo@baggins.org>
+
+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
+=Z0q9
+-----END PGP PUBLIC KEY BLOCK-----
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: B7C1 C143 60F3 53A3 6862 E4D5 231C 84CD DCC6 9C45
+Comment: Paul Dale <pauli@openssl.org>
+
+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
+=AbiA
+-----END PGP PUBLIC KEY BLOCK-----
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: A21F AB74 B008 8AA3 6115  2586 B8EF 1A6B A9DA 2D5C
+Comment: Tomáš Mráz <tm@t8m.info>
+Comment: Tomáš Mráz <tomas@arleto.cz>
+Comment: Tomáš Mráz <tomas@openssl.org>
+
+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
+TIdjvGbJ/k4qxw==
+=Ctij
+-----END PGP PUBLIC KEY BLOCK-----
+-----BEGIN PGP PUBLIC KEY BLOCK-----
+Comment: EFC0 A467 D613 CB83 C7ED  6D30 D894 E2CE 8B3D 79F5
+Comment: OpenSSL security team <openssl-security@openssl.org>
+Comment: OpenSSL OMC <openssl-omc@openssl.org>
+Comment: OpenSSL Security <openssl-security@openssl.org>
+
+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
+=Q+Oa
+-----END PGP PUBLIC KEY BLOCK-----
diff --git a/reproducible.patch b/reproducible.patch
new file mode 100644
index 0000000..6c40942
--- /dev/null
+++ b/reproducible.patch
@@ -0,0 +1,929 @@
+commit 0fbc50ef0cb8894973d4739af62e95be825b7ccf
+Author: trigpolynom <trigpolynom@gmail.com>
+Date:   Tue Oct 17 22:44:45 2023 -0400
+
+    aes-gcm-avx512.pl: fix non-reproducibility issue
+    
+    Replace the random suffix with a counter, to make the
+    build reproducible.
+    
+    Fixes #20954
+    
+    Reviewed-by: Richard Levitte <levitte@openssl.org>
+    Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
+    Reviewed-by: Tom Cosgrove <tom.cosgrove@arm.com>
+    Reviewed-by: Hugo Landau <hlandau@openssl.org>
+    (Merged from https://github.com/openssl/openssl/pull/22415)
+
+diff --git a/crypto/modes/asm/aes-gcm-avx512.pl b/crypto/modes/asm/aes-gcm-avx512.pl
+index afd2af941a..9f9124373b 100644
+--- a/crypto/modes/asm/aes-gcm-avx512.pl
++++ b/crypto/modes/asm/aes-gcm-avx512.pl
+@@ -155,6 +155,9 @@ my $STACK_LOCAL_OFFSET = ($STACK_HKEYS_OFFSET + $HKEYS_STORAGE);
+ # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ my ($arg1, $arg2, $arg3, $arg4, $arg5, $arg6, $arg7, $arg8, $arg9, $arg10, $arg11);
+ 
++# ; Counter used for assembly label generation
++my $label_count = 0;
++
+ # ; This implementation follows the convention: for non-leaf functions (they
+ # ; must call PROLOG) %rbp is used as a frame pointer, and has fixed offset from
+ # ; the function entry: $GP_STORAGE + [8 bytes alignment (Windows only)].  This
+@@ -200,15 +203,6 @@ my $CTX_OFFSET_HTable    = (16 * 6);          #  ; (Htable) Precomputed table (a
+ # ;;; Helper functions
+ # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+-# ; Generates "random" local labels
+-sub random_string() {
+-  my @chars  = ('a' .. 'z', 'A' .. 'Z', '0' .. '9', '_');
+-  my $length = 15;
+-  my $str;
+-  map { $str .= $chars[rand(33)] } 1 .. $length;
+-  return $str;
+-}
+-
+ sub BYTE {
+   my ($reg) = @_;
+   if ($reg =~ /%r[abcd]x/i) {
+@@ -417,7 +411,7 @@ ___
+ sub EPILOG {
+   my ($hkeys_storage_on_stack, $payload_len) = @_;
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   if ($hkeys_storage_on_stack && $CLEAR_HKEYS_STORAGE_ON_EXIT) {
+ 
+@@ -425,13 +419,13 @@ sub EPILOG {
+     # ; were stored in the local frame storage
+     $code .= <<___;
+         cmpq              \$`16*16`,$payload_len
+-        jbe               .Lskip_hkeys_cleanup_${rndsuffix}
++        jbe               .Lskip_hkeys_cleanup_${label_suffix}
+         vpxor             %xmm0,%xmm0,%xmm0
+ ___
+     for (my $i = 0; $i < int($HKEYS_STORAGE / 64); $i++) {
+       $code .= "vmovdqa64         %zmm0,`$STACK_HKEYS_OFFSET + 64*$i`(%rsp)\n";
+     }
+-    $code .= ".Lskip_hkeys_cleanup_${rndsuffix}:\n";
++    $code .= ".Lskip_hkeys_cleanup_${label_suffix}:\n";
+   }
+ 
+   if ($CLEAR_SCRATCH_REGISTERS) {
+@@ -537,11 +531,11 @@ sub precompute_hkeys_on_stack {
+     && $HKEYS_RANGE ne "first32"
+     && $HKEYS_RANGE ne "last32");
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   $code .= <<___;
+         test              $HKEYS_READY,$HKEYS_READY
+-        jnz               .L_skip_hkeys_precomputation_${rndsuffix}
++        jnz               .L_skip_hkeys_precomputation_${label_suffix}
+ ___
+ 
+   if ($HKEYS_RANGE eq "first16" || $HKEYS_RANGE eq "first32" || $HKEYS_RANGE eq "all") {
+@@ -615,7 +609,7 @@ ___
+     }
+   }
+ 
+-  $code .= ".L_skip_hkeys_precomputation_${rndsuffix}:\n";
++  $code .= ".L_skip_hkeys_precomputation_${label_suffix}:\n";
+ }
+ 
+ # ;; =============================================================================
+@@ -1418,20 +1412,20 @@ sub CALC_AAD_HASH {
+ 
+   my $SHFMSK = $ZT13;
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   $code .= <<___;
+         mov               $A_IN,$T1      # ; T1 = AAD
+         mov               $A_LEN,$T2     # ; T2 = aadLen
+         or                $T2,$T2
+-        jz                .L_CALC_AAD_done_${rndsuffix}
++        jz                .L_CALC_AAD_done_${label_suffix}
+ 
+         xor               $HKEYS_READY,$HKEYS_READY
+         vmovdqa64         SHUF_MASK(%rip),$SHFMSK
+ 
+-.L_get_AAD_loop48x16_${rndsuffix}:
++.L_get_AAD_loop48x16_${label_suffix}:
+         cmp               \$`(48*16)`,$T2
+-        jl                .L_exit_AAD_loop48x16_${rndsuffix}
++        jl                .L_exit_AAD_loop48x16_${label_suffix}
+ ___
+ 
+   $code .= <<___;
+@@ -1499,15 +1493,15 @@ ___
+ 
+   $code .= <<___;
+         sub               \$`(48*16)`,$T2
+-        je                .L_CALC_AAD_done_${rndsuffix}
++        je                .L_CALC_AAD_done_${label_suffix}
+ 
+         add               \$`(48*16)`,$T1
+-        jmp               .L_get_AAD_loop48x16_${rndsuffix}
++        jmp               .L_get_AAD_loop48x16_${label_suffix}
+ 
+-.L_exit_AAD_loop48x16_${rndsuffix}:
++.L_exit_AAD_loop48x16_${label_suffix}:
+         # ; Less than 48x16 bytes remaining
+         cmp               \$`(32*16)`,$T2
+-        jl                .L_less_than_32x16_${rndsuffix}
++        jl                .L_less_than_32x16_${label_suffix}
+ ___
+ 
+   $code .= <<___;
+@@ -1556,14 +1550,14 @@ ___
+ 
+   $code .= <<___;
+         sub               \$`(32*16)`,$T2
+-        je                .L_CALC_AAD_done_${rndsuffix}
++        je                .L_CALC_AAD_done_${label_suffix}
+ 
+         add               \$`(32*16)`,$T1
+-        jmp               .L_less_than_16x16_${rndsuffix}
++        jmp               .L_less_than_16x16_${label_suffix}
+ 
+-.L_less_than_32x16_${rndsuffix}:
++.L_less_than_32x16_${label_suffix}:
+         cmp               \$`(16*16)`,$T2
+-        jl                .L_less_than_16x16_${rndsuffix}
++        jl                .L_less_than_16x16_${label_suffix}
+         # ; Get next 16 blocks
+         vmovdqu64         `64*0`($T1),$ZT1
+         vmovdqu64         `64*1`($T1),$ZT2
+@@ -1588,11 +1582,11 @@ ___
+ 
+   $code .= <<___;
+         sub               \$`(16*16)`,$T2
+-        je                .L_CALC_AAD_done_${rndsuffix}
++        je                .L_CALC_AAD_done_${label_suffix}
+ 
+         add               \$`(16*16)`,$T1
+         # ; Less than 16x16 bytes remaining
+-.L_less_than_16x16_${rndsuffix}:
++.L_less_than_16x16_${label_suffix}:
+         # ;; prep mask source address
+         lea               byte64_len_to_mask_table(%rip),$T3
+         lea               ($T3,$T2,8),$T3
+@@ -1601,28 +1595,28 @@ ___
+         add               \$15,@{[DWORD($T2)]}
+         shr               \$4,@{[DWORD($T2)]}
+         cmp               \$2,@{[DWORD($T2)]}
+-        jb                .L_AAD_blocks_1_${rndsuffix}
+-        je                .L_AAD_blocks_2_${rndsuffix}
++        jb                .L_AAD_blocks_1_${label_suffix}
++        je                .L_AAD_blocks_2_${label_suffix}
+         cmp               \$4,@{[DWORD($T2)]}
+-        jb                .L_AAD_blocks_3_${rndsuffix}
+-        je                .L_AAD_blocks_4_${rndsuffix}
++        jb                .L_AAD_blocks_3_${label_suffix}
++        je                .L_AAD_blocks_4_${label_suffix}
+         cmp               \$6,@{[DWORD($T2)]}
+-        jb                .L_AAD_blocks_5_${rndsuffix}
+-        je                .L_AAD_blocks_6_${rndsuffix}
++        jb                .L_AAD_blocks_5_${label_suffix}
++        je                .L_AAD_blocks_6_${label_suffix}
+         cmp               \$8,@{[DWORD($T2)]}
+-        jb                .L_AAD_blocks_7_${rndsuffix}
+-        je                .L_AAD_blocks_8_${rndsuffix}
++        jb                .L_AAD_blocks_7_${label_suffix}
++        je                .L_AAD_blocks_8_${label_suffix}
+         cmp               \$10,@{[DWORD($T2)]}
+-        jb                .L_AAD_blocks_9_${rndsuffix}
+-        je                .L_AAD_blocks_10_${rndsuffix}
++        jb                .L_AAD_blocks_9_${label_suffix}
++        je                .L_AAD_blocks_10_${label_suffix}
+         cmp               \$12,@{[DWORD($T2)]}
+-        jb                .L_AAD_blocks_11_${rndsuffix}
+-        je                .L_AAD_blocks_12_${rndsuffix}
++        jb                .L_AAD_blocks_11_${label_suffix}
++        je                .L_AAD_blocks_12_${label_suffix}
+         cmp               \$14,@{[DWORD($T2)]}
+-        jb                .L_AAD_blocks_13_${rndsuffix}
+-        je                .L_AAD_blocks_14_${rndsuffix}
++        jb                .L_AAD_blocks_13_${label_suffix}
++        je                .L_AAD_blocks_14_${label_suffix}
+         cmp               \$15,@{[DWORD($T2)]}
+-        je                .L_AAD_blocks_15_${rndsuffix}
++        je                .L_AAD_blocks_15_${label_suffix}
+ ___
+ 
+   # ;; fall through for 16 blocks
+@@ -1635,7 +1629,7 @@ ___
+   # ;; - jump to reduction code
+ 
+   for (my $aad_blocks = 16; $aad_blocks > 0; $aad_blocks--) {
+-    $code .= ".L_AAD_blocks_${aad_blocks}_${rndsuffix}:\n";
++    $code .= ".L_AAD_blocks_${aad_blocks}_${label_suffix}:\n";
+     if ($aad_blocks > 12) {
+       $code .= "sub               \$`12*16*8`, $T3\n";
+     } elsif ($aad_blocks > 8) {
+@@ -1656,11 +1650,11 @@ ___
+     if ($aad_blocks > 1) {
+ 
+       # ;; fall through to CALC_AAD_done in 1 block case
+-      $code .= "jmp           .L_CALC_AAD_done_${rndsuffix}\n";
++      $code .= "jmp           .L_CALC_AAD_done_${label_suffix}\n";
+     }
+ 
+   }
+-  $code .= ".L_CALC_AAD_done_${rndsuffix}:\n";
++  $code .= ".L_CALC_AAD_done_${label_suffix}:\n";
+ 
+   # ;; result in AAD_HASH
+ }
+@@ -1710,13 +1704,13 @@ sub PARTIAL_BLOCK {
+   my $IA1    = $GPTMP2;
+   my $IA2    = $GPTMP0;
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   $code .= <<___;
+         # ;; if no partial block present then LENGTH/DATA_OFFSET will be set to zero
+         mov             ($PBLOCK_LEN),$LENGTH
+         or              $LENGTH,$LENGTH
+-        je              .L_partial_block_done_${rndsuffix}         #  ;Leave Macro if no partial blocks
++        je              .L_partial_block_done_${label_suffix}         #  ;Leave Macro if no partial blocks
+ ___
+ 
+   &READ_SMALL_DATA_INPUT($XTMP0, $PLAIN_CIPH_IN, $PLAIN_CIPH_LEN, $IA0, $IA2, $MASKREG);
+@@ -1755,9 +1749,9 @@ ___
+   }
+   $code .= <<___;
+         sub               \$16,$IA1
+-        jge               .L_no_extra_mask_${rndsuffix}
++        jge               .L_no_extra_mask_${label_suffix}
+         sub               $IA1,$IA0
+-.L_no_extra_mask_${rndsuffix}:
++.L_no_extra_mask_${label_suffix}:
+         # ;; get the appropriate mask to mask out bottom $LENGTH bytes of $XTMP1
+         # ;; - mask out bottom $LENGTH bytes of $XTMP1
+         # ;; sizeof(SHIFT_MASK) == 16 bytes
+@@ -1781,7 +1775,7 @@ ___
+   }
+   $code .= <<___;
+         cmp               \$0,$IA1
+-        jl                .L_partial_incomplete_${rndsuffix}
++        jl                .L_partial_incomplete_${label_suffix}
+ ___
+ 
+   # ;; GHASH computation for the last <16 Byte block
+@@ -1793,9 +1787,9 @@ ___
+         mov               $LENGTH,$IA0
+         mov               \$16,$LENGTH
+         sub               $IA0,$LENGTH
+-        jmp               .L_enc_dec_done_${rndsuffix}
++        jmp               .L_enc_dec_done_${label_suffix}
+ 
+-.L_partial_incomplete_${rndsuffix}:
++.L_partial_incomplete_${label_suffix}:
+ ___
+   if ($win64) {
+     $code .= <<___;
+@@ -1808,7 +1802,7 @@ ___
+   $code .= <<___;
+         mov               $PLAIN_CIPH_LEN,$LENGTH
+ 
+-.L_enc_dec_done_${rndsuffix}:
++.L_enc_dec_done_${label_suffix}:
+         # ;; output encrypted Bytes
+ 
+         lea               byte_len_to_mask_table(%rip),$IA0
+@@ -1826,7 +1820,7 @@ ___
+   $code .= <<___;
+         mov               $CIPH_PLAIN_OUT,$IA0
+         vmovdqu8          $XTMP1,($IA0){$MASKREG}
+-.L_partial_block_done_${rndsuffix}:
++.L_partial_block_done_${label_suffix}:
+ ___
+ }
+ 
+@@ -2016,7 +2010,7 @@ sub INITIAL_BLOCKS_PARTIAL_GHASH {
+   my $GM              = $_[23];    # [in] ZMM with mid prodcut part
+   my $GL              = $_[24];    # [in] ZMM with lo product part
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+   # ;;; - Hash all but the last partial block of data
+@@ -2034,7 +2028,7 @@ sub INITIAL_BLOCKS_PARTIAL_GHASH {
+         # ;; NOTE: the 'jl' is always taken for num_initial_blocks = 16.
+         # ;;      This is run in the context of GCM_ENC_DEC_SMALL for length < 256.
+         cmp               \$16,$LENGTH
+-        jl                .L_small_initial_partial_block_${rndsuffix}
++        jl                .L_small_initial_partial_block_${label_suffix}
+ 
+         # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+         # ;;; Handle a full length final block - encrypt and hash all blocks
+@@ -2056,11 +2050,11 @@ ___
+       &GHASH_1_TO_16($GCM128_CTX, $HASH_IN_OUT, $ZT0, $ZT1, $ZT2, $ZT3, $ZT4,
+         $ZT5, $ZT6, $ZT7, $ZT8, &ZWORD($HASH_IN_OUT), $DAT0, $DAT1, $DAT2, $DAT3, $NUM_BLOCKS, $GH, $GM, $GL);
+     }
+-    $code .= "jmp           .L_small_initial_compute_done_${rndsuffix}\n";
++    $code .= "jmp           .L_small_initial_compute_done_${label_suffix}\n";
+   }
+ 
+   $code .= <<___;
+-.L_small_initial_partial_block_${rndsuffix}:
++.L_small_initial_partial_block_${label_suffix}:
+ 
+         # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+         # ;;; Handle ghash for a <16B final block
+@@ -2125,7 +2119,7 @@ ___
+         # ;; a partial block of data, so xor that into the hash.
+         vpxorq            $LAST_GHASH_BLK,$HASH_IN_OUT,$HASH_IN_OUT
+         # ;; The result is in $HASH_IN_OUT
+-        jmp               .L_after_reduction_${rndsuffix}
++        jmp               .L_after_reduction_${label_suffix}
+ ___
+   }
+ 
+@@ -2133,7 +2127,7 @@ ___
+   # ;;; After GHASH reduction
+   # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+ 
+-  $code .= ".L_small_initial_compute_done_${rndsuffix}:\n";
++  $code .= ".L_small_initial_compute_done_${label_suffix}:\n";
+ 
+   # ;; If using init/update/finalize, we need to xor any partial block data
+   # ;; into the hash.
+@@ -2144,13 +2138,13 @@ ___
+       $code .= <<___;
+         # ;; NOTE: for $NUM_BLOCKS = 16, $LENGTH, stored in [PBlockLen] is never zero
+         or                $LENGTH,$LENGTH
+-        je                .L_after_reduction_${rndsuffix}
++        je                .L_after_reduction_${label_suffix}
+ ___
+     }
+     $code .= "vpxorq            $LAST_GHASH_BLK,$HASH_IN_OUT,$HASH_IN_OUT\n";
+   }
+ 
+-  $code .= ".L_after_reduction_${rndsuffix}:\n";
++  $code .= ".L_after_reduction_${label_suffix}:\n";
+ 
+   # ;; Final hash is now in HASH_IN_OUT
+ }
+@@ -2266,7 +2260,7 @@ sub GHASH_16_ENCRYPT_N_GHASH_N {
+   die "GHASH_16_ENCRYPT_N_GHASH_N: num_blocks is out of bounds = $NUM_BLOCKS\n"
+     if ($NUM_BLOCKS > 16 || $NUM_BLOCKS < 0);
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   my $GH1H = $HASH_IN_OUT;
+ 
+@@ -2326,16 +2320,16 @@ ___
+ 
+   $code .= <<___;
+         cmp               \$`(256 - $NUM_BLOCKS)`,@{[DWORD($CTR_CHECK)]}
+-        jae               .L_16_blocks_overflow_${rndsuffix}
++        jae               .L_16_blocks_overflow_${label_suffix}
+ ___
+ 
+   &ZMM_OPCODE3_DSTR_SRC1R_SRC2R_BLOCKS_0_16(
+     $NUM_BLOCKS, "vpaddd", $B00_03, $B04_07,     $B08_11,    $B12_15,    $CTR_BE,
+     $B00_03,     $B04_07,  $B08_11, $ADDBE_1234, $ADDBE_4x4, $ADDBE_4x4, $ADDBE_4x4);
+   $code .= <<___;
+-        jmp               .L_16_blocks_ok_${rndsuffix}
++        jmp               .L_16_blocks_ok_${label_suffix}
+ 
+-.L_16_blocks_overflow_${rndsuffix}:
++.L_16_blocks_overflow_${label_suffix}:
+         vpshufb           $SHFMSK,$CTR_BE,$CTR_BE
+         vpaddd            ddq_add_1234(%rip),$CTR_BE,$B00_03
+ ___
+@@ -2355,7 +2349,7 @@ ___
+     $NUM_BLOCKS, "vpshufb", $B00_03, $B04_07, $B08_11, $B12_15, $B00_03,
+     $B04_07,     $B08_11,   $B12_15, $SHFMSK, $SHFMSK, $SHFMSK, $SHFMSK);
+   $code .= <<___;
+-.L_16_blocks_ok_${rndsuffix}:
++.L_16_blocks_ok_${label_suffix}:
+ 
+         # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+         # ;; - pre-load constants
+@@ -2805,53 +2799,53 @@ sub GCM_ENC_DEC_LAST {
+   my $MASKREG            = $_[44];    # [clobbered] mask register
+   my $PBLOCK_LEN         = $_[45];    # [in] partial block length
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   $code .= <<___;
+         mov               @{[DWORD($LENGTH)]},@{[DWORD($IA0)]}
+         add               \$15,@{[DWORD($IA0)]}
+         shr               \$4,@{[DWORD($IA0)]}
+-        je                .L_last_num_blocks_is_0_${rndsuffix}
++        je                .L_last_num_blocks_is_0_${label_suffix}
+ 
+         cmp               \$8,@{[DWORD($IA0)]}
+-        je                .L_last_num_blocks_is_8_${rndsuffix}
+-        jb                .L_last_num_blocks_is_7_1_${rndsuffix}
++        je                .L_last_num_blocks_is_8_${label_suffix}
++        jb                .L_last_num_blocks_is_7_1_${label_suffix}
+ 
+ 
+         cmp               \$12,@{[DWORD($IA0)]}
+-        je                .L_last_num_blocks_is_12_${rndsuffix}
+-        jb                .L_last_num_blocks_is_11_9_${rndsuffix}
++        je                .L_last_num_blocks_is_12_${label_suffix}
++        jb                .L_last_num_blocks_is_11_9_${label_suffix}
+ 
+         # ;; 16, 15, 14 or 13
+         cmp               \$15,@{[DWORD($IA0)]}
+-        je                .L_last_num_blocks_is_15_${rndsuffix}
+-        ja                .L_last_num_blocks_is_16_${rndsuffix}
++        je                .L_last_num_blocks_is_15_${label_suffix}
++        ja                .L_last_num_blocks_is_16_${label_suffix}
+         cmp               \$14,@{[DWORD($IA0)]}
+-        je                .L_last_num_blocks_is_14_${rndsuffix}
+-        jmp               .L_last_num_blocks_is_13_${rndsuffix}
++        je                .L_last_num_blocks_is_14_${label_suffix}
++        jmp               .L_last_num_blocks_is_13_${label_suffix}
+ 
+-.L_last_num_blocks_is_11_9_${rndsuffix}:
++.L_last_num_blocks_is_11_9_${label_suffix}:
+         # ;; 11, 10 or 9
+         cmp               \$10,@{[DWORD($IA0)]}
+-        je                .L_last_num_blocks_is_10_${rndsuffix}
+-        ja                .L_last_num_blocks_is_11_${rndsuffix}
+-        jmp               .L_last_num_blocks_is_9_${rndsuffix}
++        je                .L_last_num_blocks_is_10_${label_suffix}
++        ja                .L_last_num_blocks_is_11_${label_suffix}
++        jmp               .L_last_num_blocks_is_9_${label_suffix}
+ 
+-.L_last_num_blocks_is_7_1_${rndsuffix}:
++.L_last_num_blocks_is_7_1_${label_suffix}:
+         cmp               \$4,@{[DWORD($IA0)]}
+-        je                .L_last_num_blocks_is_4_${rndsuffix}
+-        jb                .L_last_num_blocks_is_3_1_${rndsuffix}
++        je                .L_last_num_blocks_is_4_${label_suffix}
++        jb                .L_last_num_blocks_is_3_1_${label_suffix}
+         # ;; 7, 6 or 5
+         cmp               \$6,@{[DWORD($IA0)]}
+-        ja                .L_last_num_blocks_is_7_${rndsuffix}
+-        je                .L_last_num_blocks_is_6_${rndsuffix}
+-        jmp               .L_last_num_blocks_is_5_${rndsuffix}
++        ja                .L_last_num_blocks_is_7_${label_suffix}
++        je                .L_last_num_blocks_is_6_${label_suffix}
++        jmp               .L_last_num_blocks_is_5_${label_suffix}
+ 
+-.L_last_num_blocks_is_3_1_${rndsuffix}:
++.L_last_num_blocks_is_3_1_${label_suffix}:
+         # ;; 3, 2 or 1
+         cmp               \$2,@{[DWORD($IA0)]}
+-        ja                .L_last_num_blocks_is_3_${rndsuffix}
+-        je                .L_last_num_blocks_is_2_${rndsuffix}
++        ja                .L_last_num_blocks_is_3_${label_suffix}
++        je                .L_last_num_blocks_is_2_${label_suffix}
+ ___
+ 
+   # ;; fall through for `jmp .L_last_num_blocks_is_1`
+@@ -2859,7 +2853,7 @@ ___
+   # ;; Use rep to generate different block size variants
+   # ;; - one block size has to be the first one
+   for my $num_blocks (1 .. 16) {
+-    $code .= ".L_last_num_blocks_is_${num_blocks}_${rndsuffix}:\n";
++    $code .= ".L_last_num_blocks_is_${num_blocks}_${label_suffix}:\n";
+     &GHASH_16_ENCRYPT_N_GHASH_N(
+       $AES_KEYS,   $GCM128_CTX,  $CIPH_PLAIN_OUT, $PLAIN_CIPH_IN,  $DATA_OFFSET,
+       $LENGTH,     $CTR_BE,      $CTR_CHECK,      $HASHKEY_OFFSET, $GHASHIN_BLK_OFFSET,
+@@ -2872,10 +2866,10 @@ ___
+       $ENC_DEC,    $HASH_IN_OUT, $IA0,            $IA1,            $MASKREG,
+       $num_blocks, $PBLOCK_LEN);
+ 
+-    $code .= "jmp           .L_last_blocks_done_${rndsuffix}\n";
++    $code .= "jmp           .L_last_blocks_done_${label_suffix}\n";
+   }
+ 
+-  $code .= ".L_last_num_blocks_is_0_${rndsuffix}:\n";
++  $code .= ".L_last_num_blocks_is_0_${label_suffix}:\n";
+ 
+   # ;; if there is 0 blocks to cipher then there are only 16 blocks for ghash and reduction
+   # ;; - convert mid into end_reduce
+@@ -2891,7 +2885,7 @@ ___
+     $GHASHIN_BLK_OFFSET, 0, "%rsp", $HASHKEY_OFFSET, 0, $HASH_IN_OUT, $ZT00, $ZT01,
+     $ZT02, $ZT03, $ZT04, $ZT05, $ZT06, $ZT07, $ZT08, $ZT09);
+ 
+-  $code .= ".L_last_blocks_done_${rndsuffix}:\n";
++  $code .= ".L_last_blocks_done_${label_suffix}:\n";
+ }
+ 
+ # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+@@ -2985,20 +2979,20 @@ sub GHASH_16_ENCRYPT_16_PARALLEL {
+   my $GHDAT1 = $ZT21;
+   my $GHDAT2 = $ZT22;
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+   # ;; prepare counter blocks
+ 
+   $code .= <<___;
+         cmpb              \$`(256 - 16)`,@{[BYTE($CTR_CHECK)]}
+-        jae               .L_16_blocks_overflow_${rndsuffix}
++        jae               .L_16_blocks_overflow_${label_suffix}
+         vpaddd            $ADDBE_1234,$CTR_BE,$B00_03
+         vpaddd            $ADDBE_4x4,$B00_03,$B04_07
+         vpaddd            $ADDBE_4x4,$B04_07,$B08_11
+         vpaddd            $ADDBE_4x4,$B08_11,$B12_15
+-        jmp               .L_16_blocks_ok_${rndsuffix}
+-.L_16_blocks_overflow_${rndsuffix}:
++        jmp               .L_16_blocks_ok_${label_suffix}
++.L_16_blocks_overflow_${label_suffix}:
+         vpshufb           $SHFMSK,$CTR_BE,$CTR_BE
+         vmovdqa64         ddq_add_4444(%rip),$B12_15
+         vpaddd            ddq_add_1234(%rip),$CTR_BE,$B00_03
+@@ -3009,7 +3003,7 @@ sub GHASH_16_ENCRYPT_16_PARALLEL {
+         vpshufb           $SHFMSK,$B04_07,$B04_07
+         vpshufb           $SHFMSK,$B08_11,$B08_11
+         vpshufb           $SHFMSK,$B12_15,$B12_15
+-.L_16_blocks_ok_${rndsuffix}:
++.L_16_blocks_ok_${label_suffix}:
+ ___
+ 
+   # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+@@ -3338,25 +3332,25 @@ sub ENCRYPT_SINGLE_BLOCK {
+   my $XMM0    = $_[1];    # ; [in/out]
+   my $GPR1    = $_[2];    # ; [clobbered]
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   $code .= <<___;
+         # ; load number of rounds from AES_KEY structure (offset in bytes is
+         # ; size of the |rd_key| buffer)
+         mov             `4*15*4`($AES_KEY),@{[DWORD($GPR1)]}
+         cmp             \$9,@{[DWORD($GPR1)]}
+-        je              .Laes_128_${rndsuffix}
++        je              .Laes_128_${label_suffix}
+         cmp             \$11,@{[DWORD($GPR1)]}
+-        je              .Laes_192_${rndsuffix}
++        je              .Laes_192_${label_suffix}
+         cmp             \$13,@{[DWORD($GPR1)]}
+-        je              .Laes_256_${rndsuffix}
+-        jmp             .Lexit_aes_${rndsuffix}
++        je              .Laes_256_${label_suffix}
++        jmp             .Lexit_aes_${label_suffix}
+ ___
+   for my $keylen (sort keys %aes_rounds) {
+     my $nr = $aes_rounds{$keylen};
+     $code .= <<___;
+ .align 32
+-.Laes_${keylen}_${rndsuffix}:
++.Laes_${keylen}_${label_suffix}:
+ ___
+     $code .= "vpxorq          `16*0`($AES_KEY),$XMM0, $XMM0\n\n";
+     for (my $i = 1; $i <= $nr; $i++) {
+@@ -3364,10 +3358,10 @@ ___
+     }
+     $code .= <<___;
+         vaesenclast     `16*($nr+1)`($AES_KEY),$XMM0,$XMM0
+-        jmp .Lexit_aes_${rndsuffix}
++        jmp .Lexit_aes_${label_suffix}
+ ___
+   }
+-  $code .= ".Lexit_aes_${rndsuffix}:\n\n";
++  $code .= ".Lexit_aes_${label_suffix}:\n\n";
+ }
+ 
+ sub CALC_J0 {
+@@ -3562,52 +3556,52 @@ sub GCM_ENC_DEC_SMALL {
+   my $SHUFMASK       = $_[29];    # [in] ZMM with BE/LE shuffle mask
+   my $PBLOCK_LEN     = $_[30];    # [in] partial block length
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   $code .= <<___;
+         cmp               \$8,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_8_${rndsuffix}
+-        jl                .L_small_initial_num_blocks_is_7_1_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_8_${label_suffix}
++        jl                .L_small_initial_num_blocks_is_7_1_${label_suffix}
+ 
+ 
+         cmp               \$12,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_12_${rndsuffix}
+-        jl                .L_small_initial_num_blocks_is_11_9_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_12_${label_suffix}
++        jl                .L_small_initial_num_blocks_is_11_9_${label_suffix}
+ 
+         # ;; 16, 15, 14 or 13
+         cmp               \$16,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_16_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_16_${label_suffix}
+         cmp               \$15,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_15_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_15_${label_suffix}
+         cmp               \$14,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_14_${rndsuffix}
+-        jmp               .L_small_initial_num_blocks_is_13_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_14_${label_suffix}
++        jmp               .L_small_initial_num_blocks_is_13_${label_suffix}
+ 
+-.L_small_initial_num_blocks_is_11_9_${rndsuffix}:
++.L_small_initial_num_blocks_is_11_9_${label_suffix}:
+         # ;; 11, 10 or 9
+         cmp               \$11,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_11_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_11_${label_suffix}
+         cmp               \$10,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_10_${rndsuffix}
+-        jmp               .L_small_initial_num_blocks_is_9_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_10_${label_suffix}
++        jmp               .L_small_initial_num_blocks_is_9_${label_suffix}
+ 
+-.L_small_initial_num_blocks_is_7_1_${rndsuffix}:
++.L_small_initial_num_blocks_is_7_1_${label_suffix}:
+         cmp               \$4,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_4_${rndsuffix}
+-        jl                .L_small_initial_num_blocks_is_3_1_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_4_${label_suffix}
++        jl                .L_small_initial_num_blocks_is_3_1_${label_suffix}
+         # ;; 7, 6 or 5
+         cmp               \$7,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_7_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_7_${label_suffix}
+         cmp               \$6,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_6_${rndsuffix}
+-        jmp               .L_small_initial_num_blocks_is_5_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_6_${label_suffix}
++        jmp               .L_small_initial_num_blocks_is_5_${label_suffix}
+ 
+-.L_small_initial_num_blocks_is_3_1_${rndsuffix}:
++.L_small_initial_num_blocks_is_3_1_${label_suffix}:
+         # ;; 3, 2 or 1
+         cmp               \$3,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_3_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_3_${label_suffix}
+         cmp               \$2,$NUM_BLOCKS
+-        je                .L_small_initial_num_blocks_is_2_${rndsuffix}
++        je                .L_small_initial_num_blocks_is_2_${label_suffix}
+ 
+         # ;; for $NUM_BLOCKS == 1, just fall through and no 'jmp' needed
+ 
+@@ -3616,7 +3610,7 @@ sub GCM_ENC_DEC_SMALL {
+ ___
+ 
+   for (my $num_blocks = 1; $num_blocks <= 16; $num_blocks++) {
+-    $code .= ".L_small_initial_num_blocks_is_${num_blocks}_${rndsuffix}:\n";
++    $code .= ".L_small_initial_num_blocks_is_${num_blocks}_${label_suffix}:\n";
+     &INITIAL_BLOCKS_PARTIAL(
+       $AES_KEYS,   $GCM128_CTX, $CIPH_PLAIN_OUT, $PLAIN_CIPH_IN, $LENGTH,   $DATA_OFFSET,
+       $num_blocks, $CTR,        $HASH_IN_OUT,    $ENC_DEC,       $ZTMP0,    $ZTMP1,
+@@ -3625,11 +3619,11 @@ ___
+       $ZTMP14,     $IA0,        $IA1,            $MASKREG,       $SHUFMASK, $PBLOCK_LEN);
+ 
+     if ($num_blocks != 16) {
+-      $code .= "jmp           .L_small_initial_blocks_encrypted_${rndsuffix}\n";
++      $code .= "jmp           .L_small_initial_blocks_encrypted_${label_suffix}\n";
+     }
+   }
+ 
+-  $code .= ".L_small_initial_blocks_encrypted_${rndsuffix}:\n";
++  $code .= ".L_small_initial_blocks_encrypted_${label_suffix}:\n";
+ }
+ 
+ # ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+@@ -3710,7 +3704,7 @@ sub GCM_ENC_DEC {
+ 
+   my $MASKREG = "%k1";
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   # ;; reduction every 48 blocks, depth 32 blocks
+   # ;; @note 48 blocks is the maximum capacity of the stack frame
+@@ -3751,7 +3745,7 @@ sub GCM_ENC_DEC {
+   } else {
+     $code .= "or                $PLAIN_CIPH_LEN,$PLAIN_CIPH_LEN\n";
+   }
+-  $code .= "je            .L_enc_dec_done_${rndsuffix}\n";
++  $code .= "je            .L_enc_dec_done_${label_suffix}\n";
+ 
+   # Length value from context $CTX_OFFSET_InLen`($GCM128_CTX) is updated in
+   # 'providers/implementations/ciphers/cipher_aes_gcm_hw_vaes_avx512.inc'
+@@ -3778,12 +3772,12 @@ sub GCM_ENC_DEC {
+   # ;; There may be no more data if it was consumed in the partial block.
+   $code .= <<___;
+         sub               $DATA_OFFSET,$LENGTH
+-        je                .L_enc_dec_done_${rndsuffix}
++        je                .L_enc_dec_done_${label_suffix}
+ ___
+ 
+   $code .= <<___;
+         cmp               \$`(16 * 16)`,$LENGTH
+-        jbe              .L_message_below_equal_16_blocks_${rndsuffix}
++        jbe              .L_message_below_equal_16_blocks_${label_suffix}
+ 
+         vmovdqa64         SHUF_MASK(%rip),$SHUF_MASK
+         vmovdqa64         ddq_addbe_4444(%rip),$ADDBE_4x4
+@@ -3815,7 +3809,7 @@ ___
+ 
+   $code .= <<___;
+         cmp               \$`(32 * 16)`,$LENGTH
+-        jb                .L_message_below_32_blocks_${rndsuffix}
++        jb                .L_message_below_32_blocks_${label_suffix}
+ ___
+ 
+   # ;; ==== AES-CTR - next 16 blocks
+@@ -3836,13 +3830,13 @@ ___
+         sub               \$`(32 * 16)`,$LENGTH
+ 
+         cmp               \$`($big_loop_nblocks * 16)`,$LENGTH
+-        jb                .L_no_more_big_nblocks_${rndsuffix}
++        jb                .L_no_more_big_nblocks_${label_suffix}
+ ___
+ 
+   # ;; ====
+   # ;; ==== AES-CTR + GHASH - 48 blocks loop
+   # ;; ====
+-  $code .= ".L_encrypt_big_nblocks_${rndsuffix}:\n";
++  $code .= ".L_encrypt_big_nblocks_${label_suffix}:\n";
+ 
+   # ;; ==== AES-CTR + GHASH - 16 blocks, start
+   $aesout_offset      = ($STACK_LOCAL_OFFSET + (32 * 16));
+@@ -3893,15 +3887,15 @@ ___
+         add               \$`($big_loop_nblocks * 16)`,$DATA_OFFSET
+         sub               \$`($big_loop_nblocks * 16)`,$LENGTH
+         cmp               \$`($big_loop_nblocks * 16)`,$LENGTH
+-        jae               .L_encrypt_big_nblocks_${rndsuffix}
++        jae               .L_encrypt_big_nblocks_${label_suffix}
+ 
+-.L_no_more_big_nblocks_${rndsuffix}:
++.L_no_more_big_nblocks_${label_suffix}:
+ 
+         cmp               \$`(32 * 16)`,$LENGTH
+-        jae               .L_encrypt_32_blocks_${rndsuffix}
++        jae               .L_encrypt_32_blocks_${label_suffix}
+ 
+         cmp               \$`(16 * 16)`,$LENGTH
+-        jae               .L_encrypt_16_blocks_${rndsuffix}
++        jae               .L_encrypt_16_blocks_${label_suffix}
+ ___
+ 
+   # ;; =====================================================
+@@ -3909,7 +3903,7 @@ ___
+   # ;; ==== GHASH 1 x 16 blocks
+   # ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks
+   # ;; ====      then GHASH N blocks
+-  $code .= ".L_encrypt_0_blocks_ghash_32_${rndsuffix}:\n";
++  $code .= ".L_encrypt_0_blocks_ghash_32_${label_suffix}:\n";
+ 
+   # ;; calculate offset to the right hash key
+   $code .= <<___;
+@@ -3937,7 +3931,7 @@ ___
+     $IA0,        $IA5,        $MASKREG,        $PBLOCK_LEN);
+ 
+   $code .= "vpshufb           @{[XWORD($SHUF_MASK)]},$CTR_BLOCKx,$CTR_BLOCKx\n";
+-  $code .= "jmp           .L_ghash_done_${rndsuffix}\n";
++  $code .= "jmp           .L_ghash_done_${label_suffix}\n";
+ 
+   # ;; =====================================================
+   # ;; =====================================================
+@@ -3946,7 +3940,7 @@ ___
+   # ;; ==== GHASH 1 x 16 blocks (reduction)
+   # ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks
+   # ;; ====      then GHASH N blocks
+-  $code .= ".L_encrypt_32_blocks_${rndsuffix}:\n";
++  $code .= ".L_encrypt_32_blocks_${label_suffix}:\n";
+ 
+   # ;; ==== AES-CTR + GHASH - 16 blocks, start
+   $aesout_offset  = ($STACK_LOCAL_OFFSET + (32 * 16));
+@@ -4007,7 +4001,7 @@ ___
+     $IA0,        $IA5,        $MASKREG,        $PBLOCK_LEN);
+ 
+   $code .= "vpshufb           @{[XWORD($SHUF_MASK)]},$CTR_BLOCKx,$CTR_BLOCKx\n";
+-  $code .= "jmp           .L_ghash_done_${rndsuffix}\n";
++  $code .= "jmp           .L_ghash_done_${label_suffix}\n";
+ 
+   # ;; =====================================================
+   # ;; =====================================================
+@@ -4015,7 +4009,7 @@ ___
+   # ;; ==== GHASH 1 x 16 blocks
+   # ;; ==== GHASH 1 x 16 blocks (reduction) & encrypt N blocks
+   # ;; ====      then GHASH N blocks
+-  $code .= ".L_encrypt_16_blocks_${rndsuffix}:\n";
++  $code .= ".L_encrypt_16_blocks_${label_suffix}:\n";
+ 
+   # ;; ==== AES-CTR + GHASH - 16 blocks, start
+   $aesout_offset  = ($STACK_LOCAL_OFFSET + (32 * 16));
+@@ -4059,9 +4053,9 @@ ___
+ 
+   $code .= "vpshufb           @{[XWORD($SHUF_MASK)]},$CTR_BLOCKx,$CTR_BLOCKx\n";
+   $code .= <<___;
+-        jmp               .L_ghash_done_${rndsuffix}
++        jmp               .L_ghash_done_${label_suffix}
+ 
+-.L_message_below_32_blocks_${rndsuffix}:
++.L_message_below_32_blocks_${label_suffix}:
+         # ;; 32 > number of blocks > 16
+ 
+         sub               \$`(16 * 16)`,$LENGTH
+@@ -4094,9 +4088,9 @@ ___
+ 
+   $code .= "vpshufb           @{[XWORD($SHUF_MASK)]},$CTR_BLOCKx,$CTR_BLOCKx\n";
+   $code .= <<___;
+-        jmp           .L_ghash_done_${rndsuffix}
++        jmp           .L_ghash_done_${label_suffix}
+ 
+-.L_message_below_equal_16_blocks_${rndsuffix}:
++.L_message_below_equal_16_blocks_${label_suffix}:
+         # ;; Determine how many blocks to process
+         # ;; - process one additional block if there is a partial block
+         mov               @{[DWORD($LENGTH)]},@{[DWORD($IA1)]}
+@@ -4113,13 +4107,13 @@ ___
+ 
+   # ;; fall through to exit
+ 
+-  $code .= ".L_ghash_done_${rndsuffix}:\n";
++  $code .= ".L_ghash_done_${label_suffix}:\n";
+ 
+   # ;; save the last counter block
+   $code .= "vmovdqu64         $CTR_BLOCKx,`$CTX_OFFSET_CurCount`($GCM128_CTX)\n";
+   $code .= <<___;
+         vmovdqu64         $AAD_HASHx,`$CTX_OFFSET_AadHash`($GCM128_CTX)
+-.L_enc_dec_done_${rndsuffix}:
++.L_enc_dec_done_${label_suffix}:
+ ___
+ }
+ 
+@@ -4155,7 +4149,7 @@ sub INITIAL_BLOCKS_16 {
+   my $B08_11 = $T7;
+   my $B12_15 = $T8;
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   my $stack_offset = $BLK_OFFSET;
+   $code .= <<___;
+@@ -4163,13 +4157,13 @@ sub INITIAL_BLOCKS_16 {
+         # ;; prepare counter blocks
+ 
+         cmpb              \$`(256 - 16)`,@{[BYTE($CTR_CHECK)]}
+-        jae               .L_next_16_overflow_${rndsuffix}
++        jae               .L_next_16_overflow_${label_suffix}
+         vpaddd            $ADDBE_1234,$CTR,$B00_03
+         vpaddd            $ADDBE_4x4,$B00_03,$B04_07
+         vpaddd            $ADDBE_4x4,$B04_07,$B08_11
+         vpaddd            $ADDBE_4x4,$B08_11,$B12_15
+-        jmp               .L_next_16_ok_${rndsuffix}
+-.L_next_16_overflow_${rndsuffix}:
++        jmp               .L_next_16_ok_${label_suffix}
++.L_next_16_overflow_${label_suffix}:
+         vpshufb           $SHUF_MASK,$CTR,$CTR
+         vmovdqa64         ddq_add_4444(%rip),$B12_15
+         vpaddd            ddq_add_1234(%rip),$CTR,$B00_03
+@@ -4180,7 +4174,7 @@ sub INITIAL_BLOCKS_16 {
+         vpshufb           $SHUF_MASK,$B04_07,$B04_07
+         vpshufb           $SHUF_MASK,$B08_11,$B08_11
+         vpshufb           $SHUF_MASK,$B12_15,$B12_15
+-.L_next_16_ok_${rndsuffix}:
++.L_next_16_ok_${label_suffix}:
+         vshufi64x2        \$0b11111111,$B12_15,$B12_15,$CTR
+         addb               \$16,@{[BYTE($CTR_CHECK)]}
+         # ;; === load 16 blocks of data
+@@ -4264,7 +4258,7 @@ sub GCM_COMPLETE {
+   my $GCM128_CTX = $_[0];
+   my $PBLOCK_LEN = $_[1];
+ 
+-  my $rndsuffix = &random_string();
++  my $label_suffix = $label_count++;
+ 
+   $code .= <<___;
+         vmovdqu           @{[HashKeyByIdx(1,$GCM128_CTX)]},%xmm2
+@@ -4276,14 +4270,14 @@ ___
+ 
+         # ;; Process the final partial block.
+         cmp               \$0,$PBLOCK_LEN
+-        je                .L_partial_done_${rndsuffix}
++        je                .L_partial_done_${label_suffix}
+ ___
+ 
+   #  ;GHASH computation for the last <16 Byte block
+   &GHASH_MUL("%xmm4", "%xmm2", "%xmm0", "%xmm16", "%xmm17");
+ 
+   $code .= <<___;
+-.L_partial_done_${rndsuffix}:
++.L_partial_done_${label_suffix}:
+         vmovq           `$CTX_OFFSET_InLen`($GCM128_CTX), %xmm5
+         vpinsrq         \$1, `$CTX_OFFSET_AadLen`($GCM128_CTX), %xmm5, %xmm5    #  ; xmm5 = len(A)||len(C)
+         vpsllq          \$3, %xmm5, %xmm5                                       #  ; convert bytes into bits
+@@ -4297,7 +4291,7 @@ ___
+         vpshufb         SHUF_MASK(%rip),%xmm4,%xmm4      # ; perform a 16Byte swap
+         vpxor           %xmm4,%xmm3,%xmm3
+ 
+-.L_return_T_${rndsuffix}:
++.L_return_T_${label_suffix}:
+         vmovdqu           %xmm3,`$CTX_OFFSET_AadHash`($GCM128_CTX)
+ ___
+ }
diff --git a/showciphers.c b/showciphers.c
new file mode 100644
index 0000000..9001c31
--- /dev/null
+++ b/showciphers.c
@@ -0,0 +1,27 @@
+#include <openssl/err.h>
+#include <openssl/ssl.h>
+
+int main() {
+    SSL_CTX *ctx = NULL;
+    SSL *ssl = NULL;
+    STACK_OF(SSL_CIPHER) *sk = NULL;
+    const SSL_METHOD *meth = TLS_server_method();
+    int i;
+    const char *p;
+
+    ctx = SSL_CTX_new(meth);
+    if (ctx == NULL)
+        return 1;
+    ssl = SSL_new(ctx);
+    if (ssl == NULL)
+        return 1;
+    sk = SSL_get_ciphers(ssl);
+    for (i = 0; i < sk_SSL_CIPHER_num(sk); i++) {
+        const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, i);
+        p = SSL_CIPHER_get_name(c);
+        if (p == NULL)
+            break;
+        printf("%s\n", p);
+    }
+    return 0;
+}