diff --git a/SOURCES/0012-Disable-explicit-ec.patch b/SOURCES/0012-Disable-explicit-ec.patch
index a1df020..9c3ef57 100644
--- a/SOURCES/0012-Disable-explicit-ec.patch
+++ b/SOURCES/0012-Disable-explicit-ec.patch
@@ -1,80 +1,122 @@
-diff -up openssl-3.0.1/crypto/ec/ec_lib.c.disable_explicit_ec openssl-3.0.1/crypto/ec/ec_lib.c
---- openssl-3.0.1/crypto/ec/ec_lib.c.disable_explicit_ec	2022-02-22 09:08:48.557823665 +0100
-+++ openssl-3.0.1/crypto/ec/ec_lib.c	2022-02-22 09:09:26.634133847 +0100
-@@ -1458,7 +1458,7 @@ static EC_GROUP *ec_group_explicit_to_na
-                 goto err;
-         }
-     } else {
--        ret_group = (EC_GROUP *)group;
-+        goto err;
-     }
-     EC_GROUP_free(dup);
-     return ret_group;
-diff -up openssl-3.0.1/providers/implementations/keymgmt/ec_kmgmt.c.disable_explicit_ec openssl-3.0.1/providers/implementations/keymgmt/ec_kmgmt.c
---- openssl-3.0.1/providers/implementations/keymgmt/ec_kmgmt.c.disable_explicit_ec	2022-02-22 13:04:16.850856612 +0100
-+++ openssl-3.0.1/providers/implementations/keymgmt/ec_kmgmt.c	2022-02-22 14:16:19.848369641 +0100
-@@ -936,11 +936,8 @@ int ec_validate(const void *keydata, int
-     if ((selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
-         int flags = EC_KEY_get_flags(eck);
+diff -up openssl-3.0.1/crypto/ec/ec_asn1.c.disable_explicit_ec openssl-3.0.1/crypto/ec/ec_asn1.c
+--- openssl-3.0.1/crypto/ec/ec_asn1.c.disable_explicit_ec	2022-03-22 13:10:45.718077845 +0100
++++ openssl-3.0.1/crypto/ec/ec_asn1.c	2022-03-22 13:12:46.626599016 +0100
+@@ -895,6 +895,12 @@ EC_GROUP *d2i_ECPKParameters(EC_GROUP **
+     if (params->type == ECPKPARAMETERS_TYPE_EXPLICIT)
+         group->decoded_from_explicit_params = 1;
  
--        if ((flags & EC_FLAG_CHECK_NAMED_GROUP) != 0)
--            ok = ok && EC_GROUP_check_named_curve(EC_KEY_get0_group(eck),
--                           (flags & EC_FLAG_CHECK_NAMED_GROUP_NIST) != 0, ctx);
--        else
--            ok = ok && EC_GROUP_check(EC_KEY_get0_group(eck), ctx);
-+        ok = ok && EC_GROUP_check_named_curve(EC_KEY_get0_group(eck),
-+                      (flags & EC_FLAG_CHECK_NAMED_GROUP_NIST) != 0, ctx);
++    if (EC_GROUP_check_named_curve(group, 0, NULL) == NID_undef) {
++        EC_GROUP_free(group);
++        ECPKPARAMETERS_free(params);
++        return NULL;
++    }
++
+     if (a) {
+         EC_GROUP_free(*a);
+         *a = group;
+@@ -954,6 +959,11 @@ EC_KEY *d2i_ECPrivateKey(EC_KEY **a, con
+         goto err;
      }
  
-     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
-@@ -1217,6 +1214,10 @@ static int ec_gen_assign_group(EC_KEY *e
-         ERR_raise(ERR_LIB_PROV, PROV_R_NO_PARAMETERS_SET);
-         return 0;
-     }
-+    if (EC_GROUP_get_curve_name(group) == NID_undef) {
-+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_CURVE);
-+        return 0;
++    if (EC_GROUP_check_named_curve(ret->group, 0, NULL) == NID_undef) {
++        ERR_raise(ERR_LIB_EC, EC_R_UNKNOWN_GROUP);
++        goto err;
 +    }
-     return EC_KEY_set_group(ec, group) > 0;
- }
++
+     ret->version = priv_key->version;
  
-diff -up openssl-3.0.1/providers/common/securitycheck.c.disable_explicit_ec openssl-3.0.1/providers/common/securitycheck.c
---- openssl-3.0.1/providers/common/securitycheck.c.disable_explicit_ec	2022-02-25 11:44:19.554673396 +0100
-+++ openssl-3.0.1/providers/common/securitycheck.c	2022-02-25 12:16:38.168610089 +0100
-@@ -93,22 +93,22 @@ int ossl_rsa_check_key(OSSL_LIB_CTX *ctx
- int ossl_ec_check_key(OSSL_LIB_CTX *ctx, const EC_KEY *ec, int protect)
- {
- # if !defined(OPENSSL_NO_FIPS_SECURITYCHECKS)
--    if (ossl_securitycheck_enabled(ctx)) {
--        int nid, strength;
--        const char *curve_name;
--        const EC_GROUP *group = EC_KEY_get0_group(ec);
-+    int nid, strength;
-+    const char *curve_name;
-+    const EC_GROUP *group = EC_KEY_get0_group(ec);
+     if (priv_key->privateKey) {
+diff -up openssl-3.0.1/test/endecode_test.c.disable_explicit_ec openssl-3.0.1/test/endecode_test.c
+--- openssl-3.0.1/test/endecode_test.c.disable_explicit_ec	2022-03-21 16:55:46.005558779 +0100
++++ openssl-3.0.1/test/endecode_test.c	2022-03-21 16:56:12.636792762 +0100
+@@ -57,7 +57,7 @@ static BN_CTX *bnctx = NULL;
+ static OSSL_PARAM_BLD *bld_prime_nc = NULL;
+ static OSSL_PARAM_BLD *bld_prime = NULL;
+ static OSSL_PARAM *ec_explicit_prime_params_nc = NULL;
+-static OSSL_PARAM *ec_explicit_prime_params_explicit = NULL;
++/*static OSSL_PARAM *ec_explicit_prime_params_explicit = NULL;*/
  
--        if (group == NULL) {
--            ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "No group");
--            return 0;
--        }
--        nid = EC_GROUP_get_curve_name(group);
--        if (nid == NID_undef) {
--            ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE,
--                           "Explicit curves are not allowed in fips mode");
--            return 0;
--        }
-+    if (group == NULL) {
-+        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE, "No group");
-+        return 0;
-+    }
-+    nid = EC_GROUP_get_curve_name(group);
-+    if (nid == NID_undef) {
-+        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE,
-+                       "Explicit curves are not allowed in this build");
-+        return 0;
-+    }
+ # ifndef OPENSSL_NO_EC2M
+ static OSSL_PARAM_BLD *bld_tri_nc = NULL;
+@@ -990,9 +990,9 @@ IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC")
+ DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
+ IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC")
+ IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve, "EC")
+-DOMAIN_KEYS(ECExplicitPrime2G);
+-IMPLEMENT_TEST_SUITE(ECExplicitPrime2G, "EC")
+-IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrime2G, "EC")
++/*DOMAIN_KEYS(ECExplicitPrime2G);*/
++/*IMPLEMENT_TEST_SUITE(ECExplicitPrime2G, "EC")*/
++/*IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrime2G, "EC")*/
+ # ifndef OPENSSL_NO_EC2M
+ DOMAIN_KEYS(ECExplicitTriNamedCurve);
+ IMPLEMENT_TEST_SUITE(ECExplicitTriNamedCurve, "EC")
+@@ -1318,7 +1318,7 @@ int setup_tests(void)
+         || !create_ec_explicit_prime_params_namedcurve(bld_prime_nc)
+         || !create_ec_explicit_prime_params(bld_prime)
+         || !TEST_ptr(ec_explicit_prime_params_nc = OSSL_PARAM_BLD_to_param(bld_prime_nc))
+-        || !TEST_ptr(ec_explicit_prime_params_explicit = OSSL_PARAM_BLD_to_param(bld_prime))
++/*        || !TEST_ptr(ec_explicit_prime_params_explicit = OSSL_PARAM_BLD_to_param(bld_prime))*/
+ # ifndef OPENSSL_NO_EC2M
+         || !TEST_ptr(bld_tri_nc = OSSL_PARAM_BLD_new())
+         || !TEST_ptr(bld_tri = OSSL_PARAM_BLD_new())
+@@ -1346,7 +1346,7 @@ int setup_tests(void)
+     TEST_info("Generating EC keys...");
+     MAKE_DOMAIN_KEYS(EC, "EC", EC_params);
+     MAKE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve, "EC", ec_explicit_prime_params_nc);
+-    MAKE_DOMAIN_KEYS(ECExplicitPrime2G, "EC", ec_explicit_prime_params_explicit);
++/*    MAKE_DOMAIN_KEYS(ECExplicitPrime2G, "EC", ec_explicit_prime_params_explicit);*/
+ # ifndef OPENSSL_NO_EC2M
+     MAKE_DOMAIN_KEYS(ECExplicitTriNamedCurve, "EC", ec_explicit_tri_params_nc);
+     MAKE_DOMAIN_KEYS(ECExplicitTri2G, "EC", ec_explicit_tri_params_explicit);
+@@ -1389,8 +1389,8 @@ int setup_tests(void)
+         ADD_TEST_SUITE_LEGACY(EC);
+         ADD_TEST_SUITE(ECExplicitPrimeNamedCurve);
+         ADD_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve);
+-        ADD_TEST_SUITE(ECExplicitPrime2G);
+-        ADD_TEST_SUITE_LEGACY(ECExplicitPrime2G);
++/*        ADD_TEST_SUITE(ECExplicitPrime2G);*/
++/*        ADD_TEST_SUITE_LEGACY(ECExplicitPrime2G);*/
+ # ifndef OPENSSL_NO_EC2M
+         ADD_TEST_SUITE(ECExplicitTriNamedCurve);
+         ADD_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve);
+@@ -1427,7 +1427,7 @@ void cleanup_tests(void)
+ {
+ #ifndef OPENSSL_NO_EC
+     OSSL_PARAM_free(ec_explicit_prime_params_nc);
+-    OSSL_PARAM_free(ec_explicit_prime_params_explicit);
++/*    OSSL_PARAM_free(ec_explicit_prime_params_explicit);*/
+     OSSL_PARAM_BLD_free(bld_prime_nc);
+     OSSL_PARAM_BLD_free(bld_prime);
+ # ifndef OPENSSL_NO_EC2M
+@@ -1449,7 +1449,7 @@ void cleanup_tests(void)
+ #ifndef OPENSSL_NO_EC
+     FREE_DOMAIN_KEYS(EC);
+     FREE_DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
+-    FREE_DOMAIN_KEYS(ECExplicitPrime2G);
++/*    FREE_DOMAIN_KEYS(ECExplicitPrime2G);*/
+ # ifndef OPENSSL_NO_EC2M
+     FREE_DOMAIN_KEYS(ECExplicitTriNamedCurve);
+     FREE_DOMAIN_KEYS(ECExplicitTri2G);
+diff -up openssl-3.0.1/test/recipes/30-test_evp_data/evppkey_ecdsa.txt.disable_explicit_ec openssl-3.0.1/test/recipes/30-test_evp_data/evppkey_ecdsa.txt
+--- openssl-3.0.1/test/recipes/30-test_evp_data/evppkey_ecdsa.txt.disable_explicit_ec	2022-03-25 11:20:50.920949208 +0100
++++ openssl-3.0.1/test/recipes/30-test_evp_data/evppkey_ecdsa.txt	2022-03-25 11:21:13.177147598 +0100
+@@ -121,18 +121,6 @@ AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEB
+ 3ev1gTwRBduzqqlwd54AUSgI+pjttW8zrWNitO8H1sf59MPWOESKxNtZ1+Nl
+ -----END PRIVATE KEY-----
  
-+    if (ossl_securitycheck_enabled(ctx)) {
-         curve_name = EC_curve_nid2nist(nid);
-         if (curve_name == NULL) {
-             ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_CURVE,
+-PrivateKey = EC_EXPLICIT
+------BEGIN PRIVATE KEY-----
+-MIIBeQIBADCCAQMGByqGSM49AgEwgfcCAQEwLAYHKoZIzj0BAQIhAP////8AAAAB
+-AAAAAAAAAAAAAAAA////////////////MFsEIP////8AAAABAAAAAAAAAAAAAAAA
+-///////////////8BCBaxjXYqjqT57PrvVV2mIa8ZR0GsMxTsPY7zjw+J9JgSwMV
+-AMSdNgiG5wSTamZ44ROdJreBn36QBEEE5JcIvn36opqjEm/k59Al40rBAxWM2TPG
+-l0L13Je51zHpfXQ9Z2o7IQicMXP4wSfJ0qCgg2bgydqoxlYrlLGuVQIhAP////8A
+-AAAA//////////+85vqtpxeehPO5ysL8YyVRAgEBBG0wawIBAQQgec92jwduadCk
+-OjoNRI+YT5Be5TkzZXzYCyTLkMOikDmhRANCAATtECEhQbLEaiUj/Wu0qjcr81lL
+-46dx5zYgArz/iaSNJ3W80oO+F7v04jlQ7wxQzg96R0bwKiMeq5CcW9ZFt6xg
+------END PRIVATE KEY-----
+-
+ PrivateKey = B-163
+ -----BEGIN PRIVATE KEY-----
+ MGMCAQAwEAYHKoZIzj0CAQYFK4EEAA8ETDBKAgEBBBUDnQW0mLiHVha/jqFznX/K
diff --git a/SOURCES/0013-FIPS-provider-explicit-ec.patch b/SOURCES/0013-FIPS-provider-explicit-ec.patch
new file mode 100644
index 0000000..8cceeed
--- /dev/null
+++ b/SOURCES/0013-FIPS-provider-explicit-ec.patch
@@ -0,0 +1,77 @@
+diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
+index 78dc69082fab..8a86c9108d0d 100644
+--- a/providers/implementations/keymgmt/ec_kmgmt.c
++++ b/providers/implementations/keymgmt/ec_kmgmt.c
+@@ -470,9 +470,6 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
+     if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0
+             && (selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) == 0)
+         return 0;
+-    if ((selection & OSSL_KEYMGMT_SELECT_OTHER_PARAMETERS) != 0
+-            && (selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
+-        return 0;
+ 
+     tmpl = OSSL_PARAM_BLD_new();
+     if (tmpl == NULL)
+diff --git a/test/recipes/15-test_ecparam.t b/test/recipes/15-test_ecparam.t
+index 766524e8cfa9..80bac6741290 100644
+--- a/test/recipes/15-test_ecparam.t
++++ b/test/recipes/15-test_ecparam.t
+@@ -13,7 +13,7 @@ use warnings;
+ use File::Spec;
+ use File::Compare qw/compare_text/;
+ use OpenSSL::Glob;
+-use OpenSSL::Test qw/:DEFAULT data_file/;
++use OpenSSL::Test qw/:DEFAULT data_file srctop_file bldtop_dir/;
+ use OpenSSL::Test::Utils;
+ 
+ setup("test_ecparam");
+@@ -25,7 +25,7 @@ my @valid = glob(data_file("valid", "*.pem"));
+ my @noncanon = glob(data_file("noncanon", "*.pem"));
+ my @invalid = glob(data_file("invalid", "*.pem"));
+ 
+-plan tests => 11;
++plan tests => 12;
+ 
+ sub checkload {
+     my $files = shift; # List of files
+@@ -59,6 +59,8 @@ sub checkcompare {
+     }
+ }
+ 
++my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
++
+ subtest "Check loading valid parameters by ecparam with -check" => sub {
+     plan tests => scalar(@valid);
+     checkload(\@valid, 1, "ecparam", "-check");
+@@ -113,3 +115,31 @@ subtest "Check pkeyparam does not change the parameter file on output" => sub {
+     plan tests => 2 * scalar(@valid);
+     checkcompare(\@valid, "pkeyparam");
+ };
++
++subtest "Check loading of fips and non-fips params" => sub {
++    plan skip_all => "FIPS is disabled"
++        if $no_fips;
++    plan tests => 3;
++
++    my $fipsconf = srctop_file("test", "fips-and-base.cnf");
++    my $defaultconf = srctop_file("test", "default.cnf");
++
++    $ENV{OPENSSL_CONF} = $fipsconf;
++
++    ok(run(app(['openssl', 'ecparam',
++                '-in', data_file('valid', 'secp384r1-explicit.pem'),
++                '-check'])),
++       "Loading explicitly encoded valid curve");
++
++    ok(run(app(['openssl', 'ecparam',
++                '-in', data_file('valid', 'secp384r1-named.pem'),
++                '-check'])),
++       "Loading named valid curve");
++
++    ok(!run(app(['openssl', 'ecparam',
++                '-in', data_file('valid', 'secp112r1-named.pem'),
++                '-check'])),
++       "Fail loading named non-fips curve");
++
++    $ENV{OPENSSL_CONF} = $defaultconf;
++};
diff --git a/SOURCES/0014-FIPS-disable-explicit-ec.patch b/SOURCES/0014-FIPS-disable-explicit-ec.patch
new file mode 100644
index 0000000..7de159e
--- /dev/null
+++ b/SOURCES/0014-FIPS-disable-explicit-ec.patch
@@ -0,0 +1,421 @@
+diff --git a/crypto/ec/ec_err.c b/crypto/ec/ec_err.c
+index 9dc143c2ac69..4d6f2a76ad20 100644
+--- a/crypto/ec/ec_err.c
++++ b/crypto/ec/ec_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-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
+@@ -35,6 +35,8 @@ static const ERR_STRING_DATA EC_str_reasons[] = {
+     "discriminant is zero"},
+     {ERR_PACK(ERR_LIB_EC, 0, EC_R_EC_GROUP_NEW_BY_NAME_FAILURE),
+     "ec group new by name failure"},
++    {ERR_PACK(ERR_LIB_EC, 0, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED),
++    "explicit params not supported"},
+     {ERR_PACK(ERR_LIB_EC, 0, EC_R_FAILED_MAKING_PUBLIC_KEY),
+     "failed making public key"},
+     {ERR_PACK(ERR_LIB_EC, 0, EC_R_FIELD_TOO_LARGE), "field too large"},
+diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
+index 2aeab7e3b6b5..f686e45f899d 100644
+--- a/crypto/ec/ec_lib.c
++++ b/crypto/ec/ec_lib.c
+@@ -1387,6 +1387,7 @@ int EC_GROUP_get_pentanomial_basis(const EC_GROUP *group, unsigned int *k1,
+ }
+ #endif
+ 
++#ifndef FIPS_MODULE
+ /*
+  * Check if the explicit parameters group matches any built-in curves.
+  *
+@@ -1424,7 +1425,7 @@ static EC_GROUP *ec_group_explicit_to_named(const EC_GROUP *group,
+          * parameters with one created from a named group.
+          */
+ 
+-#ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
++# ifndef OPENSSL_NO_EC_NISTP_64_GCC_128
+         /*
+          * NID_wap_wsg_idm_ecid_wtls12 and NID_secp224r1 are both aliases for
+          * the same curve, we prefer the SECP nid when matching explicit
+@@ -1432,7 +1433,7 @@ static EC_GROUP *ec_group_explicit_to_named(const EC_GROUP *group,
+          */
+         if (curve_name_nid == NID_wap_wsg_idm_ecid_wtls12)
+             curve_name_nid = NID_secp224r1;
+-#endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
++# endif /* !def(OPENSSL_NO_EC_NISTP_64_GCC_128) */
+ 
+         ret_group = EC_GROUP_new_by_curve_name_ex(libctx, propq, curve_name_nid);
+         if (ret_group == NULL)
+@@ -1467,6 +1468,7 @@ static EC_GROUP *ec_group_explicit_to_named(const EC_GROUP *group,
+     EC_GROUP_free(ret_group);
+     return NULL;
+ }
++#endif /* FIPS_MODULE */
+ 
+ static EC_GROUP *group_new_from_name(const OSSL_PARAM *p,
+                                      OSSL_LIB_CTX *libctx, const char *propq)
+@@ -1536,9 +1538,13 @@ int ossl_ec_group_set_params(EC_GROUP *group, const OSSL_PARAM params[])
+ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+                                    OSSL_LIB_CTX *libctx, const char *propq)
+ {
+-    const OSSL_PARAM *ptmp, *pa, *pb;
++    const OSSL_PARAM *ptmp;
++    EC_GROUP *group = NULL;
++
++#ifndef FIPS_MODULE
++    const OSSL_PARAM *pa, *pb;
+     int ok = 0;
+-    EC_GROUP *group = NULL, *named_group = NULL;
++    EC_GROUP *named_group = NULL;
+     BIGNUM *p = NULL, *a = NULL, *b = NULL, *order = NULL, *cofactor = NULL;
+     EC_POINT *point = NULL;
+     int field_bits = 0;
+@@ -1546,6 +1552,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+     BN_CTX *bnctx = NULL;
+     const unsigned char *buf = NULL;
+     int encoding_flag = -1;
++#endif
+ 
+     /* This is the simple named group case */
+     ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
+@@ -1559,6 +1566,10 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+         }
+         return group;
+     }
++#ifdef FIPS_MODULE
++    ERR_raise(ERR_LIB_EC, EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED);
++    return NULL;
++#else
+     /* If it gets here then we are trying explicit parameters */
+     bnctx = BN_CTX_new_ex(libctx);
+     if (bnctx == NULL) {
+@@ -1623,10 +1634,10 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+         /* create the EC_GROUP structure */
+         group = EC_GROUP_new_curve_GFp(p, a, b, bnctx);
+     } else {
+-#ifdef OPENSSL_NO_EC2M
++# ifdef OPENSSL_NO_EC2M
+         ERR_raise(ERR_LIB_EC, EC_R_GF2M_NOT_SUPPORTED);
+         goto err;
+-#else
++# else
+         /* create the EC_GROUP structure */
+         group = EC_GROUP_new_curve_GF2m(p, a, b, NULL);
+         if (group != NULL) {
+@@ -1636,7 +1647,7 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+                 goto err;
+             }
+         }
+-#endif /* OPENSSL_NO_EC2M */
++# endif /* OPENSSL_NO_EC2M */
+     }
+ 
+     if (group == NULL) {
+@@ -1733,4 +1744,5 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+     BN_CTX_free(bnctx);
+ 
+     return group;
++#endif /* FIPS_MODULE */
+ }
+diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
+index c4a94f955905..41df7127403c 100644
+--- a/crypto/err/openssl.txt
++++ b/crypto/err/openssl.txt
+@@ -553,6 +553,7 @@ EC_R_CURVE_DOES_NOT_SUPPORT_SIGNING:159:curve does not support signing
+ EC_R_DECODE_ERROR:142:decode error
+ EC_R_DISCRIMINANT_IS_ZERO:118:discriminant is zero
+ EC_R_EC_GROUP_NEW_BY_NAME_FAILURE:119:ec group new by name failure
++EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED:127:explicit params not supported
+ EC_R_FAILED_MAKING_PUBLIC_KEY:166:failed making public key
+ EC_R_FIELD_TOO_LARGE:143:field too large
+ EC_R_GF2M_NOT_SUPPORTED:147:gf2m not supported
+diff --git a/include/crypto/ecerr.h b/include/crypto/ecerr.h
+index 07b6c7aa62dd..4658ae8fb2cd 100644
+--- a/include/crypto/ecerr.h
++++ b/include/crypto/ecerr.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-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
+diff --git a/include/openssl/ecerr.h b/include/openssl/ecerr.h
+index 49088d208b2c..46405ac62d91 100644
+--- a/include/openssl/ecerr.h
++++ b/include/openssl/ecerr.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-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
+@@ -35,6 +35,7 @@
+ #  define EC_R_DECODE_ERROR                                142
+ #  define EC_R_DISCRIMINANT_IS_ZERO                        118
+ #  define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE                119
++#  define EC_R_EXPLICIT_PARAMS_NOT_SUPPORTED               127
+ #  define EC_R_FAILED_MAKING_PUBLIC_KEY                    166
+ #  define EC_R_FIELD_TOO_LARGE                             143
+ #  define EC_R_GF2M_NOT_SUPPORTED                          147
+diff --git a/test/endecode_test.c b/test/endecode_test.c
+index 0c33dff0ee2b..3d78bea50ea3 100644
+--- a/test/endecode_test.c
++++ b/test/endecode_test.c
+@@ -147,6 +147,7 @@ typedef int (checker)(const char *file, const int line,
+ typedef void (dumper)(const char *label, const void *data, size_t data_len);
+ 
+ #define FLAG_DECODE_WITH_TYPE   0x0001
++#define FLAG_FAIL_IF_FIPS       0x0002
+ 
+ static int test_encode_decode(const char *file, const int line,
+                               const char *type, EVP_PKEY *pkey,
+@@ -170,8 +171,19 @@ static int test_encode_decode(const char *file, const int line,
+      * dumping purposes.
+      */
+     if (!TEST_true(encode_cb(file, line, &encoded, &encoded_len, pkey, selection,
+-                             output_type, output_structure, pass, pcipher))
+-        || !TEST_true(check_cb(file, line, type, encoded, encoded_len))
++                             output_type, output_structure, pass, pcipher)))
++        goto end;
++
++    if ((flags & FLAG_FAIL_IF_FIPS) != 0 && is_fips) {
++        if (TEST_false(decode_cb(file, line, (void **)&pkey2, encoded,
++                                  encoded_len, output_type, output_structure,
++                                  (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
++                                  selection, pass)))
++            ok = 1;
++        goto end;
++    }
++
++    if (!TEST_true(check_cb(file, line, type, encoded, encoded_len))
+         || !TEST_true(decode_cb(file, line, (void **)&pkey2, encoded, encoded_len,
+                                 output_type, output_structure,
+                                 (flags & FLAG_DECODE_WITH_TYPE ? type : NULL),
+@@ -525,7 +537,7 @@ static int check_unprotected_PKCS8_DER(const char *file, const int line,
+     return ok;
+ }
+ 
+-static int test_unprotected_via_DER(const char *type, EVP_PKEY *key)
++static int test_unprotected_via_DER(const char *type, EVP_PKEY *key, int fips)
+ {
+     return test_encode_decode(__FILE__, __LINE__, type, key,
+                               OSSL_KEYMGMT_SELECT_KEYPAIR
+@@ -533,7 +545,7 @@ static int test_unprotected_via_DER(const char *type, EVP_PKEY *key)
+                               "DER", "PrivateKeyInfo", NULL, NULL,
+                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+                               test_mem, check_unprotected_PKCS8_DER,
+-                              dump_der, 0);
++                              dump_der, fips ? 0 : FLAG_FAIL_IF_FIPS);
+ }
+ 
+ static int check_unprotected_PKCS8_PEM(const char *file, const int line,
+@@ -547,7 +559,7 @@ static int check_unprotected_PKCS8_PEM(const char *file, const int line,
+                         sizeof(expected_pem_header) - 1);
+ }
+ 
+-static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key)
++static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key, int fips)
+ {
+     return test_encode_decode(__FILE__, __LINE__, type, key,
+                               OSSL_KEYMGMT_SELECT_KEYPAIR
+@@ -555,7 +567,7 @@ static int test_unprotected_via_PEM(const char *type, EVP_PKEY *key)
+                               "PEM", "PrivateKeyInfo", NULL, NULL,
+                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+                               test_text, check_unprotected_PKCS8_PEM,
+-                              dump_pem, 0);
++                              dump_pem, fips ? 0 : FLAG_FAIL_IF_FIPS);
+ }
+ 
+ #ifndef OPENSSL_NO_KEYPARAMS
+@@ -702,7 +714,7 @@ static int check_protected_PKCS8_DER(const char *file, const int line,
+     return ok;
+ }
+ 
+-static int test_protected_via_DER(const char *type, EVP_PKEY *key)
++static int test_protected_via_DER(const char *type, EVP_PKEY *key, int fips)
+ {
+     return test_encode_decode(__FILE__, __LINE__, type, key,
+                               OSSL_KEYMGMT_SELECT_KEYPAIR
+@@ -711,7 +723,7 @@ static int test_protected_via_DER(const char *type, EVP_PKEY *key)
+                               pass, pass_cipher,
+                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+                               test_mem, check_protected_PKCS8_DER,
+-                              dump_der, 0);
++                              dump_der, fips ? 0 : FLAG_FAIL_IF_FIPS);
+ }
+ 
+ static int check_protected_PKCS8_PEM(const char *file, const int line,
+@@ -725,7 +737,7 @@ static int check_protected_PKCS8_PEM(const char *file, const int line,
+                         sizeof(expected_pem_header) - 1);
+ }
+ 
+-static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
++static int test_protected_via_PEM(const char *type, EVP_PKEY *key, int fips)
+ {
+     return test_encode_decode(__FILE__, __LINE__, type, key,
+                               OSSL_KEYMGMT_SELECT_KEYPAIR
+@@ -734,7 +746,7 @@ static int test_protected_via_PEM(const char *type, EVP_PKEY *key)
+                               pass, pass_cipher,
+                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+                               test_text, check_protected_PKCS8_PEM,
+-                              dump_pem, 0);
++                              dump_pem, fips ? 0 : FLAG_FAIL_IF_FIPS);
+ }
+ 
+ static int check_protected_legacy_PEM(const char *file, const int line,
+@@ -795,14 +807,15 @@ static int check_public_DER(const char *file, const int line,
+     return ok;
+ }
+ 
+-static int test_public_via_DER(const char *type, EVP_PKEY *key)
++static int test_public_via_DER(const char *type, EVP_PKEY *key, int fips)
+ {
+     return test_encode_decode(__FILE__, __LINE__, type, key,
+                               OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+                               | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
+                               "DER", "SubjectPublicKeyInfo", NULL, NULL,
+                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+-                              test_mem, check_public_DER, dump_der, 0);
++                              test_mem, check_public_DER, dump_der,
++                              fips ? 0 : FLAG_FAIL_IF_FIPS);
+ }
+ 
+ static int check_public_PEM(const char *file, const int line,
+@@ -816,14 +829,15 @@ static int check_public_PEM(const char *file, const int line,
+                      sizeof(expected_pem_header) - 1);
+ }
+ 
+-static int test_public_via_PEM(const char *type, EVP_PKEY *key)
++static int test_public_via_PEM(const char *type, EVP_PKEY *key, int fips)
+ {
+     return test_encode_decode(__FILE__, __LINE__, type, key,
+                               OSSL_KEYMGMT_SELECT_PUBLIC_KEY
+                               | OSSL_KEYMGMT_SELECT_ALL_PARAMETERS,
+                               "PEM", "SubjectPublicKeyInfo", NULL, NULL,
+                               encode_EVP_PKEY_prov, decode_EVP_PKEY_prov,
+-                              test_text, check_public_PEM, dump_pem, 0);
++                              test_text, check_public_PEM, dump_pem,
++                              fips ? 0 : FLAG_FAIL_IF_FIPS);
+ }
+ 
+ static int check_public_MSBLOB(const char *file, const int line,
+@@ -868,30 +882,30 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
+     EVP_PKEY_free(template_##KEYTYPE);                                  \
+     EVP_PKEY_free(key_##KEYTYPE)
+ 
+-#define IMPLEMENT_TEST_SUITE(KEYTYPE, KEYTYPEstr)                       \
++#define IMPLEMENT_TEST_SUITE(KEYTYPE, KEYTYPEstr, fips)                 \
+     static int test_unprotected_##KEYTYPE##_via_DER(void)               \
+     {                                                                   \
+-        return test_unprotected_via_DER(KEYTYPEstr, key_##KEYTYPE);     \
++        return test_unprotected_via_DER(KEYTYPEstr, key_##KEYTYPE, fips); \
+     }                                                                   \
+     static int test_unprotected_##KEYTYPE##_via_PEM(void)               \
+     {                                                                   \
+-        return test_unprotected_via_PEM(KEYTYPEstr, key_##KEYTYPE);     \
++        return test_unprotected_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips); \
+     }                                                                   \
+     static int test_protected_##KEYTYPE##_via_DER(void)                 \
+     {                                                                   \
+-        return test_protected_via_DER(KEYTYPEstr, key_##KEYTYPE);       \
++        return test_protected_via_DER(KEYTYPEstr, key_##KEYTYPE, fips); \
+     }                                                                   \
+     static int test_protected_##KEYTYPE##_via_PEM(void)                 \
+     {                                                                   \
+-        return test_protected_via_PEM(KEYTYPEstr, key_##KEYTYPE);       \
++        return test_protected_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips); \
+     }                                                                   \
+     static int test_public_##KEYTYPE##_via_DER(void)                    \
+     {                                                                   \
+-        return test_public_via_DER(KEYTYPEstr, key_##KEYTYPE);          \
++        return test_public_via_DER(KEYTYPEstr, key_##KEYTYPE, fips);    \
+     }                                                                   \
+     static int test_public_##KEYTYPE##_via_PEM(void)                    \
+     {                                                                   \
+-        return test_public_via_PEM(KEYTYPEstr, key_##KEYTYPE);          \
++        return test_public_via_PEM(KEYTYPEstr, key_##KEYTYPE, fips);    \
+     }
+ 
+ #define ADD_TEST_SUITE(KEYTYPE)                                 \
+@@ -965,10 +979,10 @@ static int test_public_via_MSBLOB(const char *type, EVP_PKEY *key)
+ 
+ #ifndef OPENSSL_NO_DH
+ DOMAIN_KEYS(DH);
+-IMPLEMENT_TEST_SUITE(DH, "DH")
++IMPLEMENT_TEST_SUITE(DH, "DH", 1)
+ IMPLEMENT_TEST_SUITE_PARAMS(DH, "DH")
+ DOMAIN_KEYS(DHX);
+-IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH")
++IMPLEMENT_TEST_SUITE(DHX, "X9.42 DH", 1)
+ IMPLEMENT_TEST_SUITE_PARAMS(DHX, "X9.42 DH")
+ /*
+  * DH has no support for PEM_write_bio_PrivateKey_traditional(),
+@@ -977,7 +991,7 @@ IMPLEMENT_TEST_SUITE_PARAMS(DHX, "X9.42 DH")
+ #endif
+ #ifndef OPENSSL_NO_DSA
+ DOMAIN_KEYS(DSA);
+-IMPLEMENT_TEST_SUITE(DSA, "DSA")
++IMPLEMENT_TEST_SUITE(DSA, "DSA", 1)
+ IMPLEMENT_TEST_SUITE_PARAMS(DSA, "DSA")
+ IMPLEMENT_TEST_SUITE_LEGACY(DSA, "DSA")
+ IMPLEMENT_TEST_SUITE_MSBLOB(DSA, "DSA")
+@@ -988,41 +1002,41 @@ IMPLEMENT_TEST_SUITE_PROTECTED_PVK(DSA, "DSA")
+ #endif
+ #ifndef OPENSSL_NO_EC
+ DOMAIN_KEYS(EC);
+-IMPLEMENT_TEST_SUITE(EC, "EC")
++IMPLEMENT_TEST_SUITE(EC, "EC", 1)
+ IMPLEMENT_TEST_SUITE_PARAMS(EC, "EC")
+ IMPLEMENT_TEST_SUITE_LEGACY(EC, "EC")
+ DOMAIN_KEYS(ECExplicitPrimeNamedCurve);
+-IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC")
++IMPLEMENT_TEST_SUITE(ECExplicitPrimeNamedCurve, "EC", 1)
+ IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrimeNamedCurve, "EC")
+ /*DOMAIN_KEYS(ECExplicitPrime2G);*/
+-/*IMPLEMENT_TEST_SUITE(ECExplicitPrime2G, "EC")*/
++/*IMPLEMENT_TEST_SUITE(ECExplicitPrime2G, "EC", 0)*/
+ /*IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitPrime2G, "EC")*/
+ # ifndef OPENSSL_NO_EC2M
+ DOMAIN_KEYS(ECExplicitTriNamedCurve);
+-IMPLEMENT_TEST_SUITE(ECExplicitTriNamedCurve, "EC")
++IMPLEMENT_TEST_SUITE(ECExplicitTriNamedCurve, "EC", 1)
+ IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTriNamedCurve, "EC")
+ DOMAIN_KEYS(ECExplicitTri2G);
+-IMPLEMENT_TEST_SUITE(ECExplicitTri2G, "EC")
++IMPLEMENT_TEST_SUITE(ECExplicitTri2G, "EC", 0)
+ IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTri2G, "EC")
+ # endif
+ KEYS(ED25519);
+-IMPLEMENT_TEST_SUITE(ED25519, "ED25519")
++IMPLEMENT_TEST_SUITE(ED25519, "ED25519", 1)
+ KEYS(ED448);
+-IMPLEMENT_TEST_SUITE(ED448, "ED448")
++IMPLEMENT_TEST_SUITE(ED448, "ED448", 1)
+ KEYS(X25519);
+-IMPLEMENT_TEST_SUITE(X25519, "X25519")
++IMPLEMENT_TEST_SUITE(X25519, "X25519", 1)
+ KEYS(X448);
+-IMPLEMENT_TEST_SUITE(X448, "X448")
++IMPLEMENT_TEST_SUITE(X448, "X448", 1)
+ /*
+  * ED25519, ED448, X25519 and X448 have no support for
+  * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
+  */
+ #endif
+ KEYS(RSA);
+-IMPLEMENT_TEST_SUITE(RSA, "RSA")
++IMPLEMENT_TEST_SUITE(RSA, "RSA", 1)
+ IMPLEMENT_TEST_SUITE_LEGACY(RSA, "RSA")
+ KEYS(RSA_PSS);
+-IMPLEMENT_TEST_SUITE(RSA_PSS, "RSA-PSS")
++IMPLEMENT_TEST_SUITE(RSA_PSS, "RSA-PSS", 1)
+ /*
+  * RSA-PSS has no support for PEM_write_bio_PrivateKey_traditional(),
+  * so no legacy tests.
diff --git a/SOURCES/0015-FIPS-decoded-from-explicit.patch b/SOURCES/0015-FIPS-decoded-from-explicit.patch
new file mode 100644
index 0000000..19d19a3
--- /dev/null
+++ b/SOURCES/0015-FIPS-decoded-from-explicit.patch
@@ -0,0 +1,140 @@
+diff --git a/crypto/ec/ec_backend.c b/crypto/ec/ec_backend.c
+index bea01fb38f66..48721369ae8f 100644
+--- a/crypto/ec/ec_backend.c
++++ b/crypto/ec/ec_backend.c
+@@ -318,6 +318,11 @@ int ossl_ec_group_todata(const EC_GROUP *group, OSSL_PARAM_BLD *tmpl,
+         return 0;
+     }
+ 
++    if (!ossl_param_build_set_int(tmpl, params,
++                                  OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS,
++                                  group->decoded_from_explicit_params))
++        return 0;
++
+     curve_nid = EC_GROUP_get_curve_name(group);
+ 
+     /*
+diff --git a/crypto/ec/ec_lib.c b/crypto/ec/ec_lib.c
+index 6b0591c6c8c7..b1696d93bd6d 100644
+--- a/crypto/ec/ec_lib.c
++++ b/crypto/ec/ec_lib.c
+@@ -1556,13 +1556,23 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+     /* This is the simple named group case */
+     ptmp = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_GROUP_NAME);
+     if (ptmp != NULL) {
+-        group = group_new_from_name(ptmp, libctx, propq);
+-        if (group != NULL) {
+-            if (!ossl_ec_group_set_params(group, params)) {
+-                EC_GROUP_free(group);
+-                group = NULL;
+-            }
++        int decoded = 0;
++
++        if ((group = group_new_from_name(ptmp, libctx, propq)) == NULL)
++            return NULL;
++        if (!ossl_ec_group_set_params(group, params)) {
++            EC_GROUP_free(group);
++            return NULL;
++        }
++
++        ptmp = OSSL_PARAM_locate_const(params,
++                                       OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS);
++        if (ptmp != NULL && !OSSL_PARAM_get_int(ptmp, &decoded)) {
++            ERR_raise(ERR_LIB_EC, EC_R_WRONG_CURVE_PARAMETERS);
++            EC_GROUP_free(group);
++            return NULL;
+         }
++        group->decoded_from_explicit_params = decoded > 0;
+         return group;
+     }
+ #ifdef FIPS_MODULE
+@@ -1733,6 +1743,8 @@ EC_GROUP *EC_GROUP_new_from_params(const OSSL_PARAM params[],
+         EC_GROUP_free(group);
+         group = named_group;
+     }
++    /* We've imported the group from explicit parameters, set it so. */
++    group->decoded_from_explicit_params = 1;
+     ok = 1;
+  err:
+     if (!ok) {
+diff --git a/doc/man7/EVP_PKEY-EC.pod b/doc/man7/EVP_PKEY-EC.pod
+index eed83237c3b2..ee66a074f889 100644
+--- a/doc/man7/EVP_PKEY-EC.pod
++++ b/doc/man7/EVP_PKEY-EC.pod
+@@ -70,8 +70,8 @@ I<order> multiplied by the I<cofactor> gives the number of points on the curve.
+ 
+ =item  "decoded-from-explicit" (B<OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS>) <integer>
+ 
+-Gets a flag indicating wether the key or parameters were decoded from explicit
+-curve parameters. Set to 1 if so or 0 if a named curve was used.
++Sets or gets a flag indicating whether the key or parameters were decoded from
++explicit curve parameters. Set to 1 if so or 0 if a named curve was used.
+ 
+ =item "use-cofactor-flag" (B<OSSL_PKEY_PARAM_USE_COFACTOR_ECDH>) <integer>
+ 
+diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
+index 9260d4bf3635..7aed057cac89 100644
+--- a/providers/implementations/keymgmt/ec_kmgmt.c
++++ b/providers/implementations/keymgmt/ec_kmgmt.c
+@@ -525,7 +525,8 @@ int ec_export(void *keydata, int selection, OSSL_CALLBACK *param_cb,
+     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_GENERATOR, NULL, 0),            \
+     OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_ORDER, NULL, 0),                          \
+     OSSL_PARAM_BN(OSSL_PKEY_PARAM_EC_COFACTOR, NULL, 0),                       \
+-    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0)
++    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_SEED, NULL, 0),                 \
++    OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_DECODED_FROM_EXPLICIT_PARAMS, NULL)
+ 
+ # define EC_IMEXPORTABLE_PUBLIC_KEY                                            \
+     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
+diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
+index 700bbd849c95..ede14864d5ac 100644
+--- a/test/recipes/25-test_verify.t
++++ b/test/recipes/25-test_verify.t
+@@ -12,7 +12,7 @@ use warnings;
+ 
+ use File::Spec::Functions qw/canonpath/;
+ use File::Copy;
+-use OpenSSL::Test qw/:DEFAULT srctop_file ok_nofips with/;
++use OpenSSL::Test qw/:DEFAULT srctop_file bldtop_dir ok_nofips with/;
+ use OpenSSL::Test::Utils;
+ 
+ setup("test_verify");
+@@ -29,7 +29,7 @@ sub verify {
+     run(app([@args]));
+ }
+ 
+-plan tests => 160;
++plan tests => 163;
+ 
+ # Canonical success
+ ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
+@@ -309,6 +309,29 @@ SKIP: {
+               ["ca-cert-ec-named"]),
+         "accept named curve leaf with named curve intermediate");
+ }
++# Same as above but with base provider used for decoding
++SKIP: {
++    my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
++    skip "EC is not supported or FIPS is disabled", 3
++        if disabled("ec") || $no_fips;
++
++    my $provconf = srctop_file("test", "fips-and-base.cnf");
++    my $provpath = bldtop_dir("providers");
++    my @prov = ("-provider-path", $provpath);
++    $ENV{OPENSSL_CONF} = $provconf;
++
++    ok(!verify("ee-cert-ec-explicit", "", ["root-cert"],
++               ["ca-cert-ec-named"], @prov),
++        "reject explicit curve leaf with named curve intermediate w/fips");
++    ok(!verify("ee-cert-ec-named-explicit", "", ["root-cert"],
++               ["ca-cert-ec-explicit"], @prov),
++        "reject named curve leaf with explicit curve intermediate w/fips");
++    ok(verify("ee-cert-ec-named-named", "", ["root-cert"],
++              ["ca-cert-ec-named"], @prov),
++        "accept named curve leaf with named curve intermediate w/fips");
++
++    delete $ENV{OPENSSL_CONF};
++}
+ 
+ # Depth tests, note the depth limit bounds the number of CA certificates
+ # between the trust-anchor and the leaf, so, for example, with a root->ca->leaf
diff --git a/SOURCES/0032-Force-fips.patch b/SOURCES/0032-Force-fips.patch
index 9f83fcd..1a4ea0d 100644
--- a/SOURCES/0032-Force-fips.patch
+++ b/SOURCES/0032-Force-fips.patch
@@ -4,13 +4,13 @@
 #ensure that you also add those changes to the provider_conf_activate() function.
 #additionally please add this check for cnf explicitly as shown below.
 #'ok = cnf ? provider_conf_params(prov, NULL, NULL, value, cnf) : 1;'
-diff -up openssl-3.0.1/crypto/provider_conf.c.fips-FORCE openssl-3.0.1/crypto/provider_conf.c
---- openssl-3.0.1/crypto/provider_conf.c.fips-FORCE	2022-01-18 15:36:00.956141345 +0100
-+++ openssl-3.0.1/crypto/provider_conf.c	2022-01-18 15:42:36.345172203 +0100
+diff -up openssl-3.0.1/crypto/provider_conf.c.fipsact openssl-3.0.1/crypto/provider_conf.c
+--- openssl-3.0.1/crypto/provider_conf.c.fipsact	2022-05-12 12:44:31.199034948 +0200
++++ openssl-3.0.1/crypto/provider_conf.c	2022-05-12 12:49:17.468318373 +0200
 @@ -136,58 +136,18 @@ static int prov_already_activated(const
      return 0;
  }
-
+ 
 -static int provider_conf_load(OSSL_LIB_CTX *libctx, const char *name,
 -                              const char *value, const CONF *cnf)
 +static int provider_conf_activate(OSSL_LIB_CTX *libctx,const char *name,
@@ -83,8 +83,12 @@ diff -up openssl-3.0.1/crypto/provider_conf.c.fips-FORCE openssl-3.0.1/crypto/pr
  
              if (ok) {
                  if (!ossl_provider_activate(prov, 1, 0)) {
-@@ -246,6 +206,55 @@ static int provider_conf_load(OSSL_LIB_C
+@@ -244,8 +204,59 @@ static int provider_conf_load(OSSL_LIB_C
+             }
+             if (!ok)
                  ossl_provider_free(prov);
++        } else { /* No reason to activate the provider twice, returning OK */
++            ok = 1;
          }
          CRYPTO_THREAD_unlock(pcgbl->lock);
 +    return ok;
@@ -139,7 +143,7 @@ diff -up openssl-3.0.1/crypto/provider_conf.c.fips-FORCE openssl-3.0.1/crypto/pr
      } else {
          OSSL_PROVIDER_INFO entry;
  
-@@ -306,6 +315,19 @@ static int provider_conf_init(CONF_IMODU
+@@ -306,6 +317,19 @@ static int provider_conf_init(CONF_IMODU
              return 0;
      }
  
diff --git a/SOURCES/0044-FIPS-140-3-keychecks.patch b/SOURCES/0044-FIPS-140-3-keychecks.patch
new file mode 100644
index 0000000..a0ec627
--- /dev/null
+++ b/SOURCES/0044-FIPS-140-3-keychecks.patch
@@ -0,0 +1,187 @@
+diff -up openssl-3.0.1/crypto/dh/dh_key.c.fips3 openssl-3.0.1/crypto/dh/dh_key.c
+--- openssl-3.0.1/crypto/dh/dh_key.c.fips3	2022-07-18 16:01:41.159543735 +0200
++++ openssl-3.0.1/crypto/dh/dh_key.c	2022-07-18 16:24:30.251388248 +0200
+@@ -43,6 +43,9 @@ int ossl_dh_compute_key(unsigned char *k
+     BN_MONT_CTX *mont = NULL;
+     BIGNUM *z = NULL, *pminus1;
+     int ret = -1;
++#ifdef FIPS_MODULE
++    int validate = 0;
++#endif
+ 
+     if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+         ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
+@@ -54,6 +57,13 @@ int ossl_dh_compute_key(unsigned char *k
+         return 0;
+     }
+ 
++#ifdef FIPS_MODULE
++    if (DH_check_pub_key(dh, pub_key, &validate) <= 0) {
++        ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID);
++        return 0;
++    }
++#endif
++
+     ctx = BN_CTX_new_ex(dh->libctx);
+     if (ctx == NULL)
+         goto err;
+@@ -262,6 +272,9 @@ static int generate_key(DH *dh)
+ #endif
+     BN_CTX *ctx = NULL;
+     BIGNUM *pub_key = NULL, *priv_key = NULL;
++#ifdef FIPS_MODULE
++    int validate = 0;
++#endif
+ 
+     if (BN_num_bits(dh->params.p) > OPENSSL_DH_MAX_MODULUS_BITS) {
+         ERR_raise(ERR_LIB_DH, DH_R_MODULUS_TOO_LARGE);
+@@ -354,8 +367,23 @@ static int generate_key(DH *dh)
+     if (!ossl_dh_generate_public_key(ctx, dh, priv_key, pub_key))
+         goto err;
+ 
++#ifdef FIPS_MODULE
++    if (DH_check_pub_key(dh, pub_key, &validate) <= 0) {
++        ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID);
++        goto err;
++    }
++#endif
++
+     dh->pub_key = pub_key;
+     dh->priv_key = priv_key;
++#ifdef FIPS_MODULE
++    if (ossl_dh_check_pairwise(dh) <= 0) {
++        dh->pub_key = dh->priv_key = NULL;
++        ERR_raise(ERR_LIB_DH, DH_R_CHECK_PUBKEY_INVALID);
++        goto err;
++    }
++#endif
++
+     dh->dirty_cnt++;
+     ok = 1;
+  err:
+diff -up openssl-3.0.1/crypto/ec/ec_key.c.fips3 openssl-3.0.1/crypto/ec/ec_key.c
+diff -up openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c.fips3 openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c
+--- openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c.fips3	2022-07-25 13:42:46.814952053 +0200
++++ openssl-3.0.1/providers/implementations/exchange/ecdh_exch.c	2022-07-25 13:52:12.292065706 +0200
+@@ -488,6 +488,25 @@ int ecdh_plain_derive(void *vpecdhctx, u
+     }
+ 
+     ppubkey = EC_KEY_get0_public_key(pecdhctx->peerk);
++#ifdef FIPS_MODULE
++    {
++        BN_CTX *bn_ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(privk));
++        int check = 0;
++
++        if (bn_ctx == NULL) {
++            ERR_raise(ERR_LIB_PROV, ERR_R_MALLOC_FAILURE);
++            goto end;
++        }
++
++        check = ossl_ec_key_public_check(pecdhctx->peerk, bn_ctx);
++        BN_CTX_free(bn_ctx);
++
++        if (check <= 0) {
++            ERR_raise(ERR_LIB_PROV, EC_R_INVALID_PEER_KEY);
++            goto end;
++        }
++    }
++#endif
+ 
+     retlen = ECDH_compute_key(secret, size, ppubkey, privk, NULL);
+ 
+diff -up openssl-3.0.1/crypto/ec/ec_key.c.fips3 openssl-3.0.1/crypto/ec/ec_key.c
+--- openssl-3.0.1/crypto/ec/ec_key.c.fips3	2022-07-25 14:03:34.420222507 +0200
++++ openssl-3.0.1/crypto/ec/ec_key.c	2022-07-25 14:09:00.728164294 +0200
+@@ -336,6 +336,11 @@ static int ec_generate_key(EC_KEY *eckey
+ 
+         OSSL_SELF_TEST_get_callback(eckey->libctx, &cb, &cbarg);
+         ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg);
++
++#ifdef FIPS_MODULE
++        ok &= ossl_ec_key_public_check(eckey, ctx);
++        ok &= ossl_ec_key_pairwise_check(eckey, ctx);
++#endif /* FIPS_MODULE */
+     }
+ err:
+     /* Step (9): If there is an error return an invalid keypair. */
+diff -up openssl-3.0.1/crypto/rsa/rsa_gen.c.fips3 openssl-3.0.1/crypto/rsa/rsa_gen.c
+--- openssl-3.0.1/crypto/rsa/rsa_gen.c.fips3	2022-07-25 17:02:17.807271297 +0200
++++ openssl-3.0.1/crypto/rsa/rsa_gen.c	2022-07-25 17:18:24.931959649 +0200
+@@ -23,6 +23,7 @@
+ #include <time.h>
+ #include "internal/cryptlib.h"
+ #include <openssl/bn.h>
++#include <openssl/obj_mac.h>
+ #include <openssl/self_test.h>
+ #include "prov/providercommon.h"
+ #include "rsa_local.h"
+@@ -476,52 +476,43 @@ static int rsa_keygen(OSSL_LIB_CTX *libc
+ static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg)
+ {
+     int ret = 0;
+-    unsigned int ciphertxt_len;
+-    unsigned char *ciphertxt = NULL;
+-    const unsigned char plaintxt[16] = {0};
+-    unsigned char *decoded = NULL;
+-    unsigned int decoded_len;
+-    unsigned int plaintxt_len = (unsigned int)sizeof(plaintxt_len);
+-    int padding = RSA_PKCS1_PADDING;
++    unsigned int signature_len;
++    unsigned char *signature = NULL;
+     OSSL_SELF_TEST *st = NULL;
++    static const unsigned char dgst[] = {
++        0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
++        0x48, 0xa1, 0xd6, 0x5d, 0xfc, 0x2d, 0x4b, 0x1f, 0xa3, 0xd6, 0x77, 0x28,
++        0x4a, 0xdd, 0xd2, 0x00, 0x12, 0x6d, 0x90, 0x69
++    };
+ 
+     st = OSSL_SELF_TEST_new(cb, cbarg);
+     if (st == NULL)
+         goto err;
+     OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
++                           /* No special name for RSA signature PCT*/
+                            OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1);
+ 
+-    ciphertxt_len = RSA_size(rsa);
++    signature_len = RSA_size(rsa);
+-    /*
+-     * RSA_private_encrypt() and RSA_private_decrypt() requires the 'to'
+-     * parameter to be a maximum of RSA_size() - allocate space for both.
+-     */
+-    ciphertxt = OPENSSL_zalloc(ciphertxt_len * 2);
+-    if (ciphertxt == NULL)
++    signature = OPENSSL_zalloc(signature_len);
++    if (signature == NULL)
+         goto err;
+-    decoded = ciphertxt + ciphertxt_len;
+ 
+-    ciphertxt_len = RSA_public_encrypt(plaintxt_len, plaintxt, ciphertxt, rsa,
+-                                       padding);
+-    if (ciphertxt_len <= 0)
++    if (RSA_sign(NID_sha256, dgst, sizeof(dgst), signature, &signature_len, rsa) <= 0)
+         goto err;
+-    if (ciphertxt_len == plaintxt_len
+-        && memcmp(ciphertxt, plaintxt, plaintxt_len) == 0)
++
++    if (signature_len <= 0)
+         goto err;
+ 
+-    OSSL_SELF_TEST_oncorrupt_byte(st, ciphertxt);
++    OSSL_SELF_TEST_oncorrupt_byte(st, signature);
+ 
+-    decoded_len = RSA_private_decrypt(ciphertxt_len, ciphertxt, decoded, rsa,
+-                                      padding);
+-    if (decoded_len != plaintxt_len
+-        || memcmp(decoded, plaintxt,  decoded_len) != 0)
++    if (RSA_verify(NID_sha256, dgst, sizeof(dgst), signature, signature_len, rsa) <= 0)
+         goto err;
+ 
+     ret = 1;
+ err:
+     OSSL_SELF_TEST_onend(st, ret);
+     OSSL_SELF_TEST_free(st);
+-    OPENSSL_free(ciphertxt);
++    OPENSSL_free(signature);
+ 
+     return ret;
+ }
diff --git a/SOURCES/0045-FIPS-services-minimize.patch b/SOURCES/0045-FIPS-services-minimize.patch
index 41b1646..8308990 100644
--- a/SOURCES/0045-FIPS-services-minimize.patch
+++ b/SOURCES/0045-FIPS-services-minimize.patch
@@ -1,17 +1,29 @@
-diff -up openssl-3.0.0/providers/fips/fipsprov.c.fipsmin openssl-3.0.0/providers/fips/fipsprov.c
---- openssl-3.0.0/providers/fips/fipsprov.c.fipsmin	2022-01-12 17:17:42.574377550 +0100
-+++ openssl-3.0.0/providers/fips/fipsprov.c	2022-01-12 17:19:57.590598279 +0100
-@@ -37,6 +37,9 @@ static OSSL_FUNC_provider_query_operatio
+diff -up openssl-3.0.1/providers/common/capabilities.c.fipsmin3 openssl-3.0.1/providers/common/capabilities.c
+--- openssl-3.0.1/providers/common/capabilities.c.fipsmin3	2022-05-05 17:11:36.146638536 +0200
++++ openssl-3.0.1/providers/common/capabilities.c	2022-05-05 17:12:00.138848787 +0200
+@@ -186,9 +186,9 @@ static const OSSL_PARAM param_group_list
+     TLS_GROUP_ENTRY("brainpoolP256r1", "brainpoolP256r1", "EC", 25),
+     TLS_GROUP_ENTRY("brainpoolP384r1", "brainpoolP384r1", "EC", 26),
+     TLS_GROUP_ENTRY("brainpoolP512r1", "brainpoolP512r1", "EC", 27),
+-#  endif
+     TLS_GROUP_ENTRY("x25519", "X25519", "X25519", 28),
+     TLS_GROUP_ENTRY("x448", "X448", "X448", 29),
++#  endif
+ # endif /* OPENSSL_NO_EC */
+ # ifndef OPENSSL_NO_DH
+     /* Security bit values for FFDHE groups are as per RFC 7919 */
+diff -up openssl-3.0.1/providers/fips/fipsprov.c.fipsmin2 openssl-3.0.1/providers/fips/fipsprov.c
+--- openssl-3.0.1/providers/fips/fipsprov.c.fipsmin2	2022-05-05 11:42:58.596848856 +0200
++++ openssl-3.0.1/providers/fips/fipsprov.c	2022-05-05 11:55:42.997562712 +0200
+@@ -54,7 +54,6 @@ static void fips_deinit_casecmp(void);
  
  #define ALGC(NAMES, FUNC, CHECK) { { NAMES, FIPS_DEFAULT_PROPERTIES, FUNC }, CHECK }
  #define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL)
-+#define ALGCU(NAMES, FUNC, CHECK) { { NAMES, FIPS_UNAPPROVED_PROPERTIES, FUNC }, CHECK }
-+#define ALGU(NAMES, FUNC) ALGCU(NAMES, FUNC, NULL)
-+
- 
+-
  extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
  int FIPS_security_check_enabled(OSSL_LIB_CTX *libctx);
-@@ -177,13 +177,13 @@ static int fips_get_params(void *provctx
+ 
+@@ -191,13 +190,13 @@ static int fips_get_params(void *provctx
                                                &fips_prov_ossl_ctx_method);
  
      p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_NAME);
@@ -28,98 +40,182 @@ diff -up openssl-3.0.0/providers/fips/fipsprov.c.fipsmin openssl-3.0.0/providers
          return 0;
      p = OSSL_PARAM_locate(params, OSSL_PROV_PARAM_STATUS);
      if (p != NULL && !OSSL_PARAM_set_int(p, ossl_prov_is_running()))
-@@ -264,9 +267,9 @@ static const OSSL_ALGORITHM fips_digests
+@@ -281,10 +280,11 @@ static const OSSL_ALGORITHM fips_digests
       * KECCAK-KMAC-128 and KECCAK-KMAC-256 as hashes are mostly useful for
       * KMAC128 and KMAC256.
       */
 -    { PROV_NAMES_KECCAK_KMAC_128, FIPS_DEFAULT_PROPERTIES,
-+    { PROV_NAMES_KECCAK_KMAC_128, FIPS_UNAPPROVED_PROPERTIES,
++    /* We don't certify KECCAK in our FIPS provider */
++    /* { PROV_NAMES_KECCAK_KMAC_128, FIPS_DEFAULT_PROPERTIES,
        ossl_keccak_kmac_128_functions },
--    { PROV_NAMES_KECCAK_KMAC_256, FIPS_DEFAULT_PROPERTIES,
-+    { PROV_NAMES_KECCAK_KMAC_256, FIPS_UNAPPROVED_PROPERTIES,
-       ossl_keccak_kmac_256_functions },
+     { PROV_NAMES_KECCAK_KMAC_256, FIPS_DEFAULT_PROPERTIES,
+-      ossl_keccak_kmac_256_functions },
++      ossl_keccak_kmac_256_functions }, */
      { NULL, NULL, NULL }
  };
-@@ -326,8 +329,8 @@ static const OSSL_ALGORITHM_CAPABLE fips
+ 
+@@ -343,8 +343,9 @@ static const OSSL_ALGORITHM_CAPABLE fips
      ALGC(PROV_NAMES_AES_256_CBC_HMAC_SHA256, ossl_aes256cbc_hmac_sha256_functions,
           ossl_cipher_capable_aes_cbc_hmac_sha256),
  #ifndef OPENSSL_NO_DES
 -    ALG(PROV_NAMES_DES_EDE3_ECB, ossl_tdes_ede3_ecb_functions),
 -    ALG(PROV_NAMES_DES_EDE3_CBC, ossl_tdes_ede3_cbc_functions),
-+    ALGU(PROV_NAMES_DES_EDE3_ECB, ossl_tdes_ede3_ecb_functions),
-+    ALGU(PROV_NAMES_DES_EDE3_CBC, ossl_tdes_ede3_cbc_functions),
++    /* We don't certify 3DES in our FIPS provider */
++    /* ALG(PROV_NAMES_DES_EDE3_ECB, ossl_tdes_ede3_ecb_functions),
++    ALG(PROV_NAMES_DES_EDE3_CBC, ossl_tdes_ede3_cbc_functions), */
  #endif  /* OPENSSL_NO_DES */
      { { NULL, NULL, NULL }, NULL }
  };
-@@ -339,8 +342,8 @@ static const OSSL_ALGORITHM fips_macs[]
+@@ -356,8 +357,9 @@ static const OSSL_ALGORITHM fips_macs[]
  #endif
      { PROV_NAMES_GMAC, FIPS_DEFAULT_PROPERTIES, ossl_gmac_functions },
      { PROV_NAMES_HMAC, FIPS_DEFAULT_PROPERTIES, ossl_hmac_functions },
 -    { PROV_NAMES_KMAC_128, FIPS_DEFAULT_PROPERTIES, ossl_kmac128_functions },
 -    { PROV_NAMES_KMAC_256, FIPS_DEFAULT_PROPERTIES, ossl_kmac256_functions },
-+    { PROV_NAMES_KMAC_128, FIPS_UNAPPROVED_PROPERTIES, ossl_kmac128_functions },
-+    { PROV_NAMES_KMAC_256, FIPS_UNAPPROVED_PROPERTIES, ossl_kmac256_functions },
++    /* We don't certify KMAC in our FIPS provider */
++    /*{ PROV_NAMES_KMAC_128, FIPS_DEFAULT_PROPERTIES, ossl_kmac128_functions },
++    { PROV_NAMES_KMAC_256, FIPS_DEFAULT_PROPERTIES, ossl_kmac256_functions }, */
      { NULL, NULL, NULL }
  };
  
-@@ -375,8 +378,8 @@ static const OSSL_ALGORITHM fips_keyexch
+@@ -392,8 +394,9 @@ static const OSSL_ALGORITHM fips_keyexch
  #endif
  #ifndef OPENSSL_NO_EC
      { PROV_NAMES_ECDH, FIPS_DEFAULT_PROPERTIES, ossl_ecdh_keyexch_functions },
 -    { PROV_NAMES_X25519, FIPS_DEFAULT_PROPERTIES, ossl_x25519_keyexch_functions },
 -    { PROV_NAMES_X448, FIPS_DEFAULT_PROPERTIES, ossl_x448_keyexch_functions },
-+    { PROV_NAMES_X25519, FIPS_UNAPPROVED_PROPERTIES, ossl_x25519_keyexch_functions },
-+    { PROV_NAMES_X448, FIPS_UNAPPROVED_PROPERTIES, ossl_x448_keyexch_functions },
++    /* We don't certify Edwards curves in our FIPS provider */
++    /*{ PROV_NAMES_X25519, FIPS_DEFAULT_PROPERTIES, ossl_x25519_keyexch_functions },
++    { PROV_NAMES_X448, FIPS_DEFAULT_PROPERTIES, ossl_x448_keyexch_functions },*/
  #endif
      { PROV_NAMES_TLS1_PRF, FIPS_DEFAULT_PROPERTIES,
        ossl_kdf_tls1_prf_keyexch_functions },
-@@ -386,12 +389,12 @@ static const OSSL_ALGORITHM fips_keyexch
+@@ -403,12 +406,14 @@ static const OSSL_ALGORITHM fips_keyexch
  
  static const OSSL_ALGORITHM fips_signature[] = {
  #ifndef OPENSSL_NO_DSA
 -    { PROV_NAMES_DSA, FIPS_DEFAULT_PROPERTIES, ossl_dsa_signature_functions },
-+    { PROV_NAMES_DSA, FIPS_UNAPPROVED_PROPERTIES, ossl_dsa_signature_functions },
++    /* We don't certify DSA in our FIPS provider */
++    /* { PROV_NAMES_DSA, FIPS_DEFAULT_PROPERTIES, ossl_dsa_signature_functions }, */
  #endif
      { PROV_NAMES_RSA, FIPS_DEFAULT_PROPERTIES, ossl_rsa_signature_functions },
  #ifndef OPENSSL_NO_EC
 -    { PROV_NAMES_ED25519, FIPS_DEFAULT_PROPERTIES, ossl_ed25519_signature_functions },
 -    { PROV_NAMES_ED448, FIPS_DEFAULT_PROPERTIES, ossl_ed448_signature_functions },
-+    { PROV_NAMES_ED25519, FIPS_UNAPPROVED_PROPERTIES, ossl_ed25519_signature_functions },
-+    { PROV_NAMES_ED448, FIPS_UNAPPROVED_PROPERTIES, ossl_ed448_signature_functions },
++    /* We don't certify Edwards curves in our FIPS provider */
++    /* { PROV_NAMES_ED25519, FIPS_DEFAULT_PROPERTIES, ossl_ed25519_signature_functions },
++    { PROV_NAMES_ED448, FIPS_DEFAULT_PROPERTIES, ossl_ed448_signature_functions }, */
      { PROV_NAMES_ECDSA, FIPS_DEFAULT_PROPERTIES, ossl_ecdsa_signature_functions },
  #endif
      { PROV_NAMES_HMAC, FIPS_DEFAULT_PROPERTIES,
-@@ -421,7 +424,7 @@ static const OSSL_ALGORITHM fips_keymgmt
+@@ -438,8 +443,9 @@ static const OSSL_ALGORITHM fips_keymgmt
        PROV_DESCS_DHX },
  #endif
  #ifndef OPENSSL_NO_DSA
 -    { PROV_NAMES_DSA, FIPS_DEFAULT_PROPERTIES, ossl_dsa_keymgmt_functions,
-+    { PROV_NAMES_DSA, FIPS_UNAPPROVED_PROPERTIES, ossl_dsa_keymgmt_functions,
-       PROV_DESCS_DSA },
+-      PROV_DESCS_DSA },
++    /* We don't certify DSA in our FIPS provider */
++    /* { PROV_NAMES_DSA, FIPS_DEFAULT_PROPERTIES, ossl_dsa_keymgmt_functions,
++      PROV_DESCS_DSA }, */
  #endif
      { PROV_NAMES_RSA, FIPS_DEFAULT_PROPERTIES, ossl_rsa_keymgmt_functions,
-@@ -431,13 +434,13 @@ static const OSSL_ALGORITHM fips_keymgmt
+       PROV_DESCS_RSA },
+@@ -448,14 +454,15 @@ static const OSSL_ALGORITHM fips_keymgmt
  #ifndef OPENSSL_NO_EC
      { PROV_NAMES_EC, FIPS_DEFAULT_PROPERTIES, ossl_ec_keymgmt_functions,
        PROV_DESCS_EC },
 -    { PROV_NAMES_X25519, FIPS_DEFAULT_PROPERTIES, ossl_x25519_keymgmt_functions,
-+    { PROV_NAMES_X25519, FIPS_UNAPPROVED_PROPERTIES, ossl_x25519_keymgmt_functions,
++    /* We don't certify Edwards curves in our FIPS provider */
++    /* { PROV_NAMES_X25519, FIPS_DEFAULT_PROPERTIES, ossl_x25519_keymgmt_functions,
        PROV_DESCS_X25519 },
--    { PROV_NAMES_X448, FIPS_DEFAULT_PROPERTIES, ossl_x448_keymgmt_functions,
-+    { PROV_NAMES_X448, FIPS_UNAPPROVED_PROPERTIES, ossl_x448_keymgmt_functions,
+     { PROV_NAMES_X448, FIPS_DEFAULT_PROPERTIES, ossl_x448_keymgmt_functions,
        PROV_DESCS_X448 },
--    { PROV_NAMES_ED25519, FIPS_DEFAULT_PROPERTIES, ossl_ed25519_keymgmt_functions,
-+    { PROV_NAMES_ED25519, FIPS_UNAPPROVED_PROPERTIES, ossl_ed25519_keymgmt_functions,
+     { PROV_NAMES_ED25519, FIPS_DEFAULT_PROPERTIES, ossl_ed25519_keymgmt_functions,
        PROV_DESCS_ED25519 },
--    { PROV_NAMES_ED448, FIPS_DEFAULT_PROPERTIES, ossl_ed448_keymgmt_functions,
-+    { PROV_NAMES_ED448, FIPS_UNAPPROVED_PROPERTIES, ossl_ed448_keymgmt_functions,
-       PROV_DESCS_ED448 },
+     { PROV_NAMES_ED448, FIPS_DEFAULT_PROPERTIES, ossl_ed448_keymgmt_functions,
+-      PROV_DESCS_ED448 },
++      PROV_DESCS_ED448 }, */
  #endif
      { PROV_NAMES_TLS1_PRF, FIPS_DEFAULT_PROPERTIES, ossl_kdf_keymgmt_functions,
-diff -up openssl-3.0.0/test/acvp_test.c.fipsmin openssl-3.0.0/test/acvp_test.c
---- openssl-3.0.0/test/acvp_test.c.fipsmin	2022-01-12 18:34:17.283654119 +0100
-+++ openssl-3.0.0/test/acvp_test.c	2022-01-12 18:35:46.270430676 +0100
-@@ -1473,6 +1473,7 @@ int setup_tests(void)
+       PROV_DESCS_TLS1_PRF_SIGN },
+diff -up openssl-3.0.1/providers/fips/self_test_data.inc.fipsmin3 openssl-3.0.1/providers/fips/self_test_data.inc
+--- openssl-3.0.1/providers/fips/self_test_data.inc.fipsmin3	2022-05-05 12:36:32.335069046 +0200
++++ openssl-3.0.1/providers/fips/self_test_data.inc	2022-05-05 12:40:02.427966128 +0200
+@@ -171,6 +171,7 @@ static const ST_KAT_DIGEST st_kat_digest
+ /*- CIPHER TEST DATA */
+ 
+ /* DES3 test data */
++#if 0
+ static const unsigned char des_ede3_cbc_pt[] = {
+     0x6B, 0xC1, 0xBE, 0xE2, 0x2E, 0x40, 0x9F, 0x96,
+     0xE9, 0x3D, 0x7E, 0x11, 0x73, 0x93, 0x17, 0x2A,
+@@ -191,7 +192,7 @@ static const unsigned char des_ede3_cbc_
+     0x51, 0x65, 0x70, 0x48, 0x1F, 0x25, 0xB5, 0x0F,
+     0x73, 0xC0, 0xBD, 0xA8, 0x5C, 0x8E, 0x0D, 0xA7
+ };
+-
++#endif
+ /* AES-256 GCM test data */
+ static const unsigned char aes_256_gcm_key[] = {
+     0x92, 0xe1, 0x1d, 0xcd, 0xaa, 0x86, 0x6f, 0x5c,
+@@ -235,6 +236,7 @@ static const unsigned char aes_128_ecb_c
+ };
+ 
+ static const ST_KAT_CIPHER st_kat_cipher_tests[] = {
++#if 0
+ #ifndef OPENSSL_NO_DES
+     {
+         {
+@@ -248,6 +250,7 @@ static const ST_KAT_CIPHER st_kat_cipher
+         ITM(des_ede3_cbc_iv),
+     },
+ #endif
++#endif
+     {
+         {
+             OSSL_SELF_TEST_DESC_CIPHER_AES_GCM,
+@@ -1424,8 +1427,9 @@ static const ST_KAT_PARAM ecdsa_bin_key[
+ # endif /* OPENSSL_NO_EC2M */
+ #endif /* OPENSSL_NO_EC */
+ 
+-#ifndef OPENSSL_NO_DSA
+ /* dsa 2048 */
++#if 0
++#ifndef OPENSSL_NO_DSA
+ static const unsigned char dsa_p[] = {
+     0xa2, 0x9b, 0x88, 0x72, 0xce, 0x8b, 0x84, 0x23,
+     0xb7, 0xd5, 0xd2, 0x1d, 0x4b, 0x02, 0xf5, 0x7e,
+@@ -1549,8 +1553,8 @@ static const ST_KAT_PARAM dsa_key[] = {
+     ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, dsa_priv),
+     ST_KAT_PARAM_END()
+ };
+-#endif /* OPENSSL_NO_DSA */
+-
++#endif
++#endif
+ static const ST_KAT_SIGN st_kat_sign_tests[] = {
+     {
+         OSSL_SELF_TEST_DESC_SIGN_RSA,
+@@ -1583,6 +1587,7 @@ static const ST_KAT_SIGN st_kat_sign_tes
+     },
+ # endif
+ #endif /* OPENSSL_NO_EC */
++#if 0
+ #ifndef OPENSSL_NO_DSA
+     {
+         OSSL_SELF_TEST_DESC_SIGN_DSA,
+@@ -1595,6 +1600,7 @@ static const ST_KAT_SIGN st_kat_sign_tes
+          */
+     },
+ #endif /* OPENSSL_NO_DSA */
++#endif
+ };
+ 
+ static const ST_KAT_ASYM_CIPHER st_kat_asym_cipher_tests[] = {
+diff -up openssl-3.0.1/test/acvp_test.c.fipsmin2 openssl-3.0.1/test/acvp_test.c
+--- openssl-3.0.1/test/acvp_test.c.fipsmin2	2022-05-05 11:42:58.597848865 +0200
++++ openssl-3.0.1/test/acvp_test.c	2022-05-05 11:43:30.141126336 +0200
+@@ -1476,6 +1476,7 @@ int setup_tests(void)
                    OSSL_NELEM(dh_safe_prime_keyver_data));
  #endif /* OPENSSL_NO_DH */
  
@@ -127,7 +223,7 @@ diff -up openssl-3.0.0/test/acvp_test.c.fipsmin openssl-3.0.0/test/acvp_test.c
  #ifndef OPENSSL_NO_DSA
      ADD_ALL_TESTS(dsa_keygen_test, OSSL_NELEM(dsa_keygen_data));
      ADD_ALL_TESTS(dsa_paramgen_test, OSSL_NELEM(dsa_paramgen_data));
-@@ -1480,6 +1481,7 @@ int setup_tests(void)
+@@ -1483,6 +1484,7 @@ int setup_tests(void)
      ADD_ALL_TESTS(dsa_siggen_test, OSSL_NELEM(dsa_siggen_data));
      ADD_ALL_TESTS(dsa_sigver_test, OSSL_NELEM(dsa_sigver_data));
  #endif /* OPENSSL_NO_DSA */
@@ -135,3 +231,521 @@ diff -up openssl-3.0.0/test/acvp_test.c.fipsmin openssl-3.0.0/test/acvp_test.c
  
  #ifndef OPENSSL_NO_EC
      ADD_ALL_TESTS(ecdsa_keygen_test, OSSL_NELEM(ecdsa_keygen_data));
+diff -up openssl-3.0.1/test/evp_libctx_test.c.fipsmin3 openssl-3.0.1/test/evp_libctx_test.c
+--- openssl-3.0.1/test/evp_libctx_test.c.fipsmin3	2022-05-05 14:18:46.370911817 +0200
++++ openssl-3.0.1/test/evp_libctx_test.c	2022-05-05 14:30:02.117911993 +0200
+@@ -21,6 +21,7 @@
+  */
+ #include "internal/deprecated.h"
+ #include <assert.h>
++#include <string.h>
+ #include <openssl/evp.h>
+ #include <openssl/provider.h>
+ #include <openssl/dsa.h>
+@@ -725,8 +726,10 @@ int setup_tests(void)
+     if (!test_get_libctx(&libctx, &nullprov, config_file, &libprov, prov_name))
+         return 0;
+ 
+ #if !defined(OPENSSL_NO_DSA) && !defined(OPENSSL_NO_DH)
+-    ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3);
++    if (strcmp(prov_name, "fips") != 0) {
++        ADD_ALL_TESTS(test_dsa_param_keygen, 3 * 3 * 3);
++    }
+ #endif
+ #ifndef OPENSSL_NO_DH
+     ADD_ALL_TESTS(test_dh_safeprime_param_keygen, 3 * 3 * 3);
+@@ -746,7 +750,9 @@ int setup_tests(void)
+     ADD_TEST(kem_invalid_keytype);
+ #endif
+ #ifndef OPENSSL_NO_DES
+-    ADD_TEST(test_cipher_tdes_randkey);
++    if (strcmp(prov_name, "fips") != 0) {
++        ADD_TEST(test_cipher_tdes_randkey);
++    }
+ #endif
+     return 1;
+ }
+diff -up openssl-3.0.1/test/recipes/15-test_gendsa.t.fipsmin3 openssl-3.0.1/test/recipes/15-test_gendsa.t
+--- openssl-3.0.1/test/recipes/15-test_gendsa.t.fipsmin3	2022-05-05 13:46:00.631590335 +0200
++++ openssl-3.0.1/test/recipes/15-test_gendsa.t	2022-05-05 13:46:06.999644496 +0200
+@@ -24,7 +24,7 @@ use lib bldtop_dir('.');
+ plan skip_all => "This test is unsupported in a no-dsa build"
+     if disabled("dsa");
+ 
+-my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
++my $no_fips = 1;
+ 
+ plan tests =>
+     ($no_fips ? 0 : 2)          # FIPS related tests
+diff -up openssl-3.0.1/test/recipes/20-test_cli_fips.t.fipsmin3 openssl-3.0.1/test/recipes/20-test_cli_fips.t
+--- openssl-3.0.1/test/recipes/20-test_cli_fips.t.fipsmin3	2022-05-05 13:47:55.217564900 +0200
++++ openssl-3.0.1/test/recipes/20-test_cli_fips.t	2022-05-05 13:48:02.824629600 +0200
+@@ -207,8 +207,7 @@ SKIP: {
+ }
+ 
+ SKIP : {
+-    skip "FIPS DSA tests because of no dsa in this build", 1
+-        if disabled("dsa");
++    skip "FIPS DSA tests because of no dsa in this build", 1;
+ 
+     subtest DSA => sub {
+         my $testtext_prefix = 'DSA';
+diff -up openssl-3.0.1/test/recipes/80-test_cms.t.fipsmin3 openssl-3.0.1/test/recipes/80-test_cms.t
+--- openssl-3.0.1/test/recipes/80-test_cms.t.fipsmin3	2022-05-05 13:55:05.257292637 +0200
++++ openssl-3.0.1/test/recipes/80-test_cms.t	2022-05-05 13:58:35.307150750 +0200
+@@ -95,7 +95,7 @@ my @smime_pkcs7_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "signed content DER format, DSA key",
++    [ "signed content DER format, DSA key, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER", "-nodetach",
+         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
+       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
+@@ -103,7 +103,7 @@ my @smime_pkcs7_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "signed detached content DER format, DSA key",
++    [ "signed detached content DER format, DSA key, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
+         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
+       [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms", "-inform", "DER",
+@@ -112,7 +112,7 @@ my @smime_pkcs7_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "signed detached content DER format, add RSA signer (with DSA existing)",
++    [ "signed detached content DER format, add RSA signer (with DSA existing), no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
+         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
+       [ "{cmd1}", @prov, "-resign", "-in", "{output}.cms", "-inform", "DER", "-outform", "DER",
+@@ -123,7 +123,7 @@ my @smime_pkcs7_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "signed content test streaming BER format, DSA key",
++    [ "signed content test streaming BER format, DSA key, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
+         "-nodetach", "-stream",
+         "-signer", catfile($smdir, "smdsa1.pem"), "-out", "{output}.cms" ],
+@@ -132,7 +132,7 @@ my @smime_pkcs7_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "signed content test streaming BER format, 2 DSA and 2 RSA keys",
++    [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
+         "-nodetach", "-stream",
+         "-signer", $smrsa1,
+@@ -145,7 +145,7 @@ my @smime_pkcs7_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes",
++    [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, no attributes, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
+         "-noattr", "-nodetach", "-stream",
+         "-signer", $smrsa1,
+@@ -175,7 +175,7 @@ my @smime_pkcs7_tests = (
+       \&zero_compare
+     ],
+ 
+-    [ "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys",
++    [ "signed content test streaming S/MIME format, 2 DSA and 2 RSA keys, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-nodetach",
+         "-signer", $smrsa1,
+         "-signer", catfile($smdir, "smrsa2.pem"),
+@@ -187,7 +187,7 @@ my @smime_pkcs7_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys",
++    [ "signed content test streaming multipart S/MIME format, 2 DSA and 2 RSA keys, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont,
+         "-signer", $smrsa1,
+         "-signer", catfile($smdir, "smrsa2.pem"),
+@@ -247,7 +247,7 @@ my @smime_pkcs7_tests = (
+ 
+ my @smime_cms_tests = (
+ 
+-    [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid",
++    [ "signed content test streaming BER format, 2 DSA and 2 RSA keys, keyid, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "DER",
+         "-nodetach", "-keyid",
+         "-signer", $smrsa1,
+@@ -260,7 +260,7 @@ my @smime_cms_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "signed content test streaming PEM format, 2 DSA and 2 RSA keys",
++    [ "signed content test streaming PEM format, 2 DSA and 2 RSA keys, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-sign", "-in", $smcont, "-outform", "PEM", "-nodetach",
+         "-signer", $smrsa1,
+         "-signer", catfile($smdir, "smrsa2.pem"),
+@@ -370,7 +370,7 @@ my @smime_cms_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "encrypted content test streaming PEM format, triple DES key",
++    [ "encrypted content test streaming PEM format, triple DES key, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-EncryptedData_encrypt", "-in", $smcont, "-outform", "PEM",
+         "-des3", "-secretkey", "000102030405060708090A0B0C0D0E0F1011121314151617",
+         "-stream", "-out", "{output}.cms" ],
+diff -up openssl-3.0.1/test/recipes/30-test_evp.t.fipsmin3 openssl-3.0.1/test/recipes/30-test_evp.t
+--- openssl-3.0.1/test/recipes/30-test_evp.t.fipsmin3	2022-05-05 14:43:04.276857033 +0200
++++ openssl-3.0.1/test/recipes/30-test_evp.t	2022-05-05 14:43:35.975138234 +0200
+@@ -43,7 +43,6 @@ my @files = qw(
+                 evpciph_aes_cts.txt
+                 evpciph_aes_wrap.txt
+                 evpciph_aes_stitched.txt
+-                evpciph_des3_common.txt
+                 evpkdf_hkdf.txt
+                 evpkdf_pbkdf1.txt
+                 evpkdf_pbkdf2.txt
+@@ -66,12 +65,6 @@ push @files, qw(
+                 evppkey_dh.txt
+                ) unless $no_dh;
+ push @files, qw(
+-                evpkdf_x942_des.txt
+-                evpmac_cmac_des.txt
+-               ) unless $no_des;
+-push @files, qw(evppkey_dsa.txt) unless $no_dsa;
+-push @files, qw(evppkey_ecx.txt) unless $no_ec;
+-push @files, qw(
+                 evppkey_ecc.txt
+                 evppkey_ecdh.txt
+                 evppkey_ecdsa.txt
+@@ -91,6 +84,7 @@ my @defltfiles = qw(
+                      evpciph_cast5.txt
+                      evpciph_chacha.txt
+                      evpciph_des.txt
++                     evpciph_des3_common.txt
+                      evpciph_idea.txt
+                      evpciph_rc2.txt
+                      evpciph_rc4.txt
+@@ -117,6 +111,12 @@ my @defltfiles = qw(
+                      evppkey_kdf_tls1_prf.txt
+                      evppkey_rsa.txt
+                     );
++push @defltfiles, qw(evppkey_dsa.txt) unless $no_dsa;
++push @defltfiles, qw(evppkey_ecx.txt) unless $no_ec;
++push @defltfiles, qw(
++                evpkdf_x942_des.txt
++                evpmac_cmac_des.txt
++               ) unless $no_des;
+ push @defltfiles, qw(evppkey_sm2.txt) unless $no_sm2;
+ 
+ plan tests =>
+diff -up openssl-3.0.1/test/recipes/30-test_evp_data/evpmac_common.txt.fipsmin3 openssl-3.0.1/test/recipes/30-test_evp_data/evpmac_common.txt
+--- openssl-3.0.1/test/recipes/30-test_evp_data/evpmac_common.txt.fipsmin3	2022-05-05 14:46:32.721700697 +0200
++++ openssl-3.0.1/test/recipes/30-test_evp_data/evpmac_common.txt	2022-05-05 14:51:40.205418897 +0200
+@@ -328,6 +328,7 @@ Input = 68F2E77696CE7AE8E2CA4EC588E54100
+ Output = 00BDA1B7E87608BCBF470F12157F4C07
+ 
+ 
++Availablein = default
+ Title = KMAC Tests (From NIST)
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+@@ -338,12 +339,14 @@ Ctrl = xof:0
+ OutputSize = 32
+ BlockSize = 168
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 00010203
+ Custom = "My Tagged Application"
+ Output = 3B1FBA963CD8B0B59E8C1A6D71888B7143651AF8BA0A7070C0979E2811324AA5
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -351,6 +354,7 @@ Custom = "My Tagged Application"
+ Output = 1F5B4E6CCA02209E0DCB5CA635B89A15E271ECC760071DFD805FAA38F9729230
+ Ctrl = size:32
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 00010203
+@@ -359,12 +363,14 @@ Output = 20C570C31346F703C9AC36C61C03CB6
+ OutputSize = 64
+ BlockSize = 136
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+ Custom = ""
+ Output = 75358CF39E41494E949707927CEE0AF20A3FF553904C86B08F21CC414BCFD691589D27CF5E15369CBBFF8B9A4C2EB17800855D0235FF635DA82533EC6B759B69
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -374,12 +380,14 @@ Ctrl = size:64
+ 
+ Title = KMAC XOF Tests (From NIST)
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 00010203
+ Output = CD83740BBD92CCC8CF032B1481A0F4460E7CA9DD12B08A0C4031178BACD6EC35
+ XOF = 1
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 00010203
+@@ -387,6 +395,7 @@ Custom = "My Tagged Application"
+ Output = 31A44527B4ED9F5C6101D11DE6D26F0620AA5C341DEF41299657FE9DF1A3B16C
+ XOF = 1
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -395,6 +404,7 @@ Output = 47026C7CD793084AA0283C253EF6584
+ XOF = 1
+ Ctrl = size:32
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 00010203
+@@ -402,6 +412,7 @@ Custom = "My Tagged Application"
+ Output = 1755133F1534752AAD0748F2C706FB5C784512CAB835CD15676B16C0C6647FA96FAA7AF634A0BF8FF6DF39374FA00FAD9A39E322A7C92065A64EB1FB0801EB2B
+ XOF = 1
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -409,6 +420,7 @@ Custom = ""
+ Output = FF7B171F1E8A2B24683EED37830EE797538BA8DC563F6DA1E667391A75EDC02CA633079F81CE12A25F45615EC89972031D18337331D24CEB8F8CA8E6A19FD98B
+ XOF = 1
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -419,6 +431,7 @@ XOF = 1
+ 
+ Title = KMAC long customisation string (from NIST ACVP)
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 9743DBF93102FAF11227B154B8ACD16CF142671F7AA16C559A393A38B4CEF461ED29A6A328D7379C99718790E38B54CA25E9E831CBEA463EE704D1689F94629AB795DF0C77F756DA743309C0E054596BA2D9CC1768ACF7CD351D9A7EB1ABD0A3
+ Input = BA63AC9C711F143CCE7FF92D0322649D1BE437D805FD225C0A2879A008373EC3BCCDB09971FAD2BCE5F4347AF7E5238EF01A90ED34193D6AFC1D
+@@ -429,12 +442,14 @@ XOF = 1
+ 
+ Title = KMAC XOF Tests via ctrl (From NIST)
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 00010203
+ Output = CD83740BBD92CCC8CF032B1481A0F4460E7CA9DD12B08A0C4031178BACD6EC35
+ Ctrl = xof:1
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 00010203
+@@ -442,6 +457,7 @@ Custom = "My Tagged Application"
+ Output = 31A44527B4ED9F5C6101D11DE6D26F0620AA5C341DEF41299657FE9DF1A3B16C
+ Ctrl = xof:1
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -450,6 +466,7 @@ Output = 47026C7CD793084AA0283C253EF6584
+ Ctrl = xof:1
+ Ctrl = size:32
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 00010203
+@@ -457,6 +474,7 @@ Custom = "My Tagged Application"
+ Output = 1755133F1534752AAD0748F2C706FB5C784512CAB835CD15676B16C0C6647FA96FAA7AF634A0BF8FF6DF39374FA00FAD9A39E322A7C92065A64EB1FB0801EB2B
+ Ctrl = xof:1
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -464,6 +482,7 @@ Custom = ""
+ Output = FF7B171F1E8A2B24683EED37830EE797538BA8DC563F6DA1E667391A75EDC02CA633079F81CE12A25F45615EC89972031D18337331D24CEB8F8CA8E6A19FD98B
+ Ctrl = xof:1
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -474,6 +493,7 @@ Ctrl = xof:1
+ 
+ Title = KMAC long customisation string via ctrl (from NIST ACVP)
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 9743DBF93102FAF11227B154B8ACD16CF142671F7AA16C559A393A38B4CEF461ED29A6A328D7379C99718790E38B54CA25E9E831CBEA463EE704D1689F94629AB795DF0C77F756DA743309C0E054596BA2D9CC1768ACF7CD351D9A7EB1ABD0A3
+ Input = BA63AC9C711F143CCE7FF92D0322649D1BE437D805FD225C0A2879A008373EC3BCCDB09971FAD2BCE5F4347AF7E5238EF01A90ED34193D6AFC1D
+@@ -484,6 +504,7 @@ Ctrl = xof:1
+ 
+ Title = KMAC long customisation string negative test
+ 
++Availablein = default
+ MAC = KMAC128
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+@@ -492,6 +513,7 @@ Result = MAC_INIT_ERROR
+ 
+ Title = KMAC output is too large
+ 
++Availablein = default
+ MAC = KMAC256
+ Key = 404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
+ Input = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F707172737475767778797A7B7C7D7E7F808182838485868788898A8B8C8D8E8F909192939495969798999A9B9C9D9E9FA0A1A2A3A4A5A6A7A8A9AAABACADAEAFB0B1B2B3B4B5B6B7B8B9BABBBCBDBEBFC0C1C2C3C4C5C6C7
+diff -up openssl-3.0.1/test/recipes/80-test_ssl_old.t.fipsmin3 openssl-3.0.1/test/recipes/80-test_ssl_old.t
+--- openssl-3.0.1/test/recipes/80-test_ssl_old.t.fipsmin3	2022-05-05 16:02:59.745500635 +0200
++++ openssl-3.0.1/test/recipes/80-test_ssl_old.t	2022-05-05 16:10:24.071348890 +0200
+@@ -426,7 +426,7 @@ sub testssl {
+         my @exkeys = ();
+         my $ciphers = '-PSK:-SRP:@SECLEVEL=0';
+ 
+-        if (!$no_dsa) {
++        if (!$no_dsa && $provider ne "fips") {
+             push @exkeys, "-s_cert", "certD.ss", "-s_key", $Dkey;
+         }
+ 
+diff -up openssl-3.0.1/test/endecode_test.c.fipsmin3 openssl-3.0.1/test/endecode_test.c
+--- openssl-3.0.1/test/endecode_test.c.fipsmin3	2022-05-06 16:25:57.296926271 +0200
++++ openssl-3.0.1/test/endecode_test.c	2022-05-06 16:27:42.712850840 +0200
+@@ -1387,6 +1387,7 @@ int setup_tests(void)
+          * so no legacy tests.
+          */
+ #endif
++    if (is_fips == 0) {
+ #ifndef OPENSSL_NO_DSA
+         ADD_TEST_SUITE(DSA);
+         ADD_TEST_SUITE_PARAMS(DSA);
+@@ -1397,6 +1398,7 @@ int setup_tests(void)
+         ADD_TEST_SUITE_PROTECTED_PVK(DSA);
+ # endif
+ #endif
++    }
+ #ifndef OPENSSL_NO_EC
+         ADD_TEST_SUITE(EC);
+         ADD_TEST_SUITE_PARAMS(EC);
+@@ -1411,10 +1413,12 @@ int setup_tests(void)
+         ADD_TEST_SUITE(ECExplicitTri2G);
+         ADD_TEST_SUITE_LEGACY(ECExplicitTri2G);
+ # endif
++    if (is_fips == 0) {
+         ADD_TEST_SUITE(ED25519);
+         ADD_TEST_SUITE(ED448);
+         ADD_TEST_SUITE(X25519);
+         ADD_TEST_SUITE(X448);
++    }
+         /*
+          * ED25519, ED448, X25519 and X448 have no support for
+          * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
+diff -up openssl-3.0.1/apps/req.c.dfc openssl-3.0.1/apps/req.c
+--- openssl-3.0.1/apps/req.c.dfc	2022-05-12 13:31:21.957638329 +0200
++++ openssl-3.0.1/apps/req.c	2022-05-12 13:31:49.587984867 +0200
+@@ -266,7 +266,7 @@ int req_main(int argc, char **argv)
+     unsigned long chtype = MBSTRING_ASC, reqflag = 0;
+ 
+ #ifndef OPENSSL_NO_DES
+-    cipher = (EVP_CIPHER *)EVP_des_ede3_cbc();
++    cipher = (EVP_CIPHER *)EVP_aes_256_cbc();
+ #endif
+ 
+     prog = opt_init(argc, argv, req_options);
+diff -up openssl-3.0.1/apps/ecparam.c.fips_list_curves openssl-3.0.1/apps/ecparam.c
+--- openssl-3.0.1/apps/ecparam.c.fips_list_curves	2022-05-19 11:46:22.682519422 +0200
++++ openssl-3.0.1/apps/ecparam.c	2022-05-19 11:50:44.559828701 +0200
+@@ -79,6 +79,9 @@ static int list_builtin_curves(BIO *out)
+         const char *comment = curves[n].comment;
+         const char *sname = OBJ_nid2sn(curves[n].nid);
+ 
++        if ((curves[n].nid == NID_secp256k1) && EVP_default_properties_is_fips_enabled(NULL))
++            continue;
++
+         if (comment == NULL)
+             comment = "CURVE DESCRIPTION NOT AVAILABLE";
+         if (sname == NULL)
+diff -up openssl-3.0.1/ssl/ssl_ciph.c.nokrsa openssl-3.0.1/ssl/ssl_ciph.c
+--- openssl-3.0.1/ssl/ssl_ciph.c.nokrsa	2022-05-19 13:32:32.536708638 +0200
++++ openssl-3.0.1/ssl/ssl_ciph.c	2022-05-19 13:42:29.734002959 +0200
+@@ -356,6 +356,9 @@ int ssl_load_ciphers(SSL_CTX *ctx)
+     ctx->disabled_mkey_mask = 0;
+     ctx->disabled_auth_mask = 0;
+ 
++    if (EVP_default_properties_is_fips_enabled(ctx->libctx))
++        ctx->disabled_mkey_mask |= SSL_kRSA | SSL_kRSAPSK;
++
+     /*
+      * We ignore any errors from the fetches below. They are expected to fail
+      * if theose algorithms are not available.
+diff -up openssl-3.0.1/providers/implementations/signature/rsa_sig.c.fipskeylen openssl-3.0.1/providers/implementations/signature/rsa_sig.c
+--- openssl-3.0.1/providers/implementations/signature/rsa_sig.c.fipskeylen	2022-05-23 14:58:07.764281242 +0200
++++ openssl-3.0.1/providers/implementations/signature/rsa_sig.c	2022-05-23 15:10:29.327993616 +0200
+@@ -770,6 +770,19 @@ static int rsa_verify(void *vprsactx, co
+ {
+     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
+     size_t rslen;
++# ifdef FIPS_MODULE
++    size_t rsabits = RSA_bits(prsactx->rsa);
++
++    if (rsabits < 2048) {
++        if (rsabits != 1024
++            && rsabits != 1280
++            && rsabits != 1536
++            && rsabits != 1792) {
++            ERR_raise(ERR_LIB_FIPS, PROV_R_INVALID_KEY_LENGTH);
++            return 0;
++        }
++    }
++# endif
+ 
+     if (!ossl_prov_is_running())
+         return 0;
+diff -up openssl-3.0.1/ssl/t1_lib.c.groupnames openssl-3.0.1/ssl/t1_lib.c
+--- openssl-3.0.1/ssl/t1_lib.c.groupnames	2022-06-17 09:42:50.866748854 +0200
++++ openssl-3.0.1/ssl/t1_lib.c	2022-06-17 09:49:07.715973172 +0200
+@@ -345,6 +345,7 @@ static int add_provider_groups(const OSS
+      * it.
+      */
+     ret = 1;
++    (void)ERR_set_mark();
+     keymgmt = EVP_KEYMGMT_fetch(ctx->libctx, ginf->algorithm, ctx->propq);
+     if (keymgmt != NULL) {
+         /*
+@@ -366,6 +367,7 @@ static int add_provider_groups(const OSS
+         }
+         EVP_KEYMGMT_free(keymgmt);
+     }
++    (void)ERR_pop_to_mark();
+  err:
+     if (ginf != NULL) {
+         OPENSSL_free(ginf->tlsname);
+@@ -725,8 +727,11 @@ static int gid_cb(const char *elem, int
+     etmp[len] = 0;
+ 
+     gid = tls1_group_name2id(garg->ctx, etmp);
+-    if (gid == 0)
++    if (gid == 0) {
++        ERR_raise_data(ERR_LIB_SSL, ERR_R_PASSED_INVALID_ARGUMENT,
++                       "group '%s' cannot be set", etmp);
+         return 0;
++    }
+     for (i = 0; i < garg->gidcnt; i++)
+         if (garg->gid_arr[i] == gid)
+             return 0;
diff --git a/SOURCES/0051-Support-different-R_BITS-lengths-for-KBKDF.patch b/SOURCES/0051-Support-different-R_BITS-lengths-for-KBKDF.patch
index eb8b5e3..c240628 100644
--- a/SOURCES/0051-Support-different-R_BITS-lengths-for-KBKDF.patch
+++ b/SOURCES/0051-Support-different-R_BITS-lengths-for-KBKDF.patch
@@ -293,8 +293,8 @@ index 7ae546e1d70c..7b976c0a1b5e 100644
 --- a/test/recipes/30-test_evp.t
 +++ b/test/recipes/30-test_evp.t
 @@ -45,6 +45,7 @@ my @files = qw(
+                 evpciph_aes_wrap.txt
                  evpciph_aes_stitched.txt
-                 evpciph_des3_common.txt
                  evpkdf_hkdf.txt
 +                evpkdf_kbkdf_counter.txt
                  evpkdf_pbkdf1.txt
diff --git a/SOURCES/0052-Allow-SHA1-in-seclevel-2-if-rh-allow-sha1-signatures.patch b/SOURCES/0052-Allow-SHA1-in-seclevel-2-if-rh-allow-sha1-signatures.patch
index c7cb9b7..5208f40 100644
--- a/SOURCES/0052-Allow-SHA1-in-seclevel-2-if-rh-allow-sha1-signatures.patch
+++ b/SOURCES/0052-Allow-SHA1-in-seclevel-2-if-rh-allow-sha1-signatures.patch
@@ -184,8 +184,8 @@ index 700bbd849c..2de1d76b5e 100644
      run(app([@args]));
  }
  
--plan tests => 160;
-+plan tests => 159;
+-plan tests => 163;
++plan tests => 162;
  
  # Canonical success
  ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
diff --git a/SOURCES/0054-Replace-size-check-with-more-meaningful-pubkey-check.patch b/SOURCES/0054-Replace-size-check-with-more-meaningful-pubkey-check.patch
new file mode 100644
index 0000000..a66968d
--- /dev/null
+++ b/SOURCES/0054-Replace-size-check-with-more-meaningful-pubkey-check.patch
@@ -0,0 +1,53 @@
+From 2c0f7d46b8449423446cfe1e52fc1e1ecd506b62 Mon Sep 17 00:00:00 2001
+From: Tomas Mraz <tomas@openssl.org>
+Date: Wed, 2 Feb 2022 17:47:26 +0100
+Subject: [PATCH] Replace size check with more meaningful pubkey check
+
+It does not make sense to check the size because this
+function can be used in other contexts than in TLS-1.3 and
+the value might not be padded to the size of p.
+
+However it makes sense to do the partial pubkey check because
+there is no valid reason having the pubkey value outside the
+1 < pubkey < p-1 bounds.
+
+Fixes #15465
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/17630)
+---
+ crypto/dh/dh_key.c | 11 ++++-------
+ 1 file changed, 4 insertions(+), 7 deletions(-)
+
+diff --git a/crypto/dh/dh_key.c b/crypto/dh/dh_key.c
+index 6b8cd550f2..c78ed618bf 100644
+--- a/crypto/dh/dh_key.c
++++ b/crypto/dh/dh_key.c
+@@ -375,20 +375,17 @@ int ossl_dh_buf2key(DH *dh, const unsigned char *buf, size_t len)
+     int err_reason = DH_R_BN_ERROR;
+     BIGNUM *pubkey = NULL;
+     const BIGNUM *p;
+-    size_t p_size;
++    int ret;
+ 
+     if ((pubkey = BN_bin2bn(buf, len, NULL)) == NULL)
+         goto err;
+     DH_get0_pqg(dh, &p, NULL, NULL);
+-    if (p == NULL || (p_size = BN_num_bytes(p)) == 0) {
++    if (p == NULL || BN_num_bytes(p) == 0) {
+         err_reason = DH_R_NO_PARAMETERS_SET;
+         goto err;
+     }
+-    /*
+-     * As per Section 4.2.8.1 of RFC 8446 fail if DHE's
+-     * public key is of size not equal to size of p
+-     */
+-    if (BN_is_zero(pubkey) || p_size != len) {
++    /* Prevent small subgroup attacks per RFC 8446 Section 4.2.8.1 */
++    if (!ossl_dh_check_pub_key_partial(dh, pubkey, &ret)) {
+         err_reason = DH_R_INVALID_PUBKEY;
+         goto err;
+     }
+-- 
+2.35.1
+
diff --git a/SOURCES/0056-strcasecmp.patch b/SOURCES/0056-strcasecmp.patch
index 2bbb995..ed30b2e 100644
--- a/SOURCES/0056-strcasecmp.patch
+++ b/SOURCES/0056-strcasecmp.patch
@@ -1427,7 +1427,7 @@ index f4605dcd6ce5..fc17a958ce26 100644
 +
  #define ALGC(NAMES, FUNC, CHECK) { { NAMES, FIPS_DEFAULT_PROPERTIES, FUNC }, CHECK }
  #define ALG(NAMES, FUNC) ALGC(NAMES, FUNC, NULL)
- #define ALGCU(NAMES, FUNC, CHECK) { { NAMES, FIPS_UNAPPROVED_PROPERTIES, FUNC }, CHECK }
+ extern OSSL_FUNC_core_thread_start_fn *c_thread_start;
 @@ -486,6 +503,23 @@ static const OSSL_ALGORITHM *fips_query(void *provctx, int operation_id,
      return NULL;
  }
diff --git a/SOURCES/0058-FIPS-limit-rsa-encrypt.patch b/SOURCES/0058-FIPS-limit-rsa-encrypt.patch
new file mode 100644
index 0000000..6dcf7c0
--- /dev/null
+++ b/SOURCES/0058-FIPS-limit-rsa-encrypt.patch
@@ -0,0 +1,540 @@
+diff -up openssl-3.0.1/providers/common/securitycheck.c.rsaenc openssl-3.0.1/providers/common/securitycheck.c
+--- openssl-3.0.1/providers/common/securitycheck.c.rsaenc	2022-06-24 17:14:33.634692729 +0200
++++ openssl-3.0.1/providers/common/securitycheck.c	2022-06-24 17:16:08.966540605 +0200
+@@ -27,6 +27,7 @@
+  * Set protect = 1 for encryption or signing operations, or 0 otherwise. See
+  * https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-131Ar2.pdf.
+  */
++/* Red Hat build implements some extra limitations in providers/implementations/asymciphers/rsa_enc.c */
+ int ossl_rsa_check_key(OSSL_LIB_CTX *ctx, const RSA *rsa, int operation)
+ {
+     int protect = 0;
+diff -up openssl-3.0.1/providers/implementations/asymciphers/rsa_enc.c.no_bad_pad openssl-3.0.1/providers/implementations/asymciphers/rsa_enc.c
+--- openssl-3.0.1/providers/implementations/asymciphers/rsa_enc.c.no_bad_pad	2022-05-02 16:04:47.000091901 +0200
++++ openssl-3.0.1/providers/implementations/asymciphers/rsa_enc.c	2022-05-02 16:14:50.922443581 +0200
+@@ -132,6 +132,17 @@ static int rsa_decrypt_init(void *vprsac
+     return rsa_init(vprsactx, vrsa, params, EVP_PKEY_OP_DECRYPT);
+ }
+ 
++# ifdef FIPS_MODULE
++static int fips_padding_allowed(const PROV_RSA_CTX *prsactx)
++{
++    if (prsactx->pad_mode == RSA_PKCS1_PADDING
++        || prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING)
++        return 0;
++
++    return 1;
++}
++# endif
++
+ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen,
+                        size_t outsize, const unsigned char *in, size_t inlen)
+ {
+@@ -141,6 +152,18 @@ static int rsa_encrypt(void *vprsactx, u
+     if (!ossl_prov_is_running())
+         return 0;
+ 
++# ifdef FIPS_MODULE
++    if (fips_padding_allowed(prsactx) == 0) {
++        ERR_raise(ERR_LIB_PROV, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
++        return 0;
++    }
++
++    if (RSA_bits(prsactx->rsa) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) {
++        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
++        return 0;
++    }
++# endif
++
+     if (out == NULL) {
+         size_t len = RSA_size(prsactx->rsa);
+ 
+@@ -202,6 +220,18 @@ static int rsa_decrypt(void *vprsactx, u
+     if (!ossl_prov_is_running())
+         return 0;
+ 
++# ifdef FIPS_MODULE
++    if (fips_padding_allowed(prsactx) == 0) {
++        ERR_raise(ERR_LIB_PROV, PROV_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE);
++        return 0;
++    }
++
++    if (RSA_bits(prsactx->rsa) < OPENSSL_RSA_FIPS_MIN_MODULUS_BITS) {
++        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
++        return 0;
++    }
++# endif
++
+     if (prsactx->pad_mode == RSA_PKCS1_WITH_TLS_PADDING) {
+         if (out == NULL) {
+             *outlen = SSL_MAX_MASTER_KEY_LENGTH;
+diff -up openssl-3.0.1/test/recipes/80-test_cms.t.no_bad_pad openssl-3.0.1/test/recipes/80-test_cms.t
+--- openssl-3.0.1/test/recipes/80-test_cms.t.no_bad_pad	2022-05-02 17:04:07.610782138 +0200
++++ openssl-3.0.1/test/recipes/80-test_cms.t	2022-05-02 17:06:03.595814620 +0200
+@@ -232,7 +232,7 @@ my @smime_pkcs7_tests = (
+       \&final_compare
+     ],
+ 
+-    [ "enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients",
++    [ "enveloped content test streaming S/MIME format, AES-256 cipher, 3 recipients, no Red Hat FIPS",
+       [ "{cmd1}", @prov, "-encrypt", "-in", $smcont,
+         "-aes256", "-stream", "-out", "{output}.cms",
+         $smrsa1,
+@@ -865,5 +865,8 @@ sub check_availability {
+     return "$tnam: skipped, DSA disabled\n"
+         if ($no_dsa && $tnam =~ / DSA/);
+ 
++    return "$tnam: skipped, Red Hat FIPS\n"
++        if ($tnam =~ /no Red Hat FIPS/);
++
+     return "";
+ }
+diff -up openssl-3.0.1/test/recipes/80-test_ssl_old.t.no_bad_pad openssl-3.0.1/test/recipes/80-test_ssl_old.t
+--- openssl-3.0.1/test/recipes/80-test_ssl_old.t.no_bad_pad	2022-05-02 17:26:37.962838053 +0200
++++ openssl-3.0.1/test/recipes/80-test_ssl_old.t	2022-05-02 17:34:20.297950449 +0200
+@@ -483,6 +483,18 @@ sub testssl {
+             # the default choice if TLSv1.3 enabled
+             my $flag = $protocol eq "-tls1_3" ? "" : $protocol;
+             my $ciphersuites = "";
++            my %redhat_skip_cipher = map {$_ => 1} qw(
++AES256-GCM-SHA384:@SECLEVEL=0
++AES256-CCM8:@SECLEVEL=0
++AES256-CCM:@SECLEVEL=0
++AES128-GCM-SHA256:@SECLEVEL=0
++AES128-CCM8:@SECLEVEL=0
++AES128-CCM:@SECLEVEL=0
++AES256-SHA256:@SECLEVEL=0
++AES128-SHA256:@SECLEVEL=0
++AES256-SHA:@SECLEVEL=0
++AES128-SHA:@SECLEVEL=0
++	    );
+             foreach my $cipher (@{$ciphersuites{$protocol}}) {
+                 if ($protocol eq "-ssl3" && $cipher =~ /ECDH/ ) {
+                     note "*****SKIPPING $protocol $cipher";
+@@ -494,11 +506,16 @@ sub testssl {
+                     } else {
+                         $cipher = $cipher.':@SECLEVEL=0';
+                     }
+-                    ok(run(test([@ssltest, @exkeys, "-cipher",
+-                                 $cipher,
+-                                 "-ciphersuites", $ciphersuites,
+-                                 $flag || ()])),
+-                       "Testing $cipher");
++                    if ($provider eq "fips" && exists $redhat_skip_cipher{$cipher}) {
++                        note "*****SKIPPING $cipher in Red Hat FIPS mode";
++                        ok(1);
++                    } else {
++                        ok(run(test([@ssltest, @exkeys, "-cipher",
++                                     $cipher,
++                                     "-ciphersuites", $ciphersuites,
++                                     $flag || ()])),
++                           "Testing $cipher");
++                    }
+                 }
+             }
+             next if $protocol eq "-tls1_3";
+diff -up openssl-3.0.1/test/recipes/30-test_evp_data/evppkey_rsa_common.txt.fipskeylen openssl-3.0.1/test/recipes/30-test_evp_data/evppkey_rsa_common.txt
+--- openssl-3.0.1/test/recipes/30-test_evp_data/evppkey_rsa_common.txt.fipskeylen	2022-06-16 14:26:19.383530498 +0200
++++ openssl-3.0.1/test/recipes/30-test_evp_data/evppkey_rsa_common.txt	2022-06-16 14:39:53.637777701 +0200
+@@ -263,12 +263,13 @@ Input = 64b0e9f9892371110c40ba5739dc0974
+ Output = 0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef
+ 
+ # RSA decrypt
+-
++Availablein = default
+ Decrypt = RSA-2048
+ Input = 550AF55A2904E7B9762352F8FB7FA235A9CB053AACB2D5FCB8CA48453CB2EE3619746C701ABF2D4CC67003471A187900B05AA812BD25ED05C675DFC8C97A24A7BF49BD6214992CAD766D05A9A2B57B74F26A737E0237B8B76C45F1F226A836D7CFBC75BA999BDBE48DBC09227AA46C88F21DCCBA7840141AD5A5D71FD122E6BD6AC3E564780DFE623FC1CA9B995A6037BF0BBD43B205A84AC5444F34202C05CE9113087176432476576DE6FFFF9A52EA57C08BE3EC2F49676CB8E12F762AC71FA3C321E00AC988910C85FF52F93825666CE0D40FFAA0592078919D4493F46D95CCF76364C6D57760DD0B64805F9AFC76A2365A5575CA301D5103F0EA76CB9A78
+ Output = "Hello World"
+ 
+ # Corrupted ciphertext
++Availablein = default
+ Decrypt = RSA-2048
+ Input = 550AF55A2904E7B9762352F8FB7FA235A9CB053AACB2D5FCB8CA48453CB2EE3619746C701ABF2D4CC67003471A187900B05AA812BD25ED05C675DFC8C97A24A7BF49BD6214992CAD766D05A9A2B57B74F26A737E0237B8B76C45F1F226A836D7CFBC75BA999BDBE48DBC09227AA46C88F21DCCBA7840141AD5A5D71FD122E6BD6AC3E564780DFE623FC1CA9B995A6037BF0BBD43B205A84AC5444F34202C05CE9113087176432476576DE6FFFF9A52EA57C08BE3EC2F49676CB8E12F762AC71FA3C321E00AC988910C85FF52F93825666CE0D40FFAA0592078919D4493F46D95CCF76364C6D57760DD0B64805F9AFC76A2365A5575CA301D5103F0EA76CB9A79
+ Output = "Hello World"
+@@ -665,36 +666,42 @@ vcDtKrdWo6btTWc1Kml9QhbpMhKxJ6Y9VBHOb6mN
+ h90qjKHS9PvY4Q==
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-1
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=354fe67b4a126d5d35fe36c777791a3f7ba13def484e2d3908aff722fad468fb21696de95d0be911c2d3174f8afcc201035f7b6d8e69402de5451618c21a535fa9d7bfc5b8dd9fc243f8cf927db31322d6e881eaa91a996170e657a05a266426d98c88003f8477c1227094a0d9fa1e8c4024309ce1ecccb5210035d47ac72e8a
+ Output=6628194e12073db03ba94cda9ef9532397d50dba79b987004afefe34
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-1
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=640db1acc58e0568fe5407e5f9b701dff8c3c91e716c536fc7fcec6cb5b71c1165988d4a279e1577d730fc7a29932e3f00c81515236d8d8e31017a7a09df4352d904cdeb79aa583adcc31ea698a4c05283daba9089be5491f67c1a4ee48dc74bbbe6643aef846679b4cb395a352d5ed115912df696ffe0702932946d71492b44
+ Output=750c4047f547e8e41411856523298ac9bae245efaf1397fbe56f9dd5
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-1
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=423736ed035f6026af276c35c0b3741b365e5f76ca091b4e8c29e2f0befee603595aa8322d602d2e625e95eb81b2f1c9724e822eca76db8618cf09c5343503a4360835b5903bc637e3879fb05e0ef32685d5aec5067cd7cc96fe4b2670b6eac3066b1fcf5686b68589aafb7d629b02d8f8625ca3833624d4800fb081b1cf94eb
+ Output=d94ae0832e6445ce42331cb06d531a82b1db4baad30f746dc916df24d4e3c2451fff59a6423eb0e1d02d4fe646cf699dfd818c6e97b051
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-1
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=45ead4ca551e662c9800f1aca8283b0525e6abae30be4b4aba762fa40fd3d38e22abefc69794f6ebbbc05ddbb11216247d2f412fd0fba87c6e3acd888813646fd0e48e785204f9c3f73d6d8239562722dddd8771fec48b83a31ee6f592c4cfd4bc88174f3b13a112aae3b9f7b80e0fc6f7255ba880dc7d8021e22ad6a85f0755
+ Output=52e650d98e7f2a048b4f86852153b97e01dd316f346a19f67a85
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-1
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=36f6e34d94a8d34daacba33a2139d00ad85a9345a86051e73071620056b920e219005855a213a0f23897cdcd731b45257c777fe908202befdd0b58386b1244ea0cf539a05d5d10329da44e13030fd760dcd644cfef2094d1910d3f433e1c7c6dd18bc1f2df7f643d662fb9dd37ead9059190f4fa66ca39e869c4eb449cbdc439
+ Output=8da89fd9e5f974a29feffb462b49180f6cf9e802
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-1
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+@@ -719,36 +726,42 @@ SwGNdhGLJDiac1Dsg2sAY6IXISNv2O222JtR5+64
+ eG2e4XlBcKjI6A==
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-2
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0181af8922b9fcb4d79d92ebe19815992fc0c1439d8bcd491398a0f4ad3a329a5bd9385560db532683c8b7da04e4b12aed6aacdf471c34c9cda891addcc2df3456653aa6382e9ae59b54455257eb099d562bbe10453f2b6d13c59c02e10f1f8abb5da0d0570932dacf2d0901db729d0fefcc054e70968ea540c81b04bcaefe720e
+ Output=8ff00caa605c702830634d9a6c3d42c652b58cf1d92fec570beee7
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-2
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=018759ff1df63b2792410562314416a8aeaf2ac634b46f940ab82d64dbf165eee33011da749d4bab6e2fcd18129c9e49277d8453112b429a222a8471b070993998e758861c4d3f6d749d91c4290d332c7a4ab3f7ea35ff3a07d497c955ff0ffc95006b62c6d296810d9bfab024196c7934012c2df978ef299aba239940cba10245
+ Output=2d
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-2
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=018802bab04c60325e81c4962311f2be7c2adce93041a00719c88f957575f2c79f1b7bc8ced115c706b311c08a2d986ca3b6a9336b147c29c6f229409ddec651bd1fdd5a0b7f610c9937fdb4a3a762364b8b3206b4ea485fd098d08f63d4aa8bb2697d027b750c32d7f74eaf5180d2e9b66b17cb2fa55523bc280da10d14be2053
+ Output=74fc88c51bc90f77af9d5e9a4a70133d4b4e0b34da3c37c7ef8e
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-2
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=00a4578cbc176318a638fba7d01df15746af44d4f6cd96d7e7c495cbf425b09c649d32bf886da48fbaf989a2117187cafb1fb580317690e3ccd446920b7af82b31db5804d87d01514acbfa9156e782f867f6bed9449e0e9a2c09bcecc6aa087636965e34b3ec766f2fe2e43018a2fddeb140616a0e9d82e5331024ee0652fc7641
+ Output=a7eb2a5036931d27d4e891326d99692ffadda9bf7efd3e34e622c4adc085f721dfe885072c78a203b151739be540fa8c153a10f00a
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-2
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=00ebc5f5fda77cfdad3c83641a9025e77d72d8a6fb33a810f5950f8d74c73e8d931e8634d86ab1246256ae07b6005b71b7f2fb98351218331ce69b8ffbdc9da08bbc9c704f876deb9df9fc2ec065cad87f9090b07acc17aa7f997b27aca48806e897f771d95141fe4526d8a5301b678627efab707fd40fbebd6e792a25613e7aec
+ Output=2ef2b066f854c33f3bdcbb5994a435e73d6c6c
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-2
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+@@ -773,36 +786,42 @@ iUGx07dw5a0x7jc7KKzaaf+bb0D+V4ufGvuFg2+W
+ Ya4qnqZe1onjY5o=
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-3
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=026a0485d96aebd96b4382085099b962e6a2bdec3d90c8db625e14372de85e2d5b7baab65c8faf91bb5504fb495afce5c988b3f6a52e20e1d6cbd3566c5cd1f2b8318bb542cc0ea25c4aab9932afa20760eaddec784396a07ea0ef24d4e6f4d37e5052a7a31e146aa480a111bbe926401307e00f410033842b6d82fe5ce4dfae80
+ Output=087820b569e8fa8d
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-3
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=024db89c7802989be0783847863084941bf209d761987e38f97cb5f6f1bc88da72a50b73ebaf11c879c4f95df37b850b8f65d7622e25b1b889e80fe80baca2069d6e0e1d829953fc459069de98ea9798b451e557e99abf8fe3d9ccf9096ebbf3e5255d3b4e1c6d2ecadf067a359eea86405acd47d5e165517ccafd47d6dbee4bf5
+ Output=4653acaf171960b01f52a7be63a3ab21dc368ec43b50d82ec3781e04
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-3
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0239bce681032441528877d6d1c8bb28aa3bc97f1df584563618995797683844ca86664732f4bed7a0aab083aaabfb7238f582e30958c2024e44e57043b97950fd543da977c90cdde5337d618442f99e60d7783ab59ce6dd9d69c47ad1e962bec22d05895cff8d3f64ed5261d92b2678510393484990ba3f7f06818ae6ffce8a3a
+ Output=d94cd0e08fa404ed89
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-3
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=02994c62afd76f498ba1fd2cf642857fca81f4373cb08f1cbaee6f025c3b512b42c3e8779113476648039dbe0493f9246292fac28950600e7c0f32edf9c81b9dec45c3bde0cc8d8847590169907b7dc5991ceb29bb0714d613d96df0f12ec5d8d3507c8ee7ae78dd83f216fa61de100363aca48a7e914ae9f42ddfbe943b09d9a0
+ Output=6cc641b6b61e6f963974dad23a9013284ef1
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-3
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0162042ff6969592a6167031811a239834ce638abf54fec8b99478122afe2ee67f8c5b18b0339805bfdbc5a4e6720b37c59cfba942464c597ff532a119821545fd2e59b114e61daf71820529f5029cf524954327c34ec5e6f5ba7efcc4de943ab8ad4ed787b1454329f70db798a3a8f4d92f8274e2b2948ade627ce8ee33e43c60
+ Output=df5151832b61f4f25891fb4172f328d2eddf8371ffcfdbe997939295f30eca6918017cfda1153bf7a6af87593223
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-3
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+@@ -827,36 +846,42 @@ s/XkIiO6MDAcQabYfLtw4wy308Z9JUc9sfbL8D4/
+ aD0x7TDrmEvkEro=
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-4
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=04cce19614845e094152a3fe18e54e3330c44e5efbc64ae16886cb1869014cc5781b1f8f9e045384d0112a135ca0d12e9c88a8e4063416deaae3844f60d6e96fe155145f4525b9a34431ca3766180f70e15a5e5d8e8b1a516ff870609f13f896935ced188279a58ed13d07114277d75c6568607e0ab092fd803a223e4a8ee0b1a8
+ Output=4a86609534ee434a6cbca3f7e962e76d455e3264c19f605f6e5ff6137c65c56d7fb344cd52bc93374f3d166c9f0c6f9c506bad19330972d2
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-4
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0097b698c6165645b303486fbf5a2a4479c0ee85889b541a6f0b858d6b6597b13b854eb4f839af03399a80d79bda6578c841f90d645715b280d37143992dd186c80b949b775cae97370e4ec97443136c6da484e970ffdb1323a20847821d3b18381de13bb49aaea66530c4a4b8271f3eae172cd366e07e6636f1019d2a28aed15e
+ Output=b0adc4f3fe11da59ce992773d9059943c03046497ee9d9f9a06df1166db46d98f58d27ec074c02eee6cbe2449c8b9fc5080c5c3f4433092512ec46aa793743c8
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-4
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0301f935e9c47abcb48acbbe09895d9f5971af14839da4ff95417ee453d1fd77319072bb7297e1b55d7561cd9d1bb24c1a9a37c619864308242804879d86ebd001dce5183975e1506989b70e5a83434154d5cbfd6a24787e60eb0c658d2ac193302d1192c6e622d4a12ad4b53923bca246df31c6395e37702c6a78ae081fb9d065
+ Output=bf6d42e701707b1d0206b0c8b45a1c72641ff12889219a82bdea965b5e79a96b0d0163ed9d578ec9ada20f2fbcf1ea3c4089d83419ba81b0c60f3606da99
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-4
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=02d110ad30afb727beb691dd0cf17d0af1a1e7fa0cc040ec1a4ba26a42c59d0a796a2e22c8f357ccc98b6519aceb682e945e62cb734614a529407cd452bee3e44fece8423cc19e55548b8b994b849c7ecde4933e76037e1d0ce44275b08710c68e430130b929730ed77e09b015642c5593f04e4ffb9410798102a8e96ffdfe11e4
+ Output=fb2ef112f5e766eb94019297934794f7be2f6fc1c58e
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-4
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=00dbb8a7439d90efd919a377c54fae8fe11ec58c3b858362e23ad1b8a44310799066b99347aa525691d2adc58d9b06e34f288c170390c5f0e11c0aa3645959f18ee79e8f2be8d7ac5c23d061f18dd74b8c5f2a58fcb5eb0c54f99f01a83247568292536583340948d7a8c97c4acd1e98d1e29dc320e97a260532a8aa7a758a1ec2
+ Output=28ccd447bb9e85166dabb9e5b7d1adadc4b9d39f204e96d5e440ce9ad928bc1c2284
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-4
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+@@ -881,36 +906,42 @@ OPlAQGLrhaQpJFILOPW7iGoBlvSLuNzqYP2SzAJ/
+ MSwGUGLx60i3nRyDyw==
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-5
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=036046a4a47d9ed3ba9a89139c105038eb7492b05a5d68bfd53accff4597f7a68651b47b4a4627d927e485eed7b4566420e8b409879e5d606eae251d22a5df799f7920bfc117b992572a53b1263146bcea03385cc5e853c9a101c8c3e1bda31a519807496c6cb5e5efb408823a352b8fa0661fb664efadd593deb99fff5ed000e5
+ Output=af71a901e3a61d3132f0fc1fdb474f9ea6579257ffc24d164170145b3dbde8
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-5
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=03d6eb654edce615bc59f455265ed4e5a18223cbb9be4e4069b473804d5de96f54dcaaa603d049c5d94aa1470dfcd2254066b7c7b61ff1f6f6770e3215c51399fd4e34ec5082bc48f089840ad04354ae66dc0f1bd18e461a33cc1258b443a2837a6df26759aa2302334986f87380c9cc9d53be9f99605d2c9a97da7b0915a4a7ad
+ Output=a3b844a08239a8ac41605af17a6cfda4d350136585903a417a79268760519a4b4ac3303ec73f0f87cfb32399
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-5
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0770952181649f9f9f07ff626ff3a22c35c462443d905d456a9fd0bff43cac2ca7a9f554e9478b9acc3ac838b02040ffd3e1847de2e4253929f9dd9ee4044325a9b05cabb808b2ee840d34e15d105a3f1f7b27695a1a07a2d73fe08ecaaa3c9c9d4d5a89ff890d54727d7ae40c0ec1a8dd86165d8ee2c6368141016a48b55b6967
+ Output=308b0ecbd2c76cb77fc6f70c5edd233fd2f20929d629f026953bb62a8f4a3a314bde195de85b5f816da2aab074d26cb6acddf323ae3b9c678ac3cf12fbdde7
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-5
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0812b76768ebcb642d040258e5f4441a018521bd96687e6c5e899fcd6c17588ff59a82cc8ae03a4b45b31299af1788c329f7dcd285f8cf4ced82606b97612671a45bedca133442144d1617d114f802857f0f9d739751c57a3f9ee400912c61e2e6992be031a43dd48fa6ba14eef7c422b5edc4e7afa04fdd38f402d1c8bb719abf
+ Output=15c5b9ee1185
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-5
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=07b60e14ec954bfd29e60d0047e789f51d57186c63589903306793ced3f68241c743529aba6a6374f92e19e0163efa33697e196f7661dfaaa47aac6bde5e51deb507c72c589a2ca1693d96b1460381249b2cdb9eac44769f2489c5d3d2f99f0ee3c7ee5bf64a5ac79c42bd433f149be8cb59548361640595513c97af7bc2509723
+ Output=21026e6800c7fa728fcaaba0d196ae28d7a2ac4ffd8abce794f0985f60c8a6737277365d3fea11db8923a2029a
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-5
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+@@ -935,36 +966,42 @@ xT1F29tenZbQ/s9Cdd8JdLxKBza0p0wyaQU++2hq
+ Yejn5Ly8mU2q+jBcRQ==
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-6
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0630eebcd2856c24f798806e41f9e67345eda9ceda386acc9facaea1eeed06ace583709718d9d169fadf414d5c76f92996833ef305b75b1e4b95f662a20faedc3bae0c4827a8bf8a88edbd57ec203a27a841f02e43a615bab1a8cac0701de34debdef62a088089b55ec36ea7522fd3ec8d06b6a073e6df833153bc0aefd93bd1a3
+ Output=4046ca8baa3347ca27f49e0d81f9cc1d71be9ba517d4
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-6
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0ebc37376173a4fd2f89cc55c2ca62b26b11d51c3c7ce49e8845f74e7607317c436bc8d23b9667dfeb9d087234b47bc6837175ae5c0559f6b81d7d22416d3e50f4ac533d8f0812f2db9e791fe9c775ac8b6ad0f535ad9ceb23a4a02014c58ab3f8d3161499a260f39348e714ae2a1d3443208fd8b722ccfdfb393e98011f99e63f
+ Output=5cc72c60231df03b3d40f9b57931bc31109f972527f28b19e7480c7288cb3c92b22512214e4be6c914792ddabdf57faa8aa7
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-6
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0a98bf1093619394436cf68d8f38e2f158fde8ea54f3435f239b8d06b8321844202476aeed96009492480ce3a8d705498c4c8c68f01501dc81db608f60087350c8c3b0bd2e9ef6a81458b7c801b89f2e4fe99d4900ba6a4b5e5a96d865dc676c7755928794130d6280a8160a190f2df3ea7cf9aa0271d88e9e6905ecf1c5152d65
+ Output=b20e651303092f4bccb43070c0f86d23049362ed96642fc5632c27db4a52e3d831f2ab068b23b149879c002f6bf3feee97591112562c
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-6
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=008e7a67cacfb5c4e24bec7dee149117f19598ce8c45808fef88c608ff9cd6e695263b9a3c0ad4b8ba4c95238e96a8422b8535629c8d5382374479ad13fa39974b242f9a759eeaf9c83ad5a8ca18940a0162ba755876df263f4bd50c6525c56090267c1f0e09ce0899a0cf359e88120abd9bf893445b3cae77d3607359ae9a52f8
+ Output=684e3038c5c041f7
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-6
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=00003474416c7b68bdf961c385737944d7f1f40cb395343c693cc0b4fe63b31fedf1eaeeac9ccc0678b31dc32e0977489514c4f09085f6298a9653f01aea4045ff582ee887be26ae575b73eef7f3774921e375a3d19adda0ca31aa1849887c1f42cac9677f7a2f4e923f6e5a868b38c084ef187594dc9f7f048fea2e02955384ab
+ Output=32488cb262d041d6e4dd35f987bf3ca696db1f06ac29a44693
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-6
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+@@ -989,36 +1026,42 @@ tu4XIedy0DiaVZw9PN+VUNRXxGsDe3RkGx1SFmr4
+ FMlxv0gq65dqc3DC
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-7
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=1688e4ce7794bba6cb7014169ecd559cede2a30b56a52b68d9fe18cf1973ef97b2a03153951c755f6294aa49adbdb55845ab6875fb3986c93ecf927962840d282f9e54ce8b690f7c0cb8bbd73440d9571d1b16cd9260f9eab4783cc482e5223dc60973871783ec27b0ae0fd47732cbc286a173fc92b00fb4ba6824647cd93c85c1
+ Output=47aae909
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-7
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=1052ed397b2e01e1d0ee1c50bf24363f95e504f4a03434a08fd822574ed6b9736edbb5f390db10321479a8a139350e2bd4977c3778ef331f3e78ae118b268451f20a2f01d471f5d53c566937171b2dbc2d4bde459a5799f0372d6574239b2323d245d0bb81c286b63c89a361017337e4902f88a467f4c7f244bfd5ab46437ff3b6
+ Output=1d9b2e2223d9bc13bfb9f162ce735db48ba7c68f6822a0a1a7b6ae165834e7
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-7
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=2155cd843ff24a4ee8badb7694260028a490813ba8b369a4cbf106ec148e5298707f5965be7d101c1049ea8584c24cd63455ad9c104d686282d3fb803a4c11c1c2e9b91c7178801d1b6640f003f5728df007b8a4ccc92bce05e41a27278d7c85018c52414313a5077789001d4f01910b72aad05d220aa14a58733a7489bc54556b
+ Output=d976fc
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-7
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0ab14c373aeb7d4328d0aaad8c094d88b9eb098b95f21054a29082522be7c27a312878b637917e3d819e6c3c568db5d843802b06d51d9e98a2be0bf40c031423b00edfbff8320efb9171bd2044653a4cb9c5122f6c65e83cda2ec3c126027a9c1a56ba874d0fea23f380b82cf240b8cf540004758c4c77d934157a74f3fc12bfac
+ Output=d4738623df223aa43843df8467534c41d013e0c803c624e263666b239bde40a5f29aeb8de79e3daa61dd0370f49bd4b013834b98212aef6b1c5ee373b3cb
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-7
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=028387a318277434798b4d97f460068df5298faba5041ba11761a1cb7316b24184114ec500257e2589ed3b607a1ebbe97a6cc2e02bf1b681f42312a33b7a77d8e7855c4a6de03e3c04643f786b91a264a0d6805e2cea91e68177eb7a64d9255e4f27e713b7ccec00dc200ebd21c2ea2bb890feae4942df941dc3f97890ed347478
+ Output=bb47231ca5ea1d3ad46c99345d9a8a61
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-7
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+@@ -1043,36 +1086,42 @@ njraT2MgdSwJ2AX/fR8a4NAXru7pzvoNfdf/d15E
+ 2MiPa249Z+lh3Luj0A==
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-8
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=09b3683d8a2eb0fb295b62ed1fb9290b714457b7825319f4647872af889b30409472020ad12912bf19b11d4819f49614824ffd84d09c0a17e7d17309d12919790410aa2995699f6a86dbe3242b5acc23af45691080d6b1ae810fb3e3057087f0970092ce00be9562ff4053b6262ce0caa93e13723d2e3a5ba075d45f0d61b54b61
+ Output=050b755e5e6880f7b9e9d692a74c37aae449b31bfea6deff83747a897f6c2c825bb1adbf850a3c96994b5de5b33cbc7d4a17913a7967
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-8
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=2ecf15c97c5a15b1476ae986b371b57a24284f4a162a8d0c8182e7905e792256f1812ba5f83f1f7a130e42dcc02232844edc14a31a68ee97ae564a383a3411656424c5f62ddb646093c367be1fcda426cf00a06d8acb7e57776fbbd855ac3df506fc16b1d7c3f2110f3d8068e91e186363831c8409680d8da9ecd8cf1fa20ee39d
+ Output=4eb68dcd93ca9b19df111bd43608f557026fe4aa1d5cfac227a3eb5ab9548c18a06dded23f81825986b2fcd71109ecef7eff88873f075c2aa0c469f69c92bc
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-8
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=4bc89130a5b2dabb7c2fcf90eb5d0eaf9e681b7146a38f3173a3d9cfec52ea9e0a41932e648a9d69344c50da763f51a03c95762131e8052254dcd2248cba40fd31667786ce05a2b7b531ac9dac9ed584a59b677c1a8aed8c5d15d68c05569e2be780bf7db638fd2bfd2a85ab276860f3777338fca989ffd743d13ee08e0ca9893f
+ Output=8604ac56328c1ab5ad917861
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-8
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=2e456847d8fc36ff0147d6993594b9397227d577752c79d0f904fcb039d4d812fea605a7b574dd82ca786f93752348438ee9f5b5454985d5f0e1699e3e7ad175a32e15f03deb042ab9fe1dd9db1bb86f8c089ccb45e7ef0c5ee7ca9b7290ca6b15bed47039788a8a93ff83e0e8d6244c71006362deef69b6f416fb3c684383fbd0
+ Output=fdda5fbf6ec361a9d9a4ac68af216a0686f438b1e0e5c36b955f74e107f39c0dddcc
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-8
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=1fb9356fd5c4b1796db2ebf7d0d393cc810adf6145defc2fce714f79d93800d5e2ac211ea8bbecca4b654b94c3b18b30dd576ce34dc95436ef57a09415645923359a5d7b4171ef22c24670f1b229d3603e91f76671b7df97e7317c97734476d5f3d17d21cf82b5ba9f83df2e588d36984fd1b584468bd23b2e875f32f68953f7b2
+ Output=4a5f4914bee25de3c69341de07
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-8
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+@@ -1103,36 +1152,42 @@ Z7CDuaemy2HkLbNiuMmJbbcGTgKtWuYVh9oVtGSc
+ tKo5Eb69iFQvBb4=
+ -----END PRIVATE KEY-----
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-9
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=267bcd118acab1fc8ba81c85d73003cb8610fa55c1d97da8d48a7c7f06896a4db751aa284255b9d36ad65f37653d829f1b37f97b8001942545b2fc2c55a7376ca7a1be4b1760c8e05a33e5aa2526b8d98e317088e7834c755b2a59b12631a182c05d5d43ab1779264f8456f515ce57dfdf512d5493dab7b7338dc4b7d78db9c091ac3baf537a69fc7f549d979f0eff9a94fda4169bd4d1d19a69c99e33c3b55490d501b39b1edae118ff6793a153261584d3a5f39f6e682e3d17c8cd1261fa72
+ Output=f735fd55ba92592c3b52b8f9c4f69aaa1cbef8fe88add095595412467f9cf4ec0b896c59eda16210e7549c8abb10cdbc21a12ec9b6b5b8fd2f10399eb6
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-9
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=93ac9f0671ec29acbb444effc1a5741351d60fdb0e393fbf754acf0de49761a14841df7772e9bc82773966a1584c4d72baea00118f83f35cca6e537cbd4d811f5583b29783d8a6d94cd31be70d6f526c10ff09c6fa7ce069795a3fcd0511fd5fcb564bcc80ea9c78f38b80012539d8a4ddf6fe81e9cddb7f50dbbbbcc7e5d86097ccf4ec49189fb8bf318be6d5a0715d516b49af191258cd32dc833ce6eb4673c03a19bbace88cc54895f636cc0c1ec89096d11ce235a265ca1764232a689ae8
+ Output=81b906605015a63aabe42ddf11e1978912f5404c7474b26dce3ed482bf961ecc818bf420c54659
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-9
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=81ebdd95054b0c822ef9ad7693f5a87adfb4b4c4ce70df2df84ed49c04da58ba5fc20a19e1a6e8b7a3900b22796dc4e869ee6b42792d15a8eceb56c09c69914e813cea8f6931e4b8ed6f421af298d595c97f4789c7caa612c7ef360984c21b93edc5401068b5af4c78a8771b984d53b8ea8adf2f6a7d4a0ba76c75e1dd9f658f20ded4a46071d46d7791b56803d8fea7f0b0f8e41ae3f09383a6f9585fe7753eaaffd2bf94563108beecc207bbb535f5fcc705f0dde9f708c62f49a9c90371d3
+ Output=fd326429df9b890e09b54b18b8f34f1e24
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-9
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=bcc35f94cde66cb1136625d625b94432a35b22f3d2fa11a613ff0fca5bd57f87b902ccdc1cd0aebcb0715ee869d1d1fe395f6793003f5eca465059c88660d446ff5f0818552022557e38c08a67ead991262254f10682975ec56397768537f4977af6d5f6aaceb7fb25dec5937230231fd8978af49119a29f29e424ab8272b47562792d5c94f774b8829d0b0d9f1a8c9eddf37574d5fa248eefa9c5271fc5ec2579c81bdd61b410fa61fe36e424221c113addb275664c801d34ca8c6351e4a858
+ Output=f1459b5f0c92f01a0f723a2e5662484d8f8c0a20fc29dad6acd43bb5f3effdf4e1b63e07fdfe6628d0d74ca19bf2d69e4a0abf86d293925a796772f8088e
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-9
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
+ Input=232afbc927fa08c2f6a27b87d4a5cb09c07dc26fae73d73a90558839f4fd66d281b87ec734bce237ba166698ed829106a7de6942cd6cdce78fed8d2e4d81428e66490d036264cef92af941d3e35055fe3981e14d29cbb9a4f67473063baec79a1179f5a17c9c1832f2838fd7d5e59bb9659d56dce8a019edef1bb3accc697cc6cc7a778f60a064c7f6f5d529c6210262e003de583e81e3167b89971fb8c0e15d44fffef89b53d8d64dd797d159b56d2b08ea5307ea12c241bd58d4ee278a1f2e
+ Output=53e6e8c729d6f9c319dd317e74b0db8e4ccca25f3c8305746e137ac63a63ef3739e7b595abb96e8d55e54f7bd41ab433378ffb911d
+ 
++Availablein = default
+ Decrypt=RSA-OAEP-9
+ Ctrl = rsa_padding_mode:oaep
+ Ctrl = rsa_mgf1_md:sha1
diff --git a/SOURCES/0060-FIPS-KAT-signature-tests.patch b/SOURCES/0060-FIPS-KAT-signature-tests.patch
new file mode 100644
index 0000000..184b150
--- /dev/null
+++ b/SOURCES/0060-FIPS-KAT-signature-tests.patch
@@ -0,0 +1,420 @@
+diff -up openssl-3.0.1/crypto/ec/ec_backend.c.fips_kat_signature openssl-3.0.1/crypto/ec/ec_backend.c
+--- openssl-3.0.1/crypto/ec/ec_backend.c.fips_kat_signature	2022-04-04 15:49:24.786455707 +0200
++++ openssl-3.0.1/crypto/ec/ec_backend.c	2022-04-04 16:06:13.250271963 +0200
+@@ -393,6 +393,10 @@ int ossl_ec_key_fromdata(EC_KEY *ec, con
+     const OSSL_PARAM *param_priv_key = NULL, *param_pub_key = NULL;
+     BN_CTX *ctx = NULL;
+     BIGNUM *priv_key = NULL;
++#ifdef FIPS_MODULE
++    const OSSL_PARAM *param_sign_kat_k = NULL;
++    BIGNUM *sign_kat_k = NULL;
++#endif
+     unsigned char *pub_key = NULL;
+     size_t pub_key_len;
+     const EC_GROUP *ecg = NULL;
+@@ -408,7 +412,10 @@ int ossl_ec_key_fromdata(EC_KEY *ec, con
+     if (include_private)
+         param_priv_key =
+             OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
+-
++#ifdef FIPS_MODULE
++    param_sign_kat_k =
++        OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_REDHAT_SIGN_KAT_K);
++#endif
+     ctx = BN_CTX_new_ex(ossl_ec_key_get_libctx(ec));
+     if (ctx == NULL)
+         goto err;
+@@ -481,6 +489,17 @@ int ossl_ec_key_fromdata(EC_KEY *ec, con
+         && !EC_KEY_set_public_key(ec, pub_point))
+         goto err;
+ 
++#ifdef FIPS_MODULE
++    if (param_sign_kat_k) {
++        if ((sign_kat_k = BN_secure_new()) == NULL)
++            goto err;
++        BN_set_flags(sign_kat_k, BN_FLG_CONSTTIME);
++
++        if (!OSSL_PARAM_get_BN(param_sign_kat_k, &sign_kat_k))
++            goto err;
++        ec->sign_kat_k = sign_kat_k;
++    }
++#endif
+     ok = 1;
+ 
+  err:
+diff -up openssl-3.0.1/crypto/ec/ecdsa_ossl.c.fips_kat_signature openssl-3.0.1/crypto/ec/ecdsa_ossl.c
+--- openssl-3.0.1/crypto/ec/ecdsa_ossl.c.fips_kat_signature	2022-04-04 17:01:35.725323127 +0200
++++ openssl-3.0.1/crypto/ec/ecdsa_ossl.c	2022-04-04 17:03:42.000427050 +0200
+@@ -20,6 +20,10 @@
+ #include "crypto/bn.h"
+ #include "ec_local.h"
+ 
++#ifdef FIPS_MODULE
++extern int REDHAT_FIPS_signature_st;
++#endif
++
+ int ossl_ecdsa_sign_setup(EC_KEY *eckey, BN_CTX *ctx_in, BIGNUM **kinvp,
+                           BIGNUM **rp)
+ {
+@@ -126,6 +130,11 @@ static int ecdsa_sign_setup(EC_KEY *ecke
+         goto err;
+ 
+     do {
++#ifdef FIPS_MODULE
++       if (REDHAT_FIPS_signature_st && eckey->sign_kat_k != NULL) {
++           BN_copy(k, eckey->sign_kat_k);
++       } else {
++#endif
+         /* get random k */
+         do {
+             if (dgst != NULL) {
+@@ -141,7 +150,9 @@ static int ecdsa_sign_setup(EC_KEY *ecke
+                 }
+             }
+         } while (BN_is_zero(k));
+-
++#ifdef FIPS_MODULE
++        }
++#endif
+         /* compute r the x-coordinate of generator * k */
+         if (!EC_POINT_mul(group, tmp_point, k, NULL, NULL, ctx)) {
+             ERR_raise(ERR_LIB_EC, ERR_R_EC_LIB);
+diff -up openssl-3.0.1/crypto/ec/ec_key.c.fips_kat_signature openssl-3.0.1/crypto/ec/ec_key.c
+--- openssl-3.0.1/crypto/ec/ec_key.c.fips_kat_signature	2022-04-04 13:48:52.231172299 +0200
++++ openssl-3.0.1/crypto/ec/ec_key.c	2022-04-04 14:00:35.077368605 +0200
+@@ -97,6 +97,9 @@ void EC_KEY_free(EC_KEY *r)
+     EC_GROUP_free(r->group);
+     EC_POINT_free(r->pub_key);
+     BN_clear_free(r->priv_key);
++#ifdef FIPS_MODULE
++    BN_clear_free(r->sign_kat_k);
++#endif
+     OPENSSL_free(r->propq);
+ 
+     OPENSSL_clear_free((void *)r, sizeof(EC_KEY));
+diff -up openssl-3.0.1/crypto/ec/ec_local.h.fips_kat_signature openssl-3.0.1/crypto/ec/ec_local.h
+--- openssl-3.0.1/crypto/ec/ec_local.h.fips_kat_signature	2022-04-04 13:46:57.576161867 +0200
++++ openssl-3.0.1/crypto/ec/ec_local.h	2022-04-04 13:48:07.827780835 +0200
+@@ -298,6 +298,9 @@ struct ec_key_st {
+ #ifndef FIPS_MODULE
+     CRYPTO_EX_DATA ex_data;
+ #endif
++#ifdef FIPS_MODULE
++    BIGNUM *sign_kat_k;
++#endif
+     CRYPTO_RWLOCK *lock;
+     OSSL_LIB_CTX *libctx;
+     char *propq;
+diff -up openssl-3.0.1/include/openssl/core_names.h.fips_kat_signature openssl-3.0.1/include/openssl/core_names.h
+--- openssl-3.0.1/include/openssl/core_names.h.fips_kat_signature	2022-04-04 14:06:15.717370014 +0200
++++ openssl-3.0.1/include/openssl/core_names.h	2022-04-04 14:07:35.376071229 +0200
+@@ -293,6 +293,7 @@ extern "C" {
+ #define OSSL_PKEY_PARAM_DIST_ID             "distid"
+ #define OSSL_PKEY_PARAM_PUB_KEY             "pub"
+ #define OSSL_PKEY_PARAM_PRIV_KEY            "priv"
++#define OSSL_PKEY_PARAM_REDHAT_SIGN_KAT_K   "rh_sign_kat_k"
+ 
+ /* Diffie-Hellman/DSA Parameters */
+ #define OSSL_PKEY_PARAM_FFC_P               "p"
+diff -up openssl-3.0.1/providers/implementations/keymgmt/ec_kmgmt.c.fips_kat_signature openssl-3.0.1/providers/implementations/keymgmt/ec_kmgmt.c
+--- openssl-3.0.1/providers/implementations/keymgmt/ec_kmgmt.c.fips_kat_signature	2022-04-04 14:21:03.043180906 +0200
++++ openssl-3.0.1/providers/implementations/keymgmt/ec_kmgmt.c	2022-04-04 14:38:33.949406645 +0200
+@@ -530,7 +530,8 @@ end:
+ # define EC_IMEXPORTABLE_PUBLIC_KEY                                            \
+     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PUB_KEY, NULL, 0)
+ # define EC_IMEXPORTABLE_PRIVATE_KEY                                           \
+-    OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0)
++    OSSL_PARAM_BN(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),                          \
++    OSSL_PARAM_BN(OSSL_PKEY_PARAM_REDHAT_SIGN_KAT_K, NULL, 0)
+ # define EC_IMEXPORTABLE_OTHER_PARAMETERS                                      \
+     OSSL_PARAM_int(OSSL_PKEY_PARAM_USE_COFACTOR_ECDH, NULL),                   \
+     OSSL_PARAM_int(OSSL_PKEY_PARAM_EC_INCLUDE_PUBLIC, NULL)
+diff -up openssl-3.0.1/providers/fips/self_test_kats.c.kat openssl-3.0.1/providers/fips/self_test_kats.c
+--- openssl-3.0.1/providers/fips/self_test_kats.c.kat	2022-05-10 15:10:32.502185265 +0200
++++ openssl-3.0.1/providers/fips/self_test_kats.c	2022-05-10 15:13:21.465653720 +0200
+@@ -17,6 +17,8 @@
+ #include "self_test.h"
+ #include "self_test_data.inc"
+ 
++int REDHAT_FIPS_signature_st = 0;
++
+ static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st,
+                             OSSL_LIB_CTX *libctx)
+ {
+@@ -446,6 +448,7 @@ static int self_test_sign(const ST_KAT_S
+     EVP_PKEY *pkey = NULL;
+     unsigned char sig[256];
+     BN_CTX *bnctx = NULL;
++    BIGNUM *K = NULL;
+     size_t siglen = sizeof(sig);
+     static const unsigned char dgst[] = {
+         0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
+@@ -462,6 +465,9 @@ static int self_test_sign(const ST_KAT_S
+     bnctx = BN_CTX_new_ex(libctx);
+     if (bnctx == NULL)
+         goto err;
++    K = BN_CTX_get(bnctx);
++    if (K == NULL || BN_bin2bn(dgst, sizeof(dgst), K) == NULL)
++        goto err;
+ 
+     bld = OSSL_PARAM_BLD_new();
+     if (bld == NULL)
+@@ -469,6 +475,9 @@ static int self_test_sign(const ST_KAT_S
+ 
+     if (!add_params(bld, t->key, bnctx))
+         goto err;
++    /* set K for ECDSA KAT tests */
++    if (!OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_REDHAT_SIGN_KAT_K, K))
++        goto err;
+     params = OSSL_PARAM_BLD_to_param(bld);
+ 
+     /* Create a EVP_PKEY_CTX to load the DSA key into */
+@@ -689,11 +698,13 @@ static int self_test_kas(OSSL_SELF_TEST
+ static int self_test_signatures(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
+ {
+     int i, ret = 1;
++    REDHAT_FIPS_signature_st = 1;
+ 
+     for (i = 0; i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) {
+         if (!self_test_sign(&st_kat_sign_tests[i], st, libctx))
+             ret = 0;
+     }
++    REDHAT_FIPS_signature_st = 0;
+     return ret;
+ }
+ 
+diff -up openssl-3.0.1/providers/fips/self_test_data.inc.kat openssl-3.0.1/providers/fips/self_test_data.inc
+--- openssl-3.0.1/providers/fips/self_test_data.inc.kat	2022-05-16 17:37:34.962807400 +0200
++++ openssl-3.0.1/providers/fips/self_test_data.inc	2022-05-16 17:48:10.709376779 +0200
+@@ -1399,7 +1399,151 @@ static const ST_KAT_PARAM ecdsa_prime_ke
+     ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, ecd_prime_priv),
+     ST_KAT_PARAM_END()
+ };
++static const unsigned char ec224r1_kat_sig[] = {
++0x30, 0x3c, 0x02, 0x1c, 0x2f, 0x24, 0x30, 0x96, 0x3b, 0x39, 0xe0, 0xab, 0xe2, 0x5a, 0x6f, 0xe0,
++0x40, 0x7e, 0x19, 0x30, 0x6e, 0x6a, 0xfd, 0x7a, 0x2b, 0x5d, 0xaa, 0xc2, 0x34, 0x6c, 0xc8, 0xce,
++0x02, 0x1c, 0x47, 0xe1, 0xac, 0xfd, 0xb4, 0xb8, 0x2b, 0x8c, 0x49, 0xb6, 0x36, 0xcd, 0xdd, 0x22,
++0x2a, 0x2d, 0x29, 0x64, 0x70, 0x61, 0xc3, 0x3e, 0x18, 0x51, 0xec, 0xf2, 0xad, 0x3c
++};
+ 
++static const char ecd_prime_curve_name384[] = "secp384r1";
++/*
++priv:
++    58:12:2b:94:be:29:23:13:83:f5:c4:20:e8:22:34:
++    54:73:49:91:10:05:e9:10:e9:d7:2d:72:9c:5e:6a:
++    ba:8f:6d:d6:e4:a7:eb:e0:ae:e3:d4:c9:aa:33:87:
++    4c:91:87
++pub:
++    04:d1:86:8b:f5:c4:a2:f7:a5:92:e6:85:2a:d2:92:
++    81:97:0a:8d:fa:09:3f:84:6c:17:43:03:43:49:23:
++    77:c4:31:f4:0a:a4:de:87:ac:5c:c0:d1:bc:e4:43:
++    7f:8d:44:e1:3b:5f:bc:27:c8:79:0f:d0:31:9f:a7:
++    6d:de:fb:f7:da:19:40:fd:aa:83:dc:69:ce:a6:f3:
++    4d:65:20:1c:66:82:80:03:f7:7b:2e:f3:b3:7c:1f:
++    11:f2:a3:bf:e8:0e:88
++*/
++static const unsigned char ecd_prime_priv384[] = {
++    0x58, 0x12, 0x2b, 0x94, 0xbe, 0x29, 0x23, 0x13, 0x83, 0xf5, 0xc4, 0x20, 0xe8, 0x22, 0x34,
++    0x54, 0x73, 0x49, 0x91, 0x10, 0x05, 0xe9, 0x10, 0xe9, 0xd7, 0x2d, 0x72, 0x9c, 0x5e, 0x6a,
++    0xba, 0x8f, 0x6d, 0xd6, 0xe4, 0xa7, 0xeb, 0xe0, 0xae, 0xe3, 0xd4, 0xc9, 0xaa, 0x33, 0x87,
++    0x4c, 0x91, 0x87
++};
++static const unsigned char ecd_prime_pub384[] = {
++    0x04, 0xd1, 0x86, 0x8b, 0xf5, 0xc4, 0xa2, 0xf7, 0xa5, 0x92, 0xe6, 0x85, 0x2a, 0xd2, 0x92,
++    0x81, 0x97, 0x0a, 0x8d, 0xfa, 0x09, 0x3f, 0x84, 0x6c, 0x17, 0x43, 0x03, 0x43, 0x49, 0x23,
++    0x77, 0xc4, 0x31, 0xf4, 0x0a, 0xa4, 0xde, 0x87, 0xac, 0x5c, 0xc0, 0xd1, 0xbc, 0xe4, 0x43,
++    0x7f, 0x8d, 0x44, 0xe1, 0x3b, 0x5f, 0xbc, 0x27, 0xc8, 0x79, 0x0f, 0xd0, 0x31, 0x9f, 0xa7,
++    0x6d, 0xde, 0xfb, 0xf7, 0xda, 0x19, 0x40, 0xfd, 0xaa, 0x83, 0xdc, 0x69, 0xce, 0xa6, 0xf3,
++    0x4d, 0x65, 0x20, 0x1c, 0x66, 0x82, 0x80, 0x03, 0xf7, 0x7b, 0x2e, 0xf3, 0xb3, 0x7c, 0x1f,
++    0x11, 0xf2, 0xa3, 0xbf, 0xe8, 0x0e, 0x88
++};
++static const ST_KAT_PARAM ecdsa_prime_key384[] = {
++    ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_prime_curve_name384),
++    ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecd_prime_pub384),
++    ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, ecd_prime_priv384),
++    ST_KAT_PARAM_END()
++};
++static const unsigned char ec384r1_kat_sig[] = {
++0x30, 0x65, 0x02, 0x30, 0x1a, 0xd5, 0x57, 0x1b, 0x28, 0x0f, 0xf1, 0x68, 0x66, 0x68, 0x8a, 0x98,
++0xe3, 0x9c, 0xce, 0x7f, 0xa7, 0x68, 0xdc, 0x84, 0x5a, 0x65, 0xdc, 0x2b, 0x5d, 0x7e, 0xf3, 0x9b,
++0xa0, 0x40, 0xe8, 0x7a, 0x02, 0xc7, 0x82, 0xe0, 0x0c, 0x81, 0xa5, 0xda, 0x55, 0x27, 0xbf, 0x79,
++0xee, 0x72, 0xc2, 0x14, 0x02, 0x31, 0x00, 0xd1, 0x9d, 0x67, 0xda, 0x5a, 0xd2, 0x58, 0x68, 0xe7,
++0x71, 0x08, 0xb2, 0xa4, 0xe4, 0xe8, 0x74, 0xb4, 0x0a, 0x3d, 0x76, 0x49, 0x31, 0x17, 0x6e, 0x33,
++0x16, 0xf0, 0x00, 0x1f, 0x3c, 0x1f, 0xf9, 0x7c, 0xdb, 0x93, 0x49, 0x9c, 0x7d, 0xb3, 0xd3, 0x30,
++0x98, 0x81, 0x6f, 0xb0, 0xc9, 0x30, 0x2f
++};
++static const char ecd_prime_curve_name521[] = "secp521r1";
++/*
++priv:
++    00:44:0f:96:31:a9:87:f2:5f:be:a0:bc:ef:0c:ae:
++    58:cc:5f:f8:44:9e:89:86:7e:bf:db:ce:cb:0e:20:
++    10:4a:11:ec:0b:51:1d:e4:91:ca:c6:40:fb:c6:69:
++    ad:68:33:9e:c8:f5:c4:c6:a5:93:a8:4d:a9:a9:a2:
++    af:fe:6d:cb:c2:3b
++pub:
++    04:01:5f:58:a9:40:0c:ee:9b:ed:4a:f4:7a:3c:a3:
++    89:c2:f3:7e:2c:f4:b5:53:80:ae:33:7d:36:d1:b5:
++    18:bd:ef:a9:48:00:ea:88:ee:00:5c:ca:07:08:b5:
++    67:4a:c3:2b:10:c6:07:b0:c2:45:37:b7:1d:e3:6c:
++    e1:bf:2c:44:18:4a:aa:01:af:75:40:6a:e3:f5:b2:
++    7f:d1:9d:1b:8b:29:1f:91:4d:db:93:bf:bd:8c:b7:
++    6a:8d:4b:2c:36:2a:6b:ab:54:9d:7b:31:99:a4:de:
++    c9:10:c4:f4:a3:f4:6d:94:97:62:16:a5:34:65:1f:
++    42:cd:8b:9e:e6:db:14:5d:a9:8d:19:95:8d
++*/
++static const unsigned char ecd_prime_priv521[] = {
++    0x00, 0x44, 0x0f, 0x96, 0x31, 0xa9, 0x87, 0xf2, 0x5f, 0xbe, 0xa0, 0xbc, 0xef, 0x0c, 0xae,
++    0x58, 0xcc, 0x5f, 0xf8, 0x44, 0x9e, 0x89, 0x86, 0x7e, 0xbf, 0xdb, 0xce, 0xcb, 0x0e, 0x20,
++    0x10, 0x4a, 0x11, 0xec, 0x0b, 0x51, 0x1d, 0xe4, 0x91, 0xca, 0xc6, 0x40, 0xfb, 0xc6, 0x69,
++    0xad, 0x68, 0x33, 0x9e, 0xc8, 0xf5, 0xc4, 0xc6, 0xa5, 0x93, 0xa8, 0x4d, 0xa9, 0xa9, 0xa2,
++    0xaf, 0xfe, 0x6d, 0xcb, 0xc2, 0x3b
++};
++static const unsigned char ecd_prime_pub521[] = {
++    0x04, 0x01, 0x5f, 0x58, 0xa9, 0x40, 0x0c, 0xee, 0x9b, 0xed, 0x4a, 0xf4, 0x7a, 0x3c, 0xa3,
++    0x89, 0xc2, 0xf3, 0x7e, 0x2c, 0xf4, 0xb5, 0x53, 0x80, 0xae, 0x33, 0x7d, 0x36, 0xd1, 0xb5,
++    0x18, 0xbd, 0xef, 0xa9, 0x48, 0x00, 0xea, 0x88, 0xee, 0x00, 0x5c, 0xca, 0x07, 0x08, 0xb5,
++    0x67, 0x4a, 0xc3, 0x2b, 0x10, 0xc6, 0x07, 0xb0, 0xc2, 0x45, 0x37, 0xb7, 0x1d, 0xe3, 0x6c,
++    0xe1, 0xbf, 0x2c, 0x44, 0x18, 0x4a, 0xaa, 0x01, 0xaf, 0x75, 0x40, 0x6a, 0xe3, 0xf5, 0xb2,
++    0x7f, 0xd1, 0x9d, 0x1b, 0x8b, 0x29, 0x1f, 0x91, 0x4d, 0xdb, 0x93, 0xbf, 0xbd, 0x8c, 0xb7,
++    0x6a, 0x8d, 0x4b, 0x2c, 0x36, 0x2a, 0x6b, 0xab, 0x54, 0x9d, 0x7b, 0x31, 0x99, 0xa4, 0xde,
++    0xc9, 0x10, 0xc4, 0xf4, 0xa3, 0xf4, 0x6d, 0x94, 0x97, 0x62, 0x16, 0xa5, 0x34, 0x65, 0x1f,
++    0x42, 0xcd, 0x8b, 0x9e, 0xe6, 0xdb, 0x14, 0x5d, 0xa9, 0x8d, 0x19, 0x95, 0x8d
++};
++static const ST_KAT_PARAM ecdsa_prime_key521[] = {
++    ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_prime_curve_name521),
++    ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecd_prime_pub521),
++    ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, ecd_prime_priv521),
++    ST_KAT_PARAM_END()
++};
++static const unsigned char ec521r1_kat_sig[] = {
++0x30, 0x81, 0x88, 0x02, 0x42, 0x00, 0xdf, 0x64, 0x9c, 0xc8, 0x5b, 0xdd, 0x0b, 0x7f, 0x69, 0x7e,
++0xdb, 0x83, 0x58, 0x67, 0x63, 0x43, 0xb7, 0xfa, 0x40, 0x29, 0xde, 0xb9, 0xde, 0xe9, 0x96, 0x65,
++0xe6, 0x8e, 0xf4, 0xeb, 0xd0, 0xe9, 0x6a, 0xd3, 0x27, 0x6c, 0x4d, 0x60, 0x47, 0x9c, 0x62, 0xb8,
++0x6c, 0xc1, 0x36, 0x19, 0x65, 0xff, 0xab, 0xcf, 0x24, 0xa3, 0xde, 0xd1, 0x4b, 0x1b, 0xdd, 0x89,
++0xcf, 0xf8, 0x72, 0x7b, 0x92, 0xbc, 0x02, 0x02, 0x42, 0x01, 0xf8, 0x07, 0x77, 0xb8, 0xcb, 0xa2,
++0xe2, 0x1f, 0x53, 0x9a, 0x7c, 0x16, 0xb5, 0x8e, 0xad, 0xe3, 0xc3, 0xac, 0xb7, 0xb2, 0x51, 0x8f,
++0xf9, 0x09, 0x65, 0x43, 0xf8, 0xd8, 0x3c, 0xe3, 0x5c, 0x4a, 0x5e, 0x3d, 0x6f, 0xb7, 0xbb, 0x5a,
++0x92, 0x69, 0xec, 0x71, 0xa2, 0x35, 0xe5, 0x29, 0x17, 0xaf, 0xc9, 0x69, 0xa7, 0xaa, 0x94, 0xf9,
++0xf9, 0x50, 0x87, 0x7b, 0x5d, 0x87, 0xe3, 0xd6, 0x3f, 0xb6, 0x6e
++};
++static const char ecd_prime_curve_name256[] = "prime256v1";
++/*
++priv:
++    84:88:11:3f:a9:c9:9e:23:72:8b:40:cb:a2:b1:88:
++    01:1e:92:48:af:13:2d:9b:33:8e:6d:43:40:30:c7:
++    30:fa
++pub:
++    04:22:58:b6:f9:01:3b:8c:a6:9b:9f:ae:75:fc:73:
++    cf:1b:f0:81:dc:55:a3:cc:5d:81:46:85:06:32:34:
++    99:0d:c5:7e:a1:95:bb:21:73:33:40:4b:35:17:f6:
++    8e:26:61:46:94:2c:4c:ac:9b:20:f8:08:72:25:74:
++    98:66:c4:63:a6
++*/
++static const unsigned char ecd_prime_priv256[] = {
++    0x84, 0x88, 0x11, 0x3f, 0xa9, 0xc9, 0x9e, 0x23, 0x72, 0x8b, 0x40, 0xcb, 0xa2, 0xb1, 0x88,
++    0x01, 0x1e, 0x92, 0x48, 0xaf, 0x13, 0x2d, 0x9b, 0x33, 0x8e, 0x6d, 0x43, 0x40, 0x30, 0xc7,
++    0x30, 0xfa
++};
++static const unsigned char ecd_prime_pub256[] = {
++    0x04, 0x22, 0x58, 0xb6, 0xf9, 0x01, 0x3b, 0x8c, 0xa6, 0x9b, 0x9f, 0xae, 0x75, 0xfc, 0x73,
++    0xcf, 0x1b, 0xf0, 0x81, 0xdc, 0x55, 0xa3, 0xcc, 0x5d, 0x81, 0x46, 0x85, 0x06, 0x32, 0x34,
++    0x99, 0x0d, 0xc5, 0x7e, 0xa1, 0x95, 0xbb, 0x21, 0x73, 0x33, 0x40, 0x4b, 0x35, 0x17, 0xf6,
++    0x8e, 0x26, 0x61, 0x46, 0x94, 0x2c, 0x4c, 0xac, 0x9b, 0x20, 0xf8, 0x08, 0x72, 0x25, 0x74,
++    0x98, 0x66, 0xc4, 0x63, 0xa6
++};
++static const ST_KAT_PARAM ecdsa_prime_key256[] = {
++    ST_KAT_PARAM_UTF8STRING(OSSL_PKEY_PARAM_GROUP_NAME, ecd_prime_curve_name256),
++    ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ecd_prime_pub256),
++    ST_KAT_PARAM_BIGNUM(OSSL_PKEY_PARAM_PRIV_KEY, ecd_prime_priv256),
++    ST_KAT_PARAM_END()
++};
++static const unsigned char ec256v1_kat_sig[] = {
++0x30, 0x46, 0x02, 0x21, 0x00, 0xc9, 0x11, 0x27, 0x06, 0x51, 0x2b, 0x50, 0x8c, 0x6b, 0xc0, 0xa6,
++0x85, 0xaa, 0xf4, 0x66, 0x0d, 0xe4, 0x54, 0x0a, 0x10, 0xb6, 0x9f, 0x87, 0xfc, 0xa2, 0xbc, 0x8f,
++0x3c, 0x58, 0xb4, 0xe9, 0x41, 0x02, 0x21, 0x00, 0xc9, 0x72, 0x94, 0xa9, 0xdd, 0x52, 0xca, 0x21,
++0x82, 0x66, 0x7a, 0x68, 0xcb, 0x1e, 0x3b, 0x12, 0x71, 0x4d, 0x56, 0xb5, 0xb7, 0xdd, 0xca, 0x2b,
++0x18, 0xa3, 0xa7, 0x08, 0x0d, 0xfa, 0x9c, 0x66
++};
+ # ifndef OPENSSL_NO_EC2M
+ static const char ecd_bin_curve_name[] = "sect233r1";
+ static const unsigned char ecd_bin_priv[] = {
+@@ -1571,8 +1715,42 @@ static const ST_KAT_SIGN st_kat_sign_tes
+         ecdsa_prime_key,
+         /*
+          * The ECDSA signature changes each time due to it using a random k.
+-         * So there is no expected KAT for this case.
++         * We provide this value in our build
++         */
++        ITM(ec224r1_kat_sig)
++    },
++    {
++        OSSL_SELF_TEST_DESC_SIGN_ECDSA,
++        "EC",
++        "SHA-256",
++        ecdsa_prime_key384,
++        /*
++         * The ECDSA signature changes each time due to it using a random k.
++         * We provide this value in our build
++         */
++        ITM(ec384r1_kat_sig)
++    },
++    {
++        OSSL_SELF_TEST_DESC_SIGN_ECDSA,
++        "EC",
++        "SHA-256",
++        ecdsa_prime_key521,
++        /*
++         * The ECDSA signature changes each time due to it using a random k.
++         * We provide this value in our build
++         */
++        ITM(ec521r1_kat_sig)
++    },
++    {
++        OSSL_SELF_TEST_DESC_SIGN_ECDSA,
++        "EC",
++        "SHA-256",
++        ecdsa_prime_key256,
++        /*
++         * The ECDSA signature changes each time due to it using a random k.
++         * We provide this value in our build
+          */
++        ITM(ec256v1_kat_sig)
+     },
+ # ifndef OPENSSL_NO_EC2M
+     {
+diff -up openssl-3.0.1/crypto/ec/ecp_s390x_nistp.c.fipskat openssl-3.0.1/crypto/ec/ecp_s390x_nistp.c
+--- openssl-3.0.1/crypto/ec/ecp_s390x_nistp.c.fipskat	2022-05-30 14:48:53.180999124 +0200
++++ openssl-3.0.1/crypto/ec/ecp_s390x_nistp.c	2022-05-30 14:58:52.841286228 +0200
+@@ -44,6 +44,10 @@
+ #define S390X_OFF_RN(n)                 (4 * n)
+ #define S390X_OFF_Y(n)                  (4 * n)
+ 
++#ifdef FIPS_MODULE
++extern int REDHAT_FIPS_signature_st;
++#endif
++
+ static int ec_GFp_s390x_nistp_mul(const EC_GROUP *group, EC_POINT *r,
+                                   const BIGNUM *scalar,
+                                   size_t num, const EC_POINT *points[],
+@@ -183,11 +187,21 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign
+          * because kdsa instruction constructs an in-range, invertible nonce
+          * internally implementing counter-measures for RNG weakness.
+          */
++#ifdef FIPS_MODULE
++       if (REDHAT_FIPS_signature_st && eckey->sign_kat_k != NULL) {
++           BN_bn2binpad(eckey->sign_kat_k, param + S390X_OFF_RN(len), len);
++           /* Turns KDSA internal nonce-generation off. */
++           fc |= S390X_KDSA_D;
++       } else {
++#endif
+          if (RAND_priv_bytes_ex(eckey->libctx, param + S390X_OFF_RN(len),
+                                 (size_t)len, 0) != 1) {
+              ERR_raise(ERR_LIB_EC, EC_R_RANDOM_NUMBER_GENERATION_FAILED);
+              goto ret;
+          }
++#ifdef FIPS_MODULE
++        }
++#endif
+     } else {
+         /* Reconstruct k = (k^-1)^-1. */
+         if (ossl_ec_group_do_inverse_ord(group, k, kinv, NULL) == 0
diff --git a/SOURCES/0061-Deny-SHA-1-signature-verification-in-FIPS-provider.patch b/SOURCES/0061-Deny-SHA-1-signature-verification-in-FIPS-provider.patch
new file mode 100644
index 0000000..a4ea757
--- /dev/null
+++ b/SOURCES/0061-Deny-SHA-1-signature-verification-in-FIPS-provider.patch
@@ -0,0 +1,1120 @@
+From 5f4f350ce797a7cd2fdca84c474ee196da9d6fae Mon Sep 17 00:00:00 2001
+From: Clemens Lang <cllang@redhat.com>
+Date: Wed, 18 May 2022 17:25:59 +0200
+Subject: [PATCH] Deny SHA-1 signature verification in FIPS provider
+
+For RHEL, we already disable SHA-1 signatures by default in the default
+provider, so it is unexpected that the FIPS provider would have a more
+lenient configuration in this regard. Additionally, we do not think
+continuing to accept SHA-1 signatures is a good idea due to the
+published chosen-prefix collision attacks.
+
+As a consequence, disable verification of SHA-1 signatures in the FIPS
+provider.
+
+This requires adjusting a few tests that would otherwise fail:
+- 30-test_acvp: Remove the test vectors that use SHA-1.
+- 30-test_evp: Mark tests in evppkey_rsa_common.txt and
+  evppkey_ecdsa.txt that use SHA-1 digests as "Availablein = default",
+  which will not run them when the FIPS provider is enabled.
+- 80-test_cms: Re-create all certificates in test/smime-certificates
+  with SHA256 signatures while keeping the same private keys. These
+  certificates were signed with SHA-1 and thus fail verification in the
+  FIPS provider.
+  Fix some other tests by explicitly running them in the default
+  provider, where SHA-1 is available.
+- 80-test_ssl_old: Skip tests that rely on SSLv3 and SHA-1 when run with
+  the FIPS provider.
+
+Signed-off-by: Clemens Lang <cllang@redhat.com>
+---
+ providers/implementations/signature/dsa_sig.c |  4 --
+ .../implementations/signature/ecdsa_sig.c     |  4 --
+ providers/implementations/signature/rsa_sig.c |  8 +--
+ test/acvp_test.inc                            | 20 -------
+ .../30-test_evp_data/evppkey_ecdsa.txt        |  7 +++
+ .../30-test_evp_data/evppkey_rsa_common.txt   | 51 +++++++++++++++-
+ test/recipes/80-test_cms.t                    |  4 +-
+ test/recipes/80-test_ssl_old.t                |  4 ++
+ test/smime-certs/smdh.pem                     | 18 +++---
+ test/smime-certs/smdsa1.pem                   | 60 +++++++++----------
+ test/smime-certs/smdsa2.pem                   | 60 +++++++++----------
+ test/smime-certs/smdsa3.pem                   | 60 +++++++++----------
+ test/smime-certs/smec1.pem                    | 30 +++++-----
+ test/smime-certs/smec2.pem                    | 30 +++++-----
+ test/smime-certs/smec3.pem                    | 30 +++++-----
+ test/smime-certs/smroot.pem                   | 38 ++++++------
+ test/smime-certs/smrsa1.pem                   | 38 ++++++------
+ test/smime-certs/smrsa2.pem                   | 38 ++++++------
+ test/smime-certs/smrsa3.pem                   | 38 ++++++------
+ 19 files changed, 286 insertions(+), 256 deletions(-)
+
+diff --git a/providers/implementations/signature/dsa_sig.c b/providers/implementations/signature/dsa_sig.c
+index fa3822f39f..c365d7b13a 100644
+--- a/providers/implementations/signature/dsa_sig.c
++++ b/providers/implementations/signature/dsa_sig.c
+@@ -128,11 +128,7 @@ static int dsa_setup_md(PROV_DSA_CTX *ctx,
+         EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
+         int md_nid;
+         size_t mdname_len = strlen(mdname);
+-#ifdef FIPS_MODULE
+-        int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN);
+-#else
+         int sha1_allowed = 0;
+-#endif
+         md_nid = ossl_digest_get_approved_nid_with_sha1(ctx->libctx, md,
+                                                             sha1_allowed);
+ 
+diff --git a/providers/implementations/signature/ecdsa_sig.c b/providers/implementations/signature/ecdsa_sig.c
+index 99b228e82c..44a22832ec 100644
+--- a/providers/implementations/signature/ecdsa_sig.c
++++ b/providers/implementations/signature/ecdsa_sig.c
+@@ -237,11 +237,7 @@ static int ecdsa_setup_md(PROV_ECDSA_CTX *ctx, const char *mdname,
+                        "%s could not be fetched", mdname);
+         return 0;
+     }
+-#ifdef FIPS_MODULE
+-    sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN);
+-#else
+     sha1_allowed = 0;
+-#endif
+     md_nid = ossl_digest_get_approved_nid_with_sha1(ctx->libctx, md,
+                                                     sha1_allowed);
+     if (md_nid < 0) {
+diff --git a/providers/implementations/signature/rsa_sig.c b/providers/implementations/signature/rsa_sig.c
+index f66d7705c3..34f45175e8 100644
+--- a/providers/implementations/signature/rsa_sig.c
++++ b/providers/implementations/signature/rsa_sig.c
+@@ -292,11 +292,7 @@ static int rsa_setup_md(PROV_RSA_CTX *ctx, const char *mdname,
+         EVP_MD *md = EVP_MD_fetch(ctx->libctx, mdname, mdprops);
+         int md_nid;
+         size_t mdname_len = strlen(mdname);
+-#ifdef FIPS_MODULE
+-        int sha1_allowed = (ctx->operation != EVP_PKEY_OP_SIGN);
+-#else
+         int sha1_allowed = 0;
+-#endif
+         md_nid = ossl_digest_rsa_sign_get_md_nid(ctx->libctx, md,
+                                                      sha1_allowed);
+ 
+@@ -1355,8 +1351,10 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
+ 
+     if (prsactx->md == NULL && pmdname == NULL
+         && pad_mode == RSA_PKCS1_PSS_PADDING) {
++#ifdef FIPS_MODULE
++        pmdname = RSA_DEFAULT_DIGEST_NAME_NONLEGACY;
++#else
+         pmdname = RSA_DEFAULT_DIGEST_NAME;
+-#ifndef FIPS_MODULE
+         if (!ossl_ctx_legacy_digest_signatures_allowed(prsactx->libctx, 0)) {
+             pmdname = RSA_DEFAULT_DIGEST_NAME_NONLEGACY;
+         }
+diff --git a/test/acvp_test.inc b/test/acvp_test.inc
+index ad11d3ae1e..73b24bdb0c 100644
+--- a/test/acvp_test.inc
++++ b/test/acvp_test.inc
+@@ -1841,17 +1841,6 @@ static const struct rsa_sigver_st rsa_sigver_data[] = {
+         NO_PSS_SALT_LEN,
+         FAIL
+     },
+-    {
+-        "x931",
+-        3072,
+-        "SHA1",
+-        ITM(rsa_sigverx931_0_msg),
+-        ITM(rsa_sigverx931_0_n),
+-        ITM(rsa_sigverx931_0_e),
+-        ITM(rsa_sigverx931_0_sig),
+-        NO_PSS_SALT_LEN,
+-        PASS
+-    },
+     {
+         "x931",
+         3072,
+diff --git a/test/recipes/30-test_evp_data/evppkey_ecdsa.txt b/test/recipes/30-test_evp_data/evppkey_ecdsa.txt
+index f36982845d..51e507a61c 100644
+--- a/test/recipes/30-test_evp_data/evppkey_ecdsa.txt
++++ b/test/recipes/30-test_evp_data/evppkey_ecdsa.txt
+@@ -37,12 +37,14 @@ PrivPubKeyPair = P-256:P-256-PUBLIC
+ 
+ Title = ECDSA tests
+ 
++Availablein = default
+ Verify = P-256
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1234"
+ Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec8
+ 
+ # Digest too long
++Availablein = default
+ Verify = P-256
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF12345"
+@@ -50,6 +52,7 @@ Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e
+ Result = VERIFY_ERROR
+ 
+ # Digest too short
++Availablein = default
+ Verify = P-256
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF123"
+@@ -57,6 +60,7 @@ Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e
+ Result = VERIFY_ERROR
+ 
+ # Digest invalid
++Availablein = default
+ Verify = P-256
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1235"
+@@ -64,6 +68,7 @@ Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e
+ Result = VERIFY_ERROR
+ 
+ # Invalid signature
++Availablein = default
+ Verify = P-256
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1234"
+@@ -79,12 +84,14 @@ Output = 3045022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e
+ Result = VERIFY_ERROR
+ 
+ # BER signature
++Availablein = default
+ Verify = P-256
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1234"
+ Output = 3080022100b1d1cb1a577035bccdd5a86c6148c2cc7c633cd42b7234139b593076d041e15202201898cdd52b41ca502098184b409cf83a21bc945006746e3b7cea52234e043ec80000
+ Result = VERIFY_ERROR
+ 
++Availablein = default
+ Verify = P-256-PUBLIC
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1234"
+diff --git a/test/recipes/30-test_evp_data/evppkey_rsa_common.txt b/test/recipes/30-test_evp_data/evppkey_rsa_common.txt
+index b8d8bb2993..8dd566067b 100644
+--- a/test/recipes/30-test_evp_data/evppkey_rsa_common.txt
++++ b/test/recipes/30-test_evp_data/evppkey_rsa_common.txt
+@@ -96,6 +96,7 @@ NDL6WCBbets=
+ 
+ Title = RSA tests
+ 
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1234"
+@@ -112,24 +113,28 @@ Ctrl = digest:SHA512-224
+ Input = "0123456789ABCDEF123456789ABC"
+ Output = 5f720e9488139bb21e1c2f027fd5ce5993e6d31c5a8faaee833487b3a944d66891178868ace8070cad3ee2ffbe54aa4885a15fd1a7cc5166970fe1fd8c0423e72bd3e3b56fc4a53ed80aaaeca42497f0ec3c62113edc05cd006608f5eef7ce3ad4cba1069f68731dd28a524a1f93fcdc5547112d48d45586dd943ba0d443be9635720d8a61697c54c96627f0d85c5fbeaa3b4af86a65cf2fc3800dd5de34c046985f25d0efc0bb6edccc1d08b3a4fb9c8faffe181c7e68b31e374ad1440a4a664eec9ca0dc53a9d2f5bc7d9940d866f64201bcbc63612754df45727ea24b531d7de83d1bb707444859fa35521320c33bf6f4dbeb6fb56e653adbf7af15843f17
+ 
++Availablein = default
+ VerifyRecover = RSA-2048
+ Ctrl = digest:SHA1
+ Input = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+ Output = "0123456789ABCDEF1234"
+ 
+ # Leading zero in the signature
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1234"
+ Output = 00c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+ Result = VERIFY_ERROR
+ 
++Availablein = default
+ VerifyRecover = RSA-2048
+ Ctrl = digest:SHA1
+ Input = 00c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2eaee6cd60089a52482d4809a238149520df3bdde4cb9e23d9307b05c0a6f327052325a29adf2cc95b66523be7024e2a585c3d4db15dfbe146efe0ecdc0402e33fe5d40324ee96c5c3edd374a15cdc0f5d84aa243c0f07e188c6518fbfceae158a9943be398e31097da81b62074f626eff738be6160741d5a26957a482b3251fd85d8df78b98148459de10aa93305dbb4a5230aa1da291a9b0e481918f99b7638d72bb687f97661d304ae145d64a474437a4ef39d7b8059332ddeb07e92bf6e0e3acaf8afedc93795e4511737ec1e7aab6d5bc9466afc950c1c17b48ad
+ Result = KEYOP_ERROR
+ 
+ # Mismatched digest
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1233"
+@@ -137,6 +142,7 @@ Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2
+ Result = VERIFY_ERROR
+ 
+ # Corrupted signature
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1233"
+@@ -144,6 +150,7 @@ Output = c09d402423cbf233d26cae21f954547bc43fe80fd41360a0336cfdbe9aedad05bef6fd2
+ Result = VERIFY_ERROR
+ 
+ # parameter is not NULLt
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:sha1
+ Input = "0123456789ABCDEF1234"
+@@ -151,42 +158,49 @@ Output = 3ec3fc29eb6e122bd7aa361cd09fe1bcbe85311096a7b9e4799cedfb2351ce0ab7fe4e7
+ Result = VERIFY_ERROR
+ 
+ # embedded digest too long
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:sha1
+ Input = "0123456789ABCDEF1234"
+ Output = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d
+ Result = VERIFY_ERROR
+ 
++Availablein = default
+ VerifyRecover = RSA-2048
+ Ctrl = digest:sha1
+ Input = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d
+ Result = KEYOP_ERROR
+ 
+ # embedded digest too short
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:sha1
+ Input = "0123456789ABCDEF1234"
+ Output = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d
+ Result = VERIFY_ERROR
+ 
++Availablein = default
+ VerifyRecover = RSA-2048
+ Ctrl = digest:sha1
+ Input = afec9a0d5330a08f54283bb4a9d4e7e7e70fc1342336c4c766fba713f66970151c6e27413c48c33864ea45a0238787004f338ed3e21b53b0fe9c1151c42c388cbc7cba5a06b706c407a5b48324fbe994dc7afc3a19fb3d2841e66222596c14cd72a0f0a7455a019d8eb554f59c0183f9552b75aa96fee8bf935945e079ca283d2bd3534a86f11351f6d6181fbf433e5b01a6d1422145c7a72214d3aacdd5d3af12b2d6bf6438f9f9a64010d8aeed801c87f0859412b236150b86a545f7239be022f4a7ad246b59df87514294cb4a4c7c5a997ee53c66054d9f38ca4e76c1f7af83c30f737ef70f83a45aebe18238ddb95e1998814ca4fc72388f1533147c169d
+ Result = KEYOP_ERROR
+ 
+ # Garbage after DigestInfo
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:sha1
+ Input = "0123456789ABCDEF1234"
+ Output = 9ee34872d4271a7d8808af0a4052a145a6d6a8437d00da3ed14428c7f087cd39f4d43334c41af63e7fa1ba363fee7bcef401d9d36a662abbab55ce89a696e1be0dfa19a5d09ca617dd488787b6048baaefeb29bc8688b2fe3882de2b77c905b5a8b56cf9616041e5ec934ba6de863efe93acc4eef783fe7f72a00fa65d6093ed32bf98ce527e62ccb1d56317f4be18b7e0f55d7c36617d2d0678a306e3350956b662ac15df45215dd8f6b314babb9788e6c272fa461e4c9b512a11a4b92bc77c3a4c95c903fccb238794eca5c750477bf56ea6ee6a167367d881b485ae3889e7c489af8fdf38e0c0f2aed780831182e34abedd43c39281b290774bf35cc25274
+ Result = VERIFY_ERROR
+ 
++Availablein = default
+ VerifyRecover = RSA-2048
+ Ctrl = digest:sha1
+ Input = 9ee34872d4271a7d8808af0a4052a145a6d6a8437d00da3ed14428c7f087cd39f4d43334c41af63e7fa1ba363fee7bcef401d9d36a662abbab55ce89a696e1be0dfa19a5d09ca617dd488787b6048baaefeb29bc8688b2fe3882de2b77c905b5a8b56cf9616041e5ec934ba6de863efe93acc4eef783fe7f72a00fa65d6093ed32bf98ce527e62ccb1d56317f4be18b7e0f55d7c36617d2d0678a306e3350956b662ac15df45215dd8f6b314babb9788e6c272fa461e4c9b512a11a4b92bc77c3a4c95c903fccb238794eca5c750477bf56ea6ee6a167367d881b485ae3889e7c489af8fdf38e0c0f2aed780831182e34abedd43c39281b290774bf35cc25274
+ Result = KEYOP_ERROR
+ 
+ # invalid tag for parameter
++Availablein = default
+ Verify = RSA-2048
+ Ctrl = digest:sha1
+ Input = "0123456789ABCDEF1234"
+@@ -195,6 +209,7 @@ Result = VERIFY_ERROR
+ 
+ # Verify using public key
+ 
++Availablein = default
+ Verify = RSA-2048-PUBLIC
+ Ctrl = digest:SHA1
+ Input = "0123456789ABCDEF1234"
+@@ -370,6 +385,8 @@ Input="0123456789ABCDEF0123456789ABCDEF"
+ Output=4DE433D5844043EF08D354DA03CB29068780D52706D7D1E4D50EFB7D58C9D547D83A747DDD0635A96B28F854E50145518482CB49E963054621B53C60C498D07C16E9C2789C893CF38D4D86900DE71BDE463BD2761D1271E358C7480A1AC0BAB930DDF39602AD1BC165B5D7436B516B7A7858E8EB7AB1C420EEB482F4D207F0E462B1724959320A084E13848D11D10FB593E66BF680BF6D3F345FC3E9C3DE60ABBAC37E1C6EC80A268C8D9FC49626C679097AA690BC1AA662B95EB8DB70390861AA0898229F9349B4B5FDD030D4928C47084708A933144BE23BD3C6E661B85B2C0EF9ED36D498D5B7320E8194D363D4AD478C059BAE804181965E0B81B663158A
+ 
+ # Verify using salt length auto detect
++# In the FIPS provider on RHEL-9, the default digest for PSS signatures is SHA-256
++Availablein = default
+ Verify = RSA-2048-PUBLIC
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_pss_saltlen:auto
+@@ -404,6 +421,10 @@ Output=4DE433D5844043EF08D354DA03CB29068780D52706D7D1E4D50EFB7D58C9D547D83A747DD
+ Result = VERIFY_ERROR
+ 
+ # Verify using default parameters, explicitly setting parameters
++# NOTE: RSA-PSS-DEFAULT contains a restriction to use SHA1 as digest, which
++# RHEL-9 does not support in FIPS mode; all these tests are thus marked
++# Availablein = default.
++Availablein = default
+ Verify = RSA-PSS-DEFAULT
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_pss_saltlen:20
+@@ -412,6 +433,7 @@ Input="0123456789ABCDEF0123"
+ Output = 3EFE09D88509027D837BFA5F8471CF7B69E6DF395DD999BB9CA42021F15722D9AC76670507C6BCFB73F64FB2211B611B8F140E76EBDB064BD762FDBA89D019E304A0D6B274E1C2FE1DF50005598A0306AF805416094E2A5BA60BC72BDE38CE061E853ED40F14967A8B9CA4DC739B462F89558F12FDF2D8D19FBEF16AD66FE2DDDA8BEE983ECBD873064244849D8D94B5B33F45E076871A47ED653E73257A2BE2DB3C0878094B0D2B6B682C8007DFD989425FB39A1FEEC9EED5876414601A49176EC344F5E3EDEE81CA2DDD29B7364F4638112CB3A547E2BC170E28CB66BDABE863754BE8AD5BA230567B575266F4B6B4CF81F28310ABF05351CC9E2DB85D00BF
+ 
+ # Verify explicitly setting parameters "digest" salt length
++Availablein = default
+ Verify = RSA-PSS-DEFAULT
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_pss_saltlen:digest
+@@ -420,18 +442,21 @@ Input="0123456789ABCDEF0123"
+ Output = 3EFE09D88509027D837BFA5F8471CF7B69E6DF395DD999BB9CA42021F15722D9AC76670507C6BCFB73F64FB2211B611B8F140E76EBDB064BD762FDBA89D019E304A0D6B274E1C2FE1DF50005598A0306AF805416094E2A5BA60BC72BDE38CE061E853ED40F14967A8B9CA4DC739B462F89558F12FDF2D8D19FBEF16AD66FE2DDDA8BEE983ECBD873064244849D8D94B5B33F45E076871A47ED653E73257A2BE2DB3C0878094B0D2B6B682C8007DFD989425FB39A1FEEC9EED5876414601A49176EC344F5E3EDEE81CA2DDD29B7364F4638112CB3A547E2BC170E28CB66BDABE863754BE8AD5BA230567B575266F4B6B4CF81F28310ABF05351CC9E2DB85D00BF
+ 
+ # Verify using salt length larger than minimum
++Availablein = default
+ Verify = RSA-PSS-DEFAULT
+ Ctrl = rsa_pss_saltlen:30
+ Input="0123456789ABCDEF0123"
+ Output = 6BF7EDC63A0BA184EEEC7F3020FEC8F5EBF38C2B76481881F48BCCE5796E7AB294548BA9AE810457C7723CABD1BDE94CF59CF7C0FC7461B22760C8ED703DD98E97BFDD61FA8D1181C411F6DEE5FF159F4850746D78EDEE385A363DC28E2CB373D5CAD7953F3BD5E639BE345732C03A1BDEA268814DA036EB1891C82D4012F3B903D86636055F87B96FC98806AD1B217685A4D754046A5DE0B0D7870664BE07902153EC85BA457BE7D7F89D7FE0F626D02A9CBBB2BB479DDA1A5CAE75247FB7BF6BFB15C1D3FD9E6B1573CCDBC72011C3B97716058BB11C7EA2E4E56ADAFE1F5DE6A7FD405AC5890100F9C3408EFFB5C73BF73F48177FF743B4B819D0699D507B
+ 
+ # Verify using maximum salt length
++Availablein = default
+ Verify = RSA-PSS-DEFAULT
+ Ctrl = rsa_pss_saltlen:max
+ Input="0123456789ABCDEF0123"
+ Output = 4470DCFE812DEE2E58E4301D4ED274AB348FE040B724B2CD1D8CD0914BFF375F0B86FCB32BFA8AEA9BD22BD7C4F1ADD4F3D215A5CFCC99055BAFECFC23800E9BECE19A08C66BEBC5802122D13A732E5958FC228DCC0B49B5B4B1154F032D8FA2F3564AA949C1310CC9266B0C47F86D449AC9D2E7678347E7266E2D7C888CCE1ADF44A109A293F8516AE2BD94CE220F26E137DB8E7A66BB9FCE052CDC1D0BE24D8CEBB20D10125F26B069F117044B9E1D16FDDAABCA5340AE1702F37D0E1C08A2E93801C0A41035C6C73DA02A0E32227EAFB0B85E79107B59650D0EE7DC32A6772CCCE90F06369B2880FE87ED76997BA61F5EA818091EE88F8B0D6F24D02A3FC6
+ 
+ # Attempt to change salt length below minimum
++Availablein = default
+ Verify = RSA-PSS-DEFAULT
+ Ctrl = rsa_pss_saltlen:0
+ Result = PKEY_CTRL_ERROR
+@@ -439,21 +464,25 @@ Result = PKEY_CTRL_ERROR
+ # Attempt to change padding mode
+ # Note this used to return PKEY_CTRL_INVALID
+ # but it is limited because setparams only returns 0 or 1.
++Availablein = default
+ Verify = RSA-PSS-DEFAULT
+ Ctrl = rsa_padding_mode:pkcs1
+ Result = PKEY_CTRL_ERROR
+ 
+ # Attempt to change digest
++Availablein = default
+ Verify = RSA-PSS-DEFAULT
+ Ctrl = digest:sha256
+ Result = PKEY_CTRL_ERROR
+ 
+ # Invalid key: rejected when we try to init
++Availablein = default
+ Verify = RSA-PSS-BAD
+ Result = KEYOP_INIT_ERROR
+ Reason = invalid salt length
+ 
+ # Invalid key: rejected when we try to init
++Availablein = default
+ Verify = RSA-PSS-BAD2
+ Result = KEYOP_INIT_ERROR
+ Reason = invalid salt length
+@@ -472,36 +501,42 @@ CAltWyuLbfXWce9jd8CSHLI8Jwpw4lmOb/idGfEFrMLT8Ms18pKA4Thrb2TE7yLh
+ 4fINDOjP+yJJvZohNwIDAQAB
+ -----END PUBLIC KEY-----
+ 
++Availablein = default
+ Verify=RSA-PSS-1
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=cd8b6538cb8e8de566b68bd067569dbf1ee2718e
+ Output=9074308fb598e9701b2294388e52f971faac2b60a5145af185df5287b5ed2887e57ce7fd44dc8634e407c8e0e4360bc226f3ec227f9d9e54638e8d31f5051215df6ebb9c2f9579aa77598a38f914b5b9c1bd83c4e2f9f382a0d0aa3542ffee65984a601bc69eb28deb27dca12c82c2d4c3f66cd500f1ff2b994d8a4e30cbb33c
+ 
++Availablein = default
+ Verify=RSA-PSS-1
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=e35befc17a1d160b9ce35fbd8eb16e7ee491d3fd
+ Output=3ef7f46e831bf92b32274142a585ffcefbdca7b32ae90d10fb0f0c729984f04ef29a9df0780775ce43739b97838390db0a5505e63de927028d9d29b219ca2c4517832558a55d694a6d25b9dab66003c4cccd907802193be5170d26147d37b93590241be51c25055f47ef62752cfbe21418fafe98c22c4d4d47724fdb5669e843
+ 
++Availablein = default
+ Verify=RSA-PSS-1
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0652ec67bcee30f9d2699122b91c19abdba89f91
+ Output=666026fba71bd3e7cf13157cc2c51a8e4aa684af9778f91849f34335d141c00154c4197621f9624a675b5abc22ee7d5baaffaae1c9baca2cc373b3f33e78e6143c395a91aa7faca664eb733afd14d8827259d99a7550faca501ef2b04e33c23aa51f4b9e8282efdb728cc0ab09405a91607c6369961bc8270d2d4f39fce612b1
+ 
++Availablein = default
+ Verify=RSA-PSS-1
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=39c21c4cceda9c1adf839c744e1212a6437575ec
+ Output=4609793b23e9d09362dc21bb47da0b4f3a7622649a47d464019b9aeafe53359c178c91cd58ba6bcb78be0346a7bc637f4b873d4bab38ee661f199634c547a1ad8442e03da015b136e543f7ab07c0c13e4225b8de8cce25d4f6eb8400f81f7e1833b7ee6e334d370964ca79fdb872b4d75223b5eeb08101591fb532d155a6de87
+ 
++Availablein = default
+ Verify=RSA-PSS-1
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=36dae913b77bd17cae6e7b09453d24544cebb33c
+ Output=1d2aad221ca4d31ddf13509239019398e3d14b32dc34dc5af4aeaea3c095af73479cf0a45e5629635a53a018377615b16cb9b13b3e09d671eb71e387b8545c5960da5a64776e768e82b2c93583bf104c3fdb23512b7b4e89f633dd0063a530db4524b01c3f384c09310e315a79dcd3d684022a7f31c865a664e316978b759fad
+ 
++Availablein = default
+ Verify=RSA-PSS-1
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+@@ -517,36 +552,42 @@ swU7R97S7NSkyu/WFIM9yLtiLzF+0Ha4BX/o3j+ESArV6D5KYZBKTySPs5cCc1fh
+ 0w5GMTmBXG/U/VrFuBcqRSMOy2MYoE8UVdhOWosCAwEAAQ==
+ -----END PUBLIC KEY-----
+ 
++Availablein = default
+ Verify=RSA-PSS-9
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=2715a49b8b0012cd7aee84c116446e6dfe3faec0
+ Output=586107226c3ce013a7c8f04d1a6a2959bb4b8e205ba43a27b50f124111bc35ef589b039f5932187cb696d7d9a32c0c38300a5cdda4834b62d2eb240af33f79d13dfbf095bf599e0d9686948c1964747b67e89c9aba5cd85016236f566cc5802cb13ead51bc7ca6bef3b94dcbdbb1d570469771df0e00b1a8a06777472d2316279edae86474668d4e1efff95f1de61c6020da32ae92bbf16520fef3cf4d88f61121f24bbd9fe91b59caf1235b2a93ff81fc403addf4ebdea84934a9cdaf8e1a9e
+ 
++Availablein = default
+ Verify=RSA-PSS-9
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=2dac956d53964748ac364d06595827c6b4f143cd
+ Output=80b6d643255209f0a456763897ac9ed259d459b49c2887e5882ecb4434cfd66dd7e1699375381e51cd7f554f2c271704b399d42b4be2540a0eca61951f55267f7c2878c122842dadb28b01bd5f8c025f7e228418a673c03d6bc0c736d0a29546bd67f786d9d692ccea778d71d98c2063b7a71092187a4d35af108111d83e83eae46c46aa34277e06044589903788f1d5e7cee25fb485e92949118814d6f2c3ee361489016f327fb5bc517eb50470bffa1afa5f4ce9aa0ce5b8ee19bf5501b958
+ 
++Availablein = default
+ Verify=RSA-PSS-9
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=28d98c46cccafbd3bc04e72f967a54bd3ea12298
+ Output=484408f3898cd5f53483f80819efbf2708c34d27a8b2a6fae8b322f9240237f981817aca1846f1084daa6d7c0795f6e5bf1af59c38e1858437ce1f7ec419b98c8736adf6dd9a00b1806d2bd3ad0a73775e05f52dfef3a59ab4b08143f0df05cd1ad9d04bececa6daa4a2129803e200cbc77787caf4c1d0663a6c5987b605952019782caf2ec1426d68fb94ed1d4be816a7ed081b77e6ab330b3ffc073820fecde3727fcbe295ee61a050a343658637c3fd659cfb63736de32d9f90d3c2f63eca
+ 
++Availablein = default
+ Verify=RSA-PSS-9
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=0866d2ff5a79f25ef668cd6f31b42dee421e4c0e
+ Output=84ebeb481be59845b46468bafb471c0112e02b235d84b5d911cbd1926ee5074ae0424495cb20e82308b8ebb65f419a03fb40e72b78981d88aad143053685172c97b29c8b7bf0ae73b5b2263c403da0ed2f80ff7450af7828eb8b86f0028bd2a8b176a4d228cccea18394f238b09ff758cc00bc04301152355742f282b54e663a919e709d8da24ade5500a7b9aa50226e0ca52923e6c2d860ec50ff480fa57477e82b0565f4379f79c772d5c2da80af9fbf325ece6fc20b00961614bee89a183e
+ 
++Availablein = default
+ Verify=RSA-PSS-9
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=6a5b4be4cd36cc97dfde9995efbf8f097a4a991a
+ Output=82102df8cb91e7179919a04d26d335d64fbc2f872c44833943241de8454810274cdf3db5f42d423db152af7135f701420e39b494a67cbfd19f9119da233a23da5c6439b5ba0d2bc373eee3507001378d4a4073856b7fe2aba0b5ee93b27f4afec7d4d120921c83f606765b02c19e4d6a1a3b95fa4c422951be4f52131077ef17179729cddfbdb56950dbaceefe78cb16640a099ea56d24389eef10f8fecb31ba3ea3b227c0a86698bb89e3e9363905bf22777b2a3aa521b65b4cef76d83bde4c
+ 
++Availablein = default
+ Verify=RSA-PSS-9
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+@@ -564,36 +605,42 @@ F7jfF3jbOB3OCctK0FilEQAac4GY7ifPVaE7dUU5kGWC7IsXS9WNXR89dnxhNyGu
+ BQIDAQAB
+ -----END PUBLIC KEY-----
+ 
++Availablein = default
+ Verify=RSA-PSS-10
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=9596bb630cf6a8d4ea4600422b9eba8b13675dd4
+ Output=82c2b160093b8aa3c0f7522b19f87354066c77847abf2a9fce542d0e84e920c5afb49ffdfdace16560ee94a1369601148ebad7a0e151cf16331791a5727d05f21e74e7eb811440206935d744765a15e79f015cb66c532c87a6a05961c8bfad741a9a6657022894393e7223739796c02a77455d0f555b0ec01ddf259b6207fd0fd57614cef1a5573baaff4ec00069951659b85f24300a25160ca8522dc6e6727e57d019d7e63629b8fe5e89e25cc15beb3a647577559299280b9b28f79b0409000be25bbd96408ba3b43cc486184dd1c8e62553fa1af4040f60663de7f5e49c04388e257f1ce89c95dab48a315d9b66b1b7628233876ff2385230d070d07e1666
+ 
++Availablein = default
+ Verify=RSA-PSS-10
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=b503319399277fd6c1c8f1033cbf04199ea21716
+ Output=14ae35d9dd06ba92f7f3b897978aed7cd4bf5ff0b585a40bd46ce1b42cd2703053bb9044d64e813d8f96db2dd7007d10118f6f8f8496097ad75e1ff692341b2892ad55a633a1c55e7f0a0ad59a0e203a5b8278aec54dd8622e2831d87174f8caff43ee6c46445345d84a59659bfb92ecd4c818668695f34706f66828a89959637f2bf3e3251c24bdba4d4b7649da0022218b119c84e79a6527ec5b8a5f861c159952e23ec05e1e717346faefe8b1686825bd2b262fb2531066c0de09acde2e4231690728b5d85e115a2f6b92b79c25abc9bd9399ff8bcf825a52ea1f56ea76dd26f43baafa18bfa92a504cbd35699e26d1dcc5a2887385f3c63232f06f3244c3
+ 
++Availablein = default
+ Verify=RSA-PSS-10
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=50aaede8536b2c307208b275a67ae2df196c7628
+ Output=6e3e4d7b6b15d2fb46013b8900aa5bbb3939cf2c095717987042026ee62c74c54cffd5d7d57efbbf950a0f5c574fa09d3fc1c9f513b05b4ff50dd8df7edfa20102854c35e592180119a70ce5b085182aa02d9ea2aa90d1df03f2daae885ba2f5d05afdac97476f06b93b5bc94a1a80aa9116c4d615f333b098892b25fface266f5db5a5a3bcc10a824ed55aad35b727834fb8c07da28fcf416a5d9b2224f1f8b442b36f91e456fdea2d7cfe3367268de0307a4c74e924159ed33393d5e0655531c77327b89821bdedf880161c78cd4196b5419f7acc3f13e5ebf161b6e7c6724716ca33b85c2e25640192ac2859651d50bde7eb976e51cec828b98b6563b86bb
+ 
++Availablein = default
+ Verify=RSA-PSS-10
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=aa0b72b8b371ddd10c8ae474425ccccf8842a294
+ Output=34047ff96c4dc0dc90b2d4ff59a1a361a4754b255d2ee0af7d8bf87c9bc9e7ddeede33934c63ca1c0e3d262cb145ef932a1f2c0a997aa6a34f8eaee7477d82ccf09095a6b8acad38d4eec9fb7eab7ad02da1d11d8e54c1825e55bf58c2a23234b902be124f9e9038a8f68fa45dab72f66e0945bf1d8bacc9044c6f07098c9fcec58a3aab100c805178155f030a124c450e5acbda47d0e4f10b80a23f803e774d023b0015c20b9f9bbe7c91296338d5ecb471cafb032007b67a60be5f69504a9f01abb3cb467b260e2bce860be8d95bf92c0c8e1496ed1e528593a4abb6df462dde8a0968dffe4683116857a232f5ebf6c85be238745ad0f38f767a5fdbf486fb
+ 
++Availablein = default
+ Verify=RSA-PSS-10
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+ Input=fad3902c9750622a2bc672622c48270cc57d3ea8
+ Output=7e0935ea18f4d6c1d17ce82eb2b3836c55b384589ce19dfe743363ac9948d1f346b7bfddfe92efd78adb21faefc89ade42b10f374003fe122e67429a1cb8cbd1f8d9014564c44d120116f4990f1a6e38774c194bd1b8213286b077b0499d2e7b3f434ab12289c556684deed78131934bb3dd6537236f7c6f3dcb09d476be07721e37e1ceed9b2f7b406887bd53157305e1c8b4f84d733bc1e186fe06cc59b6edb8f4bd7ffefdf4f7ba9cfb9d570689b5a1a4109a746a690893db3799255a0cb9215d2d1cd490590e952e8c8786aa0011265252470c041dfbc3eec7c3cbf71c24869d115c0cb4a956f56d530b80ab589acfefc690751ddf36e8d383f83cedd2cc
+ 
++Availablein = default
+ Verify=RSA-PSS-10
+ Ctrl = rsa_padding_mode:pss
+ Ctrl = rsa_mgf1_md:sha1
+@@ -1329,11 +1376,13 @@ Title = RSA FIPS tests
+ 
+ # FIPS tests
+ 
+-# Verifying with SHA1 is permitted in fips mode for older applications
++# Verifying with SHA1 is not permitted on RHEL-9 in FIPS mode
++Availablein = fips
+ DigestVerify = SHA1
+ Key = RSA-2048
+ Input = "Hello "
+ Output = 87ea0e2226ef35e5a2aec9ca1222fcbe39ba723f05b3203564f671dd3601271806ead3240e61d424359ee3b17bd3e32f54b82df83998a8ac4148410710361de0400f9ddf98278618fbc87747a0531972543e6e5f18ab2fdfbfda02952f6ac69690e43864690af271bf43d4be9705b303d4ff994ab3abd4d5851562b73e59be3edc01cec41a4cc13b68206329bad1a46c6608d3609e951faa321d0fdbc765d54e9a7c59248d2f67913c9903e932b769c9c8a45520cabea06e8c0b231dd3bcc7f7ec55b46b0157ccb5fc5011fa57353cd3df32edcbadcb8d168133cbd0acfb64444cb040e1298f621508a38f79e14ae8c2c5c857f90aa9d24ef5fc07d34bf23859
++Result = DIGESTVERIFYINIT_ERROR
+ 
+ # Verifying with a 1024 bit key is permitted in fips mode for older applications
+ DigestVerify = SHA256
+diff --git a/test/recipes/80-test_cms.t b/test/recipes/80-test_cms.t
+index 48a92f735d..34afe91b88 100644
+--- a/test/recipes/80-test_cms.t
++++ b/test/recipes/80-test_cms.t
+@@ -162,7 +162,7 @@ my @smime_pkcs7_tests = (
+       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont, "-md", "sha1",
+         "-certfile", $smroot,
+         "-signer", $smrsa1, "-out", "{output}.cms" ],
+-      [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
++      [ "{cmd2}", @defaultprov, "-verify", "-in", "{output}.cms",
+         "-CAfile", $smroot, "-out", "{output}.txt" ],
+       \&final_compare
+     ],
+@@ -170,7 +170,7 @@ my @smime_pkcs7_tests = (
+     [ "signed zero-length content S/MIME format, RSA key SHA1",
+       [ "{cmd1}", @defaultprov, "-sign", "-in", $smcont_zero, "-md", "sha1",
+         "-certfile", $smroot, "-signer", $smrsa1, "-out", "{output}.cms" ],
+-      [ "{cmd2}", @prov, "-verify", "-in", "{output}.cms",
++      [ "{cmd2}", @defaultprov, "-verify", "-in", "{output}.cms",
+         "-CAfile", $smroot, "-out", "{output}.txt" ],
+       \&zero_compare
+     ],
+diff --git a/test/recipes/80-test_ssl_old.t b/test/recipes/80-test_ssl_old.t
+index 8c52b637fc..ff75c5b6ec 100644
+--- a/test/recipes/80-test_ssl_old.t
++++ b/test/recipes/80-test_ssl_old.t
+@@ -394,6 +394,9 @@ sub testssl {
+                'test sslv2/sslv3 with 1024bit DHE via BIO pair');
+           }
+ 
++        SKIP: {
++          skip "SSLv3 is not supported by the FIPS provider", 4
++              if $provider eq "fips";
+           ok(run(test([@ssltest, "-bio_pair", "-server_auth", @CA])),
+              'test sslv2/sslv3 with server authentication');
+           ok(run(test([@ssltest, "-bio_pair", "-client_auth", @CA])),
+@@ -402,6 +405,7 @@ sub testssl {
+              'test sslv2/sslv3 with both client and server authentication via BIO pair');
+           ok(run(test([@ssltest, "-bio_pair", "-server_auth", "-client_auth", "-app_verify", @CA])),
+              'test sslv2/sslv3 with both client and server authentication via BIO pair and app verify');
++         }
+ 
+         SKIP: {
+             skip "No IPv4 available on this machine", 1
+diff --git a/test/smime-certs/smdh.pem b/test/smime-certs/smdh.pem
+index 7d66a6b421..894461f6da 100644
+--- a/test/smime-certs/smdh.pem
++++ b/test/smime-certs/smdh.pem
+@@ -14,10 +14,10 @@ ta+9S7L4zNsvbg8RtJyH8i4CHQCY12PTXj6Ipxbqq4d1Q+AoUqnN/H9lAS46teXv
+ BB8CHQCGE6pxpX5lWcH6+TGLDoLo3T5L2/5KTd0tRNdj
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIIFljCCBH6gAwIBAgIUYmx57362u3KsYCqtKby2mYi+pLMwDQYJKoZIhvcNAQEL
++MIIFljCCBH6gAwIBAgIUMNF4DNf+H6AXGApe99UrJWFcAnwwDQYJKoZIhvcNAQEL
+ BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
+-BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIxMDExNTEwMDk1MloXDTMwMTEy
+-NDEwMDk1MlowRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MzM0NloXDTMyMDMz
++MTE0MzM0NlowRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
+ HTAbBgNVBAMMFFRlc3QgUy9NSU1FIEVFIERIICMxMIIDQjCCAjUGByqGSM4+AgEw
+ ggIoAoIBAQCCyx9ZhD6HY5xgusGDrJZJ+FdTe9OxD/p9DQNKqoLyJ10TAUXuycoz
+ VqDAD4v1wsOAPH0TDOX9Ns87PXgTbd6DpSJtF1ZLW+1pklZs2m0cLl4raOe8CZGH
+@@ -38,10 +38,10 @@ Ixe06fY0eA9sfxx7+4lm2Jhw7XaIfguo8mgrfWjBzkkT2mcAHss/fdKcXNYrg+A+
+ xgApPiyuy7S4YkQSsdV5Ns8UFttBCuojzEuWQ49fMZcv/rIHSHSxpbg2Sdka+d6h
+ wOQHK6NgMF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYE
+ FLG7SOccVVRWmPw87GRrYH/NCegTMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaI
+-qSTm5bZsMA0GCSqGSIb3DQEBCwUAA4IBAQA5r5k39ghJIgQKjOXSffhtAaBPT0Um
+-WtLjijp/iBUAowFpncDRIp+Ng7n/feJHDdnh59H0ZHGljWqZ3rgG3HjjArvG+iUm
+-6aaS4KdM6OwK60JTUXBQ/InISXzrZof2oZ5BjO6L6yV6cpaYOLlLo3QjU8HE54G9
+-7UyR48NSvhwPw+vS1Abjib+K1En/ctnlm0CurHgP56LrJxguFZZP6+UjCnEy0wxm
+-VRr+y4+IgWikdOumMelJ+x9O9R7EPVfwQ9TYBtpo5hZQiGhSJ3Di9LZO5i0h2xjj
+-AhtR8zmzusFX2Ruh2dXQWeNx/dMEcYRJLU1P+IxUq2g1GUiCgq2Xc7ZY
++qSTm5bZsMA0GCSqGSIb3DQEBCwUAA4IBAQB9J2dIIbIAiB8ToXJcyO7HRPhdWC/Y
++TE8cqeL+JiWNvIMB9fl2gOx6gj2h+yEr3lCpK/XDoWOs576UScS/vvs6fOjFHfkb
++L4i9nHXD2KizXkM2hr9FzTRXd9c3XXLyB9t1z38qcpOMxoxAbnH8hWLQDPjFdArC
++KWIqK/Vqxz4ZcIveM9GcVf78FU2DbQF4pwHjO9TsG7AbXiV4PXyJK75W5okAbZmQ
++EmMmVXEJdXSOS4prP8DCW/LYJ5UddsVZba2BCHD3c1c2YTA4GsP3ZMoXvQoyj0L2
++/xazs/AS373Of6H0s00itRTFABxve1I7kE5dQdc3oZjn6A/DbfjYUmr5
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smdsa1.pem b/test/smime-certs/smdsa1.pem
+index b424f6704e..597d98f827 100644
+--- a/test/smime-certs/smdsa1.pem
++++ b/test/smime-certs/smdsa1.pem
+@@ -14,34 +14,34 @@ Hxb7ISDCT7dCw/lH1nCbVFBOM0ASI26SSsFSXQrvD2kryRcTZ0KkyyhhoPODWpU+
+ TQMsxQQjAiEAkolGvb/76X3vm5Ov09ezqyBYt9cdj/FLH7DyMkxO7X0=
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIIFkDCCBHigAwIBAgIJANk5lu6mSyBDMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEUx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+-ZXN0IFMvTUlNRSBFRSBEU0EgIzEwggNGMIICOQYHKoZIzjgEATCCAiwCggEBAJB8
+-uU116E+dOsYgyHDiuTS65rqTWcIbfNzJ9eWLXsF0HaTQcE9pMDdrdkd863UDDLRS
+-7TBneB0+v3PQjriGclcgai7MhqdnudhEiYe1fkkwVtd7LGjU7B3ZmzegST2dBShS
+-wzG+ZgL+CE8vlnHWk/FwcI7DNbGgbjJkyOKZc5zX9bvO8r/j+D8LP18i0PfN1zJ1
+-+Az+ErT8J5hDbXF+Gp/iaMq/2mWcJxaBOgYj7sfxUrzQwVuQ7ZApHPe8/X9OMro9
+-Gb2wR4HlvXT5K8a/aPbD4ILR9cvizqfs+0GWb9vDDzEvX8DPyTB6NRwgjUNzy43D
+-AhLAZvBoYG+XsgembbUCIQCuh1mL6cIpl1MvwiAKNfefQO6E9GRVA+PP8HpXB4tb
+-0wKCAQB+KaRQ3CewYWnuYozMkqEehCQwHWonPIgeMPND8nXGN+gXqLbtp/DX9Ypu
+-g0Pl6x5mGWEDZM7lkkHqcbEM4T2VVDFhWaX75xCPp+geHVNUkCAaXiZa695b9HP4
+-0SGkrjNV4Sx8ytuQHKk8HLLHMXVnj23nrzF0ij57yMsjwWMR1c4hSDh6EHc1jpIv
+-yvignj2P+wlZ8dwOhYf8sr1loEXw2l+Ul7cXjRLxEO8zyPYcL7LZDhDIqTUNcaIf
+-7vJAsZbOvczveQLdQGecfSEfFvshIMJPt0LD+UfWcJtUUE4zQBIjbpJKwVJdCu8P
+-aSvJFxNnQqTLKGGg84NalT5NAyzFA4IBBQACggEAGXSQADbuRIZBjiQ6NikwZl+x
+-EDEffIE0RWbvwf1tfWxw4ZvanO/djyz5FePO0AIJDBCLUjr9D32nkmIG1Hu3dWgV
+-86knQsM6uFiMSzY9nkJGZOlH3w4NHLE78pk75xR1sg1MEZr4x/t+a/ea9Y4AXklE
+-DCcaHtpMGeAx3ZAqSKec+zQOOA73JWP1/gYHGdYyTQpQtwRTsh0Gi5mOOdpoJ0vp
+-O83xYbFCZ+ZZKX1RWOjJe2OQBRtw739q1nRga1VMLAT/LFSQsSE3IOp8hiWbjnit
+-1SE6q3II2a/aHZH/x4OzszfmtQfmerty3eQSq3bgajfxCsccnRjSbLeNiazRSKNg
+-MF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFNHQYTOO
+-xaZ/N68OpxqjHKuatw6sMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZs
+-MA0GCSqGSIb3DQEBBQUAA4IBAQAAiLociMMXcLkO/uKjAjCIQMrsghrOrxn4ZGBx
+-d/mCTeqPxhcrX2UorwxVCKI2+Dmz5dTC2xKprtvkiIadJamJmxYYzeF1pgRriFN3
+-MkmMMkTbe/ekSvSeMtHQ2nHDCAJIaA/k9akWfA0+26Ec25/JKMrl3LttllsJMK1z
+-Xj7TcQpAIWORKWSNxY/ezM34+9ABHDZB2waubFqS+irlZsn38aZRuUI0K67fuuIt
+-17vMUBqQpe2hfNAjpZ8dIpEdAGjQ6izV2uwP1lXbiaK9U4dvUqmwyCIPniX7Hpaf
+-0VnX0mEViXMT6vWZTjLBUv0oKmO7xBkWHIaaX6oyF32pK5AO
++MIIFmzCCBIOgAwIBAgIUWGMqmBZZ1ykguVDk2Whn+2uKMA0wDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MjA0OFoXDTMyMDMz
++MTE0MjA0OFowRTELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HjAcBgNVBAMMFVRlc3QgUy9NSU1FIEVFIERTQSAjMTCCA0YwggI5BgcqhkjOOAQB
++MIICLAKCAQEAkHy5TXXoT506xiDIcOK5NLrmupNZwht83Mn15YtewXQdpNBwT2kw
++N2t2R3zrdQMMtFLtMGd4HT6/c9COuIZyVyBqLsyGp2e52ESJh7V+STBW13ssaNTs
++HdmbN6BJPZ0FKFLDMb5mAv4ITy+WcdaT8XBwjsM1saBuMmTI4plznNf1u87yv+P4
++Pws/XyLQ983XMnX4DP4StPwnmENtcX4an+Joyr/aZZwnFoE6BiPux/FSvNDBW5Dt
++kCkc97z9f04yuj0ZvbBHgeW9dPkrxr9o9sPggtH1y+LOp+z7QZZv28MPMS9fwM/J
++MHo1HCCNQ3PLjcMCEsBm8Ghgb5eyB6ZttQIhAK6HWYvpwimXUy/CIAo1959A7oT0
++ZFUD48/welcHi1vTAoIBAH4ppFDcJ7Bhae5ijMySoR6EJDAdaic8iB4w80PydcY3
++6Beotu2n8Nf1im6DQ+XrHmYZYQNkzuWSQepxsQzhPZVUMWFZpfvnEI+n6B4dU1SQ
++IBpeJlrr3lv0c/jRIaSuM1XhLHzK25AcqTwcsscxdWePbeevMXSKPnvIyyPBYxHV
++ziFIOHoQdzWOki/K+KCePY/7CVnx3A6Fh/yyvWWgRfDaX5SXtxeNEvEQ7zPI9hwv
++stkOEMipNQ1xoh/u8kCxls69zO95At1AZ5x9IR8W+yEgwk+3QsP5R9Zwm1RQTjNA
++EiNukkrBUl0K7w9pK8kXE2dCpMsoYaDzg1qVPk0DLMUDggEFAAKCAQAZdJAANu5E
++hkGOJDo2KTBmX7EQMR98gTRFZu/B/W19bHDhm9qc792PLPkV487QAgkMEItSOv0P
++faeSYgbUe7d1aBXzqSdCwzq4WIxLNj2eQkZk6UffDg0csTvymTvnFHWyDUwRmvjH
+++35r95r1jgBeSUQMJxoe2kwZ4DHdkCpIp5z7NA44DvclY/X+BgcZ1jJNClC3BFOy
++HQaLmY452mgnS+k7zfFhsUJn5lkpfVFY6Ml7Y5AFG3Dvf2rWdGBrVUwsBP8sVJCx
++ITcg6nyGJZuOeK3VITqrcgjZr9odkf/Hg7OzN+a1B+Z6u3Ld5BKrduBqN/EKxxyd
++GNJst42JrNFIo2AwXjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF4DAdBgNV
++HQ4EFgQU0dBhM47Fpn83rw6nGqMcq5q3DqwwHwYDVR0jBBgwFoAUyZFTCmN7FluL
++vUTwdoipJObltmwwDQYJKoZIhvcNAQELBQADggEBAC3W5L4plRWiaX03PncMHnaL
++sp48+2jJen4avzNpRZF/bTQ621x/KLWelbMzBTMxU6jtU1LwCvsiOTSenUZ6W5vq
++TGy6nwkMUrBN0nHmymVz5v40VBLtc2/5xF9UBZ1GMnmYko+d7VHBD6qu4hpi6OD1
++3Z2kxCRaZ87y3IbVnl6zqdqxDxKCj4Ca+TT6AApm/MYVwpuvCVmuXrBBvJYTFFeZ
++2J90jHlQep2rAaZu41oiIlmQUEf9flV0iPYjj+Pqdzr9ovWVbqt7l1WKOBDYdzJW
++fQ8TvFSExkDQsDc0nkkLIfJBFUFuOpNmODvq+Ac8AGUBnl/Z3pAV4KVnnobIXHw=
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smdsa2.pem b/test/smime-certs/smdsa2.pem
+index 648447fc89..a995f665bb 100644
+--- a/test/smime-certs/smdsa2.pem
++++ b/test/smime-certs/smdsa2.pem
+@@ -14,34 +14,34 @@ Hxb7ISDCT7dCw/lH1nCbVFBOM0ASI26SSsFSXQrvD2kryRcTZ0KkyyhhoPODWpU+
+ TQMsxQQiAiAdCUJ5n2Q9hIynN8BMpnRcdfH696BKejGx+2Mr2kfnnA==
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIIFkDCCBHigAwIBAgIJANk5lu6mSyBEMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEUx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+-ZXN0IFMvTUlNRSBFRSBEU0EgIzIwggNGMIICOQYHKoZIzjgEATCCAiwCggEBAJB8
+-uU116E+dOsYgyHDiuTS65rqTWcIbfNzJ9eWLXsF0HaTQcE9pMDdrdkd863UDDLRS
+-7TBneB0+v3PQjriGclcgai7MhqdnudhEiYe1fkkwVtd7LGjU7B3ZmzegST2dBShS
+-wzG+ZgL+CE8vlnHWk/FwcI7DNbGgbjJkyOKZc5zX9bvO8r/j+D8LP18i0PfN1zJ1
+-+Az+ErT8J5hDbXF+Gp/iaMq/2mWcJxaBOgYj7sfxUrzQwVuQ7ZApHPe8/X9OMro9
+-Gb2wR4HlvXT5K8a/aPbD4ILR9cvizqfs+0GWb9vDDzEvX8DPyTB6NRwgjUNzy43D
+-AhLAZvBoYG+XsgembbUCIQCuh1mL6cIpl1MvwiAKNfefQO6E9GRVA+PP8HpXB4tb
+-0wKCAQB+KaRQ3CewYWnuYozMkqEehCQwHWonPIgeMPND8nXGN+gXqLbtp/DX9Ypu
+-g0Pl6x5mGWEDZM7lkkHqcbEM4T2VVDFhWaX75xCPp+geHVNUkCAaXiZa695b9HP4
+-0SGkrjNV4Sx8ytuQHKk8HLLHMXVnj23nrzF0ij57yMsjwWMR1c4hSDh6EHc1jpIv
+-yvignj2P+wlZ8dwOhYf8sr1loEXw2l+Ul7cXjRLxEO8zyPYcL7LZDhDIqTUNcaIf
+-7vJAsZbOvczveQLdQGecfSEfFvshIMJPt0LD+UfWcJtUUE4zQBIjbpJKwVJdCu8P
+-aSvJFxNnQqTLKGGg84NalT5NAyzFA4IBBQACggEAItQlFu0t7Mw1HHROuuwKLS+E
+-h2WNNZP96MLQTygOVlqgaJY+1mJLzvl/51LLH6YezX0t89Z2Dm/3SOJEdNrdbIEt
+-tbu5rzymXxFhc8uaIYZFhST38oQwJOjM8wFitAQESe6/9HZjkexMqSqx/r5aEKTa
+-LBinqA1BJRI72So1/1dv8P99FavPADdj8V7fAccReKEQKnfnwA7mrnD+OlIqFKFn
+-3wCGk8Sw7tSJ9g6jgCI+zFwrKn2w+w+iot/Ogxl9yMAtKmAd689IAZr5GPPvV2y0
+-KOogCiUYgSTSawZhr+rjyFavfI5dBWzMq4tKx/zAi6MJ+6hGJjJ8jHoT9JAPmaNg
+-MF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFGaxw04k
+-qpufeGZC+TTBq8oMnXyrMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZs
+-MA0GCSqGSIb3DQEBBQUAA4IBAQCk2Xob1ICsdHYx/YsBzY6E1eEwcI4RZbZ3hEXp
+-VA72/Mbz60gjv1OwE5Ay4j+xG7IpTio6y2A9ZNepGpzidYcsL/Lx9Sv1LlN0Ukzb
+-uk6Czd2sZJp+PFMTTrgCd5rXKnZs/0D84Vci611vGMA1hnUnbAnBBmgLXe9pDNRV
+-6mhmCLLjJ4GOr5Wxt/hhknr7V2e1VMx3Q47GZhc0o/gExfhxXA8+gicM0nEYNakD
+-2A1F0qDhQGakjuofANHhjdUDqKJ1sxurAy80fqb0ddzJt2el89iXKN+aXx/zEX96
+-GI5ON7z/bkVwIi549lUOpWb2Mved61NBzCLKVP7HSuEIsC/I
++MIIFmzCCBIOgAwIBAgIUXgHGnvOCmrOH9biRq3yTCcDsliUwDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MjIyNloXDTMyMDMz
++MTE0MjIyNlowRTELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HjAcBgNVBAMMFVRlc3QgUy9NSU1FIEVFIERTQSAjMjCCA0YwggI5BgcqhkjOOAQB
++MIICLAKCAQEAkHy5TXXoT506xiDIcOK5NLrmupNZwht83Mn15YtewXQdpNBwT2kw
++N2t2R3zrdQMMtFLtMGd4HT6/c9COuIZyVyBqLsyGp2e52ESJh7V+STBW13ssaNTs
++HdmbN6BJPZ0FKFLDMb5mAv4ITy+WcdaT8XBwjsM1saBuMmTI4plznNf1u87yv+P4
++Pws/XyLQ983XMnX4DP4StPwnmENtcX4an+Joyr/aZZwnFoE6BiPux/FSvNDBW5Dt
++kCkc97z9f04yuj0ZvbBHgeW9dPkrxr9o9sPggtH1y+LOp+z7QZZv28MPMS9fwM/J
++MHo1HCCNQ3PLjcMCEsBm8Ghgb5eyB6ZttQIhAK6HWYvpwimXUy/CIAo1959A7oT0
++ZFUD48/welcHi1vTAoIBAH4ppFDcJ7Bhae5ijMySoR6EJDAdaic8iB4w80PydcY3
++6Beotu2n8Nf1im6DQ+XrHmYZYQNkzuWSQepxsQzhPZVUMWFZpfvnEI+n6B4dU1SQ
++IBpeJlrr3lv0c/jRIaSuM1XhLHzK25AcqTwcsscxdWePbeevMXSKPnvIyyPBYxHV
++ziFIOHoQdzWOki/K+KCePY/7CVnx3A6Fh/yyvWWgRfDaX5SXtxeNEvEQ7zPI9hwv
++stkOEMipNQ1xoh/u8kCxls69zO95At1AZ5x9IR8W+yEgwk+3QsP5R9Zwm1RQTjNA
++EiNukkrBUl0K7w9pK8kXE2dCpMsoYaDzg1qVPk0DLMUDggEFAAKCAQAi1CUW7S3s
++zDUcdE667AotL4SHZY01k/3owtBPKA5WWqBolj7WYkvO+X/nUssfph7NfS3z1nYO
++b/dI4kR02t1sgS21u7mvPKZfEWFzy5ohhkWFJPfyhDAk6MzzAWK0BARJ7r/0dmOR
++7EypKrH+vloQpNosGKeoDUElEjvZKjX/V2/w/30Vq88AN2PxXt8BxxF4oRAqd+fA
++DuaucP46UioUoWffAIaTxLDu1In2DqOAIj7MXCsqfbD7D6Ki386DGX3IwC0qYB3r
++z0gBmvkY8+9XbLQo6iAKJRiBJNJrBmGv6uPIVq98jl0FbMyri0rH/MCLown7qEYm
++MnyMehP0kA+Zo2AwXjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF4DAdBgNV
++HQ4EFgQUZrHDTiSqm594ZkL5NMGrygydfKswHwYDVR0jBBgwFoAUyZFTCmN7FluL
++vUTwdoipJObltmwwDQYJKoZIhvcNAQELBQADggEBADhpm4d9pgdWTiX1ci4qxOat
++MK+eAc3y8dwjacwiTD94fFy+MFzItAI2msF+ILXDCYDUpFZpBjlCNRzMu/ETghJx
++53g4Hg6ioYmtLcYIAFQVIz4skdgV8npztK3ZQMSN3dcateZBf8KaEdP+cRtQs4IW
++Y+EAZ6Fve2j/kz1x/cmhSFQdWhhS+WzYUCY+FLWDXMuNLh7rDWy1t8VaRHLBU4TU
++q6W/qDaN2e6dKrzjEkqUstdGZ+JAkAZ+6CIABEnHeco1dEQUU5Atry7djeRhY68r
++us++ajRd6DLWXrD4KePyTYSPc7rAcbBBYSwe48cTxlPfKItTCrRXmWJHCCZ0UBA=
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smdsa3.pem b/test/smime-certs/smdsa3.pem
+index 77acc5e46f..9f703e52f0 100644
+--- a/test/smime-certs/smdsa3.pem
++++ b/test/smime-certs/smdsa3.pem
+@@ -14,34 +14,34 @@ Hxb7ISDCT7dCw/lH1nCbVFBOM0ASI26SSsFSXQrvD2kryRcTZ0KkyyhhoPODWpU+
+ TQMsxQQjAiEArJr6p2zTbhRppQurHGTdmdYHqrDdZH4MCsD9tQCw1xY=
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIIFkDCCBHigAwIBAgIJANk5lu6mSyBFMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEUx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+-ZXN0IFMvTUlNRSBFRSBEU0EgIzMwggNGMIICOQYHKoZIzjgEATCCAiwCggEBAJB8
+-uU116E+dOsYgyHDiuTS65rqTWcIbfNzJ9eWLXsF0HaTQcE9pMDdrdkd863UDDLRS
+-7TBneB0+v3PQjriGclcgai7MhqdnudhEiYe1fkkwVtd7LGjU7B3ZmzegST2dBShS
+-wzG+ZgL+CE8vlnHWk/FwcI7DNbGgbjJkyOKZc5zX9bvO8r/j+D8LP18i0PfN1zJ1
+-+Az+ErT8J5hDbXF+Gp/iaMq/2mWcJxaBOgYj7sfxUrzQwVuQ7ZApHPe8/X9OMro9
+-Gb2wR4HlvXT5K8a/aPbD4ILR9cvizqfs+0GWb9vDDzEvX8DPyTB6NRwgjUNzy43D
+-AhLAZvBoYG+XsgembbUCIQCuh1mL6cIpl1MvwiAKNfefQO6E9GRVA+PP8HpXB4tb
+-0wKCAQB+KaRQ3CewYWnuYozMkqEehCQwHWonPIgeMPND8nXGN+gXqLbtp/DX9Ypu
+-g0Pl6x5mGWEDZM7lkkHqcbEM4T2VVDFhWaX75xCPp+geHVNUkCAaXiZa695b9HP4
+-0SGkrjNV4Sx8ytuQHKk8HLLHMXVnj23nrzF0ij57yMsjwWMR1c4hSDh6EHc1jpIv
+-yvignj2P+wlZ8dwOhYf8sr1loEXw2l+Ul7cXjRLxEO8zyPYcL7LZDhDIqTUNcaIf
+-7vJAsZbOvczveQLdQGecfSEfFvshIMJPt0LD+UfWcJtUUE4zQBIjbpJKwVJdCu8P
+-aSvJFxNnQqTLKGGg84NalT5NAyzFA4IBBQACggEAcXvtfiJfIZ0wgGpN72ZeGrJ9
+-msUXOxow7w3fDbP8r8nfVkBNbfha8rx0eY6fURFVZzIOd8EHGKypcH1gS6eZNucf
+-zgsH1g5r5cRahMZmgGXBEBsWrh2IaDG7VSKt+9ghz27EKgjAQCzyHQL5FCJgR2p7
+-cv0V4SRqgiAGYlJ191k2WtLOsVd8kX//jj1l8TUgE7TqpuSEpaSyQ4nzJROpZWZp
+-N1RwFmCURReykABU/Nzin/+rZnvZrp8WoXSXEqxeB4mShRSaH57xFnJCpRwKJ4qS
+-2uhATzJaKH7vu63k3DjftbSBVh+32YXwtHc+BGjs8S2aDtCW3FtDA7Z6J8BIxaNg
+-MF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFMJxatDE
+-FCEFGl4uoiQQ1050Ju9RMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZs
+-MA0GCSqGSIb3DQEBBQUAA4IBAQBGZD1JnMep39KMOhD0iBTmyjhtcnRemckvRask
+-pS/CqPwo+M+lPNdxpLU2w9b0QhPnj0yAS/BS1yBjsLGY4DP156k4Q3QOhwsrTmrK
+-YOxg0w7DOpkv5g11YLJpHsjSOwg5uIMoefL8mjQK6XOFOmQXHJrUtGulu+fs6FlM
+-khGJcW4xYVPK0x/mHvTT8tQaTTkgTdVHObHF5Dyx/F9NMpB3RFguQPk2kT4lJc4i
+-Up8T9mLzaxz6xc4wwh8h70Zw81lkGYhX+LRk3sfd/REq9x4QXQNP9t9qU1CgrBzv
+-4orzt9cda4r+rleSg2XjWnXzMydE6DuwPVPZlqnLbSYUy660
++MIIFmzCCBIOgAwIBAgIUMMzeluWS9FTgzFM2PCI6rSt0++QwDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MjI0MloXDTMyMDMz
++MTE0MjI0MlowRTELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HjAcBgNVBAMMFVRlc3QgUy9NSU1FIEVFIERTQSAjMzCCA0YwggI5BgcqhkjOOAQB
++MIICLAKCAQEAkHy5TXXoT506xiDIcOK5NLrmupNZwht83Mn15YtewXQdpNBwT2kw
++N2t2R3zrdQMMtFLtMGd4HT6/c9COuIZyVyBqLsyGp2e52ESJh7V+STBW13ssaNTs
++HdmbN6BJPZ0FKFLDMb5mAv4ITy+WcdaT8XBwjsM1saBuMmTI4plznNf1u87yv+P4
++Pws/XyLQ983XMnX4DP4StPwnmENtcX4an+Joyr/aZZwnFoE6BiPux/FSvNDBW5Dt
++kCkc97z9f04yuj0ZvbBHgeW9dPkrxr9o9sPggtH1y+LOp+z7QZZv28MPMS9fwM/J
++MHo1HCCNQ3PLjcMCEsBm8Ghgb5eyB6ZttQIhAK6HWYvpwimXUy/CIAo1959A7oT0
++ZFUD48/welcHi1vTAoIBAH4ppFDcJ7Bhae5ijMySoR6EJDAdaic8iB4w80PydcY3
++6Beotu2n8Nf1im6DQ+XrHmYZYQNkzuWSQepxsQzhPZVUMWFZpfvnEI+n6B4dU1SQ
++IBpeJlrr3lv0c/jRIaSuM1XhLHzK25AcqTwcsscxdWePbeevMXSKPnvIyyPBYxHV
++ziFIOHoQdzWOki/K+KCePY/7CVnx3A6Fh/yyvWWgRfDaX5SXtxeNEvEQ7zPI9hwv
++stkOEMipNQ1xoh/u8kCxls69zO95At1AZ5x9IR8W+yEgwk+3QsP5R9Zwm1RQTjNA
++EiNukkrBUl0K7w9pK8kXE2dCpMsoYaDzg1qVPk0DLMUDggEFAAKCAQBxe+1+Il8h
++nTCAak3vZl4asn2axRc7GjDvDd8Ns/yvyd9WQE1t+FryvHR5jp9REVVnMg53wQcY
++rKlwfWBLp5k25x/OCwfWDmvlxFqExmaAZcEQGxauHYhoMbtVIq372CHPbsQqCMBA
++LPIdAvkUImBHanty/RXhJGqCIAZiUnX3WTZa0s6xV3yRf/+OPWXxNSATtOqm5ISl
++pLJDifMlE6llZmk3VHAWYJRFF7KQAFT83OKf/6tme9munxahdJcSrF4HiZKFFJof
++nvEWckKlHAonipLa6EBPMloofu+7reTcON+1tIFWH7fZhfC0dz4EaOzxLZoO0Jbc
++W0MDtnonwEjFo2AwXjAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIF4DAdBgNV
++HQ4EFgQUwnFq0MQUIQUaXi6iJBDXTnQm71EwHwYDVR0jBBgwFoAUyZFTCmN7FluL
++vUTwdoipJObltmwwDQYJKoZIhvcNAQELBQADggEBAJNW/oEmpz6jZ7EjUkHhxDXR
++egsZVjBO+E2hPCciEoZaM6jIDYphrCVbdOOyy1RvLBv3SRblaECmInsRpCNwf5B5
++OaGN3hdsvx23IKnLJ7EKDauIOGhkzCMWjO8tez48UL0Wgta0+TpuiOT+UBoKb9fw
++f0f4ab9wD9pED7ghMKlwI6/oppS4PrhwYS2nwYwGXpmgu6QZDln/cgoU7cQV7r3J
++deMCpKGPyS429B9mUxlggZYvvJOm35ZiI7UAcGhJWIUrdXBxqx3DQ3CSf75vGP87
++2vn6ZoXRXSLfE48GpUtQzP6/gZti68vZrHdzKWTyZxMs4+PGoHrW5hbNDsghKDs=
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smec1.pem b/test/smime-certs/smec1.pem
+index 75a862666b..05754f3963 100644
+--- a/test/smime-certs/smec1.pem
++++ b/test/smime-certs/smec1.pem
+@@ -4,19 +4,19 @@ DMlYvkj0SmLmYvWULe2LfyXRmpWhRANCAAS+SIj2FY2DouPRuNDp9WVpsqef58tV
+ 3gIwV0EOV/xyYTzZhufZi/aBcXugWR1x758x4nHus2uEuEFi3Mr3K3+x
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIICoDCCAYigAwIBAgIJANk5lu6mSyBGMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEQx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRU
+-ZXN0IFMvTUlNRSBFRSBFQyAjMTBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABL5I
+-iPYVjYOi49G40On1ZWmyp5/ny1XeAjBXQQ5X/HJhPNmG59mL9oFxe6BZHXHvnzHi
+-ce6za4S4QWLcyvcrf7GjYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXg
+-MB0GA1UdDgQWBBR/ybxC2DI+Jydhx1FMgPbMTmLzRzAfBgNVHSMEGDAWgBTJkVMK
+-Y3sWW4u9RPB2iKkk5uW2bDANBgkqhkiG9w0BAQUFAAOCAQEAdk9si83JjtgHHHGy
+-WcgWDfM0jzlWBsgFNQ9DwAuB7gJd/LG+5Ocajg5XdA5FXAdKkfwI6be3PdcVs3Bt
+-7f/fdKfBxfr9/SvFHnK7PVAX2x1wwS4HglX1lfoyq1boSvsiJOnAX3jsqXJ9TJiV
+-FlgRVnhnrw6zz3Xs/9ZDMTENUrqDHPNsDkKEi+9SqIsqDXpMCrGHP4ic+S8Rov1y
+-S+0XioMxVyXDp6XcL4PQ/NgHbw5/+UcS0me0atZ6pW68C0vi6xeU5vxojyuZxMI1
+-DXXwMhOXWaKff7KNhXDUN0g58iWlnyaCz4XQwFsbbFs88TQ1+e/aj3bbwTxUeyN7
+-qtcHJA==
++MIICqzCCAZOgAwIBAgIUZsuXIOmILju0nz1jVSgag5GrPyMwDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MjUyNFoXDTMyMDMz
++MTE0MjUyNFowRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HTAbBgNVBAMMFFRlc3QgUy9NSU1FIEVFIEVDICMxMFkwEwYHKoZIzj0CAQYIKoZI
++zj0DAQcDQgAEvkiI9hWNg6Lj0bjQ6fVlabKnn+fLVd4CMFdBDlf8cmE82Ybn2Yv2
++gXF7oFkdce+fMeJx7rNrhLhBYtzK9yt/saNgMF4wDAYDVR0TAQH/BAIwADAOBgNV
++HQ8BAf8EBAMCBeAwHQYDVR0OBBYEFH/JvELYMj4nJ2HHUUyA9sxOYvNHMB8GA1Ud
++IwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZsMA0GCSqGSIb3DQEBCwUAA4IBAQCp
++sSEupiqT7S6oPS/5qtRF6POyxmhkH/Eh+RJitOODutxneJh+NdDqAQAOCexqcsF9
++1BH9hB/H6b3mS4CbcRG6R/EwzqMPUgy8OYXTrqWI9jzMKGyrBo59QFfGrwP1h8hj
++weVOVQU1iOloWPOfvMHehjX1Wt79/6BMMBvw+2qXXLAw2xpLFa4lU6HSoTiwoS5R
++mimrHnZ9tQZb54bsvdrW84kV3u1FIQ5G7jAduu97Wfr3eZGaJhW1MZLeoL7Z4Usy
++hRd2TJ6bZanb+wUJBcHOeW5ETj9MPtPsGIp8vETmY5XDm4UlX6tp4gAe4oeoIXFQ
++V5ASvNRiGWIJK5XF+zRY
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smec2.pem b/test/smime-certs/smec2.pem
+index 457297a760..7c502d8799 100644
+--- a/test/smime-certs/smec2.pem
++++ b/test/smime-certs/smec2.pem
+@@ -5,19 +5,19 @@ uCzLYF/8j1Scn/spczoC9vNzVhNw+Lg7dnjNL4EDIyYZLl7E0v69luzbvy+q44/8
+ 6bQ=
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIICpTCCAY2gAwIBAgIJANk5lu6mSyBHMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzFaFw0yMzA1MjYxNzI4MzFaMEQx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRU
+-ZXN0IFMvTUlNRSBFRSBFQyAjMjBeMBAGByqGSM49AgEGBSuBBAAQA0oABAXbOzq+
+-huahP4z4/b70tntqy8UE2Lu4LMtgX/yPVJyf+ylzOgL283NWE3D4uDt2eM0vgQMj
+-JhkuXsTS/r2W7Nu/L6rjj/zptKNgMF4wDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8E
+-BAMCBeAwHQYDVR0OBBYEFGf+QSQlkN20PsNN7x+jmQIJBDcXMB8GA1UdIwQYMBaA
+-FMmRUwpjexZbi71E8HaIqSTm5bZsMA0GCSqGSIb3DQEBBQUAA4IBAQBaBBryl2Ez
+-ftBrGENXMKQP3bBEw4n9ely6HvYQi9IC7HyK0ktz7B2FcJ4z96q38JN3cLxV0DhK
+-xT/72pFmQwZVJngvRaol0k1B+bdmM03llxCw/uNNZejixDjHUI9gEfbigehd7QY0
+-uYDu4k4O35/z/XPQ6O5Kzw+J2vdzU8GXlMBbWeZWAmEfLGbk3Ux0ouITnSz0ty5P
+-rkHTo0uprlFcZAsrsNY5v5iuomYT7ZXAR3sqGZL1zPOKBnyfXeNFUfnKsZW7Fnlq
+-IlYBQIjqR1HGxxgCSy66f1oplhxSch4PUpk5tqrs6LeOqc2+xROy1T5YrB3yjVs0
+-4ZdCllHZkhop
++MIICsDCCAZigAwIBAgIUWJSICrM9ZdmN6/jF/PoKng63XR0wDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MjgxOVoXDTMyMDMz
++MTE0MjgxOVowRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HTAbBgNVBAMMFFRlc3QgUy9NSU1FIEVFIEVDICMyMF4wEAYHKoZIzj0CAQYFK4EE
++ABADSgAEBds7Or6G5qE/jPj9vvS2e2rLxQTYu7gsy2Bf/I9UnJ/7KXM6Avbzc1YT
++cPi4O3Z4zS+BAyMmGS5exNL+vZbs278vquOP/Om0o2AwXjAMBgNVHRMBAf8EAjAA
++MA4GA1UdDwEB/wQEAwIF4DAdBgNVHQ4EFgQUZ/5BJCWQ3bQ+w03vH6OZAgkENxcw
++HwYDVR0jBBgwFoAUyZFTCmN7FluLvUTwdoipJObltmwwDQYJKoZIhvcNAQELBQAD
++ggEBACMGL6tuV/1lfrnx7TN/CnWdLEp55AlmzJ3MT9dXSOO1/df/fO3uAiiBNMyQ
++Rcf4vOeBZEk/Xq6GIaAbuuT5ECg50uopEGjUDR9sRWC5yiw2CRQ5ZWTcqMapv+E5
++7/1/tpaVHy+ZkJpbTV6O9gogEPy6uoft+tsel6NFoAj9ulkjuX9TortkVGPTfedd
++oevI32G3z4L4Gv1PCZvFMwEIiAuFDZBbD86gw7rH4BNihRujJRhpnxeRu8zJYB60
++cNeR2N7humdUy5uZnj6YHy3g2j0EDKOITHydIvL1KkSlihQrxEX5kMRr9RWRyFXJ
++/UfNk+5Y3g5Mm642MLvjBEUqurw=
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smec3.pem b/test/smime-certs/smec3.pem
+index 90eac867d0..5110e2984b 100644
+--- a/test/smime-certs/smec3.pem
++++ b/test/smime-certs/smec3.pem
+@@ -4,19 +4,19 @@ zSy+knGorGWZBGG5p//ke0WUSbqhRANCAARH8uHBHkuOfuyXgJj7V3lNqUEPiQNo
+ xG8ntGjVmKRHfywdUoQJ1PgfbkCEsBk334rRFmja1r+MYyqn/A9ARiGB
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIICoDCCAYigAwIBAgIJAPaEOllWs/pjMA0GCSqGSIb3DQEBCwUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xNzA4MTAxNTQyMDhaFw0yNzA2MTkxNTQyMDhaMEQx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRU
+-ZXN0IFMvTUlNRSBFRSBFQyAjMzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABEfy
+-4cEeS45+7JeAmPtXeU2pQQ+JA2jEbye0aNWYpEd/LB1ShAnU+B9uQISwGTffitEW
+-aNrWv4xjKqf8D0BGIYGjYDBeMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgXg
+-MB0GA1UdDgQWBBQLR+H9CmAY/KDyXWdVUM9FP766WzAfBgNVHSMEGDAWgBT3YQTy
+-KJTdSIrnOcPj3pm5oVNtazANBgkqhkiG9w0BAQsFAAOCAQEAmMRuf8Iz5fr9f0GA
+-HaNiOM5S7AIfZ6W7zzdeF63EF1j9HqP1DJsUW4y5b9azWmpp62kKuNaM4CGPUVvm
+-diLKJVlrDcc+6lW9oROpnBsskhjqFMTjTANPQSAKZeKiG2W3U8Q103VQpuYvE4Nj
+-OU9JT+5e4RZS7wxYk/IsvnyF/DkoF1FTMHo9/3Wiw4V4KRhpJIPnqojWNcfipmhM
+-UDpbw0Oyj5fE7x6wvaoOUr8GNJE5NudtV/5QDh9REkjyKUdVYsuUrWwKqn3NT8EI
+-OLl8wx3RqA8htRg/W+SoESx87rvW1saPGvfypBp4cl18B1IzTlC+FMbHFJvZqQn8
+-Ci1l4Q==
++MIICqzCCAZOgAwIBAgIUSG5MT0bOz48OfBayRWfoQwUcA50wDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0Mjg1MloXDTMyMDMz
++MTE0Mjg1MlowRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HTAbBgNVBAMMFFRlc3QgUy9NSU1FIEVFIEVDICMzMFkwEwYHKoZIzj0CAQYIKoZI
++zj0DAQcDQgAER/LhwR5Ljn7sl4CY+1d5TalBD4kDaMRvJ7Ro1ZikR38sHVKECdT4
++H25AhLAZN9+K0RZo2ta/jGMqp/wPQEYhgaNgMF4wDAYDVR0TAQH/BAIwADAOBgNV
++HQ8BAf8EBAMCBeAwHQYDVR0OBBYEFAtH4f0KYBj8oPJdZ1VQz0U/vrpbMB8GA1Ud
++IwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZsMA0GCSqGSIb3DQEBCwUAA4IBAQBY
++xXTNWQz38q37bRjyl6FWMdIaVRkle1Qzjo0bAVHsrYNwY36PBnJpfZE8aJS6WwD2
++PUHWVLc0zd50pXbAa41FlquOdP5FNa8wOc+jHIiyWaE8SEdt0jsxPRTJ9kElXuJ5
++wFx7icmRde7DWLG32SWwR1pFi4R/aDOOxpTzUuYvKuawfAUVQtQyCz8sahbmI8EW
++H0KDuiyuncq1YjvHfaUR7QKijMJ0eBRsjUls0HeMjkehBkTrz78u7TJBWKE/BCiB
++HzuZeMqHpSXtK6ZCRtQXTLv0HyenFmbdVSDiOFSnvdL5lyLT3aFQ19DVtGFCAUwZ
++HQdD3KNn4i073Z7Ia2Xa
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smroot.pem b/test/smime-certs/smroot.pem
+index d1a253f409..f62a54e2a3 100644
+--- a/test/smime-certs/smroot.pem
++++ b/test/smime-certs/smroot.pem
+@@ -27,23 +27,23 @@ vHkSiWpJUvZCuKG8Foh5pm9hU0qb+rbQV7NhLJ02qn1AMGO3F/WKrHPPY8/b9YhQ
+ KfvPCYimQwBjVrEnSntLPR0=
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIIDbjCCAlagAwIBAgIJAMc+8VKBJ/S9MA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MjlaFw0yMzA3MTUxNzI4MjlaMEQx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRU
+-ZXN0IFMvTUlNRSBSU0EgUm9vdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
+-ggEBALLJBcQPkfJVbCqdfLOZjfXvIxQmsh+wq9EQbYLr3V0k0eA2D6irmyO39/OT
+-JLzgC906KJwCxqjhxgsO6W2FoulsLuawQGG/ACKXQU1vmDcRG6l7Uq5N1RXVS4P+
+-LpLZWho1dQEGfWsP1ZwEFzSWfH/ha33Z5BMjr3bmm3tkc9DDY6WntNAMSXKLmo/E
+-J6bi5PSDfNtmxaqaawgxdu74rd0SmvOoDW5wpdvFSZk2QzBWzZcKaUvGtFSPwLf/
+-MQ20fXsdYLOeFH8hVxWSAi6SWR6IOwSFta9RC6ZVdHug+H8I9kBuMaqrmZW54dIe
+-untusFVkodm+hSRrbxAtaK2rVbkCAwEAAaNjMGEwHQYDVR0OBBYEFMmRUwpjexZb
+-i71E8HaIqSTm5bZsMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZsMA8G
+-A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IB
+-AQAwpIVWQey2u/XoQSMSu0jd0EZvU+lhLaFrDy/AHQeG3yX1+SAOM6f6w+efPvyb
+-Op1NPI9UkMPb4PCg9YC7jgYokBkvAcI7J4FcuDKMVhyCD3cljp0ouuKruvEf4FBl
+-zyQ9pLqA97TuG8g1hLTl8G90NzTRcmKpmhs18BmCxiqHcTfoIpb3QvPkDX8R7LVt
+-9BUGgPY+8ELCgw868TuHh/Cnc67gBtRjBp0sCYVzGZmKsO5f1XdHrAZKYN5mEp0C
+-7/OqcDoFqORTquLeycg1At/9GqhDEgxNrqA+YEsPbLGAfsNuXUsXs2ubpGsOZxKt
+-Emsny2ah6fU2z7PztrUy/A80
++MIIDeTCCAmGgAwIBAgIUF/2lFo3fH3uYuFalQVSIFqcYtd4wDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MDE1MloXDTMyMDUy
++MDE0MDE1MlowRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HTAbBgNVBAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MIIBIjANBgkqhkiG9w0BAQEF
++AAOCAQ8AMIIBCgKCAQEAsskFxA+R8lVsKp18s5mN9e8jFCayH7Cr0RBtguvdXSTR
++4DYPqKubI7f385MkvOAL3ToonALGqOHGCw7pbYWi6Wwu5rBAYb8AIpdBTW+YNxEb
++qXtSrk3VFdVLg/4uktlaGjV1AQZ9aw/VnAQXNJZ8f+FrfdnkEyOvduabe2Rz0MNj
++pae00AxJcouaj8QnpuLk9IN822bFqpprCDF27vit3RKa86gNbnCl28VJmTZDMFbN
++lwppS8a0VI/At/8xDbR9ex1gs54UfyFXFZICLpJZHog7BIW1r1ELplV0e6D4fwj2
++QG4xqquZlbnh0h66e26wVWSh2b6FJGtvEC1oratVuQIDAQABo2MwYTAdBgNVHQ4E
++FgQUyZFTCmN7FluLvUTwdoipJObltmwwHwYDVR0jBBgwFoAUyZFTCmN7FluLvUTw
++doipJObltmwwDwYDVR0TAQH/BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAQYwDQYJKoZI
++hvcNAQELBQADggEBAFUbNCqSA5JTIk4wkLiDxs6sGVgSGS/XyFurT5WtyLwR6eiN
++r1Osq3DrF1805xzOjFfk3yYk2ctMMMXVEfXZavfNWgGSyUi6GrS+X1+y5snMpP7Z
++tFlb7iXxiSn5lUE1IS3y9bAlWUwTnOwdX2RuALVAzQ6oAvGIIOhb7FTkMqwsQBDx
++kBA9sgdCKv4d7zgFGdDMh1PGuia7+ZPWS9Nt3+WfRKzy4cf2p8+FTWkv1z7PtCSo
++bZySoXgav6WYGdA0VZY29HzVWC5d/LwSkeJr7pw09UjXBPnrDHbJRa+4JpwwsMT2
++b1E+cp36aagmQW97e8dCf3VzZWcD2bNJ9QM59d8=
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smrsa1.pem b/test/smime-certs/smrsa1.pem
+index d0d0b9e66b..7eb331e2c9 100644
+--- a/test/smime-certs/smrsa1.pem
++++ b/test/smime-certs/smrsa1.pem
+@@ -27,23 +27,23 @@ iCwzDT6AJj63cS3VRO2ait3ZiLdpKdSNNW2WrlZs8FZr/mVutGEcWho8BugGMWST
+ zQpuMJliRlrq/5JkIbH6SA==
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIIDbDCCAlSgAwIBAgIJANk5lu6mSyBAMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzBaFw0yMzA1MjYxNzI4MzBaMEUx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+-ZXN0IFMvTUlNRSBFRSBSU0EgIzEwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+-AoIBAQDXr9uzB/20QXKCxhkfNnJvl2xl1hzdOcrQmAqo+AAAcA/D49ImuJDVQRaK
+-2bcj54XB26i1kXuOrxID3/etUb8yudfx8OAVwh8G0xVA4zhr8uXW85W2tBr4v0Lt
+-+W6lSd6Hmfrk4GmE9LTU/vzl9HUPW6SZShN1G0nY6oeUXvLi0vasEUKv3a51T6JF
+-Yg4c7qt5RCk/w8kwrQ0DorQwCdkOPEIiC4b+nPStF12SVm5bx8rbYzioxuY/PdSe
+-bvt0APeqgRxSpCxqYnHsCoNeHzSrGXcP0COzFeUOz2tdrhmH09JLbGZs4nbojPxM
+-kjpJSv3/ekDG2CHYxXSHXxpJstxZAgMBAAGjYDBeMAwGA1UdEwEB/wQCMAAwDgYD
+-VR0PAQH/BAQDAgXgMB0GA1UdDgQWBBTmjc+lrTQuYx/VBOBGjMvufajvhDAfBgNV
+-HSMEGDAWgBTJkVMKY3sWW4u9RPB2iKkk5uW2bDANBgkqhkiG9w0BAQUFAAOCAQEA
+-dr2IRXcFtlF16kKWs1VTaFIHHNQrfSVHBkhKblPX3f/0s/i3eXgwKUu7Hnb6T3/o
+-E8L+e4ioQNhahTLt9ruJNHWA/QDwOfkqM3tshCs2xOD1Cpy7Bd3Dn0YBrHKyNXRK
+-WelGp+HetSXJGW4IZJP7iES7Um0DGktLabhZbe25EnthRDBjNnaAmcofHECWESZp
+-lEHczGZfS9tRbzOCofxvgLbF64H7wYSyjAe6R8aain0VRbIusiD4tCHX/lOMh9xT
+-GNBW8zTL+tV9H1unjPMORLnT0YQ3oAyEND0jCu0ACA1qGl+rzxhF6bQcTUNEbRMu
+-9Hjq6s316fk4Ne0EUF3PbA==
++MIIDdzCCAl+gAwIBAgIUNrEw2I4NEV0Nbo7AVOF9z4mPBiYwDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MDczN1oXDTMyMDMz
++MTE0MDczN1owRTELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HjAcBgNVBAMMFVRlc3QgUy9NSU1FIEVFIFJTQSAjMTCCASIwDQYJKoZIhvcNAQEB
++BQADggEPADCCAQoCggEBANev27MH/bRBcoLGGR82cm+XbGXWHN05ytCYCqj4AABw
++D8Pj0ia4kNVBForZtyPnhcHbqLWRe46vEgPf961RvzK51/Hw4BXCHwbTFUDjOGvy
++5dbzlba0Gvi/Qu35bqVJ3oeZ+uTgaYT0tNT+/OX0dQ9bpJlKE3UbSdjqh5Re8uLS
++9qwRQq/drnVPokViDhzuq3lEKT/DyTCtDQOitDAJ2Q48QiILhv6c9K0XXZJWblvH
++yttjOKjG5j891J5u+3QA96qBHFKkLGpicewKg14fNKsZdw/QI7MV5Q7Pa12uGYfT
++0ktsZmziduiM/EySOklK/f96QMbYIdjFdIdfGkmy3FkCAwEAAaNgMF4wDAYDVR0T
++AQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFOaNz6WtNC5jH9UE4EaM
++y+59qO+EMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZsMA0GCSqGSIb3
++DQEBCwUAA4IBAQBMz3Ef3U0blTGhfP9HIBq09fWCgUN3aDDLZ/B6biFfWM87wlAm
++CdIuy2jhiEt8Ld8U9y8dbO7c2gzHBGc9FhScBkfQInrbhSctXL/r/wOc0divK9rq
++oXL2cL/CFfzcYPWNN3w6JAJyOhkhWnqF+/0T8+NdiRLE3a9NfX3a83GpfBVccYKQ
++kKKeVIw2K1dYbtlSo1HwOckxqUzN00IPs3xC8U9KNXKy7o0kdetKhk70DzXQ64j0
++EcmXxqPaCkgo3fl9z9nzKlWhg/qIi/1Bd1bpMP8IXAPEURDqhi0KI0w9GPCQRjfY
++7NwXrLEayBoL8TNxcJ3FwdI20+bmhhILBZgO
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smrsa2.pem b/test/smime-certs/smrsa2.pem
+index 2f17cb2978..4262742176 100644
+--- a/test/smime-certs/smrsa2.pem
++++ b/test/smime-certs/smrsa2.pem
+@@ -27,23 +27,23 @@ hT8V87esr/QzLVpjLedQDW8Xb7GiO3BsU/gVC9VcngenbL7JObl3NgvdreIYo6+n
+ yrLyf+8hjm6H6zkjqiOkHAl+
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIIDbDCCAlSgAwIBAgIJANk5lu6mSyBBMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzBaFw0yMzA1MjYxNzI4MzBaMEUx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+-ZXN0IFMvTUlNRSBFRSBSU0EgIzIwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+-AoIBAQDcYC4tS2Uvn1Z2iDgtfkJA5tAqgbN6X4yK02RtVH5xekV9+6+eTt/9S+iF
+-AzAnwqR/UB1R67ETrsWqV8u9xLg5fHIwIkmu9/6P31UU9cghO7J1lcrhHvooHaFp
+-cXepPWQacpuBq2VvcKRDlDfVmdM5z6eS3dSZPTOMMP/xk4nhZB8mcw27qiccPieS
+-0PZ9EZB63T1gmwaK1Rd5U94Pl0+zpDqhViuXmBfiIDWjjz0BzHnHSz5Rg4S3oXF1
+-NcojhptIWyI0r7dgn5J3NxC4kgKdjzysxo6iWd0nLgz7h0jUdj79EOis4fg9G4f0
+-EFWyQf7iDxGaA93Y9ePBJv5iFZVZAgMBAAGjYDBeMAwGA1UdEwEB/wQCMAAwDgYD
+-VR0PAQH/BAQDAgXgMB0GA1UdDgQWBBT0arpyYMHXDPVL7MvzE+lx71L7sjAfBgNV
+-HSMEGDAWgBTJkVMKY3sWW4u9RPB2iKkk5uW2bDANBgkqhkiG9w0BAQUFAAOCAQEA
+-I8nM42am3aImkZyrw8iGkaGhKyi/dfajSWx6B9izBUh+3FleBnUxxOA+mn7M8C47
+-Ne18iaaWK8vEux9KYTIY8BzXQZL1AuZ896cXEc6bGKsME37JSsocfuB5BIGWlYLv
+-/ON5/SJ0iVFj4fAp8z7Vn5qxRJj9BhZDxaO1Raa6cz6pm0imJy9v8y01TI6HsK8c
+-XJQLs7/U4Qb91K+IDNX/lgW3hzWjifNpIpT5JyY3DUgbkD595LFV5DDMZd0UOqcv
+-6cyN42zkX8a0TWr3i5wu7pw4k1oD19RbUyljyleEp0DBauIct4GARdBGgi5y1H2i
+-NzYzLAPBkHCMY0Is3KKIBw==
++MIIDdzCCAl+gAwIBAgIUdWyHziJTdWjooy8SanPMwLxNsPEwDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MDkyNVoXDTMyMDMz
++MTE0MDkyNVowRTELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HjAcBgNVBAMMFVRlc3QgUy9NSU1FIEVFIFJTQSAjMjCCASIwDQYJKoZIhvcNAQEB
++BQADggEPADCCAQoCggEBANxgLi1LZS+fVnaIOC1+QkDm0CqBs3pfjIrTZG1UfnF6
++RX37r55O3/1L6IUDMCfCpH9QHVHrsROuxapXy73EuDl8cjAiSa73/o/fVRT1yCE7
++snWVyuEe+igdoWlxd6k9ZBpym4GrZW9wpEOUN9WZ0znPp5Ld1Jk9M4ww//GTieFk
++HyZzDbuqJxw+J5LQ9n0RkHrdPWCbBorVF3lT3g+XT7OkOqFWK5eYF+IgNaOPPQHM
++ecdLPlGDhLehcXU1yiOGm0hbIjSvt2Cfknc3ELiSAp2PPKzGjqJZ3ScuDPuHSNR2
++Pv0Q6Kzh+D0bh/QQVbJB/uIPEZoD3dj148Em/mIVlVkCAwEAAaNgMF4wDAYDVR0T
++AQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFPRqunJgwdcM9Uvsy/MT
++6XHvUvuyMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZsMA0GCSqGSIb3
++DQEBCwUAA4IBAQBz02v4hd+EjW5NaMubkqPbgUTDRKdRq1RZM+C6m1MTMKy+8zTD
++QSKRCFf0UmSPMsdTArry9x15fmHIJW21F3bw4ISeVXRyzBhOnrGKXUt2Lg9c2MLa
++9C394ex0vw4ZGSNkrIARbM3084Chegs4PLMWLFam1H5J6wpvH8iXXYvhESW98luv
++i3HVQzqLXw7/9XHxf8RnrRcy/WhAA+KegAQMGHTo5KPLliXtypYdCxBHNcmOwJlR
++pSOp6fxhiRKN5DzcBPHOE/brZc4aNGgBHZgGg1g1Wb2lAylopgJrbyNkhEEwHVNM
++1uLCnXKV1nX+EiMKkhSV761ozdhMGljYb+GE
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/smrsa3.pem b/test/smime-certs/smrsa3.pem
+index 14c27f64aa..f7dca3a004 100644
+--- a/test/smime-certs/smrsa3.pem
++++ b/test/smime-certs/smrsa3.pem
+@@ -27,23 +27,23 @@ yzYMXLmervN7c1jJe2Y2MYv6hE+Ypj1xGW4w7s8WNKmVzLv97beisD9AZrS7sXfF
+ RvOAi5wVkYylDxV4238MAZIq
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+-MIIDbDCCAlSgAwIBAgIJANk5lu6mSyBCMA0GCSqGSIb3DQEBBQUAMEQxCzAJBgNV
+-BAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR0wGwYDVQQDDBRUZXN0IFMv
+-TUlNRSBSU0EgUm9vdDAeFw0xMzA3MTcxNzI4MzBaFw0yMzA1MjYxNzI4MzBaMEUx
+-CzAJBgNVBAYTAlVLMRYwFAYDVQQKDA1PcGVuU1NMIEdyb3VwMR4wHAYDVQQDDBVU
+-ZXN0IFMvTUlNRSBFRSBSU0EgIzMwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
+-AoIBAQCyK+BTAOJKJjjiOhY60NeZjzGGZxEBfCm62n0mwkzusW/V/e63uwj6uOVC
+-FoVBz5doMf3M6QIS2jL3Aw6Qs5+vcuLA0gHrqIwjYQz1UZ5ETLKLKbQw6YOIVfsF
+-STxytUVpfcByrubWiLKX63theG1/IVokDK/9/k52Kyt+wcCjuRb7AJQFj2OLDRuW
+-m/gavozkK103gQ+dUq4HXamZMtTq1EhQOfc0IUeCOEL6xz4jzlHHfzLdkvb7Enha
+-v2sXDfOmZp/DYf9IqS7lvFkkINPVbYFBTexaPZlFwmpGRjkmoyH/w+Jlcpzs+w6p
+-1diWRpaSn62bbkRN49j6L2dVb+DfAgMBAAGjYDBeMAwGA1UdEwEB/wQCMAAwDgYD
+-VR0PAQH/BAQDAgXgMB0GA1UdDgQWBBQ6CkW5sa6HrBsWvuPOvMjyL5AnsDAfBgNV
+-HSMEGDAWgBTJkVMKY3sWW4u9RPB2iKkk5uW2bDANBgkqhkiG9w0BAQUFAAOCAQEA
+-JhcrD7AKafVzlncA3cZ6epAruj1xwcfiE+EbuAaeWEGjoSltmevcjgoIxvijRVcp
+-sCbNmHJZ/siQlqzWjjf3yoERvLDqngJZZpQeocMIbLRQf4wgLAuiBcvT52wTE+sa
+-VexeETDy5J1OW3wE4A3rkdBp6hLaymlijFNnd5z/bP6w3AcIMWm45yPm0skM8RVr
+-O3UstEFYD/iy+p+Y/YZDoxYQSW5Vl+NkpGmc5bzet8gQz4JeXtH3z5zUGoDM4XK7
+-tXP3yUi2eecCbyjh/wgaQiVdylr1Kv3mxXcTl+cFO22asDkh0R/y72nTCu5fSILY
+-CscFo2Z2pYROGtZDmYqhRw==
++MIIDdzCCAl+gAwIBAgIUAKvI4FWjFLx8iBGifOW3mG/xkT0wDQYJKoZIhvcNAQEL
++BQAwRDELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAxHTAbBgNV
++BAMMFFRlc3QgUy9NSU1FIFJTQSBSb290MB4XDTIyMDUyMzE0MTEwNloXDTMyMDMz
++MTE0MTEwNlowRTELMAkGA1UEBhMCVUsxFjAUBgNVBAoMDU9wZW5TU0wgR3JvdXAx
++HjAcBgNVBAMMFVRlc3QgUy9NSU1FIEVFIFJTQSAjMzCCASIwDQYJKoZIhvcNAQEB
++BQADggEPADCCAQoCggEBALIr4FMA4komOOI6FjrQ15mPMYZnEQF8KbrafSbCTO6x
++b9X97re7CPq45UIWhUHPl2gx/czpAhLaMvcDDpCzn69y4sDSAeuojCNhDPVRnkRM
++sosptDDpg4hV+wVJPHK1RWl9wHKu5taIspfre2F4bX8hWiQMr/3+TnYrK37BwKO5
++FvsAlAWPY4sNG5ab+Bq+jOQrXTeBD51SrgddqZky1OrUSFA59zQhR4I4QvrHPiPO
++Ucd/Mt2S9vsSeFq/axcN86Zmn8Nh/0ipLuW8WSQg09VtgUFN7Fo9mUXCakZGOSaj
++If/D4mVynOz7DqnV2JZGlpKfrZtuRE3j2PovZ1Vv4N8CAwEAAaNgMF4wDAYDVR0T
++AQH/BAIwADAOBgNVHQ8BAf8EBAMCBeAwHQYDVR0OBBYEFDoKRbmxroesGxa+4868
++yPIvkCewMB8GA1UdIwQYMBaAFMmRUwpjexZbi71E8HaIqSTm5bZsMA0GCSqGSIb3
++DQEBCwUAA4IBAQBfCCzWyZzIvq/ci6E74ovJ8mMel5Z9MU9EcvY0k7pJSUbpCg3c
++P48CiAzt8r8Em4AymADfK1pYvvpTNVpU/USbdKR1hyxZjqWrYdsY7tlVuvZ92oFs
++s3komuKHCx2SQAe5b+LWjC1Bf8JUFx+XTjYb/BBg7nQRwi3TkYVVmW7hXLYvf4Jn
++Uyu0x02pDzUu+62jeYbNIVJnYwSU0gLHEo81QmNs06RLjnAhbneUZ6P6YuJOdDo7
++xMw/ywijZM0FxsWxRSsCBwavhabg1Kb1lO//pbgcSa9T0D7ax1XoMni3RJnHj6gu
++r0Mi3QjgZaxghR3TPh83dQLilECYDuD0uTzf
+ -----END CERTIFICATE-----
+-- 
+2.35.3
+
diff --git a/SOURCES/0062-fips-Expose-a-FIPS-indicator.patch b/SOURCES/0062-fips-Expose-a-FIPS-indicator.patch
new file mode 100644
index 0000000..6d368d8
--- /dev/null
+++ b/SOURCES/0062-fips-Expose-a-FIPS-indicator.patch
@@ -0,0 +1,466 @@
+From e3d6fca1af033d00c47bcd8f9ba28fcf1aa476aa Mon Sep 17 00:00:00 2001
+From: Clemens Lang <cllang@redhat.com>
+Date: Tue, 7 Jun 2022 12:02:49 +0200
+Subject: [PATCH] fips: Expose a FIPS indicator
+
+FIPS 140-3 requires us to indicate whether an operation was using
+approved services or not. The FIPS 140-3 implementation guidelines
+provide two basic approaches to doing this: implicit indicators, and
+explicit indicators.
+
+Implicit indicators are basically the concept of "if the operation
+passes, it was approved". We were originally aiming for implicit
+indicators in our copy of OpenSSL. However, this proved to be a problem,
+because we wanted to certify a signature service, and FIPS 140-3
+requires that a signature service computes the digest to be signed
+within the boundaries of the FIPS module. Since we were planning to
+certify fips.so only, this means that EVP_PKEY_sign/EVP_PKEY_verify
+would have to be blocked. Unfortunately, EVP_SignFinal uses
+EVP_PKEY_sign internally, but outside of fips.so and thus outside of the
+FIPS module boundary. This means that using implicit indicators in
+combination with certifying only fips.so would require us to block both
+EVP_PKEY_sign and EVP_SignFinal, which are the two APIs currently used
+by most users of OpenSSL for signatures.
+
+EVP_DigestSign would be acceptable, but has only been added in 3.0 and
+is thus not yet widely used.
+
+As a consequence, we've decided to introduce explicit indicators so that
+EVP_PKEY_sign and EVP_SignFinal can continue to work for now, but
+FIPS-aware applications can query the explicit indicator to check
+whether the operation was approved.
+
+To avoid affecting the ABI and public API too much, this is implemented
+as an exported symbol in fips.so and a private header, so applications
+that wish to use this will have to dlopen(3) fips.so, locate the
+function using dlsym(3), and then call it. These applications will have
+to build against the private header in order to use the returned
+pointer.
+
+Modify util/mkdef.pl to support exposing a symbol only for a specific
+provider identified by its name and path.
+
+Signed-off-by: Clemens Lang <cllang@redhat.com>
+---
+ doc/build.info                      |   6 ++
+ doc/man7/fips_module_indicators.pod | 154 ++++++++++++++++++++++++++++
+ providers/fips/fipsprov.c           |  71 +++++++++++++
+ providers/fips/indicator.h          |  66 ++++++++++++
+ util/mkdef.pl                       |  25 ++++-
+ util/providers.num                  |   1 +
+ 6 files changed, 322 insertions(+), 1 deletion(-)
+ create mode 100644 doc/man7/fips_module_indicators.pod
+ create mode 100644 providers/fips/indicator.h
+
+diff --git a/doc/build.info b/doc/build.info
+index b0aa4297a4..af235113bb 100644
+--- a/doc/build.info
++++ b/doc/build.info
+@@ -4389,6 +4389,10 @@ DEPEND[html/man7/fips_module.html]=man7/fips_module.pod
+ GENERATE[html/man7/fips_module.html]=man7/fips_module.pod
+ DEPEND[man/man7/fips_module.7]=man7/fips_module.pod
+ GENERATE[man/man7/fips_module.7]=man7/fips_module.pod
++DEPEND[html/man7/fips_module_indicators.html]=man7/fips_module_indicators.pod
++GENERATE[html/man7/fips_module_indicators.html]=man7/fips_module_indicators.pod
++DEPEND[man/man7/fips_module_indicators.7]=man7/fips_module_indicators.pod
++GENERATE[man/man7/fips_module_indicators.7]=man7/fips_module_indicators.pod
+ DEPEND[html/man7/life_cycle-cipher.html]=man7/life_cycle-cipher.pod
+ GENERATE[html/man7/life_cycle-cipher.html]=man7/life_cycle-cipher.pod
+ DEPEND[man/man7/life_cycle-cipher.7]=man7/life_cycle-cipher.pod
+@@ -4631,6 +4635,7 @@ html/man7/ct.html \
+ html/man7/des_modes.html \
+ html/man7/evp.html \
+ html/man7/fips_module.html \
++html/man7/fips_module_indicators.html \
+ html/man7/life_cycle-cipher.html \
+ html/man7/life_cycle-digest.html \
+ html/man7/life_cycle-kdf.html \
+@@ -4754,6 +4759,7 @@ man/man7/ct.7 \
+ man/man7/des_modes.7 \
+ man/man7/evp.7 \
+ man/man7/fips_module.7 \
++man/man7/fips_module_indicators.7 \
+ man/man7/life_cycle-cipher.7 \
+ man/man7/life_cycle-digest.7 \
+ man/man7/life_cycle-kdf.7 \
+diff --git a/doc/man7/fips_module_indicators.pod b/doc/man7/fips_module_indicators.pod
+new file mode 100644
+index 0000000000..23db2b395c
+--- /dev/null
++++ b/doc/man7/fips_module_indicators.pod
+@@ -0,0 +1,154 @@
++=pod
++
++=head1 NAME
++
++fips_module_indicators - Red Hat OpenSSL FIPS module indicators guide
++
++=head1 DESCRIPTION
++
++This guide documents how the Red Hat Enterprise Linux 9 OpenSSL FIPS provider
++implements Approved Security Service Indicators according to the FIPS 140-3
++Implementation Guidelines, section 2.4.C. See
++L<https://csrc.nist.gov/CSRC/media/Projects/cryptographic-module-validation-program/documents/fips%20140-3/FIPS%20140-3%20IG.pdf>
++for the FIPS 140-3 Implementation Guidelines.
++
++For all approved services except signatures, the Red Hat OpenSSL FIPS provider
++uses the return code as the indicator as understood by FIPS 140-3. That means
++that every operation that succeeds denotes use of an approved security service.
++Operations that do not succeed may not have been approved security services, or
++may have been used incorrectly.
++
++For signatures, an explicit indicator API is available to determine whether
++a selected operation is an approved security service, in combination with the
++return code of the operation. For a signature operation to be approved, the
++explicit indicator must claim it as approved, and it must succeed.
++
++=head2 Querying the explicit indicator
++
++The Red Hat OpenSSL FIPS provider exports a symbol named
++I<redhat_ossl_query_fipsindicator> that provides information on which signature
++operations are approved security functions. To use this function, either link
++against I<fips.so> directly, or load it at runtime using dlopen(3) and
++dlsym(3).
++
++    #include <openssl/core_dispatch.h>
++    #include "providers/fips/indicator.h"
++
++    void *provider = dlopen("/usr/lib64/ossl-modules/fips.so", RTLD_LAZY);
++    if (provider == NULL) {
++        fprintf(stderr, "%s\n", dlerror());
++        // handle error
++    }
++
++    const OSSL_RH_FIPSINDICATOR_ALORITHM *(*redhat_ossl_query_fipsindicator)(int) \
++        = dlsym(provider, "redhat_ossl_query_fipsindicator");
++    if (redhat_ossl_query_fipsindicator == NULL) {
++        fprintf(stderr, "%s\n", dlerror());
++        fprintf(stderr, "Does your copy of fips.so have the required Red Hat"
++                        " patches?\n");
++        // handle error
++    }
++
++Note that this uses the I<providers/fips/indicator.h> header, which is not
++public. Install the I<openssl-debugsource> package from the I<BaseOS-debuginfo>
++repository using I<dnf debuginfo-install openssl> and include
++I</usr/src/debug/openssl-3.*/> in the compiler's include path.
++
++I<redhat_ossl_query_fipsindicator> expects an operation ID as its only
++argument. Currently, the only supported operation ID is I<OSSL_OP_SIGNATURE> to
++obtain the indicators for signature operations. On success, the return value is
++a pointer to an array of I<OSSL_RH_FIPSINDICATOR_STRUCT>s. On failure, NULL is
++returned. The last entry in the array is indicated by I<algorithm_names> being
++NULL.
++
++    typedef struct ossl_rh_fipsindicator_algorithm_st {
++        const char *algorithm_names;     /* key */
++        const char *property_definition; /* key */
++        const OSSL_RH_FIPSINDICATOR_DISPATCH *indicators;
++    } OSSL_RH_FIPSINDICATOR_ALGORITHM;
++
++    typedef struct ossl_rh_fipsindicator_dispatch_st {
++        int function_id;
++        int approved;
++    } OSSL_RH_FIPSINDICATOR_DISPATCH;
++
++The I<algorithm_names> field is a colon-separated list of algorithm names from
++one of the I<PROV_NAMES_...> constants, e.g., I<PROV_NAMES_RSA>. strtok(3) can
++be used to locate the appropriate entry. See the example below, where
++I<algorithm> contains the algorithm name to search for:
++
++    const OSSL_RH_FIPSINDICATOR_DISPATCH *indicator_dispatch = NULL;
++    const OSSL_RH_FIPSINDICATOR_ALGORITHM *indicator =
++        redhat_ossl_query_fipsindicator(operation_id);
++    if (indicator == NULL) {
++        fprintf(stderr, "No indicator for operation, probably using implicit"
++                        " indicators.\n");
++        // handle error
++    }
++
++    for (; indicator->algorithm_names != NULL; ++indicator) {
++        char *algorithm_names = strdup(indicator->algorithm_names);
++        if (algorithm_names == NULL) {
++            perror("strdup(3)");
++            // handle error
++        }
++
++        const char *algorithm_name = strtok(algorithm_names, ":");
++        for (; algorithm_name != NULL; algorithm_name = strtok(NULL, ":")) {
++            if (strcasecmp(algorithm_name, algorithm) == 0) {
++                indicator_dispatch = indicator->indicators;
++                free(algorithm_names);
++                algorithm_names = NULL;
++                break;
++            }
++        }
++        free(algorithm_names);
++    }
++    if (indicator_dispatch == NULL) {
++        fprintf(stderr, "No indicator for algorithm %s.\n", algorithm);
++        // handle error
++    }
++
++If an appropriate I<OSSL_RH_FIPSINDICATOR_DISPATCH> array is available for the
++given algorithm name, it maps function IDs to their approval status. The last
++entry is indicated by a zero I<function_id>. I<approved> is
++I<OSSL_RH_FIPSINDICATOR_APPROVED> if the operation is an approved security
++service, or part of an approved security service, or
++I<OSSL_RH_FIPSINDICATOR_UNAPPROVED> otherwise. Any other value is invalid.
++Function IDs are I<OSSL_FUNC_*> constants from I<openssl/core_dispatch.h>,
++e.g., I<OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE> or I<OSSL_FUNC_SIGNATURE_SIGN>.
++
++Assuming I<function_id> is the function in question, the following code can be
++used to query the approval status:
++
++    for (; indicator_dispatch->function_id != 0; ++indicator_dispatch) {
++        if (indicator_dispatch->function_id == function_id) {
++            switch (indicator_dispatch->approved) {
++                case OSSL_RH_FIPSINDICATOR_APPROVED:
++                    // approved security service
++                    break;
++                case OSSL_RH_FIPSINDICATOR_UNAPPROVED:
++                    // unapproved security service
++                    break;
++                default:
++                    // invalid result
++                    break;
++            }
++            break;
++        }
++    }
++
++=head1 SEE ALSO
++
++L<fips_module(7)>, L<provider(7)>
++
++=head1 COPYRIGHT
++
++Copyright 2022 Red Hat, Inc. 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
+diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
+index de391ce067..1cfd71c5cf 100644
+--- a/providers/fips/fipsprov.c
++++ b/providers/fips/fipsprov.c
+@@ -23,6 +23,7 @@
+ #include "prov/seeding.h"
+ #include "self_test.h"
+ #include "internal/core.h"
++#include "indicator.h"
+ 
+ static const char FIPS_DEFAULT_PROPERTIES[] = "provider=fips,fips=yes";
+ static const char FIPS_UNAPPROVED_PROPERTIES[] = "provider=fips,fips=no";
+@@ -425,6 +426,68 @@ static const OSSL_ALGORITHM fips_signature[] = {
+     { NULL, NULL, NULL }
+ };
+ 
++static const OSSL_RH_FIPSINDICATOR_DISPATCH redhat_rsa_signature_indicators[] = {
++    { OSSL_FUNC_SIGNATURE_NEWCTX, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SIGN_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_SIGN, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_VERIFY_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_VERIFY, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_VERIFY_RECOVER, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_FREECTX, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DUPCTX, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { 0, OSSL_RH_FIPSINDICATOR_UNAPPROVED }
++};
++
++static const OSSL_RH_FIPSINDICATOR_DISPATCH redhat_ecdsa_signature_indicators[] = {
++    { OSSL_FUNC_SIGNATURE_NEWCTX, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SIGN_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_SIGN, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_VERIFY_INIT, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_VERIFY, OSSL_RH_FIPSINDICATOR_UNAPPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_INIT, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_UPDATE, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_INIT, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_UPDATE, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DIGEST_VERIFY_FINAL, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_FREECTX, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_DUPCTX, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_GET_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SET_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_GET_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_GETTABLE_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SET_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { OSSL_FUNC_SIGNATURE_SETTABLE_CTX_MD_PARAMS, OSSL_RH_FIPSINDICATOR_APPROVED },
++    { 0, OSSL_RH_FIPSINDICATOR_UNAPPROVED }
++};
++
++static const OSSL_RH_FIPSINDICATOR_ALGORITHM redhat_indicator_fips_signature[] = {
++    { PROV_NAMES_RSA, FIPS_DEFAULT_PROPERTIES,
++        redhat_rsa_signature_indicators },
++#ifndef OPENSSL_NO_EC
++    { PROV_NAMES_ECDSA, FIPS_DEFAULT_PROPERTIES,
++        redhat_ecdsa_signature_indicators },
++#endif
++    { NULL, NULL, NULL }
++};
++
+ static const OSSL_ALGORITHM fips_asym_cipher[] = {
+     { PROV_NAMES_RSA, FIPS_DEFAULT_PROPERTIES, ossl_rsa_asym_cipher_functions },
+     { NULL, NULL, NULL }
+@@ -527,6 +590,14 @@ static void fips_deinit_casecmp(void) {
+     freelocale(loc);
+ }
+ 
++const OSSL_RH_FIPSINDICATOR_ALGORITHM *redhat_ossl_query_fipsindicator(int operation_id) {
++    switch (operation_id) {
++    case OSSL_OP_SIGNATURE:
++        return redhat_indicator_fips_signature;
++    }
++    return NULL;
++}
++
+ static void fips_teardown(void *provctx)
+ {
+     OSSL_LIB_CTX_free(PROV_LIBCTX_OF(provctx));
+diff --git a/providers/fips/indicator.h b/providers/fips/indicator.h
+new file mode 100644
+index 0000000000..b323efe44c
+--- /dev/null
++++ b/providers/fips/indicator.h
+@@ -0,0 +1,66 @@
++/*
++ * Copyright 2019-2021 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_INDICATOR_H
++# define OPENSSL_FIPS_INDICATOR_H
++# pragma once
++
++# ifdef __cplusplus
++extern "C" {
++# endif
++
++# define OSSL_RH_FIPSINDICATOR_UNAPPROVED (0)
++# define OSSL_RH_FIPSINDICATOR_APPROVED (1)
++
++/*
++ * FIPS indicator dispatch table element.  function_id numbers and the
++ * functions are defined in core_dispatch.h, see macros with
++ * 'OSSL_CORE_MAKE_FUNC' in their names.
++ *
++ * An array of these is always terminated by function_id == 0
++ */
++typedef struct ossl_rh_fipsindicator_dispatch_st {
++    int function_id;
++    int approved;
++} OSSL_RH_FIPSINDICATOR_DISPATCH;
++
++/*
++ * Type to tie together algorithm names, property definition string and the
++ * algorithm implementation's FIPS indicator status in the form of a FIPS
++ * indicator dispatch table.
++ *
++ * An array of these is always terminated by algorithm_names == NULL
++ */
++typedef struct ossl_rh_fipsindicator_algorithm_st {
++    const char *algorithm_names;     /* key */
++    const char *property_definition; /* key */
++    const OSSL_RH_FIPSINDICATOR_DISPATCH *indicators;
++} OSSL_RH_FIPSINDICATOR_ALGORITHM;
++
++/**
++ * Query FIPS indicator status for the given operation.  Possible values for
++ * 'operation_id' are currently only OSSL_OP_SIGNATURE, as all other algorithms
++ * use implicit indicators.  The return value is an array of
++ * OSSL_RH_FIPSINDICATOR_ALGORITHMs, terminated by an entry with
++ * algorithm_names == NULL.  'algorithm_names' is a colon-separated list of
++ * algorithm names, 'property_definition' a comma-separated list of properties,
++ * and 'indicators' is a list of OSSL_RH_FIPSINDICATOR_DISPATCH structs.  This
++ * list is terminated by function_id == 0.  'function_id' is one of the
++ * OSSL_FUNC_* constants, e.g., OSSL_FUNC_SIGNATURE_DIGEST_SIGN_FINAL.
++ *
++ * If there is no entry in the returned struct for the given operation_id,
++ * algorithm name, or function_id, the algorithm is unapproved.
++ */
++const OSSL_RH_FIPSINDICATOR_ALGORITHM *redhat_ossl_query_fipsindicator(int operation_id);
++
++# ifdef __cplusplus
++}
++# endif
++
++#endif
+diff --git a/util/mkdef.pl b/util/mkdef.pl
+index a1c76f7c97..eda39b71ee 100755
+--- a/util/mkdef.pl
++++ b/util/mkdef.pl
+@@ -149,7 +149,8 @@ $ordinal_opts{filter} =
+         return
+             $item->exists()
+             && platform_filter($item)
+-            && feature_filter($item);
++            && feature_filter($item)
++            && fips_filter($item, $name);
+     };
+ my $ordinals = OpenSSL::Ordinals->new(from => $ordinals_file);
+ 
+@@ -205,6 +206,28 @@ sub feature_filter {
+     return $verdict;
+ }
+ 
++sub fips_filter {
++    my $item = shift;
++    my $name = uc(shift);
++    my @features = ( $item->features() );
++
++    # True if no features are defined
++    return 1 if scalar @features == 0;
++
++    my @matches = grep(/^ONLY_.*$/, @features);
++    if (@matches) {
++        # There is at least one only_* flag on this symbol, check if any of
++        # them match the name
++        for (@matches) {
++            if ($_ eq "ONLY_${name}") {
++                return 1;
++            }
++        }
++        return 0;
++    }
++    return 1;
++}
++
+ sub sorter_unix {
+     my $by_name = OpenSSL::Ordinals::by_name();
+     my %weight = (
+diff --git a/util/providers.num b/util/providers.num
+index 4e2fa81b98..77879d0e5f 100644
+--- a/util/providers.num
++++ b/util/providers.num
+@@ -1 +1,2 @@
+ OSSL_provider_init                     1	*	EXIST::FUNCTION:
++redhat_ossl_query_fipsindicator        1	*	EXIST::FUNCTION:ONLY_PROVIDERS/FIPS
+-- 
+2.35.3
+
diff --git a/SOURCES/0063-CVE-2022-1473.patch b/SOURCES/0063-CVE-2022-1473.patch
new file mode 100644
index 0000000..b4b12dc
--- /dev/null
+++ b/SOURCES/0063-CVE-2022-1473.patch
@@ -0,0 +1,13 @@
+diff --git a/crypto/lhash/lhash.c b/crypto/lhash/lhash.c
+index 2a574fbfe6aa..16f482db68a9 100644
+--- a/crypto/lhash/lhash.c
++++ b/crypto/lhash/lhash.c
+@@ -100,6 +100,8 @@ void OPENSSL_LH_flush(OPENSSL_LHASH *lh)
+         }
+         lh->b[i] = NULL;
+     }
++
++    lh->num_items = 0;
+ }
+ 
+ void *OPENSSL_LH_insert(OPENSSL_LHASH *lh, void *data)
diff --git a/SOURCES/0064-CVE-2022-1343.diff b/SOURCES/0064-CVE-2022-1343.diff
new file mode 100644
index 0000000..d473597
--- /dev/null
+++ b/SOURCES/0064-CVE-2022-1343.diff
@@ -0,0 +1,263 @@
+diff --git a/crypto/ocsp/ocsp_vfy.c b/crypto/ocsp/ocsp_vfy.c
+index 7a4a45d537..3c5f48ec0a 100644
+--- a/crypto/ocsp/ocsp_vfy.c
++++ b/crypto/ocsp/ocsp_vfy.c
+@@ -59,9 +59,10 @@ static int ocsp_verify_signer(X509 *signer, int response,
+ 
+     ret = X509_verify_cert(ctx);
+     if (ret <= 0) {
+-        ret = X509_STORE_CTX_get_error(ctx);
++        int err = X509_STORE_CTX_get_error(ctx);
++
+         ERR_raise_data(ERR_LIB_OCSP, OCSP_R_CERTIFICATE_VERIFY_ERROR,
+-                       "Verify error: %s", X509_verify_cert_error_string(ret));
++                       "Verify error: %s", X509_verify_cert_error_string(err));
+         goto end;
+     }
+     if (chain != NULL)
+diff --git a/test/recipes/80-test_ocsp.t b/test/recipes/80-test_ocsp.t
+index d42030cb89..34fdfcbccc 100644
+--- a/test/recipes/80-test_ocsp.t
++++ b/test/recipes/80-test_ocsp.t
+@@ -35,6 +35,7 @@ sub test_ocsp {
+         $untrusted = $CAfile;
+     }
+     my $expected_exit = shift;
++    my $nochecks = shift;
+     my $outputfile = basename($inputfile, '.ors') . '.dat';
+ 
+     run(app(["openssl", "base64", "-d",
+@@ -45,7 +46,8 @@ sub test_ocsp {
+                            "-partial_chain", @check_time,
+                            "-CAfile", catfile($ocspdir, $CAfile),
+                            "-verify_other", catfile($ocspdir, $untrusted),
+-                           "-no-CApath", "-no-CAstore"])),
++                           "-no-CApath", "-no-CAstore",
++                           $nochecks ? "-no_cert_checks" : ()])),
+                   $title); });
+ }
+ 
+@@ -55,143 +57,149 @@ subtest "=== VALID OCSP RESPONSES ===" => sub {
+     plan tests => 7;
+ 
+     test_ocsp("NON-DELEGATED; Intermediate CA -> EE",
+-              "ND1.ors", "ND1_Issuer_ICA.pem", "", 0);
++              "ND1.ors", "ND1_Issuer_ICA.pem", "", 0, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> Intermediate CA",
+-              "ND2.ors", "ND2_Issuer_Root.pem", "", 0);
++              "ND2.ors", "ND2_Issuer_Root.pem", "", 0, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> EE",
+-              "ND3.ors", "ND3_Issuer_Root.pem", "", 0);
++              "ND3.ors", "ND3_Issuer_Root.pem", "", 0, 0);
+     test_ocsp("NON-DELEGATED; 3-level CA hierarchy",
+-              "ND1.ors", "ND1_Cross_Root.pem", "ND1_Issuer_ICA-Cross.pem", 0);
++              "ND1.ors", "ND1_Cross_Root.pem", "ND1_Issuer_ICA-Cross.pem", 0, 0);
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "D1.ors", "D1_Issuer_ICA.pem", "", 0);
++              "D1.ors", "D1_Issuer_ICA.pem", "", 0, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "D2.ors", "D2_Issuer_Root.pem", "", 0);
++              "D2.ors", "D2_Issuer_Root.pem", "", 0, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "D3.ors", "D3_Issuer_Root.pem", "", 0);
++              "D3.ors", "D3_Issuer_Root.pem", "", 0, 0);
+ };
+ 
+ subtest "=== INVALID SIGNATURE on the OCSP RESPONSE ===" => sub {
+     plan tests => 6;
+ 
+     test_ocsp("NON-DELEGATED; Intermediate CA -> EE",
+-              "ISOP_ND1.ors", "ND1_Issuer_ICA.pem", "", 1);
++              "ISOP_ND1.ors", "ND1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> Intermediate CA",
+-              "ISOP_ND2.ors", "ND2_Issuer_Root.pem", "", 1);
++              "ISOP_ND2.ors", "ND2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> EE",
+-              "ISOP_ND3.ors", "ND3_Issuer_Root.pem", "", 1);
++              "ISOP_ND3.ors", "ND3_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "ISOP_D1.ors", "D1_Issuer_ICA.pem", "", 1);
++              "ISOP_D1.ors", "D1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "ISOP_D2.ors", "D2_Issuer_Root.pem", "", 1);
++              "ISOP_D2.ors", "D2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "ISOP_D3.ors", "D3_Issuer_Root.pem", "", 1);
++              "ISOP_D3.ors", "D3_Issuer_Root.pem", "", 1, 0);
+ };
+ 
+ subtest "=== WRONG RESPONDERID in the OCSP RESPONSE ===" => sub {
+     plan tests => 6;
+ 
+     test_ocsp("NON-DELEGATED; Intermediate CA -> EE",
+-              "WRID_ND1.ors", "ND1_Issuer_ICA.pem", "", 1);
++              "WRID_ND1.ors", "ND1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> Intermediate CA",
+-              "WRID_ND2.ors", "ND2_Issuer_Root.pem", "", 1);
++              "WRID_ND2.ors", "ND2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> EE",
+-              "WRID_ND3.ors", "ND3_Issuer_Root.pem", "", 1);
++              "WRID_ND3.ors", "ND3_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "WRID_D1.ors", "D1_Issuer_ICA.pem", "", 1);
++              "WRID_D1.ors", "D1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "WRID_D2.ors", "D2_Issuer_Root.pem", "", 1);
++              "WRID_D2.ors", "D2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "WRID_D3.ors", "D3_Issuer_Root.pem", "", 1);
++              "WRID_D3.ors", "D3_Issuer_Root.pem", "", 1, 0);
+ };
+ 
+ subtest "=== WRONG ISSUERNAMEHASH in the OCSP RESPONSE ===" => sub {
+     plan tests => 6;
+ 
+     test_ocsp("NON-DELEGATED; Intermediate CA -> EE",
+-              "WINH_ND1.ors", "ND1_Issuer_ICA.pem", "", 1);
++              "WINH_ND1.ors", "ND1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> Intermediate CA",
+-              "WINH_ND2.ors", "ND2_Issuer_Root.pem", "", 1);
++              "WINH_ND2.ors", "ND2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> EE",
+-              "WINH_ND3.ors", "ND3_Issuer_Root.pem", "", 1);
++              "WINH_ND3.ors", "ND3_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "WINH_D1.ors", "D1_Issuer_ICA.pem", "", 1);
++              "WINH_D1.ors", "D1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "WINH_D2.ors", "D2_Issuer_Root.pem", "", 1);
++              "WINH_D2.ors", "D2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "WINH_D3.ors", "D3_Issuer_Root.pem", "", 1);
++              "WINH_D3.ors", "D3_Issuer_Root.pem", "", 1, 0);
+ };
+ 
+ subtest "=== WRONG ISSUERKEYHASH in the OCSP RESPONSE ===" => sub {
+     plan tests => 6;
+ 
+     test_ocsp("NON-DELEGATED; Intermediate CA -> EE",
+-              "WIKH_ND1.ors", "ND1_Issuer_ICA.pem", "", 1);
++              "WIKH_ND1.ors", "ND1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> Intermediate CA",
+-              "WIKH_ND2.ors", "ND2_Issuer_Root.pem", "", 1);
++              "WIKH_ND2.ors", "ND2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> EE",
+-              "WIKH_ND3.ors", "ND3_Issuer_Root.pem", "", 1);
++              "WIKH_ND3.ors", "ND3_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "WIKH_D1.ors", "D1_Issuer_ICA.pem", "", 1);
++              "WIKH_D1.ors", "D1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "WIKH_D2.ors", "D2_Issuer_Root.pem", "", 1);
++              "WIKH_D2.ors", "D2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "WIKH_D3.ors", "D3_Issuer_Root.pem", "", 1);
++              "WIKH_D3.ors", "D3_Issuer_Root.pem", "", 1, 0);
+ };
+ 
+ subtest "=== WRONG KEY in the DELEGATED OCSP SIGNING CERTIFICATE ===" => sub {
+     plan tests => 3;
+ 
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "WKDOSC_D1.ors", "D1_Issuer_ICA.pem", "", 1);
++              "WKDOSC_D1.ors", "D1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "WKDOSC_D2.ors", "D2_Issuer_Root.pem", "", 1);
++              "WKDOSC_D2.ors", "D2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "WKDOSC_D3.ors", "D3_Issuer_Root.pem", "", 1);
++              "WKDOSC_D3.ors", "D3_Issuer_Root.pem", "", 1, 0);
+ };
+ 
+ subtest "=== INVALID SIGNATURE on the DELEGATED OCSP SIGNING CERTIFICATE ===" => sub {
+-    plan tests => 3;
++    plan tests => 6;
+ 
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "ISDOSC_D1.ors", "D1_Issuer_ICA.pem", "", 1);
++              "ISDOSC_D1.ors", "D1_Issuer_ICA.pem", "", 1, 0);
++    test_ocsp("DELEGATED; Root CA -> Intermediate CA",
++              "ISDOSC_D2.ors", "D2_Issuer_Root.pem", "", 1, 0);
++    test_ocsp("DELEGATED; Root CA -> EE",
++              "ISDOSC_D3.ors", "D3_Issuer_Root.pem", "", 1, 0);
++    test_ocsp("DELEGATED; Intermediate CA -> EE",
++              "ISDOSC_D1.ors", "D1_Issuer_ICA.pem", "", 1, 1);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "ISDOSC_D2.ors", "D2_Issuer_Root.pem", "", 1);
++              "ISDOSC_D2.ors", "D2_Issuer_Root.pem", "", 1, 1);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "ISDOSC_D3.ors", "D3_Issuer_Root.pem", "", 1);
++              "ISDOSC_D3.ors", "D3_Issuer_Root.pem", "", 1, 1);
+ };
+ 
+ subtest "=== WRONG SUBJECT NAME in the ISSUER CERTIFICATE ===" => sub {
+     plan tests => 6;
+ 
+     test_ocsp("NON-DELEGATED; Intermediate CA -> EE",
+-              "ND1.ors", "WSNIC_ND1_Issuer_ICA.pem", "", 1);
++              "ND1.ors", "WSNIC_ND1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> Intermediate CA",
+-              "ND2.ors", "WSNIC_ND2_Issuer_Root.pem", "", 1);
++              "ND2.ors", "WSNIC_ND2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> EE",
+-              "ND3.ors", "WSNIC_ND3_Issuer_Root.pem", "", 1);
++              "ND3.ors", "WSNIC_ND3_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "D1.ors", "WSNIC_D1_Issuer_ICA.pem", "", 1);
++              "D1.ors", "WSNIC_D1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "D2.ors", "WSNIC_D2_Issuer_Root.pem", "", 1);
++              "D2.ors", "WSNIC_D2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "D3.ors", "WSNIC_D3_Issuer_Root.pem", "", 1);
++              "D3.ors", "WSNIC_D3_Issuer_Root.pem", "", 1, 0);
+ };
+ 
+ subtest "=== WRONG KEY in the ISSUER CERTIFICATE ===" => sub {
+     plan tests => 6;
+ 
+     test_ocsp("NON-DELEGATED; Intermediate CA -> EE",
+-              "ND1.ors", "WKIC_ND1_Issuer_ICA.pem", "", 1);
++              "ND1.ors", "WKIC_ND1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> Intermediate CA",
+-              "ND2.ors", "WKIC_ND2_Issuer_Root.pem", "", 1);
++              "ND2.ors", "WKIC_ND2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> EE",
+-              "ND3.ors", "WKIC_ND3_Issuer_Root.pem", "", 1);
++              "ND3.ors", "WKIC_ND3_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "D1.ors", "WKIC_D1_Issuer_ICA.pem", "", 1);
++              "D1.ors", "WKIC_D1_Issuer_ICA.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "D2.ors", "WKIC_D2_Issuer_Root.pem", "", 1);
++              "D2.ors", "WKIC_D2_Issuer_Root.pem", "", 1, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "D3.ors", "WKIC_D3_Issuer_Root.pem", "", 1);
++              "D3.ors", "WKIC_D3_Issuer_Root.pem", "", 1, 0);
+ };
+ 
+ subtest "=== INVALID SIGNATURE on the ISSUER CERTIFICATE ===" => sub {
+@@ -199,17 +207,17 @@ subtest "=== INVALID SIGNATURE on the ISSUER CERTIFICATE ===" => sub {
+ 
+     # Expect success, because we're explicitly trusting the issuer certificate.
+     test_ocsp("NON-DELEGATED; Intermediate CA -> EE",
+-              "ND1.ors", "ISIC_ND1_Issuer_ICA.pem", "", 0);
++              "ND1.ors", "ISIC_ND1_Issuer_ICA.pem", "", 0, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> Intermediate CA",
+-              "ND2.ors", "ISIC_ND2_Issuer_Root.pem", "", 0);
++              "ND2.ors", "ISIC_ND2_Issuer_Root.pem", "", 0, 0);
+     test_ocsp("NON-DELEGATED; Root CA -> EE",
+-              "ND3.ors", "ISIC_ND3_Issuer_Root.pem", "", 0);
++              "ND3.ors", "ISIC_ND3_Issuer_Root.pem", "", 0, 0);
+     test_ocsp("DELEGATED; Intermediate CA -> EE",
+-              "D1.ors", "ISIC_D1_Issuer_ICA.pem", "", 0);
++              "D1.ors", "ISIC_D1_Issuer_ICA.pem", "", 0, 0);
+     test_ocsp("DELEGATED; Root CA -> Intermediate CA",
+-              "D2.ors", "ISIC_D2_Issuer_Root.pem", "", 0);
++              "D2.ors", "ISIC_D2_Issuer_Root.pem", "", 0, 0);
+     test_ocsp("DELEGATED; Root CA -> EE",
+-              "D3.ors", "ISIC_D3_Issuer_Root.pem", "", 0);
++              "D3.ors", "ISIC_D3_Issuer_Root.pem", "", 0, 0);
+ };
+ 
+ subtest "=== OCSP API TESTS===" => sub {
diff --git a/SOURCES/0065-CVE-2022-1292.patch b/SOURCES/0065-CVE-2022-1292.patch
new file mode 100644
index 0000000..5531fb3
--- /dev/null
+++ b/SOURCES/0065-CVE-2022-1292.patch
@@ -0,0 +1,58 @@
+diff --git a/tools/c_rehash.in b/tools/c_rehash.in
+index d51d8856d7..a630773a02 100644
+--- a/tools/c_rehash.in
++++ b/tools/c_rehash.in
+@@ -152,6 +152,23 @@ sub check_file {
+     return ($is_cert, $is_crl);
+ }
+ 
++sub compute_hash {
++    my $fh;
++    if ( $^O eq "VMS" ) {
++        # VMS uses the open through shell
++        # The file names are safe there and list form is unsupported
++        if (!open($fh, "-|", join(' ', @_))) {
++            print STDERR "Cannot compute hash on '$fname'\n";
++            return;
++        }
++    } else {
++        if (!open($fh, "-|", @_)) {
++            print STDERR "Cannot compute hash on '$fname'\n";
++            return;
++        }
++    }
++    return (<$fh>, <$fh>);
++}
+ 
+ # Link a certificate to its subject name hash value, each hash is of
+ # the form <hash>.<n> where n is an integer. If the hash value already exists
+@@ -161,10 +178,12 @@ sub check_file {
+ 
+ sub link_hash_cert {
+     my $fname = $_[0];
+-    $fname =~ s/\"/\\\"/g;
+-    my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`;
++    my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash,
++                                       "-fingerprint", "-noout",
++                                       "-in", $fname);
+     chomp $hash;
+     chomp $fprint;
++    return if !$hash;
+     $fprint =~ s/^.*=//;
+     $fprint =~ tr/://d;
+     my $suffix = 0;
+@@ -202,10 +221,12 @@ sub link_hash_cert {
+ 
+ sub link_hash_crl {
+     my $fname = $_[0];
+-    $fname =~ s/'/'\\''/g;
+-    my ($hash, $fprint) = `"$openssl" crl $crlhash -fingerprint -noout -in '$fname'`;
++    my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash,
++                                       "-fingerprint", "-noout",
++                                       "-in", $fname);
+     chomp $hash;
+     chomp $fprint;
++    return if !$hash;
+     $fprint =~ s/^.*=//;
+     $fprint =~ tr/://d;
+     my $suffix = 0;
diff --git a/SOURCES/0066-replace-expired-certs.patch b/SOURCES/0066-replace-expired-certs.patch
new file mode 100644
index 0000000..adc9460
--- /dev/null
+++ b/SOURCES/0066-replace-expired-certs.patch
@@ -0,0 +1,212 @@
+diff --git a/test/certs/embeddedSCTs1_issuer.pem b/test/certs/embeddedSCTs1_issuer.pem
+index 1fa449d5a098..6aa9455f09ed 100644
+--- a/test/certs/embeddedSCTs1_issuer.pem
++++ b/test/certs/embeddedSCTs1_issuer.pem
+@@ -1,18 +1,18 @@
+ -----BEGIN CERTIFICATE-----
+-MIIC0DCCAjmgAwIBAgIBADANBgkqhkiG9w0BAQUFADBVMQswCQYDVQQGEwJHQjEk
++MIIC0jCCAjugAwIBAgIBADANBgkqhkiG9w0BAQsFADBVMQswCQYDVQQGEwJHQjEk
+ MCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENBMQ4wDAYDVQQIEwVX
+-YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAeFw0xMjA2MDEwMDAwMDBaFw0yMjA2MDEw
+-MDAwMDBaMFUxCzAJBgNVBAYTAkdCMSQwIgYDVQQKExtDZXJ0aWZpY2F0ZSBUcmFu
+-c3BhcmVuY3kgQ0ExDjAMBgNVBAgTBVdhbGVzMRAwDgYDVQQHEwdFcncgV2VuMIGf
+-MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDVimhTYhCicRmTbneDIRgcKkATxtB7
+-jHbrkVfT0PtLO1FuzsvRyY2RxS90P6tjXVUJnNE6uvMa5UFEJFGnTHgW8iQ8+EjP
+-KDHM5nugSlojgZ88ujfmJNnDvbKZuDnd/iYx0ss6hPx7srXFL8/BT/9Ab1zURmnL
+-svfP34b7arnRsQIDAQABo4GvMIGsMB0GA1UdDgQWBBRfnYgNyHPmVNT4DdjmsMEk
+-tEfDVTB9BgNVHSMEdjB0gBRfnYgNyHPmVNT4DdjmsMEktEfDVaFZpFcwVTELMAkG
+-A1UEBhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRyYW5zcGFyZW5jeSBDQTEO
+-MAwGA1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW6CAQAwDAYDVR0TBAUwAwEB
+-/zANBgkqhkiG9w0BAQUFAAOBgQAGCMxKbWTyIF4UbASydvkrDvqUpdryOvw4BmBt
+-OZDQoeojPUApV2lGOwRmYef6HReZFSCa6i4Kd1F2QRIn18ADB8dHDmFYT9czQiRy
+-f1HWkLxHqd81TbD26yWVXeGJPE3VICskovPkQNJ0tU4b03YmnKliibduyqQQkOFP
+-OwqULg==
++YWxlczEQMA4GA1UEBxMHRXJ3IFdlbjAgFw0yMjA2MDExMDM4MDJaGA8yMTIyMDUw
++ODEwMzgwMlowVTELMAkGA1UEBhMCR0IxJDAiBgNVBAoTG0NlcnRpZmljYXRlIFRy
++YW5zcGFyZW5jeSBDQTEOMAwGA1UECBMFV2FsZXMxEDAOBgNVBAcTB0VydyBXZW4w
++gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBANWKaFNiEKJxGZNud4MhGBwqQBPG
++0HuMduuRV9PQ+0s7UW7Oy9HJjZHFL3Q/q2NdVQmc0Tq68xrlQUQkUadMeBbyJDz4
++SM8oMczme6BKWiOBnzy6N+Yk2cO9spm4Od3+JjHSyzqE/HuytcUvz8FP/0BvXNRG
++acuy98/fhvtqudGxAgMBAAGjga8wgawwHQYDVR0OBBYEFF+diA3Ic+ZU1PgN2Oaw
++wSS0R8NVMH0GA1UdIwR2MHSAFF+diA3Ic+ZU1PgN2OawwSS0R8NVoVmkVzBVMQsw
++CQYDVQQGEwJHQjEkMCIGA1UEChMbQ2VydGlmaWNhdGUgVHJhbnNwYXJlbmN5IENB
++MQ4wDAYDVQQIEwVXYWxlczEQMA4GA1UEBxMHRXJ3IFdlboIBADAMBgNVHRMEBTAD
++AQH/MA0GCSqGSIb3DQEBCwUAA4GBAD0aYh9OkFYfXV7kBfhrtD0PJG2U47OV/1qq
+++uFpqB0S1WO06eJT0pzYf1ebUcxjBkajbJZm/FHT85VthZ1lFHsky87aFD8XlJCo
++2IOhKOkvvWKPUdFLoO/ZVXqEVKkcsS1eXK1glFvb07eJZya3JVG0KdMhV2YoDg6c
++Doud4XrO
+ -----END CERTIFICATE-----
+diff --git a/test/certs/sm2-ca-cert.pem b/test/certs/sm2-ca-cert.pem
+index 5677ac6c9f6a..70ce71e43091 100644
+--- a/test/certs/sm2-ca-cert.pem
++++ b/test/certs/sm2-ca-cert.pem
+@@ -1,14 +1,14 @@
+ -----BEGIN CERTIFICATE-----
+-MIICJDCCAcqgAwIBAgIJAOlkpDpSrmVbMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT
++MIICJzCCAcygAwIBAgIJAOlkpDpSrmVbMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT
+ AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl
+-c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe
+-Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMGgxCzAJBgNVBAYTAkNOMQsw
+-CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn
+-MRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTBZMBMGByqG
+-SM49AgEGCCqBHM9VAYItA0IABHRYnqErofBdXPptvvO7+BSVJxcpHuTGnZ+UPrbU
+-5kVEUMaUnNOeMJZl/vRGimZCm/AkReJmRfnb15ESHR+ssp6jXTBbMB0GA1UdDgQW
+-BBTFjcWu/zJgSZ5SKUlU5Vx4/0W5dDAfBgNVHSMEGDAWgBTFjcWu/zJgSZ5SKUlU
+-5Vx4/0W5dDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzPVQGDdQNI
+-ADBFAiEAs6byi1nSQtFELOw/2tQIv5AEsZFR5MJ/oB2ztXzs2LYCIEfIw4xlUH6X
+-YFhs4RnIa0K9Ng1ebsGPrifYkudwBIk3
++c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAg
++Fw0yMjA2MDIxNTQ5MzlaGA8yMTIyMDUwOTE1NDkzOVowaDELMAkGA1UEBhMCQ04x
++CzAJBgNVBAgMAkxOMREwDwYDVQQHDAhTaGVueWFuZzERMA8GA1UECgwIVGVzdCBP
++cmcxEDAOBgNVBAsMB1Rlc3QgT1UxFDASBgNVBAMMC1Rlc3QgU00yIENBMFkwEwYH
++KoZIzj0CAQYIKoEcz1UBgi0DQgAEdFieoSuh8F1c+m2+87v4FJUnFyke5Madn5Q+
++ttTmRURQxpSc054wlmX+9EaKZkKb8CRF4mZF+dvXkRIdH6yynqNdMFswHQYDVR0O
++BBYEFMWNxa7/MmBJnlIpSVTlXHj/Rbl0MB8GA1UdIwQYMBaAFMWNxa7/MmBJnlIp
++SVTlXHj/Rbl0MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqBHM9VAYN1
++A0kAMEYCIQC3c2TkO6Lyxt5GNZqoZNuMEphjL9K7W1TsX6mHzlhHDwIhAICXy2XC
++WsTzdrMZUXLtrDDFOq+3FaD4pe1HP2LZFNpu
+ -----END CERTIFICATE-----
+diff --git a/test/certs/sm2-root.crt b/test/certs/sm2-root.crt
+index 5677ac6c9f6a..70ce71e43091 100644
+--- a/test/certs/sm2-root.crt
++++ b/test/certs/sm2-root.crt
+@@ -1,14 +1,14 @@
+ -----BEGIN CERTIFICATE-----
+-MIICJDCCAcqgAwIBAgIJAOlkpDpSrmVbMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT
++MIICJzCCAcygAwIBAgIJAOlkpDpSrmVbMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT
+ AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl
+-c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe
+-Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMGgxCzAJBgNVBAYTAkNOMQsw
+-CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn
+-MRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTBZMBMGByqG
+-SM49AgEGCCqBHM9VAYItA0IABHRYnqErofBdXPptvvO7+BSVJxcpHuTGnZ+UPrbU
+-5kVEUMaUnNOeMJZl/vRGimZCm/AkReJmRfnb15ESHR+ssp6jXTBbMB0GA1UdDgQW
+-BBTFjcWu/zJgSZ5SKUlU5Vx4/0W5dDAfBgNVHSMEGDAWgBTFjcWu/zJgSZ5SKUlU
+-5Vx4/0W5dDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzPVQGDdQNI
+-ADBFAiEAs6byi1nSQtFELOw/2tQIv5AEsZFR5MJ/oB2ztXzs2LYCIEfIw4xlUH6X
+-YFhs4RnIa0K9Ng1ebsGPrifYkudwBIk3
++c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAg
++Fw0yMjA2MDIxNTQ5MzlaGA8yMTIyMDUwOTE1NDkzOVowaDELMAkGA1UEBhMCQ04x
++CzAJBgNVBAgMAkxOMREwDwYDVQQHDAhTaGVueWFuZzERMA8GA1UECgwIVGVzdCBP
++cmcxEDAOBgNVBAsMB1Rlc3QgT1UxFDASBgNVBAMMC1Rlc3QgU00yIENBMFkwEwYH
++KoZIzj0CAQYIKoEcz1UBgi0DQgAEdFieoSuh8F1c+m2+87v4FJUnFyke5Madn5Q+
++ttTmRURQxpSc054wlmX+9EaKZkKb8CRF4mZF+dvXkRIdH6yynqNdMFswHQYDVR0O
++BBYEFMWNxa7/MmBJnlIpSVTlXHj/Rbl0MB8GA1UdIwQYMBaAFMWNxa7/MmBJnlIp
++SVTlXHj/Rbl0MAwGA1UdEwQFMAMBAf8wCwYDVR0PBAQDAgEGMAoGCCqBHM9VAYN1
++A0kAMEYCIQC3c2TkO6Lyxt5GNZqoZNuMEphjL9K7W1TsX6mHzlhHDwIhAICXy2XC
++WsTzdrMZUXLtrDDFOq+3FaD4pe1HP2LZFNpu
+ -----END CERTIFICATE-----
+diff --git a/test/certs/sm2.pem b/test/certs/sm2.pem
+index 189abb137625..daf12926aff9 100644
+--- a/test/certs/sm2.pem
++++ b/test/certs/sm2.pem
+@@ -1,13 +1,14 @@
+ -----BEGIN CERTIFICATE-----
+-MIIB6DCCAY6gAwIBAgIJAKH2BR6ITHZeMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT
+-AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl
+-c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe
+-Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMG8xCzAJBgNVBAYTAkNOMQsw
+-CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn
+-MRAwDgYDVQQLDAdUZXN0IE9VMRswGQYDVQQDDBJUZXN0IFNNMiBTaWduIENlcnQw
+-WTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAQwqeNkWp7fiu1KZnuDkAucpM8piEzE
+-TL1ymrcrOBvv8mhNNkeb20asbWgFQI2zOrSM99/sXGn9rM2/usM/MlcaoxowGDAJ
+-BgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNIADBFAiEA9edBnAqT
+-TNuGIUIvXsj6/nP+AzXA9HGtAIY4nrqW8LkCIHyZzhRTlxYtgfqkDl0OK5QQRCZH
+-OZOfmtx613VyzXwc
++MIICNDCCAdugAwIBAgIUOMbsiFLCy2BCPtfHQSdG4R1+3BowCgYIKoEcz1UBg3Uw
++aDELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAkxOMREwDwYDVQQHDAhTaGVueWFuZzER
++MA8GA1UECgwIVGVzdCBPcmcxEDAOBgNVBAsMB1Rlc3QgT1UxFDASBgNVBAMMC1Rl
++c3QgU00yIENBMCAXDTIyMDYwMjE1NTU0OFoYDzIxMjIwNTA5MTU1NTQ4WjBvMQsw
++CQYDVQQGEwJDTjELMAkGA1UECAwCTE4xETAPBgNVBAcMCFNoZW55YW5nMREwDwYD
++VQQKDAhUZXN0IE9yZzEQMA4GA1UECwwHVGVzdCBPVTEbMBkGA1UEAwwSVGVzdCBT
++TTIgU2lnbiBDZXJ0MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEMKnjZFqe34rt
++SmZ7g5ALnKTPKYhMxEy9cpq3Kzgb7/JoTTZHm9tGrG1oBUCNszq0jPff7Fxp/azN
++v7rDPzJXGqNaMFgwCQYDVR0TBAIwADALBgNVHQ8EBAMCBsAwHQYDVR0OBBYEFNPl
++u8JjXkhQPiJ5bYrrq+voqBUlMB8GA1UdIwQYMBaAFMWNxa7/MmBJnlIpSVTlXHj/
++Rbl0MAoGCCqBHM9VAYN1A0cAMEQCIG3gG1D7T7ltn6Gz1UksBZahgBE6jmkQ9Sp9
++/3aY5trlAiB5adxiK0avV0LEKfbzTdff9skoZpd7vje1QTW0l0HaGg==
+ -----END CERTIFICATE-----
+diff --git a/test/smime-certs/mksmime-certs.sh b/test/smime-certs/mksmime-certs.sh
+index 12e8a7305402..109b9c4abc28 100644
+--- a/test/smime-certs/mksmime-certs.sh
++++ b/test/smime-certs/mksmime-certs.sh
+@@ -15,23 +15,23 @@ export OPENSSL_CONF
+ 
+ # Root CA: create certificate directly
+ CN="Test S/MIME RSA Root" $OPENSSL req -config ca.cnf -x509 -noenc \
+-	-keyout smroot.pem -out smroot.pem -newkey rsa:2048 -days 3650
++	-keyout smroot.pem -out smroot.pem -newkey rsa:2048 -days 36501
+ 
+ # EE RSA certificates: create request first
+ CN="Test S/MIME EE RSA #1" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smrsa1.pem -out req.pem -newkey rsa:2048
+ # Sign request: end entity extensions
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smrsa1.pem
+ 
+ CN="Test S/MIME EE RSA #2" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smrsa2.pem -out req.pem -newkey rsa:2048
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smrsa2.pem
+ 
+ CN="Test S/MIME EE RSA #3" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smrsa3.pem -out req.pem -newkey rsa:2048
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smrsa3.pem
+ 
+ # Create DSA parameters
+@@ -40,15 +40,15 @@ $OPENSSL dsaparam -out dsap.pem 2048
+ 
+ CN="Test S/MIME EE DSA #1" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smdsa1.pem -out req.pem -newkey dsa:dsap.pem
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smdsa1.pem
+ CN="Test S/MIME EE DSA #2" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smdsa2.pem -out req.pem -newkey dsa:dsap.pem
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smdsa2.pem
+ CN="Test S/MIME EE DSA #3" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smdsa3.pem -out req.pem -newkey dsa:dsap.pem
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smdsa3.pem
+ 
+ # Create EC parameters
+@@ -58,16 +58,17 @@ $OPENSSL ecparam -out ecp2.pem -name K-283
+ 
+ CN="Test S/MIME EE EC #1" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smec1.pem -out req.pem -newkey ec:ecp.pem
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smec1.pem
+ CN="Test S/MIME EE EC #2" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smec2.pem -out req.pem -newkey ec:ecp2.pem
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smec2.pem
+-CN="Test S/MIME EE EC #3" $OPENSSL req -config ca.cnf -noenc \
+-	-keyout smec3.pem -out req.pem -newkey ec:ecp.pem
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
+-	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smec3.pem
++# Do not renew this cert as it is used for legacy data decrypt test
++#CN="Test S/MIME EE EC #3" $OPENSSL req -config ca.cnf -noenc \
++#	-keyout smec3.pem -out req.pem -newkey ec:ecp.pem
++#$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
++#	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smec3.pem
+ # Create X9.42 DH parameters.
+ $OPENSSL genpkey -genparam -algorithm DHX -out dhp.pem
+ # Generate X9.42 DH key.
+@@ -77,7 +78,7 @@ $OPENSSL pkey -pubout -in smdh.pem -out dhpub.pem
+ CN="Test S/MIME EE DH #1" $OPENSSL req -config ca.cnf -noenc \
+ 	-keyout smtmp.pem -out req.pem -newkey rsa:2048
+ # Sign request but force public key to DH
+-$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 3600 \
++$OPENSSL x509 -req -in req.pem -CA smroot.pem -days 36500 \
+ 	-force_pubkey dhpub.pem \
+ 	-extfile ca.cnf -extensions usr_cert -CAcreateserial >>smdh.pem
+ # Remove temp files.
diff --git a/SOURCES/0067-fix-ppc64-montgomery.patch b/SOURCES/0067-fix-ppc64-montgomery.patch
new file mode 100644
index 0000000..a572ef8
--- /dev/null
+++ b/SOURCES/0067-fix-ppc64-montgomery.patch
@@ -0,0 +1,662 @@
+diff --git a/crypto/bn/asm/ppc64-mont-fixed.pl b/crypto/bn/asm/ppc64-mont-fixed.pl
+index 56df89dc27da..e69de29bb2d1 100755
+--- a/crypto/bn/asm/ppc64-mont-fixed.pl
++++ b/crypto/bn/asm/ppc64-mont-fixed.pl
+@@ -1,581 +0,0 @@
+-#! /usr/bin/env perl
+-# Copyright 2021 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 Amitay Isaacs <amitay@ozlabs.org>, Martin Schwenke
+-# <martin@meltin.net> & Alastair D'Silva <alastair@d-silva.org> for
+-# the OpenSSL project.
+-# ====================================================================
+-
+-#
+-# Fixed length (n=6), unrolled PPC Montgomery Multiplication
+-#
+-
+-# 2021
+-#
+-# Although this is a generic implementation for unrolling Montgomery
+-# Multiplication for arbitrary values of n, this is currently only
+-# used for n = 6 to improve the performance of ECC p384.
+-#
+-# Unrolling allows intermediate results to be stored in registers,
+-# rather than on the stack, improving performance by ~7% compared to
+-# the existing PPC assembly code.
+-#
+-# The ISA 3.0 implementation uses combination multiply/add
+-# instructions (maddld, maddhdu) to improve performance by an
+-# additional ~10% on Power 9.
+-#
+-# Finally, saving non-volatile registers into volatile vector
+-# registers instead of onto the stack saves a little more.
+-#
+-# On a Power 9 machine we see an overall improvement of ~18%.
+-#
+-
+-use strict;
+-use warnings;
+-
+-my ($flavour, $output, $dir, $xlate);
+-
+-# $output is the last argument if it looks like a file (it has an extension)
+-# $flavour is the first argument if it doesn't look like a file
+-$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+-$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
+-
+-$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 STDOUT,"| $^X $xlate $flavour \"$output\""
+-    or die "can't call $xlate: $!";
+-
+-if ($flavour !~ /64/) {
+-	die "bad flavour ($flavour) - only ppc64 permitted";
+-}
+-
+-my $SIZE_T= 8;
+-
+-# Registers are global so the code is remotely readable
+-
+-# Parameters for Montgomery multiplication
+-my $sp	= "r1";
+-my $toc	= "r2";
+-my $rp	= "r3";
+-my $ap	= "r4";
+-my $bp	= "r5";
+-my $np	= "r6";
+-my $n0	= "r7";
+-my $num	= "r8";
+-
+-my $i	= "r9";
+-my $c0	= "r10";
+-my $bp0	= "r11";
+-my $bpi	= "r11";
+-my $bpj	= "r11";
+-my $tj	= "r12";
+-my $apj	= "r12";
+-my $npj	= "r12";
+-my $lo	= "r14";
+-my $c1	= "r14";
+-
+-# Non-volatile registers used for tp[i]
+-#
+-# 12 registers are available but the limit on unrolling is 10,
+-# since registers from $tp[0] to $tp[$n+1] are used.
+-my @tp = ("r20" .. "r31");
+-
+-# volatile VSRs for saving non-volatile GPRs - faster than stack
+-my @vsrs = ("v32" .. "v46");
+-
+-package Mont;
+-
+-sub new($$)
+-{
+-	my ($class, $n) = @_;
+-
+-	if ($n > 10) {
+-		die "Can't unroll for BN length ${n} (maximum 10)"
+-	}
+-
+-	my $self = {
+-		code => "",
+-		n => $n,
+-	};
+-	bless $self, $class;
+-
+-	return $self;
+-}
+-
+-sub add_code($$)
+-{
+-	my ($self, $c) = @_;
+-
+-	$self->{code} .= $c;
+-}
+-
+-sub get_code($)
+-{
+-	my ($self) = @_;
+-
+-	return $self->{code};
+-}
+-
+-sub get_function_name($)
+-{
+-	my ($self) = @_;
+-
+-	return "bn_mul_mont_fixed_n" . $self->{n};
+-}
+-
+-sub get_label($$)
+-{
+-	my ($self, $l) = @_;
+-
+-	return "L" . $l . "_" . $self->{n};
+-}
+-
+-sub get_labels($@)
+-{
+-	my ($self, @labels) = @_;
+-
+-	my %out = ();
+-
+-	foreach my $l (@labels) {
+-		$out{"$l"} = $self->get_label("$l");
+-	}
+-
+-	return \%out;
+-}
+-
+-sub nl($)
+-{
+-	my ($self) = @_;
+-
+-	$self->add_code("\n");
+-}
+-
+-sub copy_result($)
+-{
+-	my ($self) = @_;
+-
+-	my ($n) = $self->{n};
+-
+-	for (my $j = 0; $j < $n; $j++) {
+-		$self->add_code(<<___);
+-	std		$tp[$j],`$j*$SIZE_T`($rp)
+-___
+-	}
+-
+-}
+-
+-sub mul_mont_fixed($)
+-{
+-	my ($self) = @_;
+-
+-	my ($n) = $self->{n};
+-	my $fname = $self->get_function_name();
+-	my $label = $self->get_labels("outer", "enter", "sub", "copy", "end");
+-
+-	$self->add_code(<<___);
+-
+-.globl	.${fname}
+-.align	5
+-.${fname}:
+-
+-___
+-
+-	$self->save_registers();
+-
+-	$self->add_code(<<___);
+-	ld		$n0,0($n0)
+-
+-	ld		$bp0,0($bp)
+-
+-	ld		$apj,0($ap)
+-___
+-
+-	$self->mul_c_0($tp[0], $apj, $bp0, $c0);
+-
+-	for (my $j = 1; $j < $n - 1; $j++) {
+-		$self->add_code(<<___);
+-	ld		$apj,`$j*$SIZE_T`($ap)
+-___
+-		$self->mul($tp[$j], $apj, $bp0, $c0);
+-	}
+-
+-	$self->add_code(<<___);
+-	ld		$apj,`($n-1)*$SIZE_T`($ap)
+-___
+-
+-	$self->mul_last($tp[$n-1], $tp[$n], $apj, $bp0, $c0);
+-
+-	$self->add_code(<<___);
+-	li		$tp[$n+1],0
+-
+-___
+-
+-	$self->add_code(<<___);
+-	li		$i,0
+-	mtctr		$num
+-	b		$label->{"enter"}
+-
+-.align	4
+-$label->{"outer"}:
+-	ldx		$bpi,$bp,$i
+-
+-	ld		$apj,0($ap)
+-___
+-
+-	$self->mul_add_c_0($tp[0], $tp[0], $apj, $bpi, $c0);
+-
+-	for (my $j = 1; $j < $n; $j++) {
+-		$self->add_code(<<___);
+-	ld		$apj,`$j*$SIZE_T`($ap)
+-___
+-		$self->mul_add($tp[$j], $tp[$j], $apj, $bpi, $c0);
+-	}
+-
+-	$self->add_code(<<___);
+-	addc		$tp[$n],$tp[$n],$c0
+-	addze		$tp[$n+1],$tp[$n+1]
+-___
+-
+-	$self->add_code(<<___);
+-.align	4
+-$label->{"enter"}:
+-	mulld		$bpi,$tp[0],$n0
+-
+-	ld		$npj,0($np)
+-___
+-
+-	$self->mul_add_c_0($lo, $tp[0], $bpi, $npj, $c0);
+-
+-	for (my $j = 1; $j < $n; $j++) {
+-		$self->add_code(<<___);
+-	ld		$npj,`$j*$SIZE_T`($np)
+-___
+-		$self->mul_add($tp[$j-1], $tp[$j], $npj, $bpi, $c0);
+-	}
+-
+-	$self->add_code(<<___);
+-	addc		$tp[$n-1],$tp[$n],$c0
+-	addze		$tp[$n],$tp[$n+1]
+-
+-	addi		$i,$i,$SIZE_T
+-	bdnz		$label->{"outer"}
+-
+-	and.		$tp[$n],$tp[$n],$tp[$n]
+-	bne		$label->{"sub"}
+-
+-	cmpld	$tp[$n-1],$npj
+-	blt		$label->{"copy"}
+-
+-$label->{"sub"}:
+-___
+-
+-	#
+-	# Reduction
+-	#
+-
+-		$self->add_code(<<___);
+-	ld		$bpj,`0*$SIZE_T`($np)
+-	subfc		$c1,$bpj,$tp[0]
+-	std		$c1,`0*$SIZE_T`($rp)
+-
+-___
+-	for (my $j = 1; $j < $n - 1; $j++) {
+-		$self->add_code(<<___);
+-	ld		$bpj,`$j*$SIZE_T`($np)
+-	subfe		$c1,$bpj,$tp[$j]
+-	std		$c1,`$j*$SIZE_T`($rp)
+-
+-___
+-	}
+-
+-		$self->add_code(<<___);
+-	subfe		$c1,$npj,$tp[$n-1]
+-	std		$c1,`($n-1)*$SIZE_T`($rp)
+-
+-___
+-
+-	$self->add_code(<<___);
+-	addme.		$tp[$n],$tp[$n]
+-	beq		$label->{"end"}
+-
+-$label->{"copy"}:
+-___
+-
+-	$self->copy_result();
+-
+-	$self->add_code(<<___);
+-
+-$label->{"end"}:
+-___
+-
+-	$self->restore_registers();
+-
+-	$self->add_code(<<___);
+-	li		r3,1
+-	blr
+-.size .${fname},.-.${fname}
+-___
+-
+-}
+-
+-package Mont::GPR;
+-
+-our @ISA = ('Mont');
+-
+-sub new($$)
+-{
+-    my ($class, $n) = @_;
+-
+-    return $class->SUPER::new($n);
+-}
+-
+-sub save_registers($)
+-{
+-	my ($self) = @_;
+-
+-	my $n = $self->{n};
+-
+-	$self->add_code(<<___);
+-	std	$lo,-8($sp)
+-___
+-
+-	for (my $j = 0; $j <= $n+1; $j++) {
+-		$self->{code}.=<<___;
+-	std	$tp[$j],-`($j+2)*8`($sp)
+-___
+-	}
+-
+-	$self->add_code(<<___);
+-
+-___
+-}
+-
+-sub restore_registers($)
+-{
+-	my ($self) = @_;
+-
+-	my $n = $self->{n};
+-
+-	$self->add_code(<<___);
+-	ld	$lo,-8($sp)
+-___
+-
+-	for (my $j = 0; $j <= $n+1; $j++) {
+-		$self->{code}.=<<___;
+-	ld	$tp[$j],-`($j+2)*8`($sp)
+-___
+-	}
+-
+-	$self->{code} .=<<___;
+-
+-___
+-}
+-
+-# Direct translation of C mul()
+-sub mul($$$$$)
+-{
+-	my ($self, $r, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	mulld		$lo,$a,$w
+-	addc		$r,$lo,$c
+-	mulhdu		$c,$a,$w
+-	addze		$c,$c
+-
+-___
+-}
+-
+-# Like mul() but $c is ignored as an input - an optimisation to save a
+-# preliminary instruction that would set input $c to 0
+-sub mul_c_0($$$$$)
+-{
+-	my ($self, $r, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	mulld		$r,$a,$w
+-	mulhdu		$c,$a,$w
+-
+-___
+-}
+-
+-# Like mul() but does not to the final addition of CA into $c - an
+-# optimisation to save an instruction
+-sub mul_last($$$$$$)
+-{
+-	my ($self, $r1, $r2, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	mulld		$lo,$a,$w
+-	addc		$r1,$lo,$c
+-	mulhdu		$c,$a,$w
+-
+-	addze		$r2,$c
+-___
+-}
+-
+-# Like C mul_add() but allow $r_out and $r_in to be different
+-sub mul_add($$$$$$)
+-{
+-	my ($self, $r_out, $r_in, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	mulld		$lo,$a,$w
+-	addc		$lo,$lo,$c
+-	mulhdu		$c,$a,$w
+-	addze		$c,$c
+-	addc		$r_out,$r_in,$lo
+-	addze		$c,$c
+-
+-___
+-}
+-
+-# Like mul_add() but $c is ignored as an input - an optimisation to save a
+-# preliminary instruction that would set input $c to 0
+-sub mul_add_c_0($$$$$$)
+-{
+-	my ($self, $r_out, $r_in, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	mulld		$lo,$a,$w
+-	addc		$r_out,$r_in,$lo
+-	mulhdu		$c,$a,$w
+-	addze		$c,$c
+-
+-___
+-}
+-
+-package Mont::GPR_300;
+-
+-our @ISA = ('Mont::GPR');
+-
+-sub new($$)
+-{
+-	my ($class, $n) = @_;
+-
+-	my $mont = $class->SUPER::new($n);
+-
+-	return $mont;
+-}
+-
+-sub get_function_name($)
+-{
+-	my ($self) = @_;
+-
+-	return "bn_mul_mont_300_fixed_n" . $self->{n};
+-}
+-
+-sub get_label($$)
+-{
+-	my ($self, $l) = @_;
+-
+-	return "L" . $l . "_300_" . $self->{n};
+-}
+-
+-# Direct translation of C mul()
+-sub mul($$$$$)
+-{
+-	my ($self, $r, $a, $w, $c, $last) = @_;
+-
+-	$self->add_code(<<___);
+-	maddld		$r,$a,$w,$c
+-	maddhdu		$c,$a,$w,$c
+-
+-___
+-}
+-
+-# Save the last carry as the final entry
+-sub mul_last($$$$$)
+-{
+-	my ($self, $r1, $r2, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	maddld		$r1,$a,$w,$c
+-	maddhdu		$r2,$a,$w,$c
+-
+-___
+-}
+-
+-# Like mul() but $c is ignored as an input - an optimisation to save a
+-# preliminary instruction that would set input $c to 0
+-sub mul_c_0($$$$$)
+-{
+-	my ($self, $r, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	mulld          $r,$a,$w
+-	mulhdu          $c,$a,$w
+-
+-___
+-}
+-
+-# Like C mul_add() but allow $r_out and $r_in to be different
+-sub mul_add($$$$$$)
+-{
+-	my ($self, $r_out, $r_in, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	maddld		$lo,$a,$w,$c
+-	maddhdu		$c,$a,$w,$c
+-	addc		$r_out,$r_in,$lo
+-	addze		$c,$c
+-
+-___
+-}
+-
+-# Like mul_add() but $c is ignored as an input - an optimisation to save a
+-# preliminary instruction that would set input $c to 0
+-sub mul_add_c_0($$$$$$)
+-{
+-	my ($self, $r_out, $r_in, $a, $w, $c) = @_;
+-
+-	$self->add_code(<<___);
+-	maddld		$lo,$a,$w,$r_in
+-	maddhdu		$c,$a,$w,$r_in
+-___
+-
+-	if ($r_out ne $lo) {
+-		$self->add_code(<<___);
+-	mr			$r_out,$lo
+-___
+-	}
+-
+-	$self->nl();
+-}
+-
+-
+-package main;
+-
+-my $code;
+-
+-$code.=<<___;
+-.machine "any"
+-.text
+-___
+-
+-my $mont;
+-
+-$mont = new Mont::GPR(6);
+-$mont->mul_mont_fixed();
+-$code .= $mont->get_code();
+-
+-$mont = new Mont::GPR_300(6);
+-$mont->mul_mont_fixed();
+-$code .= $mont->get_code();
+-
+-$code =~ s/\`([^\`]*)\`/eval $1/gem;
+-
+-$code.=<<___;
+-.asciz  "Montgomery Multiplication for PPC by <amitay\@ozlabs.org>, <alastair\@d-silva.org>"
+-___
+-
+-print $code;
+-close STDOUT or die "error closing STDOUT: $!";
+diff --git a/crypto/bn/bn_ppc.c b/crypto/bn/bn_ppc.c
+index 1e9421bee213..3ee76ea96574 100644
+--- a/crypto/bn/bn_ppc.c
++++ b/crypto/bn/bn_ppc.c
+@@ -19,12 +19,6 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                         const BN_ULONG *np, const BN_ULONG *n0, int num);
+     int bn_mul4x_mont_int(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+                           const BN_ULONG *np, const BN_ULONG *n0, int num);
+-    int bn_mul_mont_fixed_n6(BN_ULONG *rp, const BN_ULONG *ap,
+-                             const BN_ULONG *bp, const BN_ULONG *np,
+-                             const BN_ULONG *n0, int num);
+-    int bn_mul_mont_300_fixed_n6(BN_ULONG *rp, const BN_ULONG *ap,
+-                                 const BN_ULONG *bp, const BN_ULONG *np,
+-                                 const BN_ULONG *n0, int num);
+ 
+     if (num < 4)
+         return 0;
+@@ -40,14 +34,5 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp,
+      * no opportunity to figure it out...
+      */
+ 
+-#if defined(_ARCH_PPC64)
+-    if (num == 6) {
+-        if (OPENSSL_ppccap_P & PPC_MADD300)
+-            return bn_mul_mont_300_fixed_n6(rp, ap, bp, np, n0, num);
+-        else
+-            return bn_mul_mont_fixed_n6(rp, ap, bp, np, n0, num);
+-    }
+-#endif
+-
+     return bn_mul_mont_int(rp, ap, bp, np, n0, num);
+ }
+diff --git a/crypto/bn/build.info b/crypto/bn/build.info
+index 987a70ae263b..4f8d0689b5ea 100644
+--- a/crypto/bn/build.info
++++ b/crypto/bn/build.info
+@@ -79,7 +79,7 @@ IF[{- !$disabled{asm} -}]
+ 
+   $BNASM_ppc32=bn_ppc.c bn-ppc.s ppc-mont.s
+   $BNDEF_ppc32=OPENSSL_BN_ASM_MONT
+-  $BNASM_ppc64=$BNASM_ppc32 ppc64-mont-fixed.s
++  $BNASM_ppc64=$BNASM_ppc32
+   $BNDEF_ppc64=$BNDEF_ppc32
+ 
+   $BNASM_c64xplus=asm/bn-c64xplus.asm
+@@ -173,7 +173,6 @@ GENERATE[parisc-mont.s]=asm/parisc-mont.pl
+ GENERATE[bn-ppc.s]=asm/ppc.pl
+ GENERATE[ppc-mont.s]=asm/ppc-mont.pl
+ GENERATE[ppc64-mont.s]=asm/ppc64-mont.pl
+-GENERATE[ppc64-mont-fixed.s]=asm/ppc64-mont-fixed.pl
+ 
+ GENERATE[alpha-mont.S]=asm/alpha-mont.pl
+ 
+diff --git a/test/recipes/30-test_evp_data/evppkey_ecdsa.txt b/test/recipes/30-test_evp_data/evppkey_ecdsa.txt
+index f36982845db4..1543ed9f7534 100644
+--- a/test/recipes/30-test_evp_data/evppkey_ecdsa.txt
++++ b/test/recipes/30-test_evp_data/evppkey_ecdsa.txt
+@@ -97,6 +97,18 @@ Key = P-256-PUBLIC
+ Input = "Hello World"
+ Output = 3046022100e7515177ec3817b77a4a94066ab3070817b7aa9d44a8a09f040da250116e8972022100ba59b0f631258e59a9026be5d84f60685f4cf22b9165a0c2736d5c21c8ec1862
+ 
++PublicKey=P-384-PUBLIC
++-----BEGIN PUBLIC KEY-----
++MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAES/TlL5WEJ+u1kV+4yVlVUbTTo/2rZ7rd
++nWwwk/QlukNjDfcfQvDrfOqpTZ9kSKhd0wMxWIJJ/S/cCzCex+2EgbwW8ngAwT19
++twD8guGxyFRaoMDTtW47/nifwYqRaIfC
++-----END PUBLIC KEY-----
++
++DigestVerify = SHA384
++Key = P-384-PUBLIC
++Input = "123400"
++Output = 304d0218389cb27e0bc8d21fa7e5f24cb74f58851313e696333ad68b023100ffffffffffffffffffffffffffffffffffffffffffffffffc7634d81f4372ddf581a0db248b0a77aecec196accc52970
++
+ # Oneshot tests
+ OneShotDigestVerify = SHA256
+ Key = P-256-PUBLIC
diff --git a/SOURCES/0068-CVE-2022-2068.patch b/SOURCES/0068-CVE-2022-2068.patch
new file mode 100644
index 0000000..c4dd7f2
--- /dev/null
+++ b/SOURCES/0068-CVE-2022-2068.patch
@@ -0,0 +1,174 @@
+diff -up openssl-3.0.1/tools/c_rehash.in.cve20222068 openssl-3.0.1/tools/c_rehash.in
+--- openssl-3.0.1/tools/c_rehash.in.cve20222068	2022-06-22 13:15:57.347421765 +0200
++++ openssl-3.0.1/tools/c_rehash.in	2022-06-22 13:16:14.797576250 +0200
+@@ -104,18 +104,41 @@ foreach (@dirlist) {
+ }
+ exit($errorcount);
+ 
++sub copy_file {
++    my ($src_fname, $dst_fname) = @_;
++
++    if (open(my $in, "<", $src_fname)) {
++        if (open(my $out, ">", $dst_fname)) {
++            print $out $_ while (<$in>);
++            close $out;
++        } else {
++            warn "Cannot open $dst_fname for write, $!";
++        }
++        close $in;
++    } else {
++        warn "Cannot open $src_fname for read, $!";
++    }
++}
++
+ sub hash_dir {
++    my $dir = shift;
+     my %hashlist;
+-    print "Doing $_[0]\n";
+-    chdir $_[0];
+-    opendir(DIR, ".");
++
++    print "Doing $dir\n";
++
++    if (!chdir $dir) {
++        print STDERR "WARNING: Cannot chdir to '$dir', $!\n";
++        return;
++    }
++
++    opendir(DIR, ".") || print STDERR "WARNING: Cannot opendir '.', $!\n";
+     my @flist = sort readdir(DIR);
+     closedir DIR;
+     if ( $removelinks ) {
+         # Delete any existing symbolic links
+         foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
+             if (-l $_) {
+-                print "unlink $_" if $verbose;
++                print "unlink $_\n" if $verbose;
+                 unlink $_ || warn "Can't unlink $_, $!\n";
+             }
+         }
+@@ -130,13 +153,16 @@ sub hash_dir {
+         link_hash_cert($fname) if ($cert);
+         link_hash_crl($fname) if ($crl);
+     }
++
++    chdir $pwd;
+ }
+ 
+ sub check_file {
+     my ($is_cert, $is_crl) = (0,0);
+     my $fname = $_[0];
+-    open IN, $fname;
+-    while(<IN>) {
++
++    open(my $in, "<", $fname);
++    while(<$in>) {
+         if (/^-----BEGIN (.*)-----/) {
+             my $hdr = $1;
+             if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
+@@ -148,7 +174,7 @@ sub check_file {
+             }
+         }
+     }
+-    close IN;
++    close $in;
+     return ($is_cert, $is_crl);
+ }
+ 
+@@ -177,76 +203,49 @@ sub compute_hash {
+ # certificate fingerprints
+ 
+ sub link_hash_cert {
+-    my $fname = $_[0];
+-    my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash,
+-                                       "-fingerprint", "-noout",
+-                                       "-in", $fname);
+-    chomp $hash;
+-    chomp $fprint;
+-    return if !$hash;
+-    $fprint =~ s/^.*=//;
+-    $fprint =~ tr/://d;
+-    my $suffix = 0;
+-    # Search for an unused hash filename
+-    while(exists $hashlist{"$hash.$suffix"}) {
+-        # Hash matches: if fingerprint matches its a duplicate cert
+-        if ($hashlist{"$hash.$suffix"} eq $fprint) {
+-            print STDERR "WARNING: Skipping duplicate certificate $fname\n";
+-            return;
+-        }
+-        $suffix++;
+-    }
+-    $hash .= ".$suffix";
+-    if ($symlink_exists) {
+-        print "link $fname -> $hash\n" if $verbose;
+-        symlink $fname, $hash || warn "Can't symlink, $!";
+-    } else {
+-        print "copy $fname -> $hash\n" if $verbose;
+-        if (open($in, "<", $fname)) {
+-            if (open($out,">", $hash)) {
+-                print $out $_ while (<$in>);
+-                close $out;
+-            } else {
+-                warn "can't open $hash for write, $!";
+-            }
+-            close $in;
+-        } else {
+-            warn "can't open $fname for read, $!";
+-        }
+-    }
+-    $hashlist{$hash} = $fprint;
++    link_hash($_[0], 'cert');
+ }
+ 
+ # Same as above except for a CRL. CRL links are of the form <hash>.r<n>
+ 
+ sub link_hash_crl {
+-    my $fname = $_[0];
+-    my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash,
++    link_hash($_[0], 'crl');
++}
++
++sub link_hash {
++    my ($fname, $type) = @_;
++    my $is_cert = $type eq 'cert';
++
++    my ($hash, $fprint) = compute_hash($openssl,
++                                       $is_cert ? "x509" : "crl",
++                                       $is_cert ? $x509hash : $crlhash,
+                                        "-fingerprint", "-noout",
+                                        "-in", $fname);
+     chomp $hash;
++    $hash =~ s/^.*=// if !$is_cert;
+     chomp $fprint;
+     return if !$hash;
+     $fprint =~ s/^.*=//;
+     $fprint =~ tr/://d;
+     my $suffix = 0;
+     # Search for an unused hash filename
+-    while(exists $hashlist{"$hash.r$suffix"}) {
++    my $crlmark = $is_cert ? "" : "r";
++    while(exists $hashlist{"$hash.$crlmark$suffix"}) {
+         # Hash matches: if fingerprint matches its a duplicate cert
+-        if ($hashlist{"$hash.r$suffix"} eq $fprint) {
+-            print STDERR "WARNING: Skipping duplicate CRL $fname\n";
++        if ($hashlist{"$hash.$crlmark$suffix"} eq $fprint) {
++            my $what = $is_cert ? 'certificate' : 'CRL';
++            print STDERR "WARNING: Skipping duplicate $what $fname\n";
+             return;
+         }
+         $suffix++;
+     }
+-    $hash .= ".r$suffix";
++    $hash .= ".$crlmark$suffix";
+     if ($symlink_exists) {
+         print "link $fname -> $hash\n" if $verbose;
+         symlink $fname, $hash || warn "Can't symlink, $!";
+     } else {
+-        print "cp $fname -> $hash\n" if $verbose;
+-        system ("cp", $fname, $hash);
+-        warn "Can't copy, $!" if ($? >> 8) != 0;
++        print "copy $fname -> $hash\n" if $verbose;
++        copy_file($fname, $hash);
+     }
+     $hashlist{$hash} = $fprint;
+ }
diff --git a/SOURCES/0069-CVE-2022-2097.patch b/SOURCES/0069-CVE-2022-2097.patch
new file mode 100644
index 0000000..47fcaa5
--- /dev/null
+++ b/SOURCES/0069-CVE-2022-2097.patch
@@ -0,0 +1,151 @@
+From a98f339ddd7e8f487d6e0088d4a9a42324885a93 Mon Sep 17 00:00:00 2001
+From: Alex Chernyakhovsky <achernya@google.com>
+Date: Thu, 16 Jun 2022 12:00:22 +1000
+Subject: [PATCH] Fix AES OCB encrypt/decrypt for x86 AES-NI
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+aesni_ocb_encrypt and aesni_ocb_decrypt operate by having a fast-path
+that performs operations on 6 16-byte blocks concurrently (the
+"grandloop") and then proceeds to handle the "short" tail (which can
+be anywhere from 0 to 5 blocks) that remain.
+
+As part of initialization, the assembly initializes $len to the true
+length, less 96 bytes and converts it to a pointer so that the $inp
+can be compared to it. Each iteration of "grandloop" checks to see if
+there's a full 96-byte chunk to process, and if so, continues. Once
+this has been exhausted, it falls through to "short", which handles
+the remaining zero to five blocks.
+
+Unfortunately, the jump at the end of "grandloop" had a fencepost
+error, doing a `jb` ("jump below") rather than `jbe` (jump below or
+equal). This should be `jbe`, as $inp is pointing to the *end* of the
+chunk currently being handled. If $inp == $len, that means that
+there's a whole 96-byte chunk waiting to be handled. If $inp > $len,
+then there's 5 or fewer 16-byte blocks left to be handled, and the
+fall-through is intended.
+
+The net effect of `jb` instead of `jbe` is that the last 16-byte block
+of the last 96-byte chunk was completely omitted. The contents of
+`out` in this position were never written to. Additionally, since
+those bytes were never processed, the authentication tag generated is
+also incorrect.
+
+The same fencepost error, and identical logic, exists in both
+aesni_ocb_encrypt and aesni_ocb_decrypt.
+
+This addresses CVE-2022-2097.
+
+Co-authored-by: Alejandro Sedeño <asedeno@google.com>
+Co-authored-by: David Benjamin <davidben@google.com>
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(cherry picked from commit 6ebf6d51596f51d23ccbc17930778d104a57d99c)
+Upstream-Status: Backport [https://github.com/openssl/openssl/commit/a98f339ddd7e8f487d6e0088d4a9a42324885a93]
+---
+ crypto/aes/asm/aesni-x86.pl | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/crypto/aes/asm/aesni-x86.pl b/crypto/aes/asm/aesni-x86.pl
+index 4245fe34e17e..7cf838db170b 100644
+--- a/crypto/aes/asm/aesni-x86.pl
++++ b/crypto/aes/asm/aesni-x86.pl
+@@ -2025,7 +2025,7 @@ sub aesni_generate6
+ 	&movdqu		(&QWP(-16*2,$out,$inp),$inout4);
+ 	&movdqu		(&QWP(-16*1,$out,$inp),$inout5);
+ 	&cmp		($inp,$len);			# done yet?
+-	&jb		(&label("grandloop"));
++	&jbe		(&label("grandloop"));
+ 
+ &set_label("short");
+ 	&add		($len,16*6);
+@@ -2451,7 +2451,7 @@ sub aesni_generate6
+ 	&pxor		($rndkey1,$inout5);
+ 	&movdqu		(&QWP(-16*1,$out,$inp),$inout5);
+ 	&cmp		($inp,$len);			# done yet?
+-	&jb		(&label("grandloop"));
++	&jbe		(&label("grandloop"));
+ 
+ &set_label("short");
+ 	&add		($len,16*6);
+From 52d50d52c2f1f4b70d37696bfa74fe5e581e7ba8 Mon Sep 17 00:00:00 2001
+From: Alex Chernyakhovsky <achernya@google.com>
+Date: Thu, 16 Jun 2022 12:02:37 +1000
+Subject: [PATCH] AES OCB test vectors
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Add test vectors for AES OCB for x86 AES-NI multiple of 96 byte issue.
+
+Co-authored-by: Alejandro Sedeño <asedeno@google.com>
+Co-authored-by: David Benjamin <davidben@google.com>
+
+Reviewed-by: Paul Dale <pauli@openssl.org>
+Reviewed-by: Tomas Mraz <tomas@openssl.org>
+(cherry picked from commit 2f19ab18a29cf9c82cdd68bc8c7e5be5061b19be)
+Upstream-Status: Backport [https://github.com/openssl/openssl/commit/52d50d52c2f1f4b70d37696bfa74fe5e581e7ba8]
+---
+ .../30-test_evp_data/evpciph_aes_ocb.txt      | 50 +++++++++++++++++++
+ 1 file changed, 50 insertions(+)
+
+diff --git a/test/recipes/30-test_evp_data/evpciph_aes_ocb.txt b/test/recipes/30-test_evp_data/evpciph_aes_ocb.txt
+index e58ee34b6b3f..de098905230b 100644
+--- a/test/recipes/30-test_evp_data/evpciph_aes_ocb.txt
++++ b/test/recipes/30-test_evp_data/evpciph_aes_ocb.txt
+@@ -207,3 +207,53 @@ Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F2021
+ Ciphertext = 09A4FD29DE949D9A9AA9924248422097AD4883B4713E6C214FF6567ADA08A967B2176C12F110DD441B7CAA3A509B13C86A023AFCEE998BEE42028D44507B15F77C528A1DE6406B519BCEE8FCB829417001E54E15A7576C4DF32366E0F439C7051CB4824B8114E9A720CBC1CE0185B156B486
+ Operation = DECRYPT
+ Result = CIPHERFINAL_ERROR
++
++#Test vectors generated to validate aesni_ocb_encrypt on x86
++Cipher = aes-128-ocb
++Key = 000102030405060708090A0B0C0D0E0F
++IV = 000000000001020304050607
++Tag = C14DFF7D62A13C4A3422456207453190
++Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F
++Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B819333
++
++Cipher = aes-128-ocb
++Key = 000102030405060708090A0B0C0D0E0F
++IV = 000000000001020304050607
++Tag = D47D84F6FF912C79B6A4223AB9BE2DB8
++Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F
++Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC204
++
++Cipher = aes-128-ocb
++Key = 000102030405060708090A0B0C0D0E0F
++IV = 000000000001020304050607
++Tag = 41970D13737B7BD1B5FBF49ED4412CA5
++Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D
++Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91
++
++Cipher = aes-128-ocb
++Key = 000102030405060708090A0B0C0D0E0F
++IV = 000000000001020304050607
++Tag = BE0228651ED4E48A11BDED68D953F3A0
++Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D
++Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F
++
++Cipher = aes-128-ocb
++Key = 000102030405060708090A0B0C0D0E0F
++IV = 000000000001020304050607
++Tag = 17BC6E10B16E5FDC52836E7D589518C7
++Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D
++Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B
++
++Cipher = aes-128-ocb
++Key = 000102030405060708090A0B0C0D0E0F
++IV = 000000000001020304050607
++Tag = E84AAC18666116990A3A37B3A5FC55BD
++Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D
++Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B11CF99263D693AEBDF8ADE1A1D838DED
++
++Cipher = aes-128-ocb
++Key = 000102030405060708090A0B0C0D0E0F
++IV = 000000000001020304050607
++Tag = 3E5EA7EE064FE83B313E28D411E91EAD
++Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D4E4F505152535455565758595A5B5C5D5E5F606162636465666768696A6B6C6D6E6F7071000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132333435363738393A3B3C3D3E3F404142434445464748494A4B4C4D
++Ciphertext = F5186C9CC3506386919B6FD9443956E05B203313F8AB35E916AB36932EBDDCD2945901BABE7CF29404929F322F954C916065FABF8F1E52F4BD7C538C0F96899519DBC6BC504D837D8EBD1436B45D33F528CB642FA2EB2C403FE604C12B8193332374120A78A1171D23ED9E9CB1ADC20412C017AD0CA498827C768DDD99B26E91EDB8681700FF30366F07AEDE8CEACC1F39BE69B91BC808FA7A193F7EEA43137B11CF99263D693AEBDF8ADE1A1D838DED48D9E09F452F8E6FBEB76A3DED47611C
diff --git a/SOURCES/0070-EVP_PKEY_Q_keygen-Call-OPENSSL_init_crypto-to-init-s.patch b/SOURCES/0070-EVP_PKEY_Q_keygen-Call-OPENSSL_init_crypto-to-init-s.patch
new file mode 100644
index 0000000..5a16ae7
--- /dev/null
+++ b/SOURCES/0070-EVP_PKEY_Q_keygen-Call-OPENSSL_init_crypto-to-init-s.patch
@@ -0,0 +1,56 @@
+From edceec7fe0c9a5534ae155c8398c63dd7dd95483 Mon Sep 17 00:00:00 2001
+From: Tomas Mraz <tomas@openssl.org>
+Date: Thu, 5 May 2022 08:11:24 +0200
+Subject: [PATCH] EVP_PKEY_Q_keygen: Call OPENSSL_init_crypto to init
+ strcasecmp
+
+Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
+Reviewed-by: Matt Caswell <matt@openssl.org>
+(Merged from https://github.com/openssl/openssl/pull/18247)
+
+(cherry picked from commit b807c2fbab2128cf3746bb2ebd51cbe3bb6914a9)
+
+Upstream-Status: Backport [https://github.com/openssl/openssl/commit/edceec7fe0c9a5534ae155c8398c63dd7dd95483]
+---
+ crypto/evp/evp_lib.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/crypto/evp/evp_lib.c b/crypto/evp/evp_lib.c
+index 3fe4743761..d9b8c0af41 100644
+--- a/crypto/evp/evp_lib.c
++++ b/crypto/evp/evp_lib.c
+@@ -24,6 +24,7 @@
+ #include <openssl/dh.h>
+ #include <openssl/ec.h>
+ #include "crypto/evp.h"
++#include "crypto/cryptlib.h"
+ #include "internal/provider.h"
+ #include "evp_local.h"
+ 
+@@ -1094,6 +1095,8 @@ int EVP_CIPHER_CTX_test_flags(const EVP_CIPHER_CTX *ctx, int flags)
+     return (ctx->flags & flags);
+ }
+ 
++#if !defined(FIPS_MODULE)
++
+ int EVP_PKEY_CTX_set_group_name(EVP_PKEY_CTX *ctx, const char *name)
+ {
+     OSSL_PARAM params[] = { OSSL_PARAM_END, OSSL_PARAM_END };
+@@ -1169,6 +1172,8 @@ EVP_PKEY *EVP_PKEY_Q_keygen(OSSL_LIB_CTX *libctx, const char *propq,
+ 
+     va_start(args, type);
+ 
++    OPENSSL_init_crypto(OPENSSL_INIT_BASE_ONLY, NULL);
++
+     if (OPENSSL_strcasecmp(type, "RSA") == 0) {
+         bits = va_arg(args, size_t);
+         params[0] = OSSL_PARAM_construct_size_t(OSSL_PKEY_PARAM_RSA_BITS, &bits);
+@@ -1189,3 +1194,5 @@ EVP_PKEY *EVP_PKEY_Q_keygen(OSSL_LIB_CTX *libctx, const char *propq,
+     va_end(args);
+     return ret;
+ }
++
++#endif /* !defined(FIPS_MODULE) */
+-- 
+2.35.3
+
diff --git a/SOURCES/0071-AES-GCM-performance-optimization.patch b/SOURCES/0071-AES-GCM-performance-optimization.patch
new file mode 100644
index 0000000..edf40ec
--- /dev/null
+++ b/SOURCES/0071-AES-GCM-performance-optimization.patch
@@ -0,0 +1,1635 @@
+Upstream-Status: Backport [https://github.com/openssl/openssl/commit/44a563dde1584cd9284e80b6e45ee5019be8d36c, https://github.com/openssl/openssl/commit/345c99b6654b8313c792d54f829943068911ddbd]
+diff --git a/crypto/modes/asm/aes-gcm-ppc.pl b/crypto/modes/asm/aes-gcm-ppc.pl
+new file mode 100644
+index 0000000..6624e6c
+--- /dev/null
++++ b/crypto/modes/asm/aes-gcm-ppc.pl
+@@ -0,0 +1,1438 @@
++#! /usr/bin/env perl
++# Copyright 2014-2020 The OpenSSL Project Authors. All Rights Reserved.
++# Copyright 2021- IBM Inc. 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 Danny Tsen <dtsen@us.ibm.com> for OpenSSL Project,
++#
++# GHASH is based on the Karatsuba multiplication method.
++#
++#    Xi xor X1
++#
++#    X1 * H^4 + X2 * H^3 + x3 * H^2 + X4 * H =
++#      (X1.h * H4.h + xX.l * H4.l + X1 * H4) +
++#      (X2.h * H3.h + X2.l * H3.l + X2 * H3) +
++#      (X3.h * H2.h + X3.l * H2.l + X3 * H2) +
++#      (X4.h * H.h + X4.l * H.l + X4 * H)
++#
++# Xi = v0
++# H Poly = v2
++# Hash keys = v3 - v14
++#     ( H.l, H, H.h)
++#     ( H^2.l, H^2, H^2.h)
++#     ( H^3.l, H^3, H^3.h)
++#     ( H^4.l, H^4, H^4.h)
++#
++# v30 is IV
++# v31 - counter 1
++#
++# AES used,
++#     vs0 - vs14 for round keys
++#     v15, v16, v17, v18, v19, v20, v21, v22 for 8 blocks (encrypted)
++#
++# This implementation uses stitched AES-GCM approach to improve overall performance.
++# AES is implemented with 8x blocks and GHASH is using 2 4x blocks.
++#
++# Current large block (16384 bytes) performance per second with 128 bit key --
++#
++#                        Encrypt  Decrypt
++# Power10[le] (3.5GHz)   5.32G    5.26G
++#
++# ===================================================================================
++#
++# $output is the last argument if it looks like a file (it has an extension)
++# $flavour is the first argument if it doesn't look like a file
++$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
++$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
++
++if ($flavour =~ /64/) {
++	$SIZE_T=8;
++	$LRSAVE=2*$SIZE_T;
++	$STU="stdu";
++	$POP="ld";
++	$PUSH="std";
++	$UCMP="cmpld";
++	$SHRI="srdi";
++} elsif ($flavour =~ /32/) {
++	$SIZE_T=4;
++	$LRSAVE=$SIZE_T;
++	$STU="stwu";
++	$POP="lwz";
++	$PUSH="stw";
++	$UCMP="cmplw";
++	$SHRI="srwi";
++} else { die "nonsense $flavour"; }
++
++$sp="r1";
++$FRAME=6*$SIZE_T+13*16;	# 13*16 is for v20-v31 offload
++
++$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 STDOUT,"| $^X $xlate $flavour \"$output\""
++    or die "can't call $xlate: $!";
++
++$code=<<___;
++.machine        "any"
++.text
++
++# 4x loops
++# v15 - v18 - input states
++# vs1 - vs9 - round keys
++#
++.macro Loop_aes_middle4x
++	xxlor	19+32, 1, 1
++	xxlor	20+32, 2, 2
++	xxlor	21+32, 3, 3
++	xxlor	22+32, 4, 4
++
++	vcipher	15, 15, 19
++	vcipher	16, 16, 19
++	vcipher	17, 17, 19
++	vcipher	18, 18, 19
++
++	vcipher	15, 15, 20
++	vcipher	16, 16, 20
++	vcipher	17, 17, 20
++	vcipher	18, 18, 20
++
++	vcipher	15, 15, 21
++	vcipher	16, 16, 21
++	vcipher	17, 17, 21
++	vcipher	18, 18, 21
++
++	vcipher	15, 15, 22
++	vcipher	16, 16, 22
++	vcipher	17, 17, 22
++	vcipher	18, 18, 22
++
++	xxlor	19+32, 5, 5
++	xxlor	20+32, 6, 6
++	xxlor	21+32, 7, 7
++	xxlor	22+32, 8, 8
++
++	vcipher	15, 15, 19
++	vcipher	16, 16, 19
++	vcipher	17, 17, 19
++	vcipher	18, 18, 19
++
++	vcipher	15, 15, 20
++	vcipher	16, 16, 20
++	vcipher	17, 17, 20
++	vcipher	18, 18, 20
++
++	vcipher	15, 15, 21
++	vcipher	16, 16, 21
++	vcipher	17, 17, 21
++	vcipher	18, 18, 21
++
++	vcipher	15, 15, 22
++	vcipher	16, 16, 22
++	vcipher	17, 17, 22
++	vcipher	18, 18, 22
++
++	xxlor	23+32, 9, 9
++	vcipher	15, 15, 23
++	vcipher	16, 16, 23
++	vcipher	17, 17, 23
++	vcipher	18, 18, 23
++.endm
++
++# 8x loops
++# v15 - v22 - input states
++# vs1 - vs9 - round keys
++#
++.macro Loop_aes_middle8x
++	xxlor	23+32, 1, 1
++	xxlor	24+32, 2, 2
++	xxlor	25+32, 3, 3
++	xxlor	26+32, 4, 4
++
++	vcipher	15, 15, 23
++	vcipher	16, 16, 23
++	vcipher	17, 17, 23
++	vcipher	18, 18, 23
++	vcipher	19, 19, 23
++	vcipher	20, 20, 23
++	vcipher	21, 21, 23
++	vcipher	22, 22, 23
++
++	vcipher	15, 15, 24
++	vcipher	16, 16, 24
++	vcipher	17, 17, 24
++	vcipher	18, 18, 24
++	vcipher	19, 19, 24
++	vcipher	20, 20, 24
++	vcipher	21, 21, 24
++	vcipher	22, 22, 24
++
++	vcipher	15, 15, 25
++	vcipher	16, 16, 25
++	vcipher	17, 17, 25
++	vcipher	18, 18, 25
++	vcipher	19, 19, 25
++	vcipher	20, 20, 25
++	vcipher	21, 21, 25
++	vcipher	22, 22, 25
++
++	vcipher	15, 15, 26
++	vcipher	16, 16, 26
++	vcipher	17, 17, 26
++	vcipher	18, 18, 26
++	vcipher	19, 19, 26
++	vcipher	20, 20, 26
++	vcipher	21, 21, 26
++	vcipher	22, 22, 26
++
++	xxlor	23+32, 5, 5
++	xxlor	24+32, 6, 6
++	xxlor	25+32, 7, 7
++	xxlor	26+32, 8, 8
++
++	vcipher	15, 15, 23
++	vcipher	16, 16, 23
++	vcipher	17, 17, 23
++	vcipher	18, 18, 23
++	vcipher	19, 19, 23
++	vcipher	20, 20, 23
++	vcipher	21, 21, 23
++	vcipher	22, 22, 23
++
++	vcipher	15, 15, 24
++	vcipher	16, 16, 24
++	vcipher	17, 17, 24
++	vcipher	18, 18, 24
++	vcipher	19, 19, 24
++	vcipher	20, 20, 24
++	vcipher	21, 21, 24
++	vcipher	22, 22, 24
++
++	vcipher	15, 15, 25
++	vcipher	16, 16, 25
++	vcipher	17, 17, 25
++	vcipher	18, 18, 25
++	vcipher	19, 19, 25
++	vcipher	20, 20, 25
++	vcipher	21, 21, 25
++	vcipher	22, 22, 25
++
++	vcipher	15, 15, 26
++	vcipher	16, 16, 26
++	vcipher	17, 17, 26
++	vcipher	18, 18, 26
++	vcipher	19, 19, 26
++	vcipher	20, 20, 26
++	vcipher	21, 21, 26
++	vcipher	22, 22, 26
++
++	xxlor	23+32, 9, 9
++	vcipher	15, 15, 23
++	vcipher	16, 16, 23
++	vcipher	17, 17, 23
++	vcipher	18, 18, 23
++	vcipher	19, 19, 23
++	vcipher	20, 20, 23
++	vcipher	21, 21, 23
++	vcipher	22, 22, 23
++.endm
++
++#
++# Compute 4x hash values based on Karatsuba method.
++#
++ppc_aes_gcm_ghash:
++	vxor		15, 15, 0
++
++	xxlxor		29, 29, 29
++
++	vpmsumd		23, 12, 15		# H4.L * X.L
++	vpmsumd		24, 9, 16
++	vpmsumd		25, 6, 17
++	vpmsumd		26, 3, 18
++
++	vxor		23, 23, 24
++	vxor		23, 23, 25
++	vxor		23, 23, 26		# L
++
++	vpmsumd		24, 13, 15		# H4.L * X.H + H4.H * X.L
++	vpmsumd		25, 10, 16		# H3.L * X1.H + H3.H * X1.L
++	vpmsumd		26, 7, 17
++	vpmsumd		27, 4, 18
++
++	vxor		24, 24, 25
++	vxor		24, 24, 26
++	vxor		24, 24, 27		# M
++
++	# sum hash and reduction with H Poly
++	vpmsumd		28, 23, 2		# reduction
++
++	xxlor		29+32, 29, 29
++	vsldoi		26, 24, 29, 8		# mL
++	vsldoi		29, 29, 24, 8		# mH
++	vxor		23, 23, 26		# mL + L
++
++	vsldoi		23, 23, 23, 8		# swap
++	vxor		23, 23, 28
++
++	vpmsumd		24, 14, 15		# H4.H * X.H
++	vpmsumd		25, 11, 16
++	vpmsumd		26, 8, 17
++	vpmsumd		27, 5, 18
++
++	vxor		24, 24, 25
++	vxor		24, 24, 26
++	vxor		24, 24, 27
++
++	vxor		24, 24, 29
++
++	# sum hash and reduction with H Poly
++	vsldoi		27, 23, 23, 8		# swap
++	vpmsumd		23, 23, 2
++	vxor		27, 27, 24
++	vxor		23, 23, 27
++
++	xxlor		32, 23+32, 23+32		# update hash
++
++	blr
++
++#
++# Combine two 4x ghash
++# v15 - v22 - input blocks
++#
++.macro ppc_aes_gcm_ghash2_4x
++	# first 4x hash
++	vxor		15, 15, 0		# Xi + X
++
++	xxlxor		29, 29, 29
++
++	vpmsumd		23, 12, 15		# H4.L * X.L
++	vpmsumd		24, 9, 16
++	vpmsumd		25, 6, 17
++	vpmsumd		26, 3, 18
++
++	vxor		23, 23, 24
++	vxor		23, 23, 25
++	vxor		23, 23, 26		# L
++
++	vpmsumd		24, 13, 15		# H4.L * X.H + H4.H * X.L
++	vpmsumd		25, 10, 16		# H3.L * X1.H + H3.H * X1.L
++	vpmsumd		26, 7, 17
++	vpmsumd		27, 4, 18
++
++	vxor		24, 24, 25
++	vxor		24, 24, 26
++
++	# sum hash and reduction with H Poly
++	vpmsumd		28, 23, 2		# reduction
++
++	xxlor		29+32, 29, 29
++
++	vxor		24, 24, 27		# M
++	vsldoi		26, 24, 29, 8		# mL
++	vsldoi		29, 29, 24, 8		# mH
++	vxor		23, 23, 26		# mL + L
++
++	vsldoi		23, 23, 23, 8		# swap
++	vxor		23, 23, 28
++
++	vpmsumd		24, 14, 15		# H4.H * X.H
++	vpmsumd		25, 11, 16
++	vpmsumd		26, 8, 17
++	vpmsumd		27, 5, 18
++
++	vxor		24, 24, 25
++	vxor		24, 24, 26
++	vxor		24, 24, 27		# H
++
++	vxor		24, 24, 29		# H + mH
++
++	# sum hash and reduction with H Poly
++	vsldoi		27, 23, 23, 8		# swap
++	vpmsumd		23, 23, 2
++	vxor		27, 27, 24
++	vxor		27, 23, 27		# 1st Xi
++
++	# 2nd 4x hash
++	vpmsumd		24, 9, 20
++	vpmsumd		25, 6, 21
++	vpmsumd		26, 3, 22
++	vxor		19, 19, 27		# Xi + X
++	vpmsumd		23, 12, 19		# H4.L * X.L
++
++	vxor		23, 23, 24
++	vxor		23, 23, 25
++	vxor		23, 23, 26		# L
++
++	vpmsumd		24, 13, 19		# H4.L * X.H + H4.H * X.L
++	vpmsumd		25, 10, 20		# H3.L * X1.H + H3.H * X1.L
++	vpmsumd		26, 7, 21
++	vpmsumd		27, 4, 22
++
++	vxor		24, 24, 25
++	vxor		24, 24, 26
++
++	# sum hash and reduction with H Poly
++	vpmsumd		28, 23, 2		# reduction
++
++	xxlor		29+32, 29, 29
++
++	vxor		24, 24, 27		# M
++	vsldoi		26, 24, 29, 8		# mL
++	vsldoi		29, 29, 24, 8		# mH
++	vxor		23, 23, 26		# mL + L
++
++	vsldoi		23, 23, 23, 8		# swap
++	vxor		23, 23, 28
++
++	vpmsumd		24, 14, 19		# H4.H * X.H
++	vpmsumd		25, 11, 20
++	vpmsumd		26, 8, 21
++	vpmsumd		27, 5, 22
++
++	vxor		24, 24, 25
++	vxor		24, 24, 26
++	vxor		24, 24, 27		# H
++
++	vxor		24, 24, 29		# H + mH
++
++	# sum hash and reduction with H Poly
++	vsldoi		27, 23, 23, 8		# swap
++	vpmsumd		23, 23, 2
++	vxor		27, 27, 24
++	vxor		23, 23, 27
++
++	xxlor		32, 23+32, 23+32		# update hash
++
++.endm
++
++#
++# Compute update single hash
++#
++.macro ppc_update_hash_1x
++	vxor		28, 28, 0
++
++	vxor		19, 19, 19
++
++	vpmsumd		22, 3, 28		# L
++	vpmsumd		23, 4, 28		# M
++	vpmsumd		24, 5, 28		# H
++
++	vpmsumd		27, 22, 2		# reduction
++
++	vsldoi		25, 23, 19, 8		# mL
++	vsldoi		26, 19, 23, 8		# mH
++	vxor		22, 22, 25		# LL + LL
++	vxor		24, 24, 26		# HH + HH
++
++	vsldoi		22, 22, 22, 8		# swap
++	vxor		22, 22, 27
++
++	vsldoi		20, 22, 22, 8		# swap
++	vpmsumd		22, 22, 2		# reduction
++	vxor		20, 20, 24
++	vxor		22, 22, 20
++
++	vmr		0, 22			# update hash
++
++.endm
++
++#
++# ppc_aes_gcm_encrypt (const void *inp, void *out, size_t len,
++#               const AES_KEY *key, unsigned char iv[16],
++#               void *Xip);
++#
++#    r3 - inp
++#    r4 - out
++#    r5 - len
++#    r6 - AES round keys
++#    r7 - iv
++#    r8 - Xi, HPoli, hash keys
++#
++.global ppc_aes_gcm_encrypt
++.align 5
++ppc_aes_gcm_encrypt:
++_ppc_aes_gcm_encrypt:
++
++	stdu 1,-512(1)
++	mflr 0
++
++	std	14,112(1)
++	std	15,120(1)
++	std	16,128(1)
++	std	17,136(1)
++	std	18,144(1)
++	std	19,152(1)
++	std	20,160(1)
++	std	21,168(1)
++	li	9, 256
++	stvx	20, 9, 1
++	addi	9, 9, 16
++	stvx	21, 9, 1
++	addi	9, 9, 16
++	stvx	22, 9, 1
++	addi	9, 9, 16
++	stvx	23, 9, 1
++	addi	9, 9, 16
++	stvx	24, 9, 1
++	addi	9, 9, 16
++	stvx	25, 9, 1
++	addi	9, 9, 16
++	stvx	26, 9, 1
++	addi	9, 9, 16
++	stvx	27, 9, 1
++	addi	9, 9, 16
++	stvx	28, 9, 1
++	addi	9, 9, 16
++	stvx	29, 9, 1
++	addi	9, 9, 16
++	stvx	30, 9, 1
++	addi	9, 9, 16
++	stvx	31, 9, 1
++	std	0, 528(1)
++
++	# Load Xi
++	lxvb16x	32, 0, 8	# load Xi
++
++	# load Hash - h^4, h^3, h^2, h
++	li	10, 32
++	lxvd2x	2+32, 10, 8	# H Poli
++	li	10, 48
++	lxvd2x	3+32, 10, 8	# Hl
++	li	10, 64
++	lxvd2x	4+32, 10, 8	# H
++	li	10, 80
++	lxvd2x	5+32, 10, 8	# Hh
++
++	li	10, 96
++	lxvd2x	6+32, 10, 8	# H^2l
++	li	10, 112
++	lxvd2x	7+32, 10, 8	# H^2
++	li	10, 128
++	lxvd2x	8+32, 10, 8	# H^2h
++
++	li	10, 144
++	lxvd2x	9+32, 10, 8	# H^3l
++	li	10, 160
++	lxvd2x	10+32, 10, 8	# H^3
++	li	10, 176
++	lxvd2x	11+32, 10, 8	# H^3h
++
++	li	10, 192
++	lxvd2x	12+32, 10, 8	# H^4l
++	li	10, 208
++	lxvd2x	13+32, 10, 8	# H^4
++	li	10, 224
++	lxvd2x	14+32, 10, 8	# H^4h
++
++	# initialize ICB: GHASH( IV ), IV - r7
++	lxvb16x	30+32, 0, 7	# load IV  - v30
++
++	mr	12, 5		# length
++	li	11, 0		# block index
++
++	# counter 1
++	vxor	31, 31, 31
++	vspltisb 22, 1
++	vsldoi	31, 31, 22,1	# counter 1
++
++	# load round key to VSR
++	lxv	0, 0(6)
++	lxv	1, 0x10(6)
++	lxv	2, 0x20(6)
++	lxv	3, 0x30(6)
++	lxv	4, 0x40(6)
++	lxv	5, 0x50(6)
++	lxv	6, 0x60(6)
++	lxv	7, 0x70(6)
++	lxv	8, 0x80(6)
++	lxv	9, 0x90(6)
++	lxv	10, 0xa0(6)
++
++	# load rounds - 10 (128), 12 (192), 14 (256)
++	lwz	9,240(6)
++
++	#
++	# vxor	state, state, w # addroundkey
++	xxlor	32+29, 0, 0
++	vxor	15, 30, 29	# IV + round key - add round key 0
++
++	cmpdi	9, 10
++	beq	Loop_aes_gcm_8x
++
++	# load 2 more round keys (v11, v12)
++	lxv	11, 0xb0(6)
++	lxv	12, 0xc0(6)
++
++	cmpdi	9, 12
++	beq	Loop_aes_gcm_8x
++
++	# load 2 more round keys (v11, v12, v13, v14)
++	lxv	13, 0xd0(6)
++	lxv	14, 0xe0(6)
++	cmpdi	9, 14
++	beq	Loop_aes_gcm_8x
++
++	b	aes_gcm_out
++
++.align 5
++Loop_aes_gcm_8x:
++	mr	14, 3
++	mr	9, 4
++
++	# n blocks
++	li	10, 128
++	divdu	10, 5, 10	# n 128 bytes-blocks
++	cmpdi	10, 0
++	beq	Loop_last_block
++
++	vaddudm	30, 30, 31	# IV + counter
++	vxor	16, 30, 29
++	vaddudm	30, 30, 31
++	vxor	17, 30, 29
++	vaddudm	30, 30, 31
++	vxor	18, 30, 29
++	vaddudm	30, 30, 31
++	vxor	19, 30, 29
++	vaddudm	30, 30, 31
++	vxor	20, 30, 29
++	vaddudm	30, 30, 31
++	vxor	21, 30, 29
++	vaddudm	30, 30, 31
++	vxor	22, 30, 29
++
++	mtctr	10
++
++	li	15, 16
++	li	16, 32
++	li	17, 48
++	li	18, 64
++	li	19, 80
++	li	20, 96
++	li	21, 112
++
++	lwz	10, 240(6)
++
++Loop_8x_block:
++
++	lxvb16x		15, 0, 14	# load block
++	lxvb16x		16, 15, 14	# load block
++	lxvb16x		17, 16, 14	# load block
++	lxvb16x		18, 17, 14	# load block
++	lxvb16x		19, 18, 14	# load block
++	lxvb16x		20, 19, 14	# load block
++	lxvb16x		21, 20, 14	# load block
++	lxvb16x		22, 21, 14	# load block
++	addi		14, 14, 128
++
++	Loop_aes_middle8x
++
++	xxlor	23+32, 10, 10
++
++	cmpdi	10, 10
++	beq	Do_next_ghash
++
++	# 192 bits
++	xxlor	24+32, 11, 11
++
++	vcipher	15, 15, 23
++	vcipher	16, 16, 23
++	vcipher	17, 17, 23
++	vcipher	18, 18, 23
++	vcipher	19, 19, 23
++	vcipher	20, 20, 23
++	vcipher	21, 21, 23
++	vcipher	22, 22, 23
++
++	vcipher	15, 15, 24
++	vcipher	16, 16, 24
++	vcipher	17, 17, 24
++	vcipher	18, 18, 24
++	vcipher	19, 19, 24
++	vcipher	20, 20, 24
++	vcipher	21, 21, 24
++	vcipher	22, 22, 24
++
++	xxlor	23+32, 12, 12
++
++	cmpdi	10, 12
++	beq	Do_next_ghash
++
++	# 256 bits
++	xxlor	24+32, 13, 13
++
++	vcipher	15, 15, 23
++	vcipher	16, 16, 23
++	vcipher	17, 17, 23
++	vcipher	18, 18, 23
++	vcipher	19, 19, 23
++	vcipher	20, 20, 23
++	vcipher	21, 21, 23
++	vcipher	22, 22, 23
++
++	vcipher	15, 15, 24
++	vcipher	16, 16, 24
++	vcipher	17, 17, 24
++	vcipher	18, 18, 24
++	vcipher	19, 19, 24
++	vcipher	20, 20, 24
++	vcipher	21, 21, 24
++	vcipher	22, 22, 24
++
++	xxlor	23+32, 14, 14
++
++	cmpdi	10, 14
++	beq	Do_next_ghash
++	b	aes_gcm_out
++
++Do_next_ghash:
++
++	#
++	# last round
++	vcipherlast     15, 15, 23
++	vcipherlast     16, 16, 23
++
++	xxlxor		47, 47, 15
++	stxvb16x        47, 0, 9	# store output
++	xxlxor		48, 48, 16
++	stxvb16x        48, 15, 9	# store output
++
++	vcipherlast     17, 17, 23
++	vcipherlast     18, 18, 23
++
++	xxlxor		49, 49, 17
++	stxvb16x        49, 16, 9	# store output
++	xxlxor		50, 50, 18
++	stxvb16x        50, 17, 9	# store output
++
++	vcipherlast     19, 19, 23
++	vcipherlast     20, 20, 23
++
++	xxlxor		51, 51, 19
++	stxvb16x        51, 18, 9	# store output
++	xxlxor		52, 52, 20
++	stxvb16x        52, 19, 9	# store output
++
++	vcipherlast     21, 21, 23
++	vcipherlast     22, 22, 23
++
++	xxlxor		53, 53, 21
++	stxvb16x        53, 20, 9	# store output
++	xxlxor		54, 54, 22
++	stxvb16x        54, 21, 9	# store output
++
++	addi		9, 9, 128
++
++	# ghash here
++	ppc_aes_gcm_ghash2_4x
++
++	xxlor	27+32, 0, 0
++	vaddudm 30, 30, 31		# IV + counter
++	vmr	29, 30
++	vxor    15, 30, 27		# add round key
++	vaddudm 30, 30, 31
++	vxor    16, 30, 27
++	vaddudm 30, 30, 31
++	vxor    17, 30, 27
++	vaddudm 30, 30, 31
++	vxor    18, 30, 27
++	vaddudm 30, 30, 31
++	vxor    19, 30, 27
++	vaddudm 30, 30, 31
++	vxor    20, 30, 27
++	vaddudm 30, 30, 31
++	vxor    21, 30, 27
++	vaddudm 30, 30, 31
++	vxor    22, 30, 27
++
++	addi    12, 12, -128
++	addi    11, 11, 128
++
++	bdnz	Loop_8x_block
++
++	vmr	30, 29
++
++Loop_last_block:
++	cmpdi   12, 0
++	beq     aes_gcm_out
++
++	# loop last few blocks
++	li      10, 16
++	divdu   10, 12, 10
++
++	mtctr   10
++
++	lwz	10, 240(6)
++
++	cmpdi   12, 16
++	blt     Final_block
++
++.macro Loop_aes_middle_1x
++	xxlor	19+32, 1, 1
++	xxlor	20+32, 2, 2
++	xxlor	21+32, 3, 3
++	xxlor	22+32, 4, 4
++
++	vcipher 15, 15, 19
++	vcipher 15, 15, 20
++	vcipher 15, 15, 21
++	vcipher 15, 15, 22
++
++	xxlor	19+32, 5, 5
++	xxlor	20+32, 6, 6
++	xxlor	21+32, 7, 7
++	xxlor	22+32, 8, 8
++
++	vcipher 15, 15, 19
++	vcipher 15, 15, 20
++	vcipher 15, 15, 21
++	vcipher 15, 15, 22
++
++	xxlor	19+32, 9, 9
++	vcipher 15, 15, 19
++.endm
++
++Next_rem_block:
++	lxvb16x 15, 0, 14		# load block
++
++	Loop_aes_middle_1x
++
++	xxlor	23+32, 10, 10
++
++	cmpdi	10, 10
++	beq	Do_next_1x
++
++	# 192 bits
++	xxlor	24+32, 11, 11
++
++	vcipher	15, 15, 23
++	vcipher	15, 15, 24
++
++	xxlor	23+32, 12, 12
++
++	cmpdi	10, 12
++	beq	Do_next_1x
++
++	# 256 bits
++	xxlor	24+32, 13, 13
++
++	vcipher	15, 15, 23
++	vcipher	15, 15, 24
++
++	xxlor	23+32, 14, 14
++
++	cmpdi	10, 14
++	beq	Do_next_1x
++
++Do_next_1x:
++	vcipherlast     15, 15, 23
++
++	xxlxor		47, 47, 15
++	stxvb16x	47, 0, 9	# store output
++	addi		14, 14, 16
++	addi		9, 9, 16
++
++	vmr		28, 15
++	ppc_update_hash_1x
++
++	addi		12, 12, -16
++	addi		11, 11, 16
++	xxlor		19+32, 0, 0
++	vaddudm		30, 30, 31		# IV + counter
++	vxor		15, 30, 19		# add round key
++
++	bdnz	Next_rem_block
++
++	cmpdi	12, 0
++	beq	aes_gcm_out
++
++Final_block:
++	Loop_aes_middle_1x
++
++	xxlor	23+32, 10, 10
++
++	cmpdi	10, 10
++	beq	Do_final_1x
++
++	# 192 bits
++	xxlor	24+32, 11, 11
++
++	vcipher	15, 15, 23
++	vcipher	15, 15, 24
++
++	xxlor	23+32, 12, 12
++
++	cmpdi	10, 12
++	beq	Do_final_1x
++
++	# 256 bits
++	xxlor	24+32, 13, 13
++
++	vcipher	15, 15, 23
++	vcipher	15, 15, 24
++
++	xxlor	23+32, 14, 14
++
++	cmpdi	10, 14
++	beq	Do_final_1x
++
++Do_final_1x:
++	vcipherlast     15, 15, 23
++
++	lxvb16x	15, 0, 14		# load last block
++	xxlxor	47, 47, 15
++
++	# create partial block mask
++	li	15, 16
++	sub	15, 15, 12		# index to the mask
++
++	vspltisb	16, -1		# first 16 bytes - 0xffff...ff
++	vspltisb	17, 0		# second 16 bytes - 0x0000...00
++	li	10, 192
++	stvx	16, 10, 1
++	addi	10, 10, 16
++	stvx	17, 10, 1
++
++	addi	10, 1, 192
++	lxvb16x	16, 15, 10		# load partial block mask
++	xxland	47, 47, 16
++
++	vmr	28, 15
++	ppc_update_hash_1x
++
++	# * should store only the remaining bytes.
++	bl	Write_partial_block
++
++	b aes_gcm_out
++
++#
++# Write partial block
++# r9 - output
++# r12 - remaining bytes
++# v15 - partial input data
++#
++Write_partial_block:
++	li		10, 192
++	stxvb16x	15+32, 10, 1		# last block
++
++	#add		10, 9, 11		# Output
++	addi		10, 9, -1
++	addi		16, 1, 191
++
++        mtctr		12			# remaining bytes
++	li		15, 0
++
++Write_last_byte:
++        lbzu		14, 1(16)
++	stbu		14, 1(10)
++        bdnz		Write_last_byte
++	blr
++
++aes_gcm_out:
++	# out = state
++	stxvb16x	32, 0, 8		# write out Xi
++	add	3, 11, 12		# return count
++
++	li	9, 256
++	lvx	20, 9, 1
++	addi	9, 9, 16
++	lvx	21, 9, 1
++	addi	9, 9, 16
++	lvx	22, 9, 1
++	addi	9, 9, 16
++	lvx	23, 9, 1
++	addi	9, 9, 16
++	lvx	24, 9, 1
++	addi	9, 9, 16
++	lvx	25, 9, 1
++	addi	9, 9, 16
++	lvx	26, 9, 1
++	addi	9, 9, 16
++	lvx	27, 9, 1
++	addi	9, 9, 16
++	lvx	28, 9, 1
++	addi	9, 9, 16
++	lvx	29, 9, 1
++	addi	9, 9, 16
++	lvx	30, 9, 1
++	addi	9, 9, 16
++	lvx	31, 9, 1
++
++	ld	0, 528(1)
++	ld      14,112(1)
++	ld      15,120(1)
++	ld      16,128(1)
++	ld      17,136(1)
++	ld      18,144(1)
++	ld      19,152(1)
++	ld      20,160(1)
++	ld	21,168(1)
++
++	mtlr	0
++	addi	1, 1, 512
++	blr
++
++#
++# 8x Decrypt
++#
++.global ppc_aes_gcm_decrypt
++.align 5
++ppc_aes_gcm_decrypt:
++_ppc_aes_gcm_decrypt:
++
++	stdu 1,-512(1)
++	mflr 0
++
++	std	14,112(1)
++	std	15,120(1)
++	std	16,128(1)
++	std	17,136(1)
++	std	18,144(1)
++	std	19,152(1)
++	std	20,160(1)
++	std	21,168(1)
++	li	9, 256
++	stvx	20, 9, 1
++	addi	9, 9, 16
++	stvx	21, 9, 1
++	addi	9, 9, 16
++	stvx	22, 9, 1
++	addi	9, 9, 16
++	stvx	23, 9, 1
++	addi	9, 9, 16
++	stvx	24, 9, 1
++	addi	9, 9, 16
++	stvx	25, 9, 1
++	addi	9, 9, 16
++	stvx	26, 9, 1
++	addi	9, 9, 16
++	stvx	27, 9, 1
++	addi	9, 9, 16
++	stvx	28, 9, 1
++	addi	9, 9, 16
++	stvx	29, 9, 1
++	addi	9, 9, 16
++	stvx	30, 9, 1
++	addi	9, 9, 16
++	stvx	31, 9, 1
++	std	0, 528(1)
++
++	# Load Xi
++	lxvb16x	32, 0, 8	# load Xi
++
++	# load Hash - h^4, h^3, h^2, h
++	li	10, 32
++	lxvd2x	2+32, 10, 8	# H Poli
++	li	10, 48
++	lxvd2x	3+32, 10, 8	# Hl
++	li	10, 64
++	lxvd2x	4+32, 10, 8	# H
++	li	10, 80
++	lxvd2x	5+32, 10, 8	# Hh
++
++	li	10, 96
++	lxvd2x	6+32, 10, 8	# H^2l
++	li	10, 112
++	lxvd2x	7+32, 10, 8	# H^2
++	li	10, 128
++	lxvd2x	8+32, 10, 8	# H^2h
++
++	li	10, 144
++	lxvd2x	9+32, 10, 8	# H^3l
++	li	10, 160
++	lxvd2x	10+32, 10, 8	# H^3
++	li	10, 176
++	lxvd2x	11+32, 10, 8	# H^3h
++
++	li	10, 192
++	lxvd2x	12+32, 10, 8	# H^4l
++	li	10, 208
++	lxvd2x	13+32, 10, 8	# H^4
++	li	10, 224
++	lxvd2x	14+32, 10, 8	# H^4h
++
++	# initialize ICB: GHASH( IV ), IV - r7
++	lxvb16x	30+32, 0, 7	# load IV  - v30
++
++	mr	12, 5		# length
++	li	11, 0		# block index
++
++	# counter 1
++	vxor	31, 31, 31
++	vspltisb 22, 1
++	vsldoi	31, 31, 22,1	# counter 1
++
++	# load round key to VSR
++	lxv	0, 0(6)
++	lxv	1, 0x10(6)
++	lxv	2, 0x20(6)
++	lxv	3, 0x30(6)
++	lxv	4, 0x40(6)
++	lxv	5, 0x50(6)
++	lxv	6, 0x60(6)
++	lxv	7, 0x70(6)
++	lxv	8, 0x80(6)
++	lxv	9, 0x90(6)
++	lxv	10, 0xa0(6)
++
++	# load rounds - 10 (128), 12 (192), 14 (256)
++	lwz	9,240(6)
++
++	#
++	# vxor	state, state, w # addroundkey
++	xxlor	32+29, 0, 0
++	vxor	15, 30, 29	# IV + round key - add round key 0
++
++	cmpdi	9, 10
++	beq	Loop_aes_gcm_8x_dec
++
++	# load 2 more round keys (v11, v12)
++	lxv	11, 0xb0(6)
++	lxv	12, 0xc0(6)
++
++	cmpdi	9, 12
++	beq	Loop_aes_gcm_8x_dec
++
++	# load 2 more round keys (v11, v12, v13, v14)
++	lxv	13, 0xd0(6)
++	lxv	14, 0xe0(6)
++	cmpdi	9, 14
++	beq	Loop_aes_gcm_8x_dec
++
++	b	aes_gcm_out
++
++.align 5
++Loop_aes_gcm_8x_dec:
++	mr	14, 3
++	mr	9, 4
++
++	# n blocks
++	li	10, 128
++	divdu	10, 5, 10	# n 128 bytes-blocks
++	cmpdi	10, 0
++	beq	Loop_last_block_dec
++
++	vaddudm	30, 30, 31	# IV + counter
++	vxor	16, 30, 29
++	vaddudm	30, 30, 31
++	vxor	17, 30, 29
++	vaddudm	30, 30, 31
++	vxor	18, 30, 29
++	vaddudm	30, 30, 31
++	vxor	19, 30, 29
++	vaddudm	30, 30, 31
++	vxor	20, 30, 29
++	vaddudm	30, 30, 31
++	vxor	21, 30, 29
++	vaddudm	30, 30, 31
++	vxor	22, 30, 29
++
++	mtctr	10
++
++	li	15, 16
++	li	16, 32
++	li	17, 48
++	li	18, 64
++	li	19, 80
++	li	20, 96
++	li	21, 112
++
++	lwz	10, 240(6)
++
++Loop_8x_block_dec:
++
++	lxvb16x		15, 0, 14	# load block
++	lxvb16x		16, 15, 14	# load block
++	lxvb16x		17, 16, 14	# load block
++	lxvb16x		18, 17, 14	# load block
++	lxvb16x		19, 18, 14	# load block
++	lxvb16x		20, 19, 14	# load block
++	lxvb16x		21, 20, 14	# load block
++	lxvb16x		22, 21, 14	# load block
++	addi		14, 14, 128
++
++	Loop_aes_middle8x
++
++	xxlor	23+32, 10, 10
++
++	cmpdi	10, 10
++	beq	Do_last_aes_dec
++
++	# 192 bits
++	xxlor	24+32, 11, 11
++
++	vcipher	15, 15, 23
++	vcipher	16, 16, 23
++	vcipher	17, 17, 23
++	vcipher	18, 18, 23
++	vcipher	19, 19, 23
++	vcipher	20, 20, 23
++	vcipher	21, 21, 23
++	vcipher	22, 22, 23
++
++	vcipher	15, 15, 24
++	vcipher	16, 16, 24
++	vcipher	17, 17, 24
++	vcipher	18, 18, 24
++	vcipher	19, 19, 24
++	vcipher	20, 20, 24
++	vcipher	21, 21, 24
++	vcipher	22, 22, 24
++
++	xxlor	23+32, 12, 12
++
++	cmpdi	10, 12
++	beq	Do_last_aes_dec
++
++	# 256 bits
++	xxlor	24+32, 13, 13
++
++	vcipher	15, 15, 23
++	vcipher	16, 16, 23
++	vcipher	17, 17, 23
++	vcipher	18, 18, 23
++	vcipher	19, 19, 23
++	vcipher	20, 20, 23
++	vcipher	21, 21, 23
++	vcipher	22, 22, 23
++
++	vcipher	15, 15, 24
++	vcipher	16, 16, 24
++	vcipher	17, 17, 24
++	vcipher	18, 18, 24
++	vcipher	19, 19, 24
++	vcipher	20, 20, 24
++	vcipher	21, 21, 24
++	vcipher	22, 22, 24
++
++	xxlor	23+32, 14, 14
++
++	cmpdi	10, 14
++	beq	Do_last_aes_dec
++	b	aes_gcm_out
++
++Do_last_aes_dec:
++
++	#
++	# last round
++	vcipherlast     15, 15, 23
++	vcipherlast     16, 16, 23
++
++	xxlxor		47, 47, 15
++	stxvb16x        47, 0, 9	# store output
++	xxlxor		48, 48, 16
++	stxvb16x        48, 15, 9	# store output
++
++	vcipherlast     17, 17, 23
++	vcipherlast     18, 18, 23
++
++	xxlxor		49, 49, 17
++	stxvb16x        49, 16, 9	# store output
++	xxlxor		50, 50, 18
++	stxvb16x        50, 17, 9	# store output
++
++	vcipherlast     19, 19, 23
++	vcipherlast     20, 20, 23
++
++	xxlxor		51, 51, 19
++	stxvb16x        51, 18, 9	# store output
++	xxlxor		52, 52, 20
++	stxvb16x        52, 19, 9	# store output
++
++	vcipherlast     21, 21, 23
++	vcipherlast     22, 22, 23
++
++	xxlxor		53, 53, 21
++	stxvb16x        53, 20, 9	# store output
++	xxlxor		54, 54, 22
++	stxvb16x        54, 21, 9	# store output
++
++	addi		9, 9, 128
++
++	xxlor		15+32, 15, 15
++	xxlor		16+32, 16, 16
++	xxlor		17+32, 17, 17
++	xxlor		18+32, 18, 18
++	xxlor		19+32, 19, 19
++	xxlor		20+32, 20, 20
++	xxlor		21+32, 21, 21
++	xxlor		22+32, 22, 22
++
++	# ghash here
++	ppc_aes_gcm_ghash2_4x
++
++	xxlor	27+32, 0, 0
++	vaddudm 30, 30, 31		# IV + counter
++	vmr	29, 30
++	vxor    15, 30, 27		# add round key
++	vaddudm 30, 30, 31
++	vxor    16, 30, 27
++	vaddudm 30, 30, 31
++	vxor    17, 30, 27
++	vaddudm 30, 30, 31
++	vxor    18, 30, 27
++	vaddudm 30, 30, 31
++	vxor    19, 30, 27
++	vaddudm 30, 30, 31
++	vxor    20, 30, 27
++	vaddudm 30, 30, 31
++	vxor    21, 30, 27
++	vaddudm 30, 30, 31
++	vxor    22, 30, 27
++	addi    12, 12, -128
++	addi    11, 11, 128
++
++	bdnz	Loop_8x_block_dec
++
++	vmr	30, 29
++
++Loop_last_block_dec:
++	cmpdi   12, 0
++	beq     aes_gcm_out
++
++	# loop last few blocks
++	li      10, 16
++	divdu   10, 12, 10
++
++	mtctr   10
++
++	lwz	10,240(6)
++
++	cmpdi   12, 16
++	blt     Final_block_dec
++
++Next_rem_block_dec:
++	lxvb16x 15, 0, 14		# load block
++
++	Loop_aes_middle_1x
++
++	xxlor	23+32, 10, 10
++
++	cmpdi	10, 10
++	beq	Do_next_1x_dec
++
++	# 192 bits
++	xxlor	24+32, 11, 11
++
++	vcipher	15, 15, 23
++	vcipher	15, 15, 24
++
++	xxlor	23+32, 12, 12
++
++	cmpdi	10, 12
++	beq	Do_next_1x_dec
++
++	# 256 bits
++	xxlor	24+32, 13, 13
++
++	vcipher	15, 15, 23
++	vcipher	15, 15, 24
++
++	xxlor	23+32, 14, 14
++
++	cmpdi	10, 14
++	beq	Do_next_1x_dec
++
++Do_next_1x_dec:
++	vcipherlast     15, 15, 23
++
++	xxlxor  47, 47, 15
++	stxvb16x        47, 0, 9	# store output
++	addi	14, 14, 16
++	addi	9, 9, 16
++
++	xxlor	28+32, 15, 15
++	ppc_update_hash_1x
++
++	addi    12, 12, -16
++	addi    11, 11, 16
++	xxlor	19+32, 0, 0
++	vaddudm 30, 30, 31		# IV + counter
++	vxor	15, 30, 19		# add round key
++
++	bdnz	Next_rem_block_dec
++
++	cmpdi	12, 0
++	beq	aes_gcm_out
++
++Final_block_dec:
++	Loop_aes_middle_1x
++
++	xxlor	23+32, 10, 10
++
++	cmpdi	10, 10
++	beq	Do_final_1x_dec
++
++	# 192 bits
++	xxlor	24+32, 11, 11
++
++	vcipher	15, 15, 23
++	vcipher	15, 15, 24
++
++	xxlor	23+32, 12, 12
++
++	cmpdi	10, 12
++	beq	Do_final_1x_dec
++
++	# 256 bits
++	xxlor	24+32, 13, 13
++
++	vcipher	15, 15, 23
++	vcipher	15, 15, 24
++
++	xxlor	23+32, 14, 14
++
++	cmpdi	10, 14
++	beq	Do_final_1x_dec
++
++Do_final_1x_dec:
++	vcipherlast     15, 15, 23
++
++	lxvb16x	15, 0, 14		# load block
++	xxlxor	47, 47, 15
++
++	# create partial block mask
++	li	15, 16
++	sub	15, 15, 12		# index to the mask
++
++	vspltisb	16, -1		# first 16 bytes - 0xffff...ff
++	vspltisb	17, 0		# second 16 bytes - 0x0000...00
++	li	10, 192
++	stvx	16, 10, 1
++	addi	10, 10, 16
++	stvx	17, 10, 1
++
++	addi	10, 1, 192
++	lxvb16x	16, 15, 10		# load block mask
++	xxland	47, 47, 16
++
++	xxlor	28+32, 15, 15
++	ppc_update_hash_1x
++
++	# * should store only the remaining bytes.
++	bl	Write_partial_block
++
++	b aes_gcm_out
++
++
++___
++
++foreach (split("\n",$code)) {
++	s/\`([^\`]*)\`/eval $1/geo;
++
++	if ($flavour =~ /le$/o) {	# little-endian
++	    s/le\?//o		or
++	    s/be\?/#be#/o;
++	} else {
++	    s/le\?/#le#/o	or
++	    s/be\?//o;
++	}
++	print $_,"\n";
++}
++
++close STDOUT or die "error closing STDOUT: $!"; # enforce flush
+diff --git a/crypto/modes/build.info b/crypto/modes/build.info
+index 687e872..0ea122e 100644
+--- a/crypto/modes/build.info
++++ b/crypto/modes/build.info
+@@ -32,7 +32,7 @@ IF[{- !$disabled{asm} -}]
+   $MODESASM_parisc20_64=$MODESASM_parisc11
+   $MODESDEF_parisc20_64=$MODESDEF_parisc11
+ 
+-  $MODESASM_ppc32=ghashp8-ppc.s
++  $MODESASM_ppc32=ghashp8-ppc.s aes-gcm-ppc.s
+   $MODESDEF_ppc32=
+   $MODESASM_ppc64=$MODESASM_ppc32
+   $MODESDEF_ppc64=$MODESDEF_ppc32
+@@ -71,6 +71,7 @@ INCLUDE[ghash-sparcv9.o]=..
+ GENERATE[ghash-alpha.S]=asm/ghash-alpha.pl
+ GENERATE[ghash-parisc.s]=asm/ghash-parisc.pl
+ GENERATE[ghashp8-ppc.s]=asm/ghashp8-ppc.pl
++GENERATE[aes-gcm-ppc.s]=asm/aes-gcm-ppc.pl
+ GENERATE[ghash-armv4.S]=asm/ghash-armv4.pl
+ INCLUDE[ghash-armv4.o]=..
+ GENERATE[ghashv8-armx.S]=asm/ghashv8-armx.pl
+diff --git a/include/crypto/aes_platform.h b/include/crypto/aes_platform.h
+index e95ad5a..0c281a3 100644
+--- a/include/crypto/aes_platform.h
++++ b/include/crypto/aes_platform.h
+@@ -74,6 +74,26 @@ void AES_xts_decrypt(const unsigned char *inp, unsigned char *out, size_t len,
+ #   define HWAES_ctr32_encrypt_blocks aes_p8_ctr32_encrypt_blocks
+ #   define HWAES_xts_encrypt aes_p8_xts_encrypt
+ #   define HWAES_xts_decrypt aes_p8_xts_decrypt
++#   define PPC_AES_GCM_CAPABLE (OPENSSL_ppccap_P & PPC_MADD300)
++#   define AES_GCM_ENC_BYTES 128
++#   define AES_GCM_DEC_BYTES 128
++size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out,
++                           size_t len, const void *key, unsigned char ivec[16],
++                           u64 *Xi);
++size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out,
++                           size_t len, const void *key, unsigned char ivec[16],
++                           u64 *Xi);
++size_t ppc_aes_gcm_encrypt_wrap(const unsigned char *in, unsigned char *out,
++                                size_t len, const void *key,
++                                unsigned char ivec[16], u64 *Xi);
++size_t ppc_aes_gcm_decrypt_wrap(const unsigned char *in, unsigned char *out,
++                                size_t len, const void *key,
++                                unsigned char ivec[16], u64 *Xi);
++#   define AES_gcm_encrypt ppc_aes_gcm_encrypt_wrap
++#   define AES_gcm_decrypt ppc_aes_gcm_decrypt_wrap
++#   define AES_GCM_ASM(gctx) ((gctx)->ctr==aes_p8_ctr32_encrypt_blocks && \
++                              (gctx)->gcm.ghash==gcm_ghash_p8)
++void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len);
+ #  endif /* PPC */
+ 
+ #  if (defined(__arm__) || defined(__arm) || defined(__aarch64__))
+diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_hw.c
+index 44fa9d4..789ec12 100644
+--- a/providers/implementations/ciphers/cipher_aes_gcm_hw.c
++++ b/providers/implementations/ciphers/cipher_aes_gcm_hw.c
+@@ -141,6 +141,8 @@ static const PROV_GCM_HW aes_gcm = {
+ # include "cipher_aes_gcm_hw_t4.inc"
+ #elif defined(AES_PMULL_CAPABLE) && defined(AES_GCM_ASM)
+ # include "cipher_aes_gcm_hw_armv8.inc"
++#elif defined(PPC_AES_GCM_CAPABLE)
++# include "cipher_aes_gcm_hw_ppc.inc"
+ #else
+ const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits)
+ {
+diff --git a/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.inc b/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.inc
+new file mode 100644
+index 0000000..4eed0f4
+--- /dev/null
++++ b/providers/implementations/ciphers/cipher_aes_gcm_hw_ppc.inc
+@@ -0,0 +1,119 @@
++/*
++ * Copyright 2001-2021 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
++ */
++
++/*-
++ * PPC support for AES GCM.
++ * This file is included by cipher_aes_gcm_hw.c
++ */
++
++static int aes_ppc_gcm_initkey(PROV_GCM_CTX *ctx, const unsigned char *key,
++                               size_t keylen)
++{
++    PROV_AES_GCM_CTX *actx = (PROV_AES_GCM_CTX *)ctx;
++    AES_KEY *ks = &actx->ks.ks;
++
++    GCM_HW_SET_KEY_CTR_FN(ks, aes_p8_set_encrypt_key, aes_p8_encrypt,
++                          aes_p8_ctr32_encrypt_blocks);
++    return 1;
++}
++
++
++extern size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len,
++                                  const void *key, unsigned char ivec[16], u64 *Xi);
++extern size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len,
++                                  const void *key, unsigned char ivec[16], u64 *Xi);
++
++static inline u32 UTO32(unsigned char *buf)
++{
++    return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | ((u32) buf[2] << 8) | ((u32) buf[3]);
++}
++
++static inline u32 add32TOU(unsigned char buf[4], u32 n)
++{
++    u32 r;
++
++    r = UTO32(buf);
++    r += n;
++    buf[0] = (unsigned char) (r >> 24) & 0xFF;
++    buf[1] = (unsigned char) (r >> 16) & 0xFF;
++    buf[2] = (unsigned char) (r >> 8) & 0xFF;
++    buf[3] = (unsigned char) r & 0xFF;
++    return r;
++}
++
++static size_t aes_p10_gcm_crypt(const unsigned char *in, unsigned char *out, size_t len,
++                                const void *key, unsigned char ivec[16], u64 *Xi, int encrypt)
++{
++    int s = 0;
++    int ndone = 0;
++    int ctr_reset = 0;
++    u64 blocks_unused;
++    u64 nb = len / 16;
++    u64 next_ctr = 0;
++    unsigned char ctr_saved[12];
++
++    memcpy(ctr_saved, ivec, 12);
++
++    while (nb) {
++        blocks_unused = (u64) 0xffffffffU + 1 - (u64) UTO32 (ivec + 12);
++        if (nb > blocks_unused) {
++            len = blocks_unused * 16;
++            nb -= blocks_unused;
++            next_ctr = blocks_unused;
++            ctr_reset = 1;
++        } else {
++            len = nb * 16;
++            next_ctr = nb;
++            nb = 0;
++        }
++
++        s = encrypt ? ppc_aes_gcm_encrypt(in, out, len, key, ivec, Xi)
++                    : ppc_aes_gcm_decrypt(in, out, len, key, ivec, Xi);
++
++        /* add counter to ivec */
++        add32TOU(ivec + 12, (u32) next_ctr);
++        if (ctr_reset) {
++            ctr_reset = 0;
++            in += len;
++            out += len;
++        }
++        memcpy(ivec, ctr_saved, 12);
++        ndone += s;
++    }
++
++    return ndone;
++}
++
++size_t ppc_aes_gcm_encrypt_wrap(const unsigned char *in, unsigned char *out, size_t len,
++                                const void *key, unsigned char ivec[16], u64 *Xi)
++{
++    return aes_p10_gcm_crypt(in, out, len, key, ivec, Xi, 1);
++}
++
++size_t ppc_aes_gcm_decrypt_wrap(const unsigned char *in, unsigned char *out, size_t len,
++                                const void *key, unsigned char ivec[16], u64 *Xi)
++{
++    return aes_p10_gcm_crypt(in, out, len, key, ivec, Xi, 0);
++}
++
++
++static const PROV_GCM_HW aes_ppc_gcm = {
++    aes_ppc_gcm_initkey,
++    ossl_gcm_setiv,
++    ossl_gcm_aad_update,
++    generic_aes_gcm_cipher_update,
++    ossl_gcm_cipher_final,
++    ossl_gcm_one_shot
++};
++
++const PROV_GCM_HW *ossl_prov_aes_hw_gcm(size_t keybits)
++{
++    return PPC_AES_GCM_CAPABLE ? &aes_ppc_gcm : &aes_gcm;
++}
++
diff --git a/SOURCES/0072-ChaCha20-performance-optimizations-for-ppc64le.patch b/SOURCES/0072-ChaCha20-performance-optimizations-for-ppc64le.patch
new file mode 100644
index 0000000..527b901
--- /dev/null
+++ b/SOURCES/0072-ChaCha20-performance-optimizations-for-ppc64le.patch
@@ -0,0 +1,1493 @@
+Upstream-Status: Backport [
+    https://github.com/openssl/openssl/commit/f596bbe4da779b56eea34d96168b557d78e1149,
+    https://github.com/openssl/openssl/commit/7e1f3ffcc5bc15fb9a12b9e3bb202f544c6ed5aa,
+    hunks in crypto/ppccap.c from https://github.com/openssl/openssl/commit/f5485b97b6c9977c0d39c7669b9f97a879312447
+]
+diff --git a/crypto/chacha/asm/chachap10-ppc.pl b/crypto/chacha/asm/chachap10-ppc.pl
+new file mode 100755
+index 0000000..36e9a8d
+--- /dev/null
++++ b/crypto/chacha/asm/chachap10-ppc.pl
+@@ -0,0 +1,1288 @@
++#! /usr/bin/env perl
++# 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
++
++#
++# ====================================================================
++# Written by Andy Polyakov <appro@openssl.org> for the OpenSSL
++# project. The module is, however, dual licensed under OpenSSL and
++# CRYPTOGAMS licenses depending on where you obtain it. For further
++# details see http://www.openssl.org/~appro/cryptogams/.
++# ====================================================================
++#
++# October 2015
++#
++# ChaCha20 for PowerPC/AltiVec.
++#
++# June 2018
++#
++# Add VSX 2.07 code path. Original 3xAltiVec+1xIALU is well-suited for
++# processors that can't issue more than one vector instruction per
++# cycle. But POWER8 (and POWER9) can issue a pair, and vector-only 4x
++# interleave would perform better. Incidentally PowerISA 2.07 (first
++# implemented by POWER8) defined new usable instructions, hence 4xVSX
++# code path...
++#
++# Performance in cycles per byte out of large buffer.
++#
++#			IALU/gcc-4.x    3xAltiVec+1xIALU	4xVSX
++#
++# Freescale e300	13.6/+115%	-			-
++# PPC74x0/G4e		6.81/+310%	3.81			-
++# PPC970/G5		9.29/+160%	?			-
++# POWER7		8.62/+61%	3.35			-
++# POWER8		8.70/+51%	2.91			2.09
++# POWER9		8.80/+29%	4.44(*)			2.45(**)
++#
++# (*)	this is trade-off result, it's possible to improve it, but
++#	then it would negatively affect all others;
++# (**)	POWER9 seems to be "allergic" to mixing vector and integer
++#	instructions, which is why switch to vector-only code pays
++#	off that much;
++
++# $output is the last argument if it looks like a file (it has an extension)
++# $flavour is the first argument if it doesn't look like a file
++$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
++$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
++
++if ($flavour =~ /64/) {
++	$SIZE_T	=8;
++	$LRSAVE	=2*$SIZE_T;
++	$STU	="stdu";
++	$POP	="ld";
++	$PUSH	="std";
++	$UCMP	="cmpld";
++} elsif ($flavour =~ /32/) {
++	$SIZE_T	=4;
++	$LRSAVE	=$SIZE_T;
++	$STU	="stwu";
++	$POP	="lwz";
++	$PUSH	="stw";
++	$UCMP	="cmplw";
++} else { die "nonsense $flavour"; }
++
++$LITTLE_ENDIAN = ($flavour=~/le$/) ? 1 : 0;
++
++$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 STDOUT,"| $^X $xlate $flavour \"$output\""
++    or die "can't call $xlate: $!";
++
++$LOCALS=6*$SIZE_T;
++$FRAME=$LOCALS+64+18*$SIZE_T;	# 64 is for local variables
++
++sub AUTOLOAD()		# thunk [simplified] x86-style perlasm
++{ my $opcode = $AUTOLOAD; $opcode =~ s/.*:://; $opcode =~ s/_/\./;
++    $code .= "\t$opcode\t".join(',',@_)."\n";
++}
++
++my $sp = "r1";
++
++my ($out,$inp,$len,$key,$ctr) = map("r$_",(3..7));
++
++
++{{{
++my ($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
++    $xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3) = map("v$_",(0..15));
++my @K = map("v$_",(16..19));
++my $CTR = "v26";
++my ($xt0,$xt1,$xt2,$xt3) = map("v$_",(27..30));
++my ($sixteen,$twelve,$eight,$seven) = ($xt0,$xt1,$xt2,$xt3);
++my $beperm = "v31";
++
++my ($x00,$x10,$x20,$x30) = (0, map("r$_",(8..10)));
++
++my $FRAME=$LOCALS+64+7*16;	# 7*16 is for v26-v31 offload
++
++
++sub VSX_lane_ROUND_4x {
++my ($a0,$b0,$c0,$d0)=@_;
++my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
++my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
++my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
++my @x=map("\"v$_\"",(0..15));
++
++	(
++	"&vadduwm	(@x[$a0],@x[$a0],@x[$b0])",	# Q1
++	 "&vadduwm	(@x[$a1],@x[$a1],@x[$b1])",	# Q2
++	  "&vadduwm	(@x[$a2],@x[$a2],@x[$b2])",	# Q3
++	   "&vadduwm	(@x[$a3],@x[$a3],@x[$b3])",	# Q4
++	"&vxor		(@x[$d0],@x[$d0],@x[$a0])",
++	 "&vxor		(@x[$d1],@x[$d1],@x[$a1])",
++	  "&vxor	(@x[$d2],@x[$d2],@x[$a2])",
++	   "&vxor	(@x[$d3],@x[$d3],@x[$a3])",
++	"&vrlw		(@x[$d0],@x[$d0],'$sixteen')",
++	 "&vrlw		(@x[$d1],@x[$d1],'$sixteen')",
++	  "&vrlw	(@x[$d2],@x[$d2],'$sixteen')",
++	   "&vrlw	(@x[$d3],@x[$d3],'$sixteen')",
++
++	"&vadduwm	(@x[$c0],@x[$c0],@x[$d0])",
++	 "&vadduwm	(@x[$c1],@x[$c1],@x[$d1])",
++	  "&vadduwm	(@x[$c2],@x[$c2],@x[$d2])",
++	   "&vadduwm	(@x[$c3],@x[$c3],@x[$d3])",
++	"&vxor		(@x[$b0],@x[$b0],@x[$c0])",
++	 "&vxor		(@x[$b1],@x[$b1],@x[$c1])",
++	  "&vxor	(@x[$b2],@x[$b2],@x[$c2])",
++	   "&vxor	(@x[$b3],@x[$b3],@x[$c3])",
++	"&vrlw		(@x[$b0],@x[$b0],'$twelve')",
++	 "&vrlw		(@x[$b1],@x[$b1],'$twelve')",
++	  "&vrlw	(@x[$b2],@x[$b2],'$twelve')",
++	   "&vrlw	(@x[$b3],@x[$b3],'$twelve')",
++
++	"&vadduwm	(@x[$a0],@x[$a0],@x[$b0])",
++	 "&vadduwm	(@x[$a1],@x[$a1],@x[$b1])",
++	  "&vadduwm	(@x[$a2],@x[$a2],@x[$b2])",
++	   "&vadduwm	(@x[$a3],@x[$a3],@x[$b3])",
++	"&vxor		(@x[$d0],@x[$d0],@x[$a0])",
++	 "&vxor		(@x[$d1],@x[$d1],@x[$a1])",
++	  "&vxor	(@x[$d2],@x[$d2],@x[$a2])",
++	   "&vxor	(@x[$d3],@x[$d3],@x[$a3])",
++	"&vrlw		(@x[$d0],@x[$d0],'$eight')",
++	 "&vrlw		(@x[$d1],@x[$d1],'$eight')",
++	  "&vrlw	(@x[$d2],@x[$d2],'$eight')",
++	   "&vrlw	(@x[$d3],@x[$d3],'$eight')",
++
++	"&vadduwm	(@x[$c0],@x[$c0],@x[$d0])",
++	 "&vadduwm	(@x[$c1],@x[$c1],@x[$d1])",
++	  "&vadduwm	(@x[$c2],@x[$c2],@x[$d2])",
++	   "&vadduwm	(@x[$c3],@x[$c3],@x[$d3])",
++	"&vxor		(@x[$b0],@x[$b0],@x[$c0])",
++	 "&vxor		(@x[$b1],@x[$b1],@x[$c1])",
++	  "&vxor	(@x[$b2],@x[$b2],@x[$c2])",
++	   "&vxor	(@x[$b3],@x[$b3],@x[$c3])",
++	"&vrlw		(@x[$b0],@x[$b0],'$seven')",
++	 "&vrlw		(@x[$b1],@x[$b1],'$seven')",
++	  "&vrlw	(@x[$b2],@x[$b2],'$seven')",
++	   "&vrlw	(@x[$b3],@x[$b3],'$seven')"
++	);
++}
++
++$code.=<<___;
++
++.globl	.ChaCha20_ctr32_vsx_p10
++.align	5
++.ChaCha20_ctr32_vsx_p10:
++	${UCMP}i $len,255
++	bgt 	ChaCha20_ctr32_vsx_8x
++	$STU	$sp,-$FRAME($sp)
++	mflr	r0
++	li	r10,`15+$LOCALS+64`
++	li	r11,`31+$LOCALS+64`
++	mfspr	r12,256
++	stvx	v26,r10,$sp
++	addi	r10,r10,32
++	stvx	v27,r11,$sp
++	addi	r11,r11,32
++	stvx	v28,r10,$sp
++	addi	r10,r10,32
++	stvx	v29,r11,$sp
++	addi	r11,r11,32
++	stvx	v30,r10,$sp
++	stvx	v31,r11,$sp
++	stw	r12,`$FRAME-4`($sp)		# save vrsave
++	li	r12,-4096+63
++	$PUSH	r0, `$FRAME+$LRSAVE`($sp)
++	mtspr	256,r12				# preserve 29 AltiVec registers
++
++	bl	Lconsts				# returns pointer Lsigma in r12
++	lvx_4w	@K[0],0,r12			# load sigma
++	addi	r12,r12,0x70
++	li	$x10,16
++	li	$x20,32
++	li	$x30,48
++	li	r11,64
++
++	lvx_4w	@K[1],0,$key			# load key
++	lvx_4w	@K[2],$x10,$key
++	lvx_4w	@K[3],0,$ctr			# load counter
++
++	vxor	$xt0,$xt0,$xt0
++	lvx_4w	$xt1,r11,r12
++	vspltw	$CTR,@K[3],0
++	vsldoi	@K[3],@K[3],$xt0,4
++	vsldoi	@K[3],$xt0,@K[3],12		# clear @K[3].word[0]
++	vadduwm	$CTR,$CTR,$xt1
++
++	be?lvsl	$beperm,0,$x10			# 0x00..0f
++	be?vspltisb $xt0,3			# 0x03..03
++	be?vxor	$beperm,$beperm,$xt0		# swap bytes within words
++
++	li	r0,10				# inner loop counter
++	mtctr	r0
++	b	Loop_outer_vsx
++
++.align	5
++Loop_outer_vsx:
++	lvx	$xa0,$x00,r12			# load [smashed] sigma
++	lvx	$xa1,$x10,r12
++	lvx	$xa2,$x20,r12
++	lvx	$xa3,$x30,r12
++
++	vspltw	$xb0,@K[1],0			# smash the key
++	vspltw	$xb1,@K[1],1
++	vspltw	$xb2,@K[1],2
++	vspltw	$xb3,@K[1],3
++
++	vspltw	$xc0,@K[2],0
++	vspltw	$xc1,@K[2],1
++	vspltw	$xc2,@K[2],2
++	vspltw	$xc3,@K[2],3
++
++	vmr	$xd0,$CTR			# smash the counter
++	vspltw	$xd1,@K[3],1
++	vspltw	$xd2,@K[3],2
++	vspltw	$xd3,@K[3],3
++
++	vspltisw $sixteen,-16			# synthesize constants
++	vspltisw $twelve,12
++	vspltisw $eight,8
++	vspltisw $seven,7
++
++Loop_vsx_4x:
++___
++	foreach (&VSX_lane_ROUND_4x(0, 4, 8,12)) { eval; }
++	foreach (&VSX_lane_ROUND_4x(0, 5,10,15)) { eval; }
++$code.=<<___;
++
++	bdnz	Loop_vsx_4x
++
++	vadduwm	$xd0,$xd0,$CTR
++
++	vmrgew	$xt0,$xa0,$xa1			# transpose data
++	vmrgew	$xt1,$xa2,$xa3
++	vmrgow	$xa0,$xa0,$xa1
++	vmrgow	$xa2,$xa2,$xa3
++	vmrgew	$xt2,$xb0,$xb1
++	vmrgew	$xt3,$xb2,$xb3
++	vpermdi	$xa1,$xa0,$xa2,0b00
++	vpermdi	$xa3,$xa0,$xa2,0b11
++	vpermdi	$xa0,$xt0,$xt1,0b00
++	vpermdi	$xa2,$xt0,$xt1,0b11
++
++	vmrgow	$xb0,$xb0,$xb1
++	vmrgow	$xb2,$xb2,$xb3
++	vmrgew	$xt0,$xc0,$xc1
++	vmrgew	$xt1,$xc2,$xc3
++	vpermdi	$xb1,$xb0,$xb2,0b00
++	vpermdi	$xb3,$xb0,$xb2,0b11
++	vpermdi	$xb0,$xt2,$xt3,0b00
++	vpermdi	$xb2,$xt2,$xt3,0b11
++
++	vmrgow	$xc0,$xc0,$xc1
++	vmrgow	$xc2,$xc2,$xc3
++	vmrgew	$xt2,$xd0,$xd1
++	vmrgew	$xt3,$xd2,$xd3
++	vpermdi	$xc1,$xc0,$xc2,0b00
++	vpermdi	$xc3,$xc0,$xc2,0b11
++	vpermdi	$xc0,$xt0,$xt1,0b00
++	vpermdi	$xc2,$xt0,$xt1,0b11
++
++	vmrgow	$xd0,$xd0,$xd1
++	vmrgow	$xd2,$xd2,$xd3
++	vspltisw $xt0,4
++	vadduwm  $CTR,$CTR,$xt0		# next counter value
++	vpermdi	$xd1,$xd0,$xd2,0b00
++	vpermdi	$xd3,$xd0,$xd2,0b11
++	vpermdi	$xd0,$xt2,$xt3,0b00
++	vpermdi	$xd2,$xt2,$xt3,0b11
++
++	vadduwm	$xa0,$xa0,@K[0]
++	vadduwm	$xb0,$xb0,@K[1]
++	vadduwm	$xc0,$xc0,@K[2]
++	vadduwm	$xd0,$xd0,@K[3]
++
++	be?vperm $xa0,$xa0,$xa0,$beperm
++	be?vperm $xb0,$xb0,$xb0,$beperm
++	be?vperm $xc0,$xc0,$xc0,$beperm
++	be?vperm $xd0,$xd0,$xd0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx
++
++	lvx_4w	$xt0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xt0,$xt0,$xa0
++	vxor	$xt1,$xt1,$xb0
++	vxor	$xt2,$xt2,$xc0
++	vxor	$xt3,$xt3,$xd0
++
++	stvx_4w	$xt0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx
++
++	vadduwm	$xa0,$xa1,@K[0]
++	vadduwm	$xb0,$xb1,@K[1]
++	vadduwm	$xc0,$xc1,@K[2]
++	vadduwm	$xd0,$xd1,@K[3]
++
++	be?vperm $xa0,$xa0,$xa0,$beperm
++	be?vperm $xb0,$xb0,$xb0,$beperm
++	be?vperm $xc0,$xc0,$xc0,$beperm
++	be?vperm $xd0,$xd0,$xd0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx
++
++	lvx_4w	$xt0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xt0,$xt0,$xa0
++	vxor	$xt1,$xt1,$xb0
++	vxor	$xt2,$xt2,$xc0
++	vxor	$xt3,$xt3,$xd0
++
++	stvx_4w	$xt0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx
++
++	vadduwm	$xa0,$xa2,@K[0]
++	vadduwm	$xb0,$xb2,@K[1]
++	vadduwm	$xc0,$xc2,@K[2]
++	vadduwm	$xd0,$xd2,@K[3]
++
++	be?vperm $xa0,$xa0,$xa0,$beperm
++	be?vperm $xb0,$xb0,$xb0,$beperm
++	be?vperm $xc0,$xc0,$xc0,$beperm
++	be?vperm $xd0,$xd0,$xd0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx
++
++	lvx_4w	$xt0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xt0,$xt0,$xa0
++	vxor	$xt1,$xt1,$xb0
++	vxor	$xt2,$xt2,$xc0
++	vxor	$xt3,$xt3,$xd0
++
++	stvx_4w	$xt0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx
++
++	vadduwm	$xa0,$xa3,@K[0]
++	vadduwm	$xb0,$xb3,@K[1]
++	vadduwm	$xc0,$xc3,@K[2]
++	vadduwm	$xd0,$xd3,@K[3]
++
++	be?vperm $xa0,$xa0,$xa0,$beperm
++	be?vperm $xb0,$xb0,$xb0,$beperm
++	be?vperm $xc0,$xc0,$xc0,$beperm
++	be?vperm $xd0,$xd0,$xd0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx
++
++	lvx_4w	$xt0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xt0,$xt0,$xa0
++	vxor	$xt1,$xt1,$xb0
++	vxor	$xt2,$xt2,$xc0
++	vxor	$xt3,$xt3,$xd0
++
++	stvx_4w	$xt0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	mtctr	r0
++	bne	Loop_outer_vsx
++
++Ldone_vsx:
++	lwz	r12,`$FRAME-4`($sp)		# pull vrsave
++	li	r10,`15+$LOCALS+64`
++	li	r11,`31+$LOCALS+64`
++	$POP	r0, `$FRAME+$LRSAVE`($sp)
++	mtspr	256,r12				# restore vrsave
++	lvx	v26,r10,$sp
++	addi	r10,r10,32
++	lvx	v27,r11,$sp
++	addi	r11,r11,32
++	lvx	v28,r10,$sp
++	addi	r10,r10,32
++	lvx	v29,r11,$sp
++	addi	r11,r11,32
++	lvx	v30,r10,$sp
++	lvx	v31,r11,$sp
++	mtlr	r0
++	addi	$sp,$sp,$FRAME
++	blr
++
++.align	4
++Ltail_vsx:
++	addi	r11,$sp,$LOCALS
++	mtctr	$len
++	stvx_4w	$xa0,$x00,r11			# offload block to stack
++	stvx_4w	$xb0,$x10,r11
++	stvx_4w	$xc0,$x20,r11
++	stvx_4w	$xd0,$x30,r11
++	subi	r12,r11,1			# prepare for *++ptr
++	subi	$inp,$inp,1
++	subi	$out,$out,1
++
++Loop_tail_vsx:
++	lbzu	r6,1(r12)
++	lbzu	r7,1($inp)
++	xor	r6,r6,r7
++	stbu	r6,1($out)
++	bdnz	Loop_tail_vsx
++
++	stvx_4w	$K[0],$x00,r11			# wipe copy of the block
++	stvx_4w	$K[0],$x10,r11
++	stvx_4w	$K[0],$x20,r11
++	stvx_4w	$K[0],$x30,r11
++
++	b	Ldone_vsx
++	.long	0
++	.byte	0,12,0x04,1,0x80,0,5,0
++	.long	0
++.size	.ChaCha20_ctr32_vsx_p10,.-.ChaCha20_ctr32_vsx_p10
++___
++}}}
++
++##This is 8 block in parallel implementation. The heart of chacha round uses vector instruction that has access to
++# vsr[32+X]. To perform the 8 parallel block we tend to use all 32 register to hold the 8 block info.
++# WE need to store few register value on side, so we can use VSR{32+X} for few vector instructions used in round op and hold intermediate value.
++# WE use the VSR[0]-VSR[31] for holding intermediate value and perform 8 block in parallel.
++#
++{{{
++#### ($out,$inp,$len,$key,$ctr) = map("r$_",(3..7));
++my ($xa0,$xa1,$xa2,$xa3, $xb0,$xb1,$xb2,$xb3,
++    $xc0,$xc1,$xc2,$xc3, $xd0,$xd1,$xd2,$xd3,
++    $xa4,$xa5,$xa6,$xa7, $xb4,$xb5,$xb6,$xb7,
++    $xc4,$xc5,$xc6,$xc7, $xd4,$xd5,$xd6,$xd7) = map("v$_",(0..31));
++my ($xcn4,$xcn5,$xcn6,$xcn7, $xdn4,$xdn5,$xdn6,$xdn7) = map("v$_",(8..15));
++my ($xan0,$xbn0,$xcn0,$xdn0) = map("v$_",(0..3));
++my @K = map("v$_",27,(24..26));
++my ($xt0,$xt1,$xt2,$xt3,$xt4) = map("v$_",23,(28..31));
++my $xr0 = "v4";
++my $CTR0 = "v22";
++my $CTR1 = "v5";
++my $beperm = "v31";
++my ($x00,$x10,$x20,$x30) = (0, map("r$_",(8..10)));
++my ($xv0,$xv1,$xv2,$xv3,$xv4,$xv5,$xv6,$xv7) = map("v$_",(0..7));
++my ($xv8,$xv9,$xv10,$xv11,$xv12,$xv13,$xv14,$xv15,$xv16,$xv17) = map("v$_",(8..17));
++my ($xv18,$xv19,$xv20,$xv21) = map("v$_",(18..21));
++my ($xv22,$xv23,$xv24,$xv25,$xv26) = map("v$_",(22..26));
++
++my $FRAME=$LOCALS+64+9*16;	# 8*16 is for v24-v31 offload
++
++sub VSX_lane_ROUND_8x {
++my ($a0,$b0,$c0,$d0,$a4,$b4,$c4,$d4)=@_;
++my ($a1,$b1,$c1,$d1)=map(($_&~3)+(($_+1)&3),($a0,$b0,$c0,$d0));
++my ($a2,$b2,$c2,$d2)=map(($_&~3)+(($_+1)&3),($a1,$b1,$c1,$d1));
++my ($a3,$b3,$c3,$d3)=map(($_&~3)+(($_+1)&3),($a2,$b2,$c2,$d2));
++my ($a5,$b5,$c5,$d5)=map(($_&~3)+(($_+1)&3),($a4,$b4,$c4,$d4));
++my ($a6,$b6,$c6,$d6)=map(($_&~3)+(($_+1)&3),($a5,$b5,$c5,$d5));
++my ($a7,$b7,$c7,$d7)=map(($_&~3)+(($_+1)&3),($a6,$b6,$c6,$d6));
++my ($xv8,$xv9,$xv10,$xv11,$xv12,$xv13,$xv14,$xv15,$xv16,$xv17) = map("\"v$_\"",(8..17));
++my @x=map("\"v$_\"",(0..31));
++
++	(
++	"&vxxlor        ($xv15 ,@x[$c7],@x[$c7])",      #copy v30 to v13
++	"&vxxlorc       (@x[$c7], $xv9,$xv9)",
++
++	"&vadduwm	(@x[$a0],@x[$a0],@x[$b0])",	# Q1
++	 "&vadduwm	(@x[$a1],@x[$a1],@x[$b1])",	# Q2
++	  "&vadduwm	(@x[$a2],@x[$a2],@x[$b2])",	# Q3
++	   "&vadduwm	(@x[$a3],@x[$a3],@x[$b3])",	# Q4
++	"&vadduwm	(@x[$a4],@x[$a4],@x[$b4])",	# Q1
++	 "&vadduwm	(@x[$a5],@x[$a5],@x[$b5])",	# Q2
++	  "&vadduwm	(@x[$a6],@x[$a6],@x[$b6])",	# Q3
++	   "&vadduwm	(@x[$a7],@x[$a7],@x[$b7])",	# Q4
++
++	"&vxor		(@x[$d0],@x[$d0],@x[$a0])",
++	 "&vxor		(@x[$d1],@x[$d1],@x[$a1])",
++	  "&vxor	(@x[$d2],@x[$d2],@x[$a2])",
++	   "&vxor	(@x[$d3],@x[$d3],@x[$a3])",
++	"&vxor		(@x[$d4],@x[$d4],@x[$a4])",
++	 "&vxor		(@x[$d5],@x[$d5],@x[$a5])",
++	  "&vxor	(@x[$d6],@x[$d6],@x[$a6])",
++	   "&vxor	(@x[$d7],@x[$d7],@x[$a7])",
++
++	"&vrlw		(@x[$d0],@x[$d0],@x[$c7])",
++	 "&vrlw		(@x[$d1],@x[$d1],@x[$c7])",
++	  "&vrlw	(@x[$d2],@x[$d2],@x[$c7])",
++	   "&vrlw	(@x[$d3],@x[$d3],@x[$c7])",
++	"&vrlw		(@x[$d4],@x[$d4],@x[$c7])",
++	 "&vrlw		(@x[$d5],@x[$d5],@x[$c7])",
++	  "&vrlw	(@x[$d6],@x[$d6],@x[$c7])",
++	   "&vrlw	(@x[$d7],@x[$d7],@x[$c7])",
++
++	"&vxxlor        ($xv13 ,@x[$a7],@x[$a7])",
++	"&vxxlorc       (@x[$c7], $xv15,$xv15)",
++	"&vxxlorc       (@x[$a7], $xv10,$xv10)",
++
++	"&vadduwm	(@x[$c0],@x[$c0],@x[$d0])",
++	 "&vadduwm	(@x[$c1],@x[$c1],@x[$d1])",
++	  "&vadduwm	(@x[$c2],@x[$c2],@x[$d2])",
++	   "&vadduwm	(@x[$c3],@x[$c3],@x[$d3])",
++	"&vadduwm	(@x[$c4],@x[$c4],@x[$d4])",
++	 "&vadduwm	(@x[$c5],@x[$c5],@x[$d5])",
++	  "&vadduwm	(@x[$c6],@x[$c6],@x[$d6])",
++	   "&vadduwm	(@x[$c7],@x[$c7],@x[$d7])",
++
++	"&vxor		(@x[$b0],@x[$b0],@x[$c0])",
++	 "&vxor		(@x[$b1],@x[$b1],@x[$c1])",
++	  "&vxor	(@x[$b2],@x[$b2],@x[$c2])",
++	   "&vxor	(@x[$b3],@x[$b3],@x[$c3])",
++	"&vxor		(@x[$b4],@x[$b4],@x[$c4])",
++	 "&vxor		(@x[$b5],@x[$b5],@x[$c5])",
++	  "&vxor	(@x[$b6],@x[$b6],@x[$c6])",
++	   "&vxor	(@x[$b7],@x[$b7],@x[$c7])",
++
++	"&vrlw		(@x[$b0],@x[$b0],@x[$a7])",
++	 "&vrlw		(@x[$b1],@x[$b1],@x[$a7])",
++	  "&vrlw	(@x[$b2],@x[$b2],@x[$a7])",
++	   "&vrlw	(@x[$b3],@x[$b3],@x[$a7])",
++	"&vrlw		(@x[$b4],@x[$b4],@x[$a7])",
++	 "&vrlw		(@x[$b5],@x[$b5],@x[$a7])",
++	  "&vrlw	(@x[$b6],@x[$b6],@x[$a7])",
++	   "&vrlw	(@x[$b7],@x[$b7],@x[$a7])",
++
++	"&vxxlorc       (@x[$a7], $xv13,$xv13)",
++	"&vxxlor	($xv15 ,@x[$c7],@x[$c7])",
++	"&vxxlorc       (@x[$c7], $xv11,$xv11)",
++
++
++	"&vadduwm	(@x[$a0],@x[$a0],@x[$b0])",
++	 "&vadduwm	(@x[$a1],@x[$a1],@x[$b1])",
++	  "&vadduwm	(@x[$a2],@x[$a2],@x[$b2])",
++	   "&vadduwm	(@x[$a3],@x[$a3],@x[$b3])",
++	"&vadduwm	(@x[$a4],@x[$a4],@x[$b4])",
++	 "&vadduwm	(@x[$a5],@x[$a5],@x[$b5])",
++	  "&vadduwm	(@x[$a6],@x[$a6],@x[$b6])",
++	   "&vadduwm	(@x[$a7],@x[$a7],@x[$b7])",
++
++	"&vxor		(@x[$d0],@x[$d0],@x[$a0])",
++	 "&vxor		(@x[$d1],@x[$d1],@x[$a1])",
++	  "&vxor	(@x[$d2],@x[$d2],@x[$a2])",
++	   "&vxor	(@x[$d3],@x[$d3],@x[$a3])",
++	"&vxor		(@x[$d4],@x[$d4],@x[$a4])",
++	 "&vxor		(@x[$d5],@x[$d5],@x[$a5])",
++	  "&vxor	(@x[$d6],@x[$d6],@x[$a6])",
++	   "&vxor	(@x[$d7],@x[$d7],@x[$a7])",
++
++	"&vrlw		(@x[$d0],@x[$d0],@x[$c7])",
++	 "&vrlw		(@x[$d1],@x[$d1],@x[$c7])",
++	  "&vrlw	(@x[$d2],@x[$d2],@x[$c7])",
++	   "&vrlw	(@x[$d3],@x[$d3],@x[$c7])",
++	"&vrlw		(@x[$d4],@x[$d4],@x[$c7])",
++	 "&vrlw		(@x[$d5],@x[$d5],@x[$c7])",
++	  "&vrlw	(@x[$d6],@x[$d6],@x[$c7])",
++	   "&vrlw	(@x[$d7],@x[$d7],@x[$c7])",
++
++	"&vxxlorc       (@x[$c7], $xv15,$xv15)",
++	"&vxxlor        ($xv13 ,@x[$a7],@x[$a7])",
++	"&vxxlorc       (@x[$a7], $xv12,$xv12)",
++
++	"&vadduwm	(@x[$c0],@x[$c0],@x[$d0])",
++	 "&vadduwm	(@x[$c1],@x[$c1],@x[$d1])",
++	  "&vadduwm	(@x[$c2],@x[$c2],@x[$d2])",
++	   "&vadduwm	(@x[$c3],@x[$c3],@x[$d3])",
++	"&vadduwm	(@x[$c4],@x[$c4],@x[$d4])",
++	 "&vadduwm	(@x[$c5],@x[$c5],@x[$d5])",
++	  "&vadduwm	(@x[$c6],@x[$c6],@x[$d6])",
++	   "&vadduwm	(@x[$c7],@x[$c7],@x[$d7])",
++	"&vxor		(@x[$b0],@x[$b0],@x[$c0])",
++	 "&vxor		(@x[$b1],@x[$b1],@x[$c1])",
++	  "&vxor	(@x[$b2],@x[$b2],@x[$c2])",
++	   "&vxor	(@x[$b3],@x[$b3],@x[$c3])",
++	"&vxor		(@x[$b4],@x[$b4],@x[$c4])",
++	 "&vxor		(@x[$b5],@x[$b5],@x[$c5])",
++	  "&vxor	(@x[$b6],@x[$b6],@x[$c6])",
++	   "&vxor	(@x[$b7],@x[$b7],@x[$c7])",
++	"&vrlw		(@x[$b0],@x[$b0],@x[$a7])",
++	 "&vrlw		(@x[$b1],@x[$b1],@x[$a7])",
++	  "&vrlw	(@x[$b2],@x[$b2],@x[$a7])",
++	   "&vrlw	(@x[$b3],@x[$b3],@x[$a7])",
++	"&vrlw		(@x[$b4],@x[$b4],@x[$a7])",
++	 "&vrlw		(@x[$b5],@x[$b5],@x[$a7])",
++	  "&vrlw	(@x[$b6],@x[$b6],@x[$a7])",
++	   "&vrlw	(@x[$b7],@x[$b7],@x[$a7])",
++
++	"&vxxlorc       (@x[$a7], $xv13,$xv13)",
++	);
++}
++
++$code.=<<___;
++
++.globl	.ChaCha20_ctr32_vsx_8x
++.align	5
++.ChaCha20_ctr32_vsx_8x:
++	$STU	$sp,-$FRAME($sp)
++	mflr	r0
++	li	r10,`15+$LOCALS+64`
++	li	r11,`31+$LOCALS+64`
++	mfspr	r12,256
++	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
++	addi	r11,r11,32
++	stvx	v28,r10,$sp
++	addi	r10,r10,32
++	stvx	v29,r11,$sp
++	addi	r11,r11,32
++	stvx	v30,r10,$sp
++	stvx	v31,r11,$sp
++	stw	r12,`$FRAME-4`($sp)		# save vrsave
++	li	r12,-4096+63
++	$PUSH	r0, `$FRAME+$LRSAVE`($sp)
++	mtspr	256,r12				# preserve 29 AltiVec registers
++
++	bl	Lconsts				# returns pointer Lsigma in r12
++
++	lvx_4w	@K[0],0,r12			# load sigma
++	addi	r12,r12,0x70
++	li	$x10,16
++	li	$x20,32
++	li	$x30,48
++	li	r11,64
++
++	vspltisw $xa4,-16			# synthesize constants
++	vspltisw $xb4,12			# synthesize constants
++	vspltisw $xc4,8			# synthesize constants
++	vspltisw $xd4,7			# synthesize constants
++
++	lvx	$xa0,$x00,r12			# load [smashed] sigma
++	lvx	$xa1,$x10,r12
++	lvx	$xa2,$x20,r12
++	lvx	$xa3,$x30,r12
++
++	vxxlor	$xv9   ,$xa4,$xa4               #save shift val in vr9-12
++	vxxlor	$xv10  ,$xb4,$xb4
++	vxxlor	$xv11  ,$xc4,$xc4
++	vxxlor	$xv12  ,$xd4,$xd4
++	vxxlor	$xv22  ,$xa0,$xa0               #save sigma in vr22-25
++	vxxlor	$xv23  ,$xa1,$xa1
++	vxxlor	$xv24  ,$xa2,$xa2
++	vxxlor	$xv25  ,$xa3,$xa3
++
++	lvx_4w	@K[1],0,$key			# load key
++	lvx_4w	@K[2],$x10,$key
++	lvx_4w	@K[3],0,$ctr			# load counter
++	vspltisw $xt3,4
++
++
++	vxor	$xt2,$xt2,$xt2
++	lvx_4w	$xt1,r11,r12
++	vspltw	$xa2,@K[3],0			#save the original count after spltw
++	vsldoi	@K[3],@K[3],$xt2,4
++	vsldoi	@K[3],$xt2,@K[3],12		# clear @K[3].word[0]
++	vadduwm	$xt1,$xa2,$xt1
++	vadduwm $xt3,$xt1,$xt3     		# next counter value
++	vspltw	$xa0,@K[2],2                    # save the K[2] spltw 2 and save v8.
++
++	be?lvsl	  $beperm,0,$x10			# 0x00..0f
++	be?vspltisb $xt0,3			# 0x03..03
++	be?vxor   $beperm,$beperm,$xt0		# swap bytes within words
++	be?vxxlor $xv26 ,$beperm,$beperm
++
++	vxxlor	$xv0 ,@K[0],@K[0]               # K0,k1,k2 to vr0,1,2
++	vxxlor	$xv1 ,@K[1],@K[1]
++	vxxlor	$xv2 ,@K[2],@K[2]
++	vxxlor	$xv3 ,@K[3],@K[3]
++	vxxlor	$xv4 ,$xt1,$xt1                #CTR ->4, CTR+4-> 5
++	vxxlor	$xv5 ,$xt3,$xt3
++	vxxlor	$xv8 ,$xa0,$xa0
++
++	li	r0,10				# inner loop counter
++	mtctr	r0
++	b	Loop_outer_vsx_8x
++
++.align	5
++Loop_outer_vsx_8x:
++	vxxlorc	$xa0,$xv22,$xv22	        # load [smashed] sigma
++	vxxlorc	$xa1,$xv23,$xv23
++	vxxlorc	$xa2,$xv24,$xv24
++	vxxlorc	$xa3,$xv25,$xv25
++	vxxlorc	$xa4,$xv22,$xv22
++	vxxlorc	$xa5,$xv23,$xv23
++	vxxlorc	$xa6,$xv24,$xv24
++	vxxlorc	$xa7,$xv25,$xv25
++
++	vspltw	$xb0,@K[1],0			# smash the key
++	vspltw	$xb1,@K[1],1
++	vspltw	$xb2,@K[1],2
++	vspltw	$xb3,@K[1],3
++	vspltw	$xb4,@K[1],0			# smash the key
++	vspltw	$xb5,@K[1],1
++	vspltw	$xb6,@K[1],2
++	vspltw	$xb7,@K[1],3
++
++	vspltw	$xc0,@K[2],0
++	vspltw	$xc1,@K[2],1
++	vspltw	$xc2,@K[2],2
++	vspltw	$xc3,@K[2],3
++	vspltw	$xc4,@K[2],0
++	vspltw	$xc7,@K[2],3
++	vspltw	$xc5,@K[2],1
++
++	vxxlorc	$xd0,$xv4,$xv4			# smash the counter
++	vspltw	$xd1,@K[3],1
++	vspltw	$xd2,@K[3],2
++	vspltw	$xd3,@K[3],3
++	vxxlorc	$xd4,$xv5,$xv5			# smash the counter
++	vspltw	$xd5,@K[3],1
++	vspltw	$xd6,@K[3],2
++	vspltw	$xd7,@K[3],3
++	vxxlorc	$xc6,$xv8,$xv8                  #copy of vlspt k[2],2 is in v8.v26 ->k[3] so need to wait until k3 is done
++
++Loop_vsx_8x:
++___
++	foreach (&VSX_lane_ROUND_8x(0,4, 8,12,16,20,24,28)) { eval; }
++	foreach (&VSX_lane_ROUND_8x(0,5,10,15,16,21,26,31)) { eval; }
++$code.=<<___;
++
++	bdnz	        Loop_vsx_8x
++	vxxlor	        $xv13 ,$xd4,$xd4                # save the register vr24-31
++	vxxlor	        $xv14 ,$xd5,$xd5                #
++	vxxlor	        $xv15 ,$xd6,$xd6                #
++	vxxlor	        $xv16 ,$xd7,$xd7                #
++
++	vxxlor	        $xv18 ,$xc4,$xc4                #
++	vxxlor	        $xv19 ,$xc5,$xc5                #
++	vxxlor	        $xv20 ,$xc6,$xc6                #
++	vxxlor	        $xv21 ,$xc7,$xc7                #
++
++	vxxlor	        $xv6  ,$xb6,$xb6                # save vr23, so we get 8 regs
++	vxxlor	        $xv7  ,$xb7,$xb7                # save vr23, so we get 8 regs
++	be?vxxlorc      $beperm,$xv26,$xv26             # copy back the the beperm.
++
++	vxxlorc	   @K[0],$xv0,$xv0                #27
++	vxxlorc	   @K[1],$xv1,$xv1 		  #24
++	vxxlorc	   @K[2],$xv2,$xv2		  #25
++	vxxlorc	   @K[3],$xv3,$xv3		  #26
++	vxxlorc	   $CTR0,$xv4,$xv4
++###changing to vertical
++
++	vmrgew	$xt0,$xa0,$xa1			# transpose data
++	vmrgew	$xt1,$xa2,$xa3
++	vmrgow	$xa0,$xa0,$xa1
++	vmrgow	$xa2,$xa2,$xa3
++
++	vmrgew	$xt2,$xb0,$xb1
++	vmrgew	$xt3,$xb2,$xb3
++	vmrgow	$xb0,$xb0,$xb1
++	vmrgow	$xb2,$xb2,$xb3
++
++	vadduwm	$xd0,$xd0,$CTR0
++
++	vpermdi	$xa1,$xa0,$xa2,0b00
++	vpermdi	$xa3,$xa0,$xa2,0b11
++	vpermdi	$xa0,$xt0,$xt1,0b00
++	vpermdi	$xa2,$xt0,$xt1,0b11
++	vpermdi	$xb1,$xb0,$xb2,0b00
++	vpermdi	$xb3,$xb0,$xb2,0b11
++	vpermdi	$xb0,$xt2,$xt3,0b00
++	vpermdi	$xb2,$xt2,$xt3,0b11
++
++	vmrgew	$xt0,$xc0,$xc1
++	vmrgew	$xt1,$xc2,$xc3
++	vmrgow	$xc0,$xc0,$xc1
++	vmrgow	$xc2,$xc2,$xc3
++	vmrgew	$xt2,$xd0,$xd1
++	vmrgew	$xt3,$xd2,$xd3
++	vmrgow	$xd0,$xd0,$xd1
++	vmrgow	$xd2,$xd2,$xd3
++
++	vpermdi	$xc1,$xc0,$xc2,0b00
++	vpermdi	$xc3,$xc0,$xc2,0b11
++	vpermdi	$xc0,$xt0,$xt1,0b00
++	vpermdi	$xc2,$xt0,$xt1,0b11
++	vpermdi	$xd1,$xd0,$xd2,0b00
++	vpermdi	$xd3,$xd0,$xd2,0b11
++	vpermdi	$xd0,$xt2,$xt3,0b00
++	vpermdi	$xd2,$xt2,$xt3,0b11
++
++	vspltisw $xt0,8
++	vadduwm  $CTR0,$CTR0,$xt0		# next counter value
++	vxxlor	 $xv4 ,$CTR0,$CTR0	        #CTR+4-> 5
++
++	vadduwm	$xa0,$xa0,@K[0]
++	vadduwm	$xb0,$xb0,@K[1]
++	vadduwm	$xc0,$xc0,@K[2]
++	vadduwm	$xd0,$xd0,@K[3]
++
++	be?vperm $xa0,$xa0,$xa0,$beperm
++	be?vperm $xb0,$xb0,$xb0,$beperm
++	be?vperm $xc0,$xc0,$xc0,$beperm
++	be?vperm $xd0,$xd0,$xd0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx_8x
++
++	lvx_4w	$xt0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xt0,$xt0,$xa0
++	vxor	$xt1,$xt1,$xb0
++	vxor	$xt2,$xt2,$xc0
++	vxor	$xt3,$xt3,$xd0
++
++	stvx_4w	$xt0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx_8x
++
++	vadduwm	$xa0,$xa1,@K[0]
++	vadduwm	$xb0,$xb1,@K[1]
++	vadduwm	$xc0,$xc1,@K[2]
++	vadduwm	$xd0,$xd1,@K[3]
++
++	be?vperm $xa0,$xa0,$xa0,$beperm
++	be?vperm $xb0,$xb0,$xb0,$beperm
++	be?vperm $xc0,$xc0,$xc0,$beperm
++	be?vperm $xd0,$xd0,$xd0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx_8x
++
++	lvx_4w	$xt0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xt0,$xt0,$xa0
++	vxor	$xt1,$xt1,$xb0
++	vxor	$xt2,$xt2,$xc0
++	vxor	$xt3,$xt3,$xd0
++
++	stvx_4w	$xt0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx_8x
++
++	vadduwm	$xa0,$xa2,@K[0]
++	vadduwm	$xb0,$xb2,@K[1]
++	vadduwm	$xc0,$xc2,@K[2]
++	vadduwm	$xd0,$xd2,@K[3]
++
++	be?vperm $xa0,$xa0,$xa0,$beperm
++	be?vperm $xb0,$xb0,$xb0,$beperm
++	be?vperm $xc0,$xc0,$xc0,$beperm
++	be?vperm $xd0,$xd0,$xd0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx_8x
++
++	lvx_4w	$xt0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xt0,$xt0,$xa0
++	vxor	$xt1,$xt1,$xb0
++	vxor	$xt2,$xt2,$xc0
++	vxor	$xt3,$xt3,$xd0
++
++	stvx_4w	$xt0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx_8x
++
++	vadduwm	$xa0,$xa3,@K[0]
++	vadduwm	$xb0,$xb3,@K[1]
++	vadduwm	$xc0,$xc3,@K[2]
++	vadduwm	$xd0,$xd3,@K[3]
++
++	be?vperm $xa0,$xa0,$xa0,$beperm
++	be?vperm $xb0,$xb0,$xb0,$beperm
++	be?vperm $xc0,$xc0,$xc0,$beperm
++	be?vperm $xd0,$xd0,$xd0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx_8x
++
++	lvx_4w	$xt0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xt0,$xt0,$xa0
++	vxor	$xt1,$xt1,$xb0
++	vxor	$xt2,$xt2,$xc0
++	vxor	$xt3,$xt3,$xd0
++
++	stvx_4w	$xt0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx_8x
++
++#blk4-7: 24:31 remain the same as we can use the same logic above . Reg a4-b7 remain same.Load c4,d7--> position 8-15.we can reuse vr24-31.
++#VR0-3 : are used to load temp value, vr4 --> as xr0 instead of xt0.
++
++	vxxlorc	   $CTR1 ,$xv5,$xv5
++
++	vxxlorc	   $xcn4 ,$xv18,$xv18
++	vxxlorc	   $xcn5 ,$xv19,$xv19
++	vxxlorc	   $xcn6 ,$xv20,$xv20
++	vxxlorc	   $xcn7 ,$xv21,$xv21
++
++	vxxlorc	   $xdn4 ,$xv13,$xv13
++	vxxlorc	   $xdn5 ,$xv14,$xv14
++	vxxlorc	   $xdn6 ,$xv15,$xv15
++	vxxlorc	   $xdn7 ,$xv16,$xv16
++	vadduwm	   $xdn4,$xdn4,$CTR1
++
++	vxxlorc	   $xb6 ,$xv6,$xv6
++	vxxlorc	   $xb7 ,$xv7,$xv7
++#use xa1->xr0, as xt0...in the block 4-7
++
++	vmrgew	$xr0,$xa4,$xa5			# transpose data
++	vmrgew	$xt1,$xa6,$xa7
++	vmrgow	$xa4,$xa4,$xa5
++	vmrgow	$xa6,$xa6,$xa7
++	vmrgew	$xt2,$xb4,$xb5
++	vmrgew	$xt3,$xb6,$xb7
++	vmrgow	$xb4,$xb4,$xb5
++	vmrgow	$xb6,$xb6,$xb7
++
++	vpermdi	$xa5,$xa4,$xa6,0b00
++	vpermdi	$xa7,$xa4,$xa6,0b11
++	vpermdi	$xa4,$xr0,$xt1,0b00
++	vpermdi	$xa6,$xr0,$xt1,0b11
++	vpermdi	$xb5,$xb4,$xb6,0b00
++	vpermdi	$xb7,$xb4,$xb6,0b11
++	vpermdi	$xb4,$xt2,$xt3,0b00
++	vpermdi	$xb6,$xt2,$xt3,0b11
++
++	vmrgew	$xr0,$xcn4,$xcn5
++	vmrgew	$xt1,$xcn6,$xcn7
++	vmrgow	$xcn4,$xcn4,$xcn5
++	vmrgow	$xcn6,$xcn6,$xcn7
++	vmrgew	$xt2,$xdn4,$xdn5
++	vmrgew	$xt3,$xdn6,$xdn7
++	vmrgow	$xdn4,$xdn4,$xdn5
++	vmrgow	$xdn6,$xdn6,$xdn7
++
++	vpermdi	$xcn5,$xcn4,$xcn6,0b00
++	vpermdi	$xcn7,$xcn4,$xcn6,0b11
++	vpermdi	$xcn4,$xr0,$xt1,0b00
++	vpermdi	$xcn6,$xr0,$xt1,0b11
++	vpermdi	$xdn5,$xdn4,$xdn6,0b00
++	vpermdi	$xdn7,$xdn4,$xdn6,0b11
++	vpermdi	$xdn4,$xt2,$xt3,0b00
++	vpermdi	$xdn6,$xt2,$xt3,0b11
++
++	vspltisw $xr0,8
++	vadduwm  $CTR1,$CTR1,$xr0		# next counter value
++	vxxlor	 $xv5 ,$CTR1,$CTR1	        #CTR+4-> 5
++
++	vadduwm	$xan0,$xa4,@K[0]
++	vadduwm	$xbn0,$xb4,@K[1]
++	vadduwm	$xcn0,$xcn4,@K[2]
++	vadduwm	$xdn0,$xdn4,@K[3]
++
++	be?vperm $xan0,$xa4,$xa4,$beperm
++	be?vperm $xbn0,$xb4,$xb4,$beperm
++	be?vperm $xcn0,$xcn4,$xcn4,$beperm
++	be?vperm $xdn0,$xdn4,$xdn4,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx_8x_1
++
++	lvx_4w	$xr0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xr0,$xr0,$xan0
++	vxor	$xt1,$xt1,$xbn0
++	vxor	$xt2,$xt2,$xcn0
++	vxor	$xt3,$xt3,$xdn0
++
++	stvx_4w	$xr0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx_8x
++
++	vadduwm	$xan0,$xa5,@K[0]
++	vadduwm	$xbn0,$xb5,@K[1]
++	vadduwm	$xcn0,$xcn5,@K[2]
++	vadduwm	$xdn0,$xdn5,@K[3]
++
++	be?vperm $xan0,$xan0,$xan0,$beperm
++	be?vperm $xbn0,$xbn0,$xbn0,$beperm
++	be?vperm $xcn0,$xcn0,$xcn0,$beperm
++	be?vperm $xdn0,$xdn0,$xdn0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx_8x_1
++
++	lvx_4w	$xr0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xr0,$xr0,$xan0
++	vxor	$xt1,$xt1,$xbn0
++	vxor	$xt2,$xt2,$xcn0
++	vxor	$xt3,$xt3,$xdn0
++
++	stvx_4w	$xr0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx_8x
++
++	vadduwm	$xan0,$xa6,@K[0]
++	vadduwm	$xbn0,$xb6,@K[1]
++	vadduwm	$xcn0,$xcn6,@K[2]
++	vadduwm	$xdn0,$xdn6,@K[3]
++
++	be?vperm $xan0,$xan0,$xan0,$beperm
++	be?vperm $xbn0,$xbn0,$xbn0,$beperm
++	be?vperm $xcn0,$xcn0,$xcn0,$beperm
++	be?vperm $xdn0,$xdn0,$xdn0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx_8x_1
++
++	lvx_4w	$xr0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xr0,$xr0,$xan0
++	vxor	$xt1,$xt1,$xbn0
++	vxor	$xt2,$xt2,$xcn0
++	vxor	$xt3,$xt3,$xdn0
++
++	stvx_4w	$xr0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx_8x
++
++	vadduwm	$xan0,$xa7,@K[0]
++	vadduwm	$xbn0,$xb7,@K[1]
++	vadduwm	$xcn0,$xcn7,@K[2]
++	vadduwm	$xdn0,$xdn7,@K[3]
++
++	be?vperm $xan0,$xan0,$xan0,$beperm
++	be?vperm $xbn0,$xbn0,$xbn0,$beperm
++	be?vperm $xcn0,$xcn0,$xcn0,$beperm
++	be?vperm $xdn0,$xdn0,$xdn0,$beperm
++
++	${UCMP}i $len,0x40
++	blt	Ltail_vsx_8x_1
++
++	lvx_4w	$xr0,$x00,$inp
++	lvx_4w	$xt1,$x10,$inp
++	lvx_4w	$xt2,$x20,$inp
++	lvx_4w	$xt3,$x30,$inp
++
++	vxor	$xr0,$xr0,$xan0
++	vxor	$xt1,$xt1,$xbn0
++	vxor	$xt2,$xt2,$xcn0
++	vxor	$xt3,$xt3,$xdn0
++
++	stvx_4w	$xr0,$x00,$out
++	stvx_4w	$xt1,$x10,$out
++	addi	$inp,$inp,0x40
++	stvx_4w	$xt2,$x20,$out
++	subi	$len,$len,0x40
++	stvx_4w	$xt3,$x30,$out
++	addi	$out,$out,0x40
++	beq	Ldone_vsx_8x
++
++	mtctr	r0
++	bne	Loop_outer_vsx_8x
++
++Ldone_vsx_8x:
++	lwz	r12,`$FRAME-4`($sp)		# pull vrsave
++	li	r10,`15+$LOCALS+64`
++	li	r11,`31+$LOCALS+64`
++	$POP	r0, `$FRAME+$LRSAVE`($sp)
++	mtspr	256,r12				# restore vrsave
++	lvx	v24,r10,$sp
++	addi	r10,r10,32
++	lvx	v25,r11,$sp
++	addi	r11,r11,32
++	lvx	v26,r10,$sp
++	addi	r10,r10,32
++	lvx	v27,r11,$sp
++	addi	r11,r11,32
++	lvx	v28,r10,$sp
++	addi	r10,r10,32
++	lvx	v29,r11,$sp
++	addi	r11,r11,32
++	lvx	v30,r10,$sp
++	lvx	v31,r11,$sp
++	mtlr	r0
++	addi	$sp,$sp,$FRAME
++	blr
++
++.align	4
++Ltail_vsx_8x:
++	addi	r11,$sp,$LOCALS
++	mtctr	$len
++	stvx_4w	$xa0,$x00,r11			# offload block to stack
++	stvx_4w	$xb0,$x10,r11
++	stvx_4w	$xc0,$x20,r11
++	stvx_4w	$xd0,$x30,r11
++	subi	r12,r11,1			# prepare for *++ptr
++	subi	$inp,$inp,1
++	subi	$out,$out,1
++	bl      Loop_tail_vsx_8x
++Ltail_vsx_8x_1:
++	addi	r11,$sp,$LOCALS
++	mtctr	$len
++	stvx_4w	$xan0,$x00,r11			# offload block to stack
++	stvx_4w	$xbn0,$x10,r11
++	stvx_4w	$xcn0,$x20,r11
++	stvx_4w	$xdn0,$x30,r11
++	subi	r12,r11,1			# prepare for *++ptr
++	subi	$inp,$inp,1
++	subi	$out,$out,1
++        bl      Loop_tail_vsx_8x
++
++Loop_tail_vsx_8x:
++	lbzu	r6,1(r12)
++	lbzu	r7,1($inp)
++	xor	r6,r6,r7
++	stbu	r6,1($out)
++	bdnz	Loop_tail_vsx_8x
++
++	stvx_4w	$K[0],$x00,r11			# wipe copy of the block
++	stvx_4w	$K[0],$x10,r11
++	stvx_4w	$K[0],$x20,r11
++	stvx_4w	$K[0],$x30,r11
++
++	b	Ldone_vsx_8x
++	.long	0
++	.byte	0,12,0x04,1,0x80,0,5,0
++	.long	0
++.size	.ChaCha20_ctr32_vsx_8x,.-.ChaCha20_ctr32_vsx_8x
++___
++}}}
++
++
++$code.=<<___;
++.align	5
++Lconsts:
++	mflr	r0
++	bcl	20,31,\$+4
++	mflr	r12	#vvvvv "distance between . and Lsigma
++	addi	r12,r12,`64-8`
++	mtlr	r0
++	blr
++	.long	0
++	.byte	0,12,0x14,0,0,0,0,0
++	.space	`64-9*4`
++Lsigma:
++	.long   0x61707865,0x3320646e,0x79622d32,0x6b206574
++	.long	1,0,0,0
++	.long	2,0,0,0
++	.long	3,0,0,0
++	.long	4,0,0,0
++___
++$code.=<<___ 	if ($LITTLE_ENDIAN);
++	.long	0x0e0f0c0d,0x0a0b0809,0x06070405,0x02030001
++	.long	0x0d0e0f0c,0x090a0b08,0x05060704,0x01020300
++___
++$code.=<<___ 	if (!$LITTLE_ENDIAN);	# flipped words
++	.long	0x02030001,0x06070405,0x0a0b0809,0x0e0f0c0d
++	.long	0x01020300,0x05060704,0x090a0b08,0x0d0e0f0c
++___
++$code.=<<___;
++	.long	0x61707865,0x61707865,0x61707865,0x61707865
++	.long	0x3320646e,0x3320646e,0x3320646e,0x3320646e
++	.long	0x79622d32,0x79622d32,0x79622d32,0x79622d32
++	.long	0x6b206574,0x6b206574,0x6b206574,0x6b206574
++	.long	0,1,2,3
++        .long   0x03020100,0x07060504,0x0b0a0908,0x0f0e0d0c
++.asciz  "ChaCha20 for PowerPC/AltiVec, CRYPTOGAMS by <appro\@openssl.org>"
++.align	2
++___
++
++foreach (split("\n",$code)) {
++	s/\`([^\`]*)\`/eval $1/ge;
++
++	# instructions prefixed with '?' are endian-specific and need
++	# to be adjusted accordingly...
++	if ($flavour !~ /le$/) {	# big-endian
++	    s/be\?//		or
++	    s/le\?/#le#/	or
++	    s/\?lvsr/lvsl/	or
++	    s/\?lvsl/lvsr/	or
++	    s/\?(vperm\s+v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+,\s*)(v[0-9]+)/$1$3$2$4/ or
++	    s/vrldoi(\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9]+)/vsldoi$1$2$2 16-$3/;
++	} else {			# little-endian
++	    s/le\?//		or
++	    s/be\?/#be#/	or
++	    s/\?([a-z]+)/$1/	or
++	    s/vrldoi(\s+v[0-9]+,\s*)(v[0-9]+,)\s*([0-9]+)/vsldoi$1$2$2 $3/;
++	}
++
++	print $_,"\n";
++}
++
++close STDOUT or die "error closing STDOUT: $!";
+diff --git a/crypto/chacha/build.info b/crypto/chacha/build.info
+index c12cb9c..2a819b2 100644
+--- a/crypto/chacha/build.info
++++ b/crypto/chacha/build.info
+@@ -12,7 +12,7 @@ IF[{- !$disabled{asm} -}]
+   $CHACHAASM_armv4=chacha-armv4.S
+   $CHACHAASM_aarch64=chacha-armv8.S
+ 
+-  $CHACHAASM_ppc32=chacha_ppc.c chacha-ppc.s
++  $CHACHAASM_ppc32=chacha_ppc.c chacha-ppc.s chachap10-ppc.s
+   $CHACHAASM_ppc64=$CHACHAASM_ppc32
+ 
+   $CHACHAASM_c64xplus=chacha-c64xplus.s
+@@ -29,6 +29,7 @@ SOURCE[../../libcrypto]=$CHACHAASM
+ GENERATE[chacha-x86.s]=asm/chacha-x86.pl
+ GENERATE[chacha-x86_64.s]=asm/chacha-x86_64.pl
+ GENERATE[chacha-ppc.s]=asm/chacha-ppc.pl
++GENERATE[chachap10-ppc.s]=asm/chachap10-ppc.pl
+ GENERATE[chacha-armv4.S]=asm/chacha-armv4.pl
+ INCLUDE[chacha-armv4.o]=..
+ GENERATE[chacha-armv8.S]=asm/chacha-armv8.pl
+diff --git a/crypto/chacha/chacha_ppc.c b/crypto/chacha/chacha_ppc.c
+index 5319040..f99cca8 100644
+--- a/crypto/chacha/chacha_ppc.c
++++ b/crypto/chacha/chacha_ppc.c
+@@ -23,13 +23,18 @@ void ChaCha20_ctr32_vmx(unsigned char *out, const unsigned char *inp,
+ void ChaCha20_ctr32_vsx(unsigned char *out, const unsigned char *inp,
+                         size_t len, const unsigned int key[8],
+                         const unsigned int counter[4]);
++void ChaCha20_ctr32_vsx_p10(unsigned char *out, const unsigned char *inp,
++                        size_t len, const unsigned int key[8],
++                        const unsigned int counter[4]);
+ void ChaCha20_ctr32(unsigned char *out, const unsigned char *inp,
+                     size_t len, const unsigned int key[8],
+                     const unsigned int counter[4])
+ {
+-    OPENSSL_ppccap_P & PPC_CRYPTO207
+-        ? ChaCha20_ctr32_vsx(out, inp, len, key, counter)
+-        : OPENSSL_ppccap_P & PPC_ALTIVEC
+-            ? ChaCha20_ctr32_vmx(out, inp, len, key, counter)
+-            : ChaCha20_ctr32_int(out, inp, len, key, counter);
++    OPENSSL_ppccap_P & PPC_BRD31
++        ? ChaCha20_ctr32_vsx_p10(out, inp, len, key, counter)
++        :OPENSSL_ppccap_P & PPC_CRYPTO207
++            ? ChaCha20_ctr32_vsx(out, inp, len, key, counter)
++            : OPENSSL_ppccap_P & PPC_ALTIVEC
++                 ? ChaCha20_ctr32_vmx(out, inp, len, key, counter)
++                 : ChaCha20_ctr32_int(out, inp, len, key, counter);
+ }
+diff --git a/crypto/perlasm/ppc-xlate.pl b/crypto/perlasm/ppc-xlate.pl
+index 2ee4440..4590340 100755
+--- a/crypto/perlasm/ppc-xlate.pl
++++ b/crypto/perlasm/ppc-xlate.pl
+@@ -293,6 +293,14 @@ my $vpermdi	= sub {				# xxpermdi
+     $dm = oct($dm) if ($dm =~ /^0/);
+     "	.long	".sprintf "0x%X",(60<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|($dm<<8)|(10<<3)|7;
+ };
++my $vxxlor	= sub {				# xxlor
++    my ($f, $vrt, $vra, $vrb) = @_;
++    "	.long	".sprintf "0x%X",(60<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|(146<<3)|6;
++};
++my $vxxlorc	= sub {				# xxlor
++    my ($f, $vrt, $vra, $vrb) = @_;
++    "	.long	".sprintf "0x%X",(60<<26)|($vrt<<21)|($vra<<16)|($vrb<<11)|(146<<3)|1;
++};
+ 
+ # PowerISA 2.07 stuff
+ sub vcrypto_op {
+@@ -377,6 +385,15 @@ my $addex = sub {
+ };
+ my $vmsumudm	= sub { vfour_vsr(@_, 35); };
+ 
++# PowerISA 3.1 stuff
++my $brd = sub {
++    my ($f, $ra, $rs) = @_;
++    "  .long   ".sprintf "0x%X",(31<<26)|($rs<<21)|($ra<<16)|(187<<1);
++};
++my $vsrq	= sub { vcrypto_op(@_, 517); };
++
++
++
+ while($line=<>) {
+ 
+     $line =~ s|[#!;].*$||;	# get rid of asm-style comments...
+diff --git a/crypto/ppccap.c b/crypto/ppccap.c
+index 8bcfed2..664627c 100644
+--- a/crypto/ppccap.c
++++ b/crypto/ppccap.c
+@@ -45,6 +45,7 @@ void OPENSSL_ppc64_probe(void);
+ void OPENSSL_altivec_probe(void);
+ void OPENSSL_crypto207_probe(void);
+ void OPENSSL_madd300_probe(void);
++void OPENSSL_brd31_probe(void);
+ 
+ long OPENSSL_rdtsc_mftb(void);
+ long OPENSSL_rdtsc_mfspr268(void);
+@@ -117,16 +118,21 @@ static unsigned long getauxval(unsigned long key)
+ #endif
+ 
+ /* I wish <sys/auxv.h> was universally available */
+-#define HWCAP                   16      /* AT_HWCAP */
++#ifndef AT_HWCAP
++# define AT_HWCAP               16      /* AT_HWCAP */
++#endif
+ #define HWCAP_PPC64             (1U << 30)
+ #define HWCAP_ALTIVEC           (1U << 28)
+ #define HWCAP_FPU               (1U << 27)
+ #define HWCAP_POWER6_EXT        (1U << 9)
+ #define HWCAP_VSX               (1U << 7)
+ 
+-#define HWCAP2                  26      /* AT_HWCAP2 */
++#ifndef AT_HWCAP2
++# define AT_HWCAP2              26      /* AT_HWCAP2 */
++#endif
+ #define HWCAP_VEC_CRYPTO        (1U << 25)
+ #define HWCAP_ARCH_3_00         (1U << 23)
++#define HWCAP_ARCH_3_1          (1U << 18)
+ 
+ # if defined(__GNUC__) && __GNUC__>=2
+ __attribute__ ((constructor))
+@@ -187,6 +193,9 @@ void OPENSSL_cpuid_setup(void)
+     if (__power_set(0xffffffffU<<17))           /* POWER9 and later */
+         OPENSSL_ppccap_P |= PPC_MADD300;
+ 
++    if (__power_set(0xffffffffU<<18))           /* POWER10 and later */
++        OPENSSL_ppccap_P |= PPC_BRD31;
++
+     return;
+ # endif
+ #endif
+@@ -215,8 +224,8 @@ void OPENSSL_cpuid_setup(void)
+ 
+ #ifdef OSSL_IMPLEMENT_GETAUXVAL
+     {
+-        unsigned long hwcap = getauxval(HWCAP);
+-        unsigned long hwcap2 = getauxval(HWCAP2);
++        unsigned long hwcap = getauxval(AT_HWCAP);
++        unsigned long hwcap2 = getauxval(AT_HWCAP2);
+ 
+         if (hwcap & HWCAP_FPU) {
+             OPENSSL_ppccap_P |= PPC_FPU;
+@@ -242,6 +251,10 @@ void OPENSSL_cpuid_setup(void)
+         if (hwcap2 & HWCAP_ARCH_3_00) {
+             OPENSSL_ppccap_P |= PPC_MADD300;
+         }
++
++        if (hwcap2 & HWCAP_ARCH_3_1) {
++            OPENSSL_ppccap_P |= PPC_BRD31;
++        }
+     }
+ #endif
+ 
+@@ -263,7 +276,7 @@ void OPENSSL_cpuid_setup(void)
+     sigaction(SIGILL, &ill_act, &ill_oact);
+ 
+ #ifndef OSSL_IMPLEMENT_GETAUXVAL
+-    if (sigsetjmp(ill_jmp,1) == 0) {
++    if (sigsetjmp(ill_jmp, 1) == 0) {
+         OPENSSL_fpu_probe();
+         OPENSSL_ppccap_P |= PPC_FPU;
+ 
+diff --git a/crypto/ppccpuid.pl b/crypto/ppccpuid.pl
+index c6555df..706164a 100755
+--- a/crypto/ppccpuid.pl
++++ b/crypto/ppccpuid.pl
+@@ -81,6 +81,17 @@ $code=<<___;
+ 	.long	0
+ 	.byte	0,12,0x14,0,0,0,0,0
+ 
++.globl	.OPENSSL_brd31_probe
++.align	4
++.OPENSSL_brd31_probe:
++	xor	r0,r0,r0
++	brd	r3,r0
++	blr
++	.long	0
++	.byte	0,12,0x14,0,0,0,0,0
++.size	.OPENSSL_brd31_probe,.-.OPENSSL_brd31_probe
++
++
+ .globl	.OPENSSL_wipe_cpu
+ .align	4
+ .OPENSSL_wipe_cpu:
+diff --git a/include/crypto/ppc_arch.h b/include/crypto/ppc_arch.h
+index 3b3ce4b..fcc846c 100644
+--- a/include/crypto/ppc_arch.h
++++ b/include/crypto/ppc_arch.h
+@@ -24,5 +24,6 @@ extern unsigned int OPENSSL_ppccap_P;
+ # define PPC_MADD300     (1<<4)
+ # define PPC_MFTB        (1<<5)
+ # define PPC_MFSPR268    (1<<6)
++# define PPC_BRD31       (1<<7)
+ 
+ #endif
diff --git a/SOURCES/0073-FIPS-Use-OAEP-in-KATs-support-fixed-OAEP-seed.patch b/SOURCES/0073-FIPS-Use-OAEP-in-KATs-support-fixed-OAEP-seed.patch
new file mode 100644
index 0000000..27f86f5
--- /dev/null
+++ b/SOURCES/0073-FIPS-Use-OAEP-in-KATs-support-fixed-OAEP-seed.patch
@@ -0,0 +1,367 @@
+From 4a2239bd7d444c30c55b20ea8b4aeadafdfe1afd Mon Sep 17 00:00:00 2001
+From: Clemens Lang <cllang@redhat.com>
+Date: Fri, 22 Jul 2022 13:59:37 +0200
+Subject: [PATCH] FIPS: Use OAEP in KATs, support fixed OAEP seed
+
+Review by our lab for FIPS 140-3 certification expects the RSA
+encryption and decryption tests to use a supported padding mode, not raw
+RSA signatures. Switch to RSA-OAEP for the self tests to fulfill that.
+
+The FIPS 140-3 Implementation Guidance specifies in section 10.3.A
+"Cryptographic Algorithm Self-Test Requirements" that a self-test may be
+a known-answer test, a comparison test, or a fault-detection test.
+
+Comparison tests are not an option, because they would require
+a separate implementation of RSA-OAEP, which we do not have. Fault
+detection tests require implementing fault detection mechanisms into the
+cryptographic algorithm implementation, we we also do not have.
+
+As a consequence, a known-answer test must be used to test RSA
+encryption and decryption, but RSA encryption with OAEP padding is not
+deterministic, and thus encryption will always yield different results
+that could not be compared to known answers. For this reason, this
+change explicitly sets the seed in OAEP (see RFC 8017 section 7.1.1),
+which is the source of randomness for RSA-OAEP, to a fixed value. This
+setting is only available during self-test execution, and the parameter
+set using EVP_PKEY_CTX_set_params() will be ignored otherwise.
+
+Signed-off-by: Clemens Lang <cllang@redhat.com>
+---
+ crypto/rsa/rsa_local.h                        |  8 ++
+ crypto/rsa/rsa_oaep.c                         | 34 ++++++--
+ include/openssl/core_names.h                  |  3 +
+ providers/fips/self_test_data.inc             | 83 +++++++++++--------
+ providers/fips/self_test_kats.c               |  7 ++
+ .../implementations/asymciphers/rsa_enc.c     | 41 ++++++++-
+ 6 files changed, 133 insertions(+), 43 deletions(-)
+
+diff --git a/crypto/rsa/rsa_local.h b/crypto/rsa/rsa_local.h
+index ea70da05ad..dde57a1a0e 100644
+--- a/crypto/rsa/rsa_local.h
++++ b/crypto/rsa/rsa_local.h
+@@ -193,4 +193,12 @@ int ossl_rsa_padding_add_PKCS1_type_2_ex(OSSL_LIB_CTX *libctx, unsigned char *to
+                                          int tlen, const unsigned char *from,
+                                          int flen);
+ 
++int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex2(OSSL_LIB_CTX *libctx,
++                                             unsigned char *to, int tlen,
++                                             const unsigned char *from, int flen,
++                                             const unsigned char *param,
++                                             int plen, const EVP_MD *md,
++                                             const EVP_MD *mgf1md,
++                                             const char *redhat_st_seed);
++
+ #endif /* OSSL_CRYPTO_RSA_LOCAL_H */
+diff --git a/crypto/rsa/rsa_oaep.c b/crypto/rsa/rsa_oaep.c
+index d9be1a4f98..b2f7f7dc4b 100644
+--- a/crypto/rsa/rsa_oaep.c
++++ b/crypto/rsa/rsa_oaep.c
+@@ -44,6 +44,10 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+                                                    param, plen, NULL, NULL);
+ }
+ 
++#ifdef FIPS_MODULE
++extern int REDHAT_FIPS_asym_cipher_st;
++#endif /* FIPS_MODULE */
++
+ /*
+  * Perform the padding as per NIST 800-56B 7.2.2.3
+  *      from (K) is the key material.
+@@ -51,12 +55,13 @@ int RSA_padding_add_PKCS1_OAEP(unsigned char *to, int tlen,
+  * Step numbers are included here but not in the constant time inverse below
+  * to avoid complicating an already difficult enough function.
+  */
+-int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx,
+-                                            unsigned char *to, int tlen,
+-                                            const unsigned char *from, int flen,
+-                                            const unsigned char *param,
+-                                            int plen, const EVP_MD *md,
+-                                            const EVP_MD *mgf1md)
++int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex2(OSSL_LIB_CTX *libctx,
++                                             unsigned char *to, int tlen,
++                                             const unsigned char *from, int flen,
++                                             const unsigned char *param,
++                                             int plen, const EVP_MD *md,
++                                             const EVP_MD *mgf1md,
++                                             const char *redhat_st_seed)
+ {
+     int rv = 0;
+     int i, emlen = tlen - 1;
+@@ -107,6 +112,11 @@ int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx,
+     db[emlen - flen - mdlen - 1] = 0x01;
+     memcpy(db + emlen - flen - mdlen, from, (unsigned int)flen);
+     /* step 3d: generate random byte string */
++#ifdef FIPS_MODULE
++    if (redhat_st_seed != NULL && REDHAT_FIPS_asym_cipher_st) {
++        memcpy(seed, redhat_st_seed, mdlen);
++    } else
++#endif
+     if (RAND_bytes_ex(libctx, seed, mdlen, 0) <= 0)
+         goto err;
+ 
+@@ -138,6 +148,18 @@ int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx,
+     return rv;
+ }
+ 
++int ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(OSSL_LIB_CTX *libctx,
++                                            unsigned char *to, int tlen,
++                                            const unsigned char *from, int flen,
++                                            const unsigned char *param,
++                                            int plen, const EVP_MD *md,
++                                            const EVP_MD *mgf1md)
++{
++    return ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex2(libctx, to, tlen, from,
++                                                    flen, param, plen, md,
++                                                    mgf1md, NULL);
++}
++
+ int RSA_padding_add_PKCS1_OAEP_mgf1(unsigned char *to, int tlen,
+                                     const unsigned char *from, int flen,
+                                     const unsigned char *param, int plen,
+diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
+index 59a6e79566..11216fb8f8 100644
+--- a/include/openssl/core_names.h
++++ b/include/openssl/core_names.h
+@@ -469,6 +469,9 @@ extern "C" {
+ #define OSSL_ASYM_CIPHER_PARAM_OAEP_LABEL               "oaep-label"
+ #define OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION       "tls-client-version"
+ #define OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION   "tls-negotiated-version"
++#ifdef FIPS_MODULE
++#define OSSL_ASYM_CIPHER_PARAM_REDHAT_KAT_OEAP_SEED     "redhat-kat-oaep-seed"
++#endif
+ 
+ /*
+  * Encoder / decoder parameters
+diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc
+index 4e30ec56dd..0103c87528 100644
+--- a/providers/fips/self_test_data.inc
++++ b/providers/fips/self_test_data.inc
+@@ -1294,9 +1294,22 @@ static const ST_KAT_PARAM rsa_priv_key[] = {
+     ST_KAT_PARAM_END()
+ };
+ 
++/*-
++ * Using OSSL_PKEY_RSA_PAD_MODE_OAEP directly in the expansion of the
++ * ST_KAT_PARAM_UTF8STRING macro below causes a failure on ancient
++ * HP/UX PA-RISC compilers.
++ */
++static const char pad_mode_oaep[] = OSSL_PKEY_RSA_PAD_MODE_OAEP;
++static const char oaep_fixed_seed[] = {
++    0xf6, 0x10, 0xef, 0x0a, 0x97, 0xbf, 0x91, 0x25,
++    0x97, 0xcf, 0x8e, 0x0a, 0x75, 0x51, 0x2f, 0xab,
++    0x2e, 0x4b, 0x2c, 0xe6
++};
++
+ static const ST_KAT_PARAM rsa_enc_params[] = {
+-    ST_KAT_PARAM_UTF8STRING(OSSL_ASYM_CIPHER_PARAM_PAD_MODE,
+-                            OSSL_PKEY_RSA_PAD_MODE_NONE),
++    ST_KAT_PARAM_UTF8STRING(OSSL_ASYM_CIPHER_PARAM_PAD_MODE, pad_mode_oaep),
++    ST_KAT_PARAM_OCTET(OSSL_ASYM_CIPHER_PARAM_REDHAT_KAT_OEAP_SEED,
++                       oaep_fixed_seed),
+     ST_KAT_PARAM_END()
+ };
+ 
+@@ -1335,43 +1348,43 @@ static const unsigned char rsa_expected_sig[256] = {
+     0x2c, 0x68, 0xf0, 0x37, 0xa9, 0xd2, 0x56, 0xd6
+ };
+ 
+-static const unsigned char rsa_asym_plaintext_encrypt[256] = {
++static const unsigned char rsa_asym_plaintext_encrypt[208] = {
+    0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
+    0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10,
+ };
+ static const unsigned char rsa_asym_expected_encrypt[256] = {
+-    0x54, 0xac, 0x23, 0x96, 0x1d, 0x82, 0x5d, 0x8b,
+-    0x8f, 0x36, 0x33, 0xd0, 0xf4, 0x02, 0xa2, 0x61,
+-    0xb1, 0x13, 0xd4, 0x4a, 0x46, 0x06, 0x37, 0x3c,
+-    0xbf, 0x40, 0x05, 0x3c, 0xc6, 0x3b, 0x64, 0xdc,
+-    0x22, 0x22, 0xaf, 0x36, 0x79, 0x62, 0x45, 0xf0,
+-    0x97, 0x82, 0x22, 0x44, 0x86, 0x4a, 0x7c, 0xfa,
+-    0xac, 0x03, 0x21, 0x84, 0x3f, 0x31, 0xad, 0x2a,
+-    0xa4, 0x6e, 0x7a, 0xc5, 0x93, 0xf3, 0x0f, 0xfc,
+-    0xf1, 0x62, 0xce, 0x82, 0x12, 0x45, 0xc9, 0x35,
+-    0xb0, 0x7a, 0xcd, 0x99, 0x8c, 0x91, 0x6b, 0x5a,
+-    0xd3, 0x46, 0xdb, 0xf9, 0x9e, 0x52, 0x49, 0xbd,
+-    0x1e, 0xe8, 0xda, 0xac, 0x61, 0x47, 0xc2, 0xda,
+-    0xfc, 0x1e, 0xfb, 0x74, 0xd7, 0xd6, 0xc1, 0x18,
+-    0x86, 0x3e, 0x20, 0x9c, 0x7a, 0xe1, 0x04, 0xb7,
+-    0x38, 0x43, 0xb1, 0x4e, 0xa0, 0xd8, 0xc1, 0x39,
+-    0x4d, 0xe1, 0xd3, 0xb0, 0xb3, 0xf1, 0x82, 0x87,
+-    0x1f, 0x74, 0xb5, 0x69, 0xfd, 0x33, 0xd6, 0x21,
+-    0x7c, 0x61, 0x60, 0x28, 0xca, 0x70, 0xdb, 0xa0,
+-    0xbb, 0xc8, 0x73, 0xa9, 0x82, 0xf8, 0x6b, 0xd8,
+-    0xf0, 0xc9, 0x7b, 0x20, 0xdf, 0x9d, 0xfb, 0x8c,
+-    0xd4, 0xa2, 0x89, 0xe1, 0x9b, 0x04, 0xad, 0xaa,
+-    0x11, 0x6c, 0x8f, 0xce, 0x83, 0x29, 0x56, 0x69,
+-    0xbb, 0x00, 0x3b, 0xef, 0xca, 0x2d, 0xcd, 0x52,
+-    0xc8, 0xf1, 0xb3, 0x9b, 0xb4, 0x4f, 0x6d, 0x9c,
+-    0x3d, 0x69, 0xcc, 0x6d, 0x1f, 0x38, 0x4d, 0xe6,
+-    0xbb, 0x0c, 0x87, 0xdc, 0x5f, 0xa9, 0x24, 0x93,
+-    0x03, 0x46, 0xa2, 0x33, 0x6c, 0xf4, 0xd8, 0x5d,
+-    0x68, 0xf3, 0xd3, 0xe0, 0xf2, 0x30, 0xdb, 0xf5,
+-    0x4f, 0x0f, 0xad, 0xc7, 0xd0, 0xaa, 0x47, 0xd9,
+-    0x9f, 0x85, 0x1b, 0x2e, 0x6c, 0x3c, 0x57, 0x04,
+-    0x29, 0xf4, 0xf5, 0x66, 0x7d, 0x93, 0x4a, 0xaa,
+-    0x05, 0x52, 0x55, 0xc1, 0xc6, 0x06, 0x90, 0xab,
++    0x6c, 0x21, 0xc1, 0x9e, 0x94, 0xee, 0xdf, 0x74,
++    0x3a, 0x3c, 0x7c, 0x04, 0x1a, 0x53, 0x9e, 0x7c,
++    0x42, 0xac, 0x7e, 0x28, 0x9a, 0xb7, 0xe2, 0x4e,
++    0x87, 0xd4, 0x00, 0x69, 0x71, 0xf0, 0x3e, 0x0b,
++    0xc1, 0xda, 0xd6, 0xbd, 0x21, 0x39, 0x4f, 0x25,
++    0x22, 0x1f, 0x76, 0x0d, 0x62, 0x1f, 0xa2, 0x89,
++    0xdb, 0x38, 0x32, 0x88, 0x21, 0x1d, 0x89, 0xf1,
++    0xe0, 0x14, 0xd4, 0xb7, 0x90, 0xfc, 0xbc, 0x50,
++    0xb0, 0x8d, 0x5c, 0x2f, 0x49, 0x9e, 0x90, 0x17,
++    0x9e, 0x60, 0x9f, 0xe1, 0x77, 0x4f, 0x11, 0xa2,
++    0xcf, 0x16, 0x65, 0x2d, 0x4a, 0x2c, 0x12, 0xcb,
++    0x1e, 0x3c, 0x29, 0x8b, 0xdc, 0x27, 0x06, 0x9d,
++    0xf4, 0x0d, 0xe1, 0xc9, 0xeb, 0x14, 0x6a, 0x7e,
++    0xfd, 0xa7, 0xa8, 0xa7, 0x51, 0x82, 0x62, 0x0f,
++    0x29, 0x8d, 0x8c, 0x5e, 0xf2, 0xb8, 0xcd, 0xd3,
++    0x51, 0x92, 0xa7, 0x25, 0x39, 0x9d, 0xdd, 0x06,
++    0xff, 0xb1, 0xb0, 0xd5, 0x61, 0x03, 0x8f, 0x25,
++    0x5c, 0x49, 0x12, 0xc1, 0x50, 0x67, 0x61, 0x78,
++    0xb3, 0xe3, 0xc4, 0xf6, 0x36, 0x16, 0xa9, 0x04,
++    0x91, 0x0a, 0x4b, 0x27, 0x28, 0x97, 0x50, 0x7c,
++    0x65, 0x2d, 0xd0, 0x08, 0x71, 0x84, 0xe7, 0x47,
++    0x79, 0x83, 0x91, 0x46, 0xd9, 0x8f, 0x79, 0xce,
++    0x49, 0xcb, 0xcd, 0x8b, 0x34, 0xac, 0x61, 0xe0,
++    0xe6, 0x55, 0xbf, 0x10, 0xe4, 0xac, 0x9a, 0xd6,
++    0xed, 0xc1, 0xc2, 0xb6, 0xb6, 0xf7, 0x41, 0x99,
++    0xde, 0xfa, 0xde, 0x11, 0x16, 0xa2, 0x18, 0x30,
++    0x30, 0xdc, 0x95, 0x76, 0x2f, 0x46, 0x43, 0x20,
++    0xc4, 0xe7, 0x50, 0xb9, 0x1e, 0xcd, 0x69, 0xbb,
++    0x29, 0x94, 0x27, 0x9c, 0xc9, 0xab, 0xb4, 0x27,
++    0x8b, 0x4d, 0xe1, 0xcb, 0xc1, 0x04, 0x2c, 0x66,
++    0x41, 0x3a, 0x4d, 0xeb, 0x61, 0x4c, 0x77, 0x5a,
++    0xee, 0xb0, 0xca, 0x99, 0x0e, 0x7f, 0xbe, 0x06
+ };
+ 
+ #ifndef OPENSSL_NO_EC
+diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c
+index 064794d9bf..b6d5e8e134 100644
+--- a/providers/fips/self_test_kats.c
++++ b/providers/fips/self_test_kats.c
+@@ -647,14 +647,21 @@ static int self_test_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
+     return ret;
+ }
+ 
++int REDHAT_FIPS_asym_cipher_st = 0;
++
+ static int self_test_asym_ciphers(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
+ {
+     int i, ret = 1;
+ 
++    REDHAT_FIPS_asym_cipher_st = 1;
++
+     for (i = 0; i < (int)OSSL_NELEM(st_kat_asym_cipher_tests); ++i) {
+         if (!self_test_asym_cipher(&st_kat_asym_cipher_tests[i], st, libctx))
+             ret = 0;
+     }
++
++    REDHAT_FIPS_asym_cipher_st = 0;
++
+     return ret;
+ }
+ 
+diff --git a/providers/implementations/asymciphers/rsa_enc.c b/providers/implementations/asymciphers/rsa_enc.c
+index 00cf65fcd6..83be3d8ede 100644
+--- a/providers/implementations/asymciphers/rsa_enc.c
++++ b/providers/implementations/asymciphers/rsa_enc.c
+@@ -30,6 +30,9 @@
+ #include "prov/implementations.h"
+ #include "prov/providercommon.h"
+ #include "prov/securitycheck.h"
++#ifdef FIPS_MODULE
++# include "crypto/rsa/rsa_local.h"
++#endif
+ 
+ #include <stdlib.h>
+ 
+@@ -75,6 +78,9 @@ typedef struct {
+     /* TLS padding */
+     unsigned int client_version;
+     unsigned int alt_version;
++#ifdef FIPS_MODULE
++    char *redhat_st_oaep_seed;
++#endif /* FIPS_MODULE */
+ } PROV_RSA_CTX;
+ 
+ static void *rsa_newctx(void *provctx)
+@@ -190,12 +196,21 @@ static int rsa_encrypt(void *vprsactx, unsigned char *out, size_t *outlen,
+             return 0;
+         }
+         ret =
+-            ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(prsactx->libctx, tbuf,
++#ifdef FIPS_MODULE
++            ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex2(
++#else
++            ossl_rsa_padding_add_PKCS1_OAEP_mgf1_ex(
++#endif
++                                                    prsactx->libctx, tbuf,
+                                                     rsasize, in, inlen,
+                                                     prsactx->oaep_label,
+                                                     prsactx->oaep_labellen,
+                                                     prsactx->oaep_md,
+-                                                    prsactx->mgf1_md);
++                                                    prsactx->mgf1_md
++#ifdef FIPS_MODULE
++                                                    , prsactx->redhat_st_oaep_seed
++#endif
++                                                    );
+ 
+         if (!ret) {
+             OPENSSL_free(tbuf);
+@@ -326,6 +341,9 @@ static void rsa_freectx(void *vprsactx)
+     EVP_MD_free(prsactx->oaep_md);
+     EVP_MD_free(prsactx->mgf1_md);
+     OPENSSL_free(prsactx->oaep_label);
++#ifdef FIPS_MODULE
++    OPENSSL_free(prsactx->redhat_st_oaep_seed);
++#endif /* FIPS_MODULE */
+ 
+     OPENSSL_free(prsactx);
+ }
+@@ -445,6 +463,9 @@ static const OSSL_PARAM known_gettable_ctx_params[] = {
+                     NULL, 0),
+     OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION, NULL),
+     OSSL_PARAM_uint(OSSL_ASYM_CIPHER_PARAM_TLS_NEGOTIATED_VERSION, NULL),
++#ifdef FIPS_MODULE
++    OSSL_PARAM_octet_string(OSSL_ASYM_CIPHER_PARAM_REDHAT_KAT_OEAP_SEED, NULL, 0),
++#endif /* FIPS_MODULE */
+     OSSL_PARAM_END
+ };
+ 
+@@ -454,6 +475,10 @@ static const OSSL_PARAM *rsa_gettable_ctx_params(ossl_unused void *vprsactx,
+     return known_gettable_ctx_params;
+ }
+ 
++#ifdef FIPS_MODULE
++extern int REDHAT_FIPS_asym_cipher_st;
++#endif /* FIPS_MODULE */
++
+ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
+ {
+     PROV_RSA_CTX *prsactx = (PROV_RSA_CTX *)vprsactx;
+@@ -563,6 +588,18 @@ static int rsa_set_ctx_params(void *vprsactx, const OSSL_PARAM params[])
+         prsactx->oaep_labellen = tmp_labellen;
+     }
+ 
++#ifdef FIPS_MODULE
++    p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_REDHAT_KAT_OEAP_SEED);
++    if (p != NULL && REDHAT_FIPS_asym_cipher_st) {
++        void *tmp_oaep_seed = NULL;
++
++        if (!OSSL_PARAM_get_octet_string(p, &tmp_oaep_seed, 0, NULL))
++            return 0;
++        OPENSSL_free(prsactx->redhat_st_oaep_seed);
++        prsactx->redhat_st_oaep_seed = (char *)tmp_oaep_seed;
++    }
++#endif /* FIPS_MODULE */
++
+     p = OSSL_PARAM_locate_const(params, OSSL_ASYM_CIPHER_PARAM_TLS_CLIENT_VERSION);
+     if (p != NULL) {
+         unsigned int client_version;
+-- 
+2.37.1
+
diff --git a/SOURCES/0074-FIPS-Use-digest_sign-digest_verify-in-self-test.patch b/SOURCES/0074-FIPS-Use-digest_sign-digest_verify-in-self-test.patch
new file mode 100644
index 0000000..c7e4731
--- /dev/null
+++ b/SOURCES/0074-FIPS-Use-digest_sign-digest_verify-in-self-test.patch
@@ -0,0 +1,313 @@
+From 97ac06e5a8e3a8699279c06eeb64c8e958bad7bd Mon Sep 17 00:00:00 2001
+From: Clemens Lang <cllang@redhat.com>
+Date: Fri, 15 Jul 2022 17:45:40 +0200
+Subject: [PATCH] FIPS: Use digest_sign & digest_verify in self test
+
+In review for FIPS 140-3, the lack of a self-test for the digest_sign
+and digest_verify provider functions was highlighted as a problem. NIST
+no longer provides ACVP tests for the RSA SigVer primitive (see
+https://github.com/usnistgov/ACVP/issues/1347). Because FIPS 140-3
+recommends the use of functions that compute the digest and signature
+within the module, we have been advised in our module review that the
+self tests should also use the combined digest and signature APIs, i.e.
+the digest_sign and digest_verify provider functions.
+
+Modify the signature self-test to use these instead by switching to
+EVP_DigestSign and EVP_DigestVerify. This requires adding more ifdefs to
+crypto/evp/m_sigver.c to make these functions usable in the FIPS module.
+
+Signed-off-by: Clemens Lang <cllang@redhat.com>
+---
+ crypto/evp/m_sigver.c           | 43 +++++++++++++++++++++++++++------
+ providers/fips/self_test_kats.c | 37 +++++++++++++++-------------
+ 2 files changed, 56 insertions(+), 24 deletions(-)
+
+diff --git a/crypto/evp/m_sigver.c b/crypto/evp/m_sigver.c
+index db1a1d7bc3..c94c3c53bd 100644
+--- a/crypto/evp/m_sigver.c
++++ b/crypto/evp/m_sigver.c
+@@ -88,6 +88,7 @@ static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
+     ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED);
+     return 0;
+ }
++#endif /* !defined(FIPS_MODULE) */
+ 
+ /*
+  * If we get the "NULL" md then the name comes back as "UNDEF". We want to use
+@@ -130,8 +131,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+         reinit = 0;
+         if (e == NULL)
+             ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props);
++#ifndef FIPS_MODULE
+         else
+             ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
++#endif /* !defined(FIPS_MODULE) */
+     }
+     if (ctx->pctx == NULL)
+         return 0;
+@@ -139,8 +142,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+     locpctx = ctx->pctx;
+     ERR_set_mark();
+ 
++#ifndef FIPS_MODULE
+     if (evp_pkey_ctx_is_legacy(locpctx))
+         goto legacy;
++#endif /* !defined(FIPS_MODULE) */
+ 
+     /* do not reinitialize if pkey is set or operation is different */
+     if (reinit
+@@ -225,8 +230,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+             signature =
+                 evp_signature_fetch_from_prov((OSSL_PROVIDER *)tmp_prov,
+                                               supported_sig, locpctx->propquery);
++#ifndef FIPS_MODULE
+             if (signature == NULL)
+                 goto legacy;
++#endif /* !defined(FIPS_MODULE) */
+             break;
+         }
+         if (signature == NULL)
+@@ -310,6 +317,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+             ctx->fetched_digest = EVP_MD_fetch(locpctx->libctx, mdname, props);
+             if (ctx->fetched_digest != NULL) {
+                 ctx->digest = ctx->reqdigest = ctx->fetched_digest;
++#ifndef FIPS_MODULE
+             } else {
+                 /* legacy engine support : remove the mark when this is deleted */
+                 ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname);
+@@ -318,11 +326,13 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+                     ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+                     goto err;
+                 }
++#endif /* !defined(FIPS_MODULE) */
+             }
+             (void)ERR_pop_to_mark();
+         }
+     }
+ 
++#ifndef FIPS_MODULE
+     if (ctx->reqdigest != NULL
+             && !EVP_PKEY_is_a(locpctx->pkey, SN_hmac)
+             && !EVP_PKEY_is_a(locpctx->pkey, SN_tls1_prf)
+@@ -334,6 +344,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+             goto err;
+         }
+     }
++#endif /* !defined(FIPS_MODULE) */
+ 
+     if (ver) {
+         if (signature->digest_verify_init == NULL) {
+@@ -366,6 +377,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+     EVP_KEYMGMT_free(tmp_keymgmt);
+     return 0;
+ 
++#ifndef FIPS_MODULE
+  legacy:
+     /*
+      * If we don't have the full support we need with provided methods,
+@@ -437,6 +449,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+         ctx->pctx->flag_call_digest_custom = 1;
+ 
+     ret = 1;
++#endif /* !defined(FIPS_MODULE) */
+ 
+  end:
+ #ifndef FIPS_MODULE
+@@ -479,7 +492,6 @@ int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
+     return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1,
+                           NULL);
+ }
+-#endif /* FIPS_MDOE */
+ 
+ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
+ {
+@@ -541,23 +553,29 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
+     return EVP_DigestUpdate(ctx, data, dsize);
+ }
+ 
+-#ifndef FIPS_MODULE
+ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+                         size_t *siglen)
+ {
+-    int sctx = 0, r = 0;
+-    EVP_PKEY_CTX *dctx, *pctx = ctx->pctx;
++    int r = 0;
++#ifndef FIPS_MODULE
++    int sctx = 0;
++    EVP_PKEY_CTX *dctx;
++#endif /* !defined(FIPS_MODULE) */
++    EVP_PKEY_CTX *pctx = ctx->pctx;
+ 
++#ifndef FIPS_MODULE
+     if (pctx == NULL
+             || pctx->operation != EVP_PKEY_OP_SIGNCTX
+             || pctx->op.sig.algctx == NULL
+             || pctx->op.sig.signature == NULL)
+         goto legacy;
++#endif /* !defined(FIPS_MODULE) */
+ 
+     if (sigret == NULL || (ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0)
+         return pctx->op.sig.signature->digest_sign_final(pctx->op.sig.algctx,
+                                                          sigret, siglen,
+                                                          (siglen == NULL) ? 0 : *siglen);
++#ifndef FIPS_MODULE
+     dctx = EVP_PKEY_CTX_dup(pctx);
+     if (dctx == NULL)
+         return 0;
+@@ -566,8 +584,10 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+                                                   sigret, siglen,
+                                                   (siglen == NULL) ? 0 : *siglen);
+     EVP_PKEY_CTX_free(dctx);
++#endif /* defined(FIPS_MODULE) */
+     return r;
+ 
++#ifndef FIPS_MODULE
+  legacy:
+     if (pctx == NULL || pctx->pmeth == NULL) {
+         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+@@ -639,6 +659,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
+         }
+     }
+     return 1;
++#endif /* !defined(FIPS_MODULE) */
+ }
+ 
+ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
+@@ -669,21 +690,27 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
+ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
+                           size_t siglen)
+ {
+-    unsigned char md[EVP_MAX_MD_SIZE];
+     int r = 0;
++#ifndef FIPS_MODULE
++    unsigned char md[EVP_MAX_MD_SIZE];
+     unsigned int mdlen = 0;
+     int vctx = 0;
+-    EVP_PKEY_CTX *dctx, *pctx = ctx->pctx;
++    EVP_PKEY_CTX *dctx;
++#endif /* !defined(FIPS_MODULE) */
++    EVP_PKEY_CTX *pctx = ctx->pctx;
+ 
++#ifndef FIPS_MODULE
+     if (pctx == NULL
+             || pctx->operation != EVP_PKEY_OP_VERIFYCTX
+             || pctx->op.sig.algctx == NULL
+             || pctx->op.sig.signature == NULL)
+         goto legacy;
++#endif /* !defined(FIPS_MODULE) */
+ 
+     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISE) != 0)
+         return pctx->op.sig.signature->digest_verify_final(pctx->op.sig.algctx,
+                                                            sig, siglen);
++#ifndef FIPS_MODULE
+     dctx = EVP_PKEY_CTX_dup(pctx);
+     if (dctx == NULL)
+         return 0;
+@@ -691,8 +718,10 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
+     r = dctx->op.sig.signature->digest_verify_final(dctx->op.sig.algctx,
+                                                     sig, siglen);
+     EVP_PKEY_CTX_free(dctx);
++#endif /* !defined(FIPS_MODULE) */
+     return r;
+ 
++#ifndef FIPS_MODULE
+  legacy:
+     if (pctx == NULL || pctx->pmeth == NULL) {
+         ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+@@ -732,6 +761,7 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
+     if (vctx || !r)
+         return r;
+     return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen);
++#endif /* !defined(FIPS_MODULE) */
+ }
+ 
+ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
+@@ -757,4 +787,3 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
+         return -1;
+     return EVP_DigestVerifyFinal(ctx, sigret, siglen);
+ }
+-#endif /* FIPS_MODULE */
+diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c
+index b6d5e8e134..77eec075e6 100644
+--- a/providers/fips/self_test_kats.c
++++ b/providers/fips/self_test_kats.c
+@@ -444,11 +444,14 @@ static int self_test_sign(const ST_KAT_SIGN *t,
+     int ret = 0;
+     OSSL_PARAM *params = NULL, *params_sig = NULL;
+     OSSL_PARAM_BLD *bld = NULL;
++    EVP_MD *md = NULL;
++    EVP_MD_CTX *ctx = NULL;
+     EVP_PKEY_CTX *sctx = NULL, *kctx = NULL;
+     EVP_PKEY *pkey = NULL;
+-    unsigned char sig[256];
+     BN_CTX *bnctx = NULL;
+     BIGNUM *K = NULL;
++    const char *msg = "Hello World!";
++    unsigned char sig[256];
+     size_t siglen = sizeof(sig);
+     static const unsigned char dgst[] = {
+         0x7f, 0x83, 0xb1, 0x65, 0x7f, 0xf1, 0xfc, 0x53, 0xb9, 0x2d, 0xc1, 0x81,
+@@ -488,23 +491,26 @@ static int self_test_sign(const ST_KAT_SIGN *t,
+         || EVP_PKEY_fromdata(kctx, &pkey, EVP_PKEY_KEYPAIR, params) <= 0)
+         goto err;
+ 
+-    /* Create a EVP_PKEY_CTX to use for the signing operation */
+-    sctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, NULL);
+-    if (sctx == NULL
+-        || EVP_PKEY_sign_init(sctx) <= 0)
+-        goto err;
+-
+-    /* set signature parameters */
+-    if (!OSSL_PARAM_BLD_push_utf8_string(bld, OSSL_SIGNATURE_PARAM_DIGEST,
+-                                         t->mdalgorithm,
+-                                         strlen(t->mdalgorithm) + 1))
+-        goto err;
++    /* Create a EVP_MD_CTX to use for the signature operation, assign signature
++     * parameters and sign */
+     params_sig = OSSL_PARAM_BLD_to_param(bld);
+-    if (EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0)
++    md = EVP_MD_fetch(libctx, "SHA256", NULL);
++    ctx = EVP_MD_CTX_new();
++    if (md == NULL || ctx == NULL)
++        goto err;
++    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE | EVP_MD_CTX_FLAG_ONESHOT);
++    if (EVP_DigestSignInit(ctx, &sctx, md, NULL, pkey) <= 0
++        || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0
++        || EVP_DigestSign(ctx, sig, &siglen, (const unsigned char *)msg, strlen(msg)) <= 0
++        || EVP_MD_CTX_reset(ctx) <= 0)
+         goto err;
+ 
+-    if (EVP_PKEY_sign(sctx, sig, &siglen, dgst, sizeof(dgst)) <= 0
+-        || EVP_PKEY_verify_init(sctx) <= 0
++    /* sctx is not freed automatically inside the FIPS module */
++    EVP_PKEY_CTX_free(sctx);
++    sctx = NULL;
++
++    EVP_MD_CTX_set_flags(ctx, EVP_MD_CTX_FLAG_FINALISE | EVP_MD_CTX_FLAG_ONESHOT);
++    if (EVP_DigestVerifyInit(ctx, &sctx, md, NULL, pkey) <= 0
+         || EVP_PKEY_CTX_set_params(sctx, params_sig) <= 0)
+         goto err;
+ 
+@@ -509,14 +510,17 @@ static int self_test_sign(const ST_KAT_SIGN *t,
+         goto err;
+ 
+     OSSL_SELF_TEST_oncorrupt_byte(st, sig);
+-    if (EVP_PKEY_verify(sctx, sig, siglen, dgst, sizeof(dgst)) <= 0)
++    if (EVP_DigestVerify(ctx, sig, siglen, (const unsigned char *)msg, strlen(msg)) <= 0)
+         goto err;
+     ret = 1;
+ err:
+     BN_CTX_free(bnctx);
+     EVP_PKEY_free(pkey);
+-    EVP_PKEY_CTX_free(kctx);
++    EVP_MD_free(md);
++    EVP_MD_CTX_free(ctx);
++    /* sctx is not freed automatically inside the FIPS module */
+     EVP_PKEY_CTX_free(sctx);
++    EVP_PKEY_CTX_free(kctx);
+     OSSL_PARAM_free(params);
+     OSSL_PARAM_free(params_sig);
+     OSSL_PARAM_BLD_free(bld);
+-- 
+2.37.1
+
diff --git a/SOURCES/0075-FIPS-Use-FFDHE2048-in-self-test.patch b/SOURCES/0075-FIPS-Use-FFDHE2048-in-self-test.patch
new file mode 100644
index 0000000..096e62d
--- /dev/null
+++ b/SOURCES/0075-FIPS-Use-FFDHE2048-in-self-test.patch
@@ -0,0 +1,378 @@
+From e385647549c467fe263b68b72dd21bdfb875ee88 Mon Sep 17 00:00:00 2001
+From: Clemens Lang <cllang@redhat.com>
+Date: Fri, 22 Jul 2022 17:51:16 +0200
+Subject: [PATCH 2/2] FIPS: Use FFDHE2048 in self test
+
+Signed-off-by: Clemens Lang <cllang@redhat.com>
+---
+ providers/fips/self_test_data.inc | 342 +++++++++++++++---------------
+ 1 file changed, 172 insertions(+), 170 deletions(-)
+
+diff --git a/providers/fips/self_test_data.inc b/providers/fips/self_test_data.inc
+index a29cc650b5..1b5623833f 100644
+--- a/providers/fips/self_test_data.inc
++++ b/providers/fips/self_test_data.inc
+@@ -821,188 +821,190 @@ static const ST_KAT_DRBG st_kat_drbg_tests[] =
+ 
+ #ifndef OPENSSL_NO_DH
+ /* DH KAT */
++/* RFC7919 FFDHE2048 p */
+ static const unsigned char dh_p[] = {
+-    0xdc, 0xca, 0x15, 0x11, 0xb2, 0x31, 0x32, 0x25,
+-    0xf5, 0x21, 0x16, 0xe1, 0x54, 0x27, 0x89, 0xe0,
+-    0x01, 0xf0, 0x42, 0x5b, 0xcc, 0xc7, 0xf3, 0x66,
+-    0xf7, 0x40, 0x64, 0x07, 0xf1, 0xc9, 0xfa, 0x8b,
+-    0xe6, 0x10, 0xf1, 0x77, 0x8b, 0xb1, 0x70, 0xbe,
+-    0x39, 0xdb, 0xb7, 0x6f, 0x85, 0xbf, 0x24, 0xce,
+-    0x68, 0x80, 0xad, 0xb7, 0x62, 0x9f, 0x7c, 0x6d,
+-    0x01, 0x5e, 0x61, 0xd4, 0x3f, 0xa3, 0xee, 0x4d,
+-    0xe1, 0x85, 0xf2, 0xcf, 0xd0, 0x41, 0xff, 0xde,
+-    0x9d, 0x41, 0x84, 0x07, 0xe1, 0x51, 0x38, 0xbb,
+-    0x02, 0x1d, 0xae, 0xb3, 0x5f, 0x76, 0x2d, 0x17,
+-    0x82, 0xac, 0xc6, 0x58, 0xd3, 0x2b, 0xd4, 0xb0,
+-    0x23, 0x2c, 0x92, 0x7d, 0xd3, 0x8f, 0xa0, 0x97,
+-    0xb3, 0xd1, 0x85, 0x9f, 0xa8, 0xac, 0xaf, 0xb9,
+-    0x8f, 0x06, 0x66, 0x08, 0xfc, 0x64, 0x4e, 0xc7,
+-    0xdd, 0xb6, 0xf0, 0x85, 0x99, 0xf9, 0x2a, 0xc1,
+-    0xb5, 0x98, 0x25, 0xda, 0x84, 0x32, 0x07, 0x7d,
+-    0xef, 0x69, 0x56, 0x46, 0x06, 0x3c, 0x20, 0x82,
+-    0x3c, 0x95, 0x07, 0xab, 0x6f, 0x01, 0x76, 0xd4,
+-    0x73, 0x0d, 0x99, 0x0d, 0xbb, 0xe6, 0x36, 0x1c,
+-    0xd8, 0xb2, 0xb9, 0x4d, 0x3d, 0x2f, 0x32, 0x9b,
+-    0x82, 0x09, 0x9b, 0xd6, 0x61, 0xf4, 0x29, 0x50,
+-    0xf4, 0x03, 0xdf, 0x3e, 0xde, 0x62, 0xa3, 0x31,
+-    0x88, 0xb0, 0x27, 0x98, 0xba, 0x82, 0x3f, 0x44,
+-    0xb9, 0x46, 0xfe, 0x9d, 0xf6, 0x77, 0xa0, 0xc5,
+-    0xa1, 0x23, 0x8e, 0xaa, 0x97, 0xb7, 0x0f, 0x80,
+-    0xda, 0x8c, 0xac, 0x88, 0xe0, 0x92, 0xb1, 0x12,
+-    0x70, 0x60, 0xff, 0xbf, 0x45, 0x57, 0x99, 0x94,
+-    0x01, 0x1d, 0xc2, 0xfa, 0xa5, 0xe7, 0xf6, 0xc7,
+-    0x62, 0x45, 0xe1, 0xcc, 0x31, 0x22, 0x31, 0xc1,
+-    0x7d, 0x1c, 0xa6, 0xb1, 0x90, 0x07, 0xef, 0x0d,
+-    0xb9, 0x9f, 0x9c, 0xb6, 0x0e, 0x1d, 0x5f, 0x69
+-};
++    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++    0xad, 0xf8, 0x54, 0x58, 0xa2, 0xbb, 0x4a, 0x9a,
++    0xaf, 0xdc, 0x56, 0x20, 0x27, 0x3d, 0x3c, 0xf1,
++    0xd8, 0xb9, 0xc5, 0x83, 0xce, 0x2d, 0x36, 0x95,
++    0xa9, 0xe1, 0x36, 0x41, 0x14, 0x64, 0x33, 0xfb,
++    0xcc, 0x93, 0x9d, 0xce, 0x24, 0x9b, 0x3e, 0xf9,
++    0x7d, 0x2f, 0xe3, 0x63, 0x63, 0x0c, 0x75, 0xd8,
++    0xf6, 0x81, 0xb2, 0x02, 0xae, 0xc4, 0x61, 0x7a,
++    0xd3, 0xdf, 0x1e, 0xd5, 0xd5, 0xfd, 0x65, 0x61,
++    0x24, 0x33, 0xf5, 0x1f, 0x5f, 0x06, 0x6e, 0xd0,
++    0x85, 0x63, 0x65, 0x55, 0x3d, 0xed, 0x1a, 0xf3,
++    0xb5, 0x57, 0x13, 0x5e, 0x7f, 0x57, 0xc9, 0x35,
++    0x98, 0x4f, 0x0c, 0x70, 0xe0, 0xe6, 0x8b, 0x77,
++    0xe2, 0xa6, 0x89, 0xda, 0xf3, 0xef, 0xe8, 0x72,
++    0x1d, 0xf1, 0x58, 0xa1, 0x36, 0xad, 0xe7, 0x35,
++    0x30, 0xac, 0xca, 0x4f, 0x48, 0x3a, 0x79, 0x7a,
++    0xbc, 0x0a, 0xb1, 0x82, 0xb3, 0x24, 0xfb, 0x61,
++    0xd1, 0x08, 0xa9, 0x4b, 0xb2, 0xc8, 0xe3, 0xfb,
++    0xb9, 0x6a, 0xda, 0xb7, 0x60, 0xd7, 0xf4, 0x68,
++    0x1d, 0x4f, 0x42, 0xa3, 0xde, 0x39, 0x4d, 0xf4,
++    0xae, 0x56, 0xed, 0xe7, 0x63, 0x72, 0xbb, 0x19,
++    0x0b, 0x07, 0xa7, 0xc8, 0xee, 0x0a, 0x6d, 0x70,
++    0x9e, 0x02, 0xfc, 0xe1, 0xcd, 0xf7, 0xe2, 0xec,
++    0xc0, 0x34, 0x04, 0xcd, 0x28, 0x34, 0x2f, 0x61,
++    0x91, 0x72, 0xfe, 0x9c, 0xe9, 0x85, 0x83, 0xff,
++    0x8e, 0x4f, 0x12, 0x32, 0xee, 0xf2, 0x81, 0x83,
++    0xc3, 0xfe, 0x3b, 0x1b, 0x4c, 0x6f, 0xad, 0x73,
++    0x3b, 0xb5, 0xfc, 0xbc, 0x2e, 0xc2, 0x20, 0x05,
++    0xc5, 0x8e, 0xf1, 0x83, 0x7d, 0x16, 0x83, 0xb2,
++    0xc6, 0xf3, 0x4a, 0x26, 0xc1, 0xb2, 0xef, 0xfa,
++    0x88, 0x6b, 0x42, 0x38, 0x61, 0x28, 0x5c, 0x97,
++    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
++};
++/* RFC7919 FFDHE2048 q */
+ static const unsigned char dh_q[] = {
+-    0x89, 0x8b, 0x22, 0x67, 0x17, 0xef, 0x03, 0x9e,
+-    0x60, 0x3e, 0x82, 0xe5, 0xc7, 0xaf, 0xe4, 0x83,
+-    0x74, 0xac, 0x5f, 0x62, 0x5c, 0x54, 0xf1, 0xea,
+-    0x11, 0xac, 0xb5, 0x7d
+-};
++    0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++    0xd6, 0xfc, 0x2a, 0x2c, 0x51, 0x5d, 0xa5, 0x4d,
++    0x57, 0xee, 0x2b, 0x10, 0x13, 0x9e, 0x9e, 0x78,
++    0xec, 0x5c, 0xe2, 0xc1, 0xe7, 0x16, 0x9b, 0x4a,
++    0xd4, 0xf0, 0x9b, 0x20, 0x8a, 0x32, 0x19, 0xfd,
++    0xe6, 0x49, 0xce, 0xe7, 0x12, 0x4d, 0x9f, 0x7c,
++    0xbe, 0x97, 0xf1, 0xb1, 0xb1, 0x86, 0x3a, 0xec,
++    0x7b, 0x40, 0xd9, 0x01, 0x57, 0x62, 0x30, 0xbd,
++    0x69, 0xef, 0x8f, 0x6a, 0xea, 0xfe, 0xb2, 0xb0,
++    0x92, 0x19, 0xfa, 0x8f, 0xaf, 0x83, 0x37, 0x68,
++    0x42, 0xb1, 0xb2, 0xaa, 0x9e, 0xf6, 0x8d, 0x79,
++    0xda, 0xab, 0x89, 0xaf, 0x3f, 0xab, 0xe4, 0x9a,
++    0xcc, 0x27, 0x86, 0x38, 0x70, 0x73, 0x45, 0xbb,
++    0xf1, 0x53, 0x44, 0xed, 0x79, 0xf7, 0xf4, 0x39,
++    0x0e, 0xf8, 0xac, 0x50, 0x9b, 0x56, 0xf3, 0x9a,
++    0x98, 0x56, 0x65, 0x27, 0xa4, 0x1d, 0x3c, 0xbd,
++    0x5e, 0x05, 0x58, 0xc1, 0x59, 0x92, 0x7d, 0xb0,
++    0xe8, 0x84, 0x54, 0xa5, 0xd9, 0x64, 0x71, 0xfd,
++    0xdc, 0xb5, 0x6d, 0x5b, 0xb0, 0x6b, 0xfa, 0x34,
++    0x0e, 0xa7, 0xa1, 0x51, 0xef, 0x1c, 0xa6, 0xfa,
++    0x57, 0x2b, 0x76, 0xf3, 0xb1, 0xb9, 0x5d, 0x8c,
++    0x85, 0x83, 0xd3, 0xe4, 0x77, 0x05, 0x36, 0xb8,
++    0x4f, 0x01, 0x7e, 0x70, 0xe6, 0xfb, 0xf1, 0x76,
++    0x60, 0x1a, 0x02, 0x66, 0x94, 0x1a, 0x17, 0xb0,
++    0xc8, 0xb9, 0x7f, 0x4e, 0x74, 0xc2, 0xc1, 0xff,
++    0xc7, 0x27, 0x89, 0x19, 0x77, 0x79, 0x40, 0xc1,
++    0xe1, 0xff, 0x1d, 0x8d, 0xa6, 0x37, 0xd6, 0xb9,
++    0x9d, 0xda, 0xfe, 0x5e, 0x17, 0x61, 0x10, 0x02,
++    0xe2, 0xc7, 0x78, 0xc1, 0xbe, 0x8b, 0x41, 0xd9,
++    0x63, 0x79, 0xa5, 0x13, 0x60, 0xd9, 0x77, 0xfd,
++    0x44, 0x35, 0xa1, 0x1c, 0x30, 0x94, 0x2e, 0x4b,
++    0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
++};
++/* RFC7919 FFDHE2048 g */
+ static const unsigned char dh_g[] = {
+-    0x5e, 0xf7, 0xb8, 0x8f, 0x2d, 0xf6, 0x01, 0x39,
+-    0x35, 0x1d, 0xfb, 0xfe, 0x12, 0x66, 0x80, 0x5f,
+-    0xdf, 0x35, 0x6c, 0xdf, 0xd1, 0x3a, 0x4d, 0xa0,
+-    0x05, 0x0c, 0x7e, 0xde, 0x24, 0x6d, 0xf5, 0x9f,
+-    0x6a, 0xbf, 0x96, 0xad, 0xe5, 0xf2, 0xb2, 0x8f,
+-    0xfe, 0x88, 0xd6, 0xbc, 0xe7, 0xf7, 0x89, 0x4a,
+-    0x3d, 0x53, 0x5f, 0xc8, 0x21, 0x26, 0xdd, 0xd4,
+-    0x24, 0x87, 0x2e, 0x16, 0xb8, 0x38, 0xdf, 0x8c,
+-    0x51, 0xe9, 0x01, 0x6f, 0x88, 0x9c, 0x7c, 0x20,
+-    0x3e, 0x98, 0xa8, 0xb6, 0x31, 0xf9, 0xc7, 0x25,
+-    0x63, 0xd3, 0x8a, 0x49, 0x58, 0x9a, 0x07, 0x53,
+-    0xd3, 0x58, 0xe7, 0x83, 0x31, 0x8c, 0xef, 0xd9,
+-    0x67, 0x7c, 0x7b, 0x2d, 0xbb, 0x77, 0xd6, 0xdc,
+-    0xe2, 0xa1, 0x96, 0x37, 0x95, 0xca, 0x64, 0xb9,
+-    0x2d, 0x1c, 0x9a, 0xac, 0x6d, 0x0e, 0x8d, 0x43,
+-    0x1d, 0xe5, 0xe5, 0x00, 0x60, 0xdf, 0xf7, 0x86,
+-    0x89, 0xc9, 0xec, 0xa1, 0xc1, 0x24, 0x8c, 0x16,
+-    0xed, 0x09, 0xc7, 0xad, 0x41, 0x2a, 0x17, 0x40,
+-    0x6d, 0x2b, 0x52, 0x5a, 0xa1, 0xca, 0xbb, 0x23,
+-    0x7b, 0x97, 0x34, 0xec, 0x7b, 0x8c, 0xe3, 0xfa,
+-    0xe0, 0x2f, 0x29, 0xc5, 0xef, 0xed, 0x30, 0xd6,
+-    0x91, 0x87, 0xda, 0x10, 0x9c, 0x2c, 0x9f, 0xe2,
+-    0xaa, 0xdb, 0xb0, 0xc2, 0x2a, 0xf5, 0x4c, 0x61,
+-    0x66, 0x55, 0x00, 0x0c, 0x43, 0x1c, 0x6b, 0x4a,
+-    0x37, 0x97, 0x63, 0xb0, 0xa9, 0x16, 0x58, 0xef,
+-    0xc8, 0x4e, 0x8b, 0x06, 0x35, 0x8c, 0x8b, 0x4f,
+-    0x21, 0x37, 0x10, 0xfd, 0x10, 0x17, 0x2c, 0xf3,
+-    0x9b, 0x83, 0x0c, 0x2d, 0xd8, 0x4a, 0x0c, 0x8a,
+-    0xb8, 0x25, 0x16, 0xec, 0xab, 0x99, 0x5f, 0xa4,
+-    0x21, 0x5e, 0x02, 0x3e, 0x4e, 0xcf, 0x80, 0x74,
+-    0xc3, 0x9d, 0x6c, 0x88, 0xb7, 0x0d, 0x1e, 0xe4,
+-    0xe9, 0x6f, 0xdc, 0x20, 0xea, 0x11, 0x5c, 0x32
++    0x02
+ };
+ static const unsigned char dh_priv[] = {
+-    0x14, 0x33, 0xe0, 0xb5, 0xa9, 0x17, 0xb6, 0x0a,
+-    0x30, 0x23, 0xf2, 0xf8, 0xaa, 0x2c, 0x2d, 0x70,
+-    0xd2, 0x96, 0x8a, 0xba, 0x9a, 0xea, 0xc8, 0x15,
+-    0x40, 0xb8, 0xfc, 0xe6
++    0x01, 0xdc, 0x2a, 0xb9, 0x87, 0x71, 0x57, 0x0f,
++    0xcd, 0x93, 0x65, 0x4c, 0xa1, 0xd6, 0x56, 0x6d,
++    0xc5, 0x35, 0xd5, 0xcb, 0x4c, 0xb8, 0xad, 0x8d,
++    0x6c, 0xdc, 0x5d, 0x6e, 0x94
+ };
+ static const unsigned char dh_pub[] = {
+-    0x95, 0xdd, 0x33, 0x8d, 0x29, 0xe5, 0x71, 0x04,
+-    0x92, 0xb9, 0x18, 0x31, 0x7b, 0x72, 0xa3, 0x69,
+-    0x36, 0xe1, 0x95, 0x1a, 0x2e, 0xe5, 0xa5, 0x59,
+-    0x16, 0x99, 0xc0, 0x48, 0x6d, 0x0d, 0x4f, 0x9b,
+-    0xdd, 0x6d, 0x5a, 0x3f, 0x6b, 0x98, 0x89, 0x0c,
+-    0x62, 0xb3, 0x76, 0x52, 0xd3, 0x6e, 0x71, 0x21,
+-    0x11, 0xe6, 0x8a, 0x73, 0x55, 0x37, 0x25, 0x06,
+-    0x99, 0xef, 0xe3, 0x30, 0x53, 0x73, 0x91, 0xfb,
+-    0xc2, 0xc5, 0x48, 0xbc, 0x5a, 0xc3, 0xe5, 0xb2,
+-    0x33, 0x86, 0xc3, 0xee, 0xf5, 0xeb, 0x43, 0xc0,
+-    0x99, 0xd7, 0x0a, 0x52, 0x02, 0x68, 0x7e, 0x83,
+-    0x96, 0x42, 0x48, 0xfc, 0xa9, 0x1f, 0x40, 0x90,
+-    0x8e, 0x8f, 0xb3, 0x31, 0x93, 0x15, 0xf6, 0xd2,
+-    0x60, 0x6d, 0x7f, 0x7c, 0xd5, 0x2c, 0xc6, 0xe7,
+-    0xc5, 0x84, 0x3a, 0xfb, 0x22, 0x51, 0x9c, 0xf0,
+-    0xf0, 0xf9, 0xd3, 0xa0, 0xa4, 0xe8, 0xc8, 0x88,
+-    0x99, 0xef, 0xed, 0xe7, 0x36, 0x43, 0x51, 0xfb,
+-    0x6a, 0x36, 0x3e, 0xe7, 0x17, 0xe5, 0x44, 0x5a,
+-    0xda, 0xb4, 0xc9, 0x31, 0xa6, 0x48, 0x39, 0x97,
+-    0xb8, 0x7d, 0xad, 0x83, 0x67, 0x7e, 0x4d, 0x1d,
+-    0x3a, 0x77, 0x75, 0xe0, 0xf6, 0xd0, 0x0f, 0xdf,
+-    0x73, 0xc7, 0xad, 0x80, 0x1e, 0x66, 0x5a, 0x0e,
+-    0x5a, 0x79, 0x6d, 0x0a, 0x03, 0x80, 0xa1, 0x9f,
+-    0xa1, 0x82, 0xef, 0xc8, 0xa0, 0x4f, 0x5e, 0x4d,
+-    0xb9, 0x0d, 0x1a, 0x86, 0x37, 0xf9, 0x5d, 0xb1,
+-    0x64, 0x36, 0xbd, 0xc8, 0xf3, 0xfc, 0x09, 0x6c,
+-    0x4f, 0xf7, 0xf2, 0x34, 0xbe, 0x8f, 0xef, 0x47,
+-    0x9a, 0xc4, 0xb0, 0xdc, 0x4b, 0x77, 0x26, 0x3e,
+-    0x07, 0xd9, 0x95, 0x9d, 0xe0, 0xf1, 0xbf, 0x3f,
+-    0x0a, 0xe3, 0xd9, 0xd5, 0x0e, 0x4b, 0x89, 0xc9,
+-    0x9e, 0x3e, 0xa1, 0x21, 0x73, 0x43, 0xdd, 0x8c,
+-    0x65, 0x81, 0xac, 0xc4, 0x95, 0x9c, 0x91, 0xd3
++    0x00, 0xc4, 0x82, 0x14, 0x69, 0x16, 0x4c, 0x05,
++    0x55, 0x2a, 0x7e, 0x55, 0x6d, 0x02, 0xbb, 0x7f,
++    0xcc, 0x63, 0x74, 0xee, 0xcb, 0xb4, 0x98, 0x43,
++    0x0e, 0x29, 0x43, 0x0d, 0x44, 0xc7, 0xf1, 0x23,
++    0x81, 0xca, 0x1c, 0x5c, 0xc3, 0xff, 0x01, 0x4a,
++    0x1a, 0x03, 0x9e, 0x5f, 0xd1, 0x4e, 0xa0, 0x0b,
++    0xb9, 0x5c, 0x0d, 0xef, 0x14, 0x01, 0x62, 0x3c,
++    0x8a, 0x8e, 0x60, 0xbb, 0x39, 0xd6, 0x38, 0x63,
++    0xb7, 0x65, 0xd0, 0x0b, 0x1a, 0xaf, 0x53, 0x38,
++    0x10, 0x0f, 0x3e, 0xeb, 0x9d, 0x0c, 0x24, 0xf6,
++    0xe3, 0x70, 0x08, 0x8a, 0x4d, 0x01, 0xf8, 0x7a,
++    0x87, 0x49, 0x64, 0x72, 0xb1, 0x75, 0x3b, 0x94,
++    0xc8, 0x09, 0x2d, 0x6a, 0x63, 0xd8, 0x9a, 0x92,
++    0xb9, 0x5b, 0x1a, 0xc3, 0x47, 0x0b, 0x63, 0x44,
++    0x3b, 0xe3, 0xc0, 0x09, 0xc9, 0xf9, 0x02, 0x53,
++    0xd8, 0xfb, 0x06, 0x44, 0xdb, 0xdf, 0xe8, 0x13,
++    0x2b, 0x40, 0x6a, 0xd4, 0x13, 0x4e, 0x52, 0x30,
++    0xd6, 0xc1, 0xd8, 0x59, 0x9d, 0x59, 0xba, 0x1b,
++    0xbf, 0xaa, 0x6f, 0xe9, 0x3d, 0xfd, 0xff, 0x01,
++    0x0b, 0x54, 0xe0, 0x6a, 0x4e, 0x27, 0x2b, 0x3d,
++    0xe8, 0xef, 0xb0, 0xbe, 0x52, 0xc3, 0x52, 0x18,
++    0x6f, 0xa3, 0x27, 0xab, 0x6c, 0x12, 0xc3, 0x81,
++    0xcb, 0xae, 0x23, 0x11, 0xa0, 0x5d, 0xc3, 0x6f,
++    0x23, 0x17, 0x40, 0xb3, 0x05, 0x4f, 0x5d, 0xb7,
++    0x34, 0xbe, 0x87, 0x2c, 0xa9, 0x9e, 0x98, 0x39,
++    0xbf, 0x2e, 0x9d, 0xad, 0x4f, 0x70, 0xad, 0xed,
++    0x1b, 0x5e, 0x47, 0x90, 0x49, 0x2e, 0x61, 0x71,
++    0x5f, 0x07, 0x0b, 0x35, 0x04, 0xfc, 0x53, 0xce,
++    0x58, 0x60, 0x6c, 0x5b, 0x8b, 0xfe, 0x70, 0x04,
++    0x2a, 0x6a, 0x98, 0x0a, 0xd0, 0x80, 0xae, 0x69,
++    0x95, 0xf9, 0x99, 0x18, 0xfc, 0xe4, 0x8e, 0xed,
++    0x61, 0xd9, 0x02, 0x9d, 0x4e, 0x05, 0xe9, 0xf2,
++    0x32
+ };
+ static const unsigned char dh_peer_pub[] = {
+-    0x1f, 0xc1, 0xda, 0x34, 0x1d, 0x1a, 0x84, 0x6a,
+-    0x96, 0xb7, 0xbe, 0x24, 0x34, 0x0f, 0x87, 0x7d,
+-    0xd0, 0x10, 0xaa, 0x03, 0x56, 0xd5, 0xad, 0x58,
+-    0xaa, 0xe9, 0xc7, 0xb0, 0x8f, 0x74, 0x9a, 0x32,
+-    0x23, 0x51, 0x10, 0xb5, 0xd8, 0x8e, 0xb5, 0xdb,
+-    0xfa, 0x97, 0x8d, 0x27, 0xec, 0xc5, 0x30, 0xf0,
+-    0x2d, 0x31, 0x14, 0x00, 0x5b, 0x64, 0xb1, 0xc0,
+-    0xe0, 0x24, 0xcb, 0x8a, 0xe2, 0x16, 0x98, 0xbc,
+-    0xa9, 0xe6, 0x0d, 0x42, 0x80, 0x86, 0x22, 0xf1,
+-    0x81, 0xc5, 0x6e, 0x1d, 0xe7, 0xa9, 0x6e, 0x6e,
+-    0xfe, 0xe9, 0xd6, 0x65, 0x67, 0xe9, 0x1b, 0x97,
+-    0x70, 0x42, 0xc7, 0xe3, 0xd0, 0x44, 0x8f, 0x05,
+-    0xfb, 0x77, 0xf5, 0x22, 0xb9, 0xbf, 0xc8, 0xd3,
+-    0x3c, 0xc3, 0xc3, 0x1e, 0xd3, 0xb3, 0x1f, 0x0f,
+-    0xec, 0xb6, 0xdb, 0x4f, 0x6e, 0xa3, 0x11, 0xe7,
+-    0x7a, 0xfd, 0xbc, 0xd4, 0x7a, 0xee, 0x1b, 0xb1,
+-    0x50, 0xf2, 0x16, 0x87, 0x35, 0x78, 0xfb, 0x96,
+-    0x46, 0x8e, 0x8f, 0x9f, 0x3d, 0xe8, 0xef, 0xbf,
+-    0xce, 0x75, 0x62, 0x4b, 0x1d, 0xf0, 0x53, 0x22,
+-    0xa3, 0x4f, 0x14, 0x63, 0xe8, 0x39, 0xe8, 0x98,
+-    0x4c, 0x4a, 0xd0, 0xa9, 0x6e, 0x1a, 0xc8, 0x42,
+-    0xe5, 0x31, 0x8c, 0xc2, 0x3c, 0x06, 0x2a, 0x8c,
+-    0xa1, 0x71, 0xb8, 0xd5, 0x75, 0x98, 0x0d, 0xde,
+-    0x7f, 0xc5, 0x6f, 0x15, 0x36, 0x52, 0x38, 0x20,
+-    0xd4, 0x31, 0x92, 0xbf, 0xd5, 0x1e, 0x8e, 0x22,
+-    0x89, 0x78, 0xac, 0xa5, 0xb9, 0x44, 0x72, 0xf3,
+-    0x39, 0xca, 0xeb, 0x99, 0x31, 0xb4, 0x2b, 0xe3,
+-    0x01, 0x26, 0x8b, 0xc9, 0x97, 0x89, 0xc9, 0xb2,
+-    0x55, 0x71, 0xc3, 0xc0, 0xe4, 0xcb, 0x3f, 0x00,
+-    0x7f, 0x1a, 0x51, 0x1c, 0xbb, 0x53, 0xc8, 0x51,
+-    0x9c, 0xdd, 0x13, 0x02, 0xab, 0xca, 0x6c, 0x0f,
+-    0x34, 0xf9, 0x67, 0x39, 0xf1, 0x7f, 0xf4, 0x8b
++    0x00, 0xef, 0x15, 0x02, 0xf5, 0x56, 0xa3, 0x79,
++    0x40, 0x58, 0xbc, 0xeb, 0x56, 0xad, 0xcb, 0xda,
++    0x8c, 0xda, 0xb8, 0xd1, 0xda, 0x6f, 0x25, 0x29,
++    0x9e, 0x43, 0x76, 0x2d, 0xb2, 0xd8, 0xbc, 0x84,
++    0xbc, 0x85, 0xd0, 0x94, 0x8d, 0x44, 0x27, 0x57,
++    0xe4, 0xdf, 0xc1, 0x78, 0x42, 0x8f, 0x08, 0xf5,
++    0x74, 0xfe, 0x02, 0x56, 0xd2, 0x09, 0xc8, 0x68,
++    0xef, 0xed, 0x18, 0xc9, 0xfd, 0x2e, 0x95, 0x6c,
++    0xba, 0x6c, 0x00, 0x0e, 0xf5, 0xd1, 0x1b, 0xf6,
++    0x15, 0x14, 0x5b, 0x67, 0x22, 0x7c, 0x6a, 0x20,
++    0x76, 0x43, 0x51, 0xef, 0x5e, 0x1e, 0xf9, 0x2d,
++    0xd6, 0xb4, 0xc5, 0xc6, 0x18, 0x33, 0xd1, 0xa3,
++    0x3b, 0xe6, 0xdd, 0x57, 0x9d, 0xad, 0x13, 0x7a,
++    0x53, 0xde, 0xb3, 0x97, 0xc0, 0x7e, 0xd7, 0x77,
++    0x6b, 0xf8, 0xbd, 0x13, 0x70, 0x8c, 0xba, 0x73,
++    0x80, 0xb3, 0x80, 0x6f, 0xfb, 0x1c, 0xda, 0x53,
++    0x4d, 0x3c, 0x8a, 0x2e, 0xa1, 0x37, 0xce, 0xb1,
++    0xde, 0x45, 0x97, 0x58, 0x65, 0x4d, 0xcf, 0x05,
++    0xbb, 0xc3, 0xd7, 0x38, 0x6d, 0x0a, 0x59, 0x7a,
++    0x99, 0x15, 0xb7, 0x9a, 0x3d, 0xfd, 0x61, 0xe5,
++    0x1a, 0xa2, 0xcc, 0xf6, 0xfe, 0xb1, 0xee, 0xe9,
++    0xa9, 0xe2, 0xeb, 0x06, 0xbc, 0x14, 0x6e, 0x91,
++    0x0d, 0xf1, 0xe3, 0xbb, 0xe0, 0x7e, 0x1d, 0x31,
++    0x79, 0xf1, 0x6d, 0x5f, 0xcb, 0xaf, 0xb2, 0x4f,
++    0x22, 0x12, 0xbf, 0x72, 0xbd, 0xd0, 0x30, 0xe4,
++    0x1c, 0x35, 0x96, 0x61, 0x98, 0x39, 0xfb, 0x7e,
++    0x6d, 0x66, 0xc4, 0x69, 0x41, 0x0d, 0x0d, 0x59,
++    0xbb, 0xa7, 0xbf, 0x34, 0xe0, 0x39, 0x36, 0x84,
++    0x5e, 0x0e, 0x03, 0x2d, 0xcf, 0xaa, 0x02, 0x8a,
++    0xba, 0x59, 0x88, 0x47, 0xc4, 0x4d, 0xd7, 0xbd,
++    0x78, 0x76, 0x24, 0xf1, 0x45, 0x56, 0x44, 0xc2,
++    0x4a, 0xc2, 0xd5, 0x3a, 0x59, 0x40, 0xab, 0x87,
++    0x64
+ };
+ 
+ static const unsigned char dh_secret_expected[] = {
+-    0x08, 0xff, 0x33, 0xbb, 0x2e, 0xcf, 0xf4, 0x9a,
+-    0x7d, 0x4a, 0x79, 0x12, 0xae, 0xb1, 0xbb, 0x6a,
+-    0xb5, 0x11, 0x64, 0x1b, 0x4a, 0x76, 0x77, 0x0c,
+-    0x8c, 0xc1, 0xbc, 0xc2, 0x33, 0x34, 0x3d, 0xfe,
+-    0x70, 0x0d, 0x11, 0x81, 0x3d, 0x2c, 0x9e, 0xd2,
+-    0x3b, 0x21, 0x1c, 0xa9, 0xe8, 0x78, 0x69, 0x21,
+-    0xed, 0xca, 0x28, 0x3c, 0x68, 0xb1, 0x61, 0x53,
+-    0xfa, 0x01, 0xe9, 0x1a, 0xb8, 0x2c, 0x90, 0xdd,
+-    0xab, 0x4a, 0x95, 0x81, 0x67, 0x70, 0xa9, 0x87,
+-    0x10, 0xe1, 0x4c, 0x92, 0xab, 0x83, 0xb6, 0xe4,
+-    0x6e, 0x1e, 0x42, 0x6e, 0xe8, 0x52, 0x43, 0x0d,
+-    0x61, 0x87, 0xda, 0xa3, 0x72, 0x0a, 0x6b, 0xcd,
+-    0x73, 0x23, 0x5c, 0x6b, 0x0f, 0x94, 0x1f, 0x33,
+-    0x64, 0xf5, 0x04, 0x20, 0x55, 0x1a, 0x4b, 0xfe,
+-    0xaf, 0xe2, 0xbc, 0x43, 0x85, 0x05, 0xa5, 0x9a,
+-    0x4a, 0x40, 0xda, 0xca, 0x7a, 0x89, 0x5a, 0x73,
+-    0xdb, 0x57, 0x5c, 0x74, 0xc1, 0x3a, 0x23, 0xad,
+-    0x88, 0x32, 0x95, 0x7d, 0x58, 0x2d, 0x38, 0xf0,
+-    0xa6, 0x16, 0x5f, 0xb0, 0xd7, 0xe9, 0xb8, 0x79,
+-    0x9e, 0x42, 0xfd, 0x32, 0x20, 0xe3, 0x32, 0xe9,
+-    0x81, 0x85, 0xa0, 0xc9, 0x42, 0x97, 0x57, 0xb2,
+-    0xd0, 0xd0, 0x2c, 0x17, 0xdb, 0xaa, 0x1f, 0xf6,
+-    0xed, 0x93, 0xd7, 0xe7, 0x3e, 0x24, 0x1e, 0xae,
+-    0xd9, 0x0c, 0xaf, 0x39, 0x4d, 0x2b, 0xc6, 0x57,
+-    0x0f, 0x18, 0xc8, 0x1f, 0x2b, 0xe5, 0xd0, 0x1a,
+-    0x2c, 0xa9, 0x9f, 0xf1, 0x42, 0xb5, 0xd9, 0x63,
+-    0xf9, 0xf5, 0x00, 0x32, 0x5e, 0x75, 0x56, 0xf9,
+-    0x58, 0x49, 0xb3, 0xff, 0xc7, 0x47, 0x94, 0x86,
+-    0xbe, 0x1d, 0x45, 0x96, 0xa3, 0x10, 0x6b, 0xd5,
+-    0xcb, 0x4f, 0x61, 0xc5, 0x7e, 0xc5, 0xf1, 0x00,
+-    0xfb, 0x7a, 0x0c, 0x82, 0xa1, 0x0b, 0x82, 0x52,
+-    0x6a, 0x97, 0xd1, 0xd9, 0x7d, 0x98, 0xea, 0xf6
++    0x56, 0x13, 0xe3, 0x12, 0x6b, 0x5f, 0x67, 0xe5,
++    0x08, 0xe5, 0x35, 0x0e, 0x11, 0x90, 0x9d, 0xf5,
++    0x1a, 0x24, 0xfa, 0x42, 0xd1, 0x4a, 0x50, 0x93,
++    0x5b, 0xf4, 0x11, 0x6f, 0xd0, 0xc3, 0xc5, 0xa5,
++    0x80, 0xae, 0x01, 0x3d, 0x66, 0x92, 0xc0, 0x3e,
++    0x5f, 0xe9, 0x75, 0xb6, 0x5b, 0x37, 0x82, 0x39,
++    0x72, 0x66, 0x0b, 0xa2, 0x73, 0x94, 0xe5, 0x04,
++    0x7c, 0x0c, 0x19, 0x9a, 0x03, 0x53, 0xc4, 0x9d,
++    0xc1, 0x0f, 0xc3, 0xec, 0x0e, 0x2e, 0xa3, 0x7c,
++    0x07, 0x0e, 0xaf, 0x18, 0x1d, 0xc7, 0x8b, 0x47,
++    0x4b, 0x94, 0x05, 0x6d, 0xec, 0xdd, 0xa1, 0xae,
++    0x7b, 0x21, 0x86, 0x53, 0xd3, 0x62, 0x38, 0x08,
++    0xea, 0xda, 0xdc, 0xb2, 0x5a, 0x7c, 0xef, 0x19,
++    0xf8, 0x29, 0xef, 0xf8, 0xd0, 0xfb, 0xde, 0xe8,
++    0xb8, 0x2f, 0xb3, 0xa1, 0x16, 0xa2, 0xd0, 0x8f,
++    0x48, 0xdc, 0x7d, 0xcb, 0xee, 0x5c, 0x06, 0x1e,
++    0x2a, 0x66, 0xe8, 0x1f, 0xdb, 0x18, 0xe9, 0xd2,
++    0xfd, 0xa2, 0x4e, 0x39, 0xa3, 0x2e, 0x88, 0x3d,
++    0x7d, 0xac, 0x15, 0x18, 0x25, 0xe6, 0xba, 0xd4,
++    0x0e, 0x89, 0x26, 0x60, 0x8f, 0xdc, 0x4a, 0xb4,
++    0x49, 0x8f, 0x98, 0xe8, 0x62, 0x8c, 0xc6, 0x66,
++    0x20, 0x4c, 0xe1, 0xed, 0xfc, 0x01, 0x88, 0x46,
++    0xa7, 0x67, 0x48, 0x39, 0xc5, 0x22, 0x95, 0xa0,
++    0x23, 0xb9, 0xd1, 0xed, 0x87, 0xcf, 0xa7, 0x70,
++    0x1c, 0xac, 0xd3, 0xaf, 0x5c, 0x26, 0x50, 0x3c,
++    0xe4, 0x23, 0xb6, 0xcc, 0xd7, 0xc5, 0xda, 0x2f,
++    0xf4, 0x45, 0xf1, 0xe4, 0x40, 0xb5, 0x0a, 0x25,
++    0x86, 0xe6, 0xde, 0x11, 0x3c, 0x46, 0x16, 0xbc,
++    0x41, 0xc2, 0x28, 0x19, 0x81, 0x5a, 0x46, 0x02,
++    0x87, 0xd0, 0x15, 0x0c, 0xd2, 0xfe, 0x75, 0x04,
++    0x82, 0xd2, 0x0a, 0xb7, 0xbc, 0xc5, 0x6c, 0xb1,
++    0x41, 0xa8, 0x2b, 0x28, 0xbb, 0x86, 0x0c, 0x89
+ };
+ 
+ static const ST_KAT_PARAM dh_group[] = {
+-- 
+2.35.3
+
diff --git a/SOURCES/0076-FIPS-140-3-DRBG.patch b/SOURCES/0076-FIPS-140-3-DRBG.patch
new file mode 100644
index 0000000..0d91598
--- /dev/null
+++ b/SOURCES/0076-FIPS-140-3-DRBG.patch
@@ -0,0 +1,129 @@
+diff -up openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c.fipsrand openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c
+--- openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c.fipsrand	2022-08-03 11:09:01.301637515 +0200
++++ openssl-3.0.1/providers/implementations/rands/seeding/rand_unix.c	2022-08-03 11:13:00.058688605 +0200
+@@ -48,6 +48,8 @@
+ # include <fcntl.h>
+ # include <unistd.h>
+ # include <sys/time.h>
++# include <sys/random.h>
++# include <openssl/evp.h>
+ 
+ static uint64_t get_time_stamp(void);
+ static uint64_t get_timer_bits(void);
+@@ -342,66 +342,8 @@ static ssize_t syscall_random(void *buf,
+      * which is way below the OSSL_SSIZE_MAX limit. Therefore sign conversion
+      * between size_t and ssize_t is safe even without a range check.
+      */
+-
+-    /*
+-     * Do runtime detection to find getentropy().
+-     *
+-     * Known OSs that should support this:
+-     * - Darwin since 16 (OSX 10.12, IOS 10.0).
+-     * - Solaris since 11.3
+-     * - OpenBSD since 5.6
+-     * - Linux since 3.17 with glibc 2.25
+-     * - FreeBSD since 12.0 (1200061)
+-     *
+-     * Note: Sometimes getentropy() can be provided but not implemented
+-     * internally. So we need to check errno for ENOSYS
+-     */
+-#  if !defined(__DragonFly__) && !defined(__NetBSD__)
+-#    if defined(__GNUC__) && __GNUC__>=2 && defined(__ELF__) && !defined(__hpux)
+-    extern int getentropy(void *buffer, size_t length) __attribute__((weak));
+-
+-    if (getentropy != NULL) {
+-        if (getentropy(buf, buflen) == 0)
+-            return (ssize_t)buflen;
+-        if (errno != ENOSYS)
+-            return -1;
+-    }
+-#    elif defined(OPENSSL_APPLE_CRYPTO_RANDOM)
+-
+-    if (CCRandomGenerateBytes(buf, buflen) == kCCSuccess)
+-	    return (ssize_t)buflen;
+-
+-    return -1;
+-#    else
+-    union {
+-        void *p;
+-        int (*f)(void *buffer, size_t length);
+-    } p_getentropy;
+-
+-    /*
+-     * We could cache the result of the lookup, but we normally don't
+-     * call this function often.
+-     */
+-    ERR_set_mark();
+-    p_getentropy.p = DSO_global_lookup("getentropy");
+-    ERR_pop_to_mark();
+-    if (p_getentropy.p != NULL)
+-        return p_getentropy.f(buf, buflen) == 0 ? (ssize_t)buflen : -1;
+-#    endif
+-#  endif /* !__DragonFly__ */
+-
+-    /* Linux supports this since version 3.17 */
+-#  if defined(__linux) && defined(__NR_getrandom)
+-    return syscall(__NR_getrandom, buf, buflen, 0);
+-#  elif (defined(__FreeBSD__) || defined(__NetBSD__)) && defined(KERN_ARND)
+-    return sysctl_random(buf, buflen);
+-#  elif (defined(__DragonFly__)  && __DragonFly_version >= 500700) \
+-     || (defined(__NetBSD__) && __NetBSD_Version >= 1000000000)
+-    return getrandom(buf, buflen, 0);
+-#  else
+-    errno = ENOSYS;
+-    return -1;
+-#  endif
++    /* Red Hat uses downstream patch to always seed from getrandom() */
++    return EVP_default_properties_is_fips_enabled(NULL) ? getrandom(buf, buflen, GRND_RANDOM) : getrandom(buf, buflen, 0);
+ }
+ #  endif    /* defined(OPENSSL_RAND_SEED_GETRANDOM) */
+ 
+diff -up openssl-3.0.1/providers/implementations/rands/drbg.c.fipsrand openssl-3.0.1/providers/implementations/rands/drbg.c
+--- openssl-3.0.1/providers/implementations/rands/drbg.c.fipsrand	2022-08-03 12:14:39.409370134 +0200
++++ openssl-3.0.1/providers/implementations/rands/drbg.c	2022-08-03 12:19:06.320700346 +0200
+@@ -575,6 +575,9 @@ int ossl_prov_drbg_reseed(PROV_DRBG *drb
+ #endif
+     }
+ 
++#ifdef FIPS_MODULE
++    prediction_resistance = 1;
++#endif
+     /* Reseed using our sources in addition */
+     entropylen = get_entropy(drbg, &entropy, drbg->strength,
+                              drbg->min_entropylen, drbg->max_entropylen,
+diff -up openssl-3.0.1/crypto/rand/prov_seed.c.fipsrand openssl-3.0.1/crypto/rand/prov_seed.c
+--- openssl-3.0.1/crypto/rand/prov_seed.c.fipsrand	2022-08-04 12:17:52.148556301 +0200
++++ openssl-3.0.1/crypto/rand/prov_seed.c	2022-08-04 12:19:41.783533552 +0200
+@@ -20,7 +20,14 @@ size_t ossl_rand_get_entropy(ossl_unused
+     size_t entropy_available;
+     RAND_POOL *pool;
+ 
+-    pool = ossl_rand_pool_new(entropy, 1, min_len, max_len);
++    /*
++     * OpenSSL still implements an internal entropy pool of
++     * some size that is hashed to get seed data.
++     * Note that this is a conditioning step for which SP800-90C requires
++     * 64 additional bits from the entropy source to claim the requested
++     * amount of entropy.
++     */
++    pool = ossl_rand_pool_new(entropy + 64, 1, min_len, max_len);
+     if (pool == NULL) {
+         ERR_raise(ERR_LIB_RAND, ERR_R_MALLOC_FAILURE);
+         return 0;
+diff -up openssl-3.0.1/providers/implementations/rands/crngt.c.fipsrand openssl-3.0.1/providers/implementations/rands/crngt.c
+--- openssl-3.0.1/providers/implementations/rands/crngt.c.fipsrand	2022-08-04 11:56:10.100950299 +0200
++++ openssl-3.0.1/providers/implementations/rands/crngt.c	2022-08-04 11:59:11.241564925 +0200
+@@ -139,7 +139,11 @@ size_t ossl_crngt_get_entropy(PROV_DRBG
+      * to the nearest byte.  If the entropy is of less than full quality,
+      * the amount required should be scaled up appropriately here.
+      */
+-    bytes_needed = (entropy + 7) / 8;
++    /*
++     * FIPS 140-3: the yet draft SP800-90C requires requested entropy
++     * + 128 bits during initial seeding
++     */
++    bytes_needed = (entropy + 128 + 7) / 8;
+     if (bytes_needed < min_len)
+         bytes_needed = min_len;
+     if (bytes_needed > max_len)
diff --git a/SOURCES/0077-FIPS-140-3-zeroization.patch b/SOURCES/0077-FIPS-140-3-zeroization.patch
new file mode 100644
index 0000000..f6a50a5
--- /dev/null
+++ b/SOURCES/0077-FIPS-140-3-zeroization.patch
@@ -0,0 +1,76 @@
+diff -up openssl-3.0.1/crypto/ffc/ffc_params.c.fipszero openssl-3.0.1/crypto/ffc/ffc_params.c
+--- openssl-3.0.1/crypto/ffc/ffc_params.c.fipszero	2022-08-05 13:11:27.211413931 +0200
++++ openssl-3.0.1/crypto/ffc/ffc_params.c	2022-08-05 13:11:34.151475891 +0200
+@@ -27,10 +27,10 @@ void ossl_ffc_params_init(FFC_PARAMS *pa
+ 
+ void ossl_ffc_params_cleanup(FFC_PARAMS *params)
+ {
+-    BN_free(params->p);
+-    BN_free(params->q);
+-    BN_free(params->g);
+-    BN_free(params->j);
++    BN_clear_free(params->p);
++    BN_clear_free(params->q);
++    BN_clear_free(params->g);
++    BN_clear_free(params->j);
+     OPENSSL_free(params->seed);
+     ossl_ffc_params_init(params);
+ }
+diff -up openssl-3.0.1/crypto/rsa/rsa_lib.c.fipszero openssl-3.0.1/crypto/rsa/rsa_lib.c
+--- openssl-3.0.1/crypto/rsa/rsa_lib.c.fipszero	2022-08-05 13:08:31.875848536 +0200
++++ openssl-3.0.1/crypto/rsa/rsa_lib.c	2022-08-05 13:09:35.438416025 +0200
+@@ -155,8 +155,8 @@ void RSA_free(RSA *r)
+ 
+     CRYPTO_THREAD_lock_free(r->lock);
+ 
+-    BN_free(r->n);
+-    BN_free(r->e);
++    BN_clear_free(r->n);
++    BN_clear_free(r->e);
+     BN_clear_free(r->d);
+     BN_clear_free(r->p);
+     BN_clear_free(r->q);
+diff -up openssl-3.0.1/providers/implementations/kdfs/hkdf.c.fipszero openssl-3.0.1/providers/implementations/kdfs/hkdf.c
+--- openssl-3.0.1/providers/implementations/kdfs/hkdf.c.fipszero	2022-08-05 13:14:58.827303241 +0200
++++ openssl-3.0.1/providers/implementations/kdfs/hkdf.c	2022-08-05 13:16:24.530068399 +0200
+@@ -116,7 +116,7 @@ static void kdf_hkdf_reset(void *vctx)
+     void *provctx = ctx->provctx;
+ 
+     ossl_prov_digest_reset(&ctx->digest);
+-    OPENSSL_free(ctx->salt);
++    OPENSSL_clear_free(ctx->salt, ctx->salt_len);
+     OPENSSL_free(ctx->prefix);
+     OPENSSL_free(ctx->label);
+     OPENSSL_clear_free(ctx->data, ctx->data_len);
+diff -up openssl-3.0.1/providers/implementations/kdfs/pbkdf2.c.fipszero openssl-3.0.1/providers/implementations/kdfs/pbkdf2.c
+--- openssl-3.0.1/providers/implementations/kdfs/pbkdf2.c.fipszero	2022-08-05 13:12:40.552068717 +0200
++++ openssl-3.0.1/providers/implementations/kdfs/pbkdf2.c	2022-08-05 13:13:34.324548799 +0200
+@@ -83,7 +83,7 @@ static void *kdf_pbkdf2_new(void *provct
+ static void kdf_pbkdf2_cleanup(KDF_PBKDF2 *ctx)
+ {
+     ossl_prov_digest_reset(&ctx->digest);
+-    OPENSSL_free(ctx->salt);
++    OPENSSL_clear_free(ctx->salt, ctx->salt_len);
+     OPENSSL_clear_free(ctx->pass, ctx->pass_len);
+     memset(ctx, 0, sizeof(*ctx));
+ }
+diff -up openssl-3.0.1/crypto/ec/ec_lib.c.fipszero openssl-3.0.1/crypto/ec/ec_lib.c
+--- openssl-3.0.1/crypto/ec/ec_lib.c.fipszero	2022-08-05 13:48:32.221345774 +0200
++++ openssl-3.0.1/crypto/ec/ec_lib.c	2022-08-05 13:49:16.138741452 +0200
+@@ -744,12 +744,16 @@ EC_POINT *EC_POINT_new(const EC_GROUP *g
+ 
+ void EC_POINT_free(EC_POINT *point)
+ {
++#ifdef FIPS_MODULE
++    EC_POINT_clear_free(point);
++#else
+     if (point == NULL)
+         return;
+ 
+     if (point->meth->point_finish != 0)
+         point->meth->point_finish(point);
+     OPENSSL_free(point);
++#endif
+ }
+ 
+ void EC_POINT_clear_free(EC_POINT *point)
diff --git a/SOURCES/0078-Add-FIPS-indicator-parameter-to-HKDF.patch b/SOURCES/0078-Add-FIPS-indicator-parameter-to-HKDF.patch
new file mode 100644
index 0000000..31e3c7d
--- /dev/null
+++ b/SOURCES/0078-Add-FIPS-indicator-parameter-to-HKDF.patch
@@ -0,0 +1,119 @@
+From c4b086fc4de06128695e1fe428f56d776d25e748 Mon Sep 17 00:00:00 2001
+From: Clemens Lang <cllang@redhat.com>
+Date: Thu, 11 Aug 2022 09:27:12 +0200
+Subject: [PATCH] Add FIPS indicator parameter to HKDF
+
+NIST considers HKDF only acceptable when used as in TLS 1.3, and
+otherwise unapproved. Add an explicit indicator attached to the
+EVP_KDF_CTX that can be queried using EVP_KDF_CTX_get_params() to
+determine whether the KDF operation was approved after performing it.
+
+Related: rhbz#2114772
+Signed-off-by: Clemens Lang <cllang@redhat.com>
+---
+ include/openssl/core_names.h          |  1 +
+ include/openssl/kdf.h                 |  4 ++
+ providers/implementations/kdfs/hkdf.c | 53 +++++++++++++++++++++++++++
+ 3 files changed, 58 insertions(+)
+
+diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
+index 21c94d0488..87786680d7 100644
+--- a/include/openssl/core_names.h
++++ b/include/openssl/core_names.h
+@@ -223,6 +223,7 @@ extern "C" {
+ #define OSSL_KDF_PARAM_X942_SUPP_PUBINFO    "supp-pubinfo"
+ #define OSSL_KDF_PARAM_X942_SUPP_PRIVINFO   "supp-privinfo"
+ #define OSSL_KDF_PARAM_X942_USE_KEYBITS     "use-keybits"
++#define OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR "hkdf-fips-indicator"
+ 
+ /* Known KDF names */
+ #define OSSL_KDF_NAME_HKDF           "HKDF"
+diff --git a/include/openssl/kdf.h b/include/openssl/kdf.h
+index 0983230a48..869f23d8fb 100644
+--- a/include/openssl/kdf.h
++++ b/include/openssl/kdf.h
+@@ -63,6 +63,10 @@ int EVP_KDF_names_do_all(const EVP_KDF *kdf,
+ # define EVP_KDF_HKDF_MODE_EXTRACT_ONLY        1
+ # define EVP_KDF_HKDF_MODE_EXPAND_ONLY         2
+ 
++# define EVP_KDF_HKDF_FIPS_INDICATOR_UNDETERMINED 0
++# define EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED     1
++# define EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED 2
++
+ #define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_CLI_TO_SRV     65
+ #define EVP_KDF_SSHKDF_TYPE_INITIAL_IV_SRV_TO_CLI     66
+ #define EVP_KDF_SSHKDF_TYPE_ENCRYPTION_KEY_CLI_TO_SRV 67
+diff --git a/providers/implementations/kdfs/hkdf.c b/providers/implementations/kdfs/hkdf.c
+index afdb7138e1..9d28d292d8 100644
+--- a/providers/implementations/kdfs/hkdf.c
++++ b/providers/implementations/kdfs/hkdf.c
+@@ -298,6 +298,56 @@ static int kdf_hkdf_get_ctx_params(void *vctx, OSSL_PARAM params[])
+             return 0;
+         return OSSL_PARAM_set_size_t(p, sz);
+     }
++
++#ifdef FIPS_MODULE
++    if ((p = OSSL_PARAM_locate(params,
++                OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR)) != NULL) {
++        int fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_UNDETERMINED;
++        switch (ctx->mode) {
++        case EVP_KDF_HKDF_MODE_EXTRACT_AND_EXPAND:
++            /* TLS 1.3 never uses extract-and-expand */
++            fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
++            break;
++        case EVP_KDF_HKDF_MODE_EXTRACT_ONLY:
++            {
++                /* When TLS 1.3 uses extract, the following holds:
++                 * 1. The salt length matches the hash length, and either
++                 * 2.1. the key is all zeroes and matches the hash length, or
++                 * 2.2. the key originates from a PSK (resumption_master_secret
++                 *   or some externally esablished key), or an ECDH or DH key
++                 *   derivation. See
++                 *   https://www.rfc-editor.org/rfc/rfc8446#section-7.1.
++                 * Unfortunately at this point, we cannot verify where the key
++                 * comes from, so all we can do is check the salt length.
++                 */
++                const EVP_MD *md = ossl_prov_digest_md(&ctx->digest);
++                if (md != NULL && ctx->salt_len == EVP_MD_get_size(md))
++                    fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED;
++                else
++                    fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
++            }
++            break;
++        case EVP_KDF_HKDF_MODE_EXPAND_ONLY:
++            /* When TLS 1.3 uses expand, it always provides a label that
++             * contains an uint16 for the length, followed by between 7 and 255
++             * bytes for a label string that starts with "tls13 " or "dtls13".
++             * For compatibility with future versions, we only check for "tls"
++             * or "dtls". See
++             * https://www.rfc-editor.org/rfc/rfc8446#section-7.1 and
++             * https://www.rfc-editor.org/rfc/rfc9147#section-5.9. */
++            if (ctx->label != NULL
++                    && ctx->label_len >= 2 /* length */ + 4 /* "dtls" */
++                    && (strncmp("tls", (const char *)ctx->label + 2, 3) == 0 ||
++                        strncmp("dtls", (const char *)ctx->label + 2, 4) == 0))
++                fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_APPROVED;
++            else
++                fips_indicator = EVP_KDF_HKDF_FIPS_INDICATOR_NOT_APPROVED;
++            break;
++        }
++        return OSSL_PARAM_set_int(p, fips_indicator);
++    }
++#endif /* defined(FIPS_MODULE) */
++
+     return -2;
+ }
+ 
+@@ -306,6 +356,9 @@ 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),
++#ifdef FIPS_MODULE
++        OSSL_PARAM_int(OSSL_KDF_PARAM_HKDF_REDHAT_FIPS_INDICATOR, NULL),
++#endif /* defined(FIPS_MODULE) */
+         OSSL_PARAM_END
+     };
+     return known_gettable_ctx_params;
+-- 
+2.37.1
+
diff --git a/SOURCES/ectest.c b/SOURCES/ectest.c
index 2ba662f..b2708ea 100644
--- a/SOURCES/ectest.c
+++ b/SOURCES/ectest.c
@@ -2284,7 +2284,7 @@ int setup_tests(void)
         return 0;
 
     ADD_TEST(parameter_test);
-    ADD_TEST(cofactor_range_test);
+    /*ADD_TEST(cofactor_range_test);*/
     ADD_ALL_TESTS(cardinality_test, crv_len);
     ADD_TEST(prime_field_tests);
 #ifndef OPENSSL_NO_EC2M
diff --git a/SPECS/openssl.spec b/SPECS/openssl.spec
index 566c0f8..005e9ab 100644
--- a/SPECS/openssl.spec
+++ b/SPECS/openssl.spec
@@ -10,12 +10,26 @@
 # also be handled in opensslconf-new.h.
 %define multilib_arches %{ix86} ia64 %{mips} ppc ppc64 s390 s390x sparcv9 sparc64 x86_64
 
+%define srpmhash() %{lua:
+local files = rpm.expand("%_specdir/openssl.spec")
+for i, p in ipairs(patches) do
+   files = files.." "..p
+end
+for i, p in ipairs(sources) do
+   files = files.." "..p
+end
+local sha256sum = assert(io.popen("cat "..files.." 2>/dev/null | sha256sum"))
+local hash = sha256sum:read("*a")
+sha256sum:close()
+print(string.sub(hash, 0, 16))
+}
+
 %global _performance_build 1
 
 Summary: Utilities from the general purpose cryptography library with TLS implementation
 Name: openssl
 Version: 3.0.1
-Release: 23%{?dist}
+Release: 41%{?dist}
 Epoch: 1
 # We have to remove certain patented algorithms from the openssl source
 # tarball with the hobble-openssl script which is included below.
@@ -54,8 +68,14 @@ Patch9: 0009-Add-Kernel-FIPS-mode-flag-support.patch
 # remove unsupported EC curves
 Patch11: 0011-Remove-EC-curves.patch
 # Disable explicit EC curves
-# https://bugzilla.redhat.com/show_bug.cgi?id=1977867
+# https://bugzilla.redhat.com/show_bug.cgi?id=2066412
 Patch12: 0012-Disable-explicit-ec.patch
+# https://github.com/openssl/openssl/pull/17981
+Patch13: 0013-FIPS-provider-explicit-ec.patch
+# https://github.com/openssl/openssl/pull/17998
+Patch14: 0014-FIPS-disable-explicit-ec.patch
+# https://github.com/openssl/openssl/pull/18609
+Patch15: 0015-FIPS-decoded-from-explicit.patch
 # Instructions to load legacy provider in openssl.cnf
 Patch24: 0024-load-legacy-prov.patch
 # Tmp: test name change
@@ -68,6 +88,8 @@ Patch33: 0033-FIPS-embed-hmac.patch
 Patch34: 0034.fipsinstall_disable.patch
 # Skip unavailable algorithms running `openssl speed`
 Patch35: 0035-speed-skip-unavailable-dgst.patch
+# Extra public/private key checks required by FIPS-140-3
+Patch44: 0044-FIPS-140-3-keychecks.patch
 # Minimize fips services
 Patch45: 0045-FIPS-services-minimize.patch
 # Backport of s390x hardening, https://github.com/openssl/openssl/pull/17486
@@ -86,12 +108,60 @@ Patch51: 0051-Support-different-R_BITS-lengths-for-KBKDF.patch
 Patch52: 0052-Allow-SHA1-in-seclevel-2-if-rh-allow-sha1-signatures.patch
 # CVE 2022-0778
 Patch53: 0053-CVE-2022-0778.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2004915, backport of 2c0f7d46b8449423446cfe1e52fc1e1ecd506b62
+Patch54: 0054-Replace-size-check-with-more-meaningful-pubkey-check.patch
 # https://github.com/openssl/openssl/pull/17324
 Patch55: 0055-nonlegacy-fetch-null-deref.patch
 # https://github.com/openssl/openssl/pull/18103
 Patch56: 0056-strcasecmp.patch
 # https://github.com/openssl/openssl/pull/18175
 Patch57: 0057-strcasecmp-fix.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2053289
+Patch58: 0058-FIPS-limit-rsa-encrypt.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2069235
+Patch60: 0060-FIPS-KAT-signature-tests.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2087147
+Patch61: 0061-Deny-SHA-1-signature-verification-in-FIPS-provider.patch
+Patch62: 0062-fips-Expose-a-FIPS-indicator.patch
+# https://github.com/openssl/openssl/pull/18141
+Patch63: 0063-CVE-2022-1473.patch
+# upstream commits 55c80c222293a972587004c185dc5653ae207a0e 2eda98790c5c2741d76d23cc1e74b0dc4f4b391a
+Patch64: 0064-CVE-2022-1343.diff
+# upstream commit 1ad73b4d27bd8c1b369a3cd453681d3a4f1bb9b2
+Patch65: 0065-CVE-2022-1292.patch
+# https://github.com/openssl/openssl/pull/18444
+# https://github.com/openssl/openssl/pull/18467
+Patch66: 0066-replace-expired-certs.patch
+# https://github.com/openssl/openssl/pull/18512
+Patch67: 0067-fix-ppc64-montgomery.patch
+#https://github.com/openssl/openssl/commit/2c9c35870601b4a44d86ddbf512b38df38285cfa
+#https://github.com/openssl/openssl/commit/8a3579a7b7067a983e69a4eda839ac408c120739
+Patch68: 0068-CVE-2022-2068.patch
+# https://github.com/openssl/openssl/commit/a98f339ddd7e8f487d6e0088d4a9a42324885a93
+# https://github.com/openssl/openssl/commit/52d50d52c2f1f4b70d37696bfa74fe5e581e7ba8
+Patch69: 0069-CVE-2022-2097.patch
+# https://github.com/openssl/openssl/commit/edceec7fe0c9a5534ae155c8398c63dd7dd95483
+Patch70: 0070-EVP_PKEY_Q_keygen-Call-OPENSSL_init_crypto-to-init-s.patch
+# https://github.com/openssl/openssl/commit/44a563dde1584cd9284e80b6e45ee5019be8d36c
+# https://github.com/openssl/openssl/commit/345c99b6654b8313c792d54f829943068911ddbd
+Patch71: 0071-AES-GCM-performance-optimization.patch
+# https://github.com/openssl/openssl/commit/f596bbe4da779b56eea34d96168b557d78e1149
+# https://github.com/openssl/openssl/commit/7e1f3ffcc5bc15fb9a12b9e3bb202f544c6ed5aa
+# hunks in crypto/ppccap.c from https://github.com/openssl/openssl/commit/f5485b97b6c9977c0d39c7669b9f97a879312447
+Patch72: 0072-ChaCha20-performance-optimizations-for-ppc64le.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2102535
+Patch73: 0073-FIPS-Use-OAEP-in-KATs-support-fixed-OAEP-seed.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2102535
+Patch74: 0074-FIPS-Use-digest_sign-digest_verify-in-self-test.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2102535
+Patch75: 0075-FIPS-Use-FFDHE2048-in-self-test.patch
+# Downstream only. Reseed DRBG using getrandom(GRND_RANDOM)
+# https://bugzilla.redhat.com/show_bug.cgi?id=2102541
+Patch76: 0076-FIPS-140-3-DRBG.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2102542
+Patch77: 0077-FIPS-140-3-zeroization.patch
+# https://bugzilla.redhat.com/show_bug.cgi?id=2114772
+Patch78: 0078-Add-FIPS-indicator-parameter-to-HKDF.patch
 
 License: ASL 2.0
 URL: http://www.openssl.org/
@@ -224,7 +294,7 @@ RPM_OPT_FLAGS="$RPM_OPT_FLAGS -Wa,--noexecstack -Wa,--generate-missing-build-not
 
 export HASHBANGPERL=/usr/bin/perl
 
-%define fips %{version}-%(date +%Y%m%d)
+%define fips %{version}-%{srpmhash}
 # ia64, x86_64, ppc are OK by default
 # Configure the build tree.  Override OpenSSL defaults with known-good defaults
 # usable on all platforms.  The Configure script already knows to use -fPIC and
@@ -422,6 +492,128 @@ install -m644 %{SOURCE9} \
 %ldconfig_scriptlets libs
 
 %changelog
+* Thu Aug 11 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-41
+- Zeroize public keys as required by FIPS 140-3
+  Resolves: rhbz#2115861
+- Add FIPS indicator for HKDF
+  Resolves: rhbz#2118388
+
+* Fri Aug 05 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-40
+- Deal with DH keys in FIPS mode according FIPS-140-3 requirements
+  Related: rhbz#2115856
+- Deal with ECDH keys in FIPS mode according FIPS-140-3 requirements
+  Related: rhbz#2115857
+- Use signature for RSA pairwise test according FIPS-140-3 requirements
+  Related: rhbz#2115858
+- Reseed all the parent DRBGs in chain on reseeding a DRBG
+  Related: rhbz#2115859
+- Zeroization according to FIPS-140-3 requirements
+  Related: rhbz#2115861
+
+* Mon Aug 01 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-39
+- Use RSA-OAEP in FIPS RSA encryption/decryption FIPS self-test
+- Use Use digest_sign & digest_verify in FIPS signature self test
+- Use FFDHE2048 in Diffie-Hellman FIPS self-test
+  Resolves: rhbz#2112978
+
+* Thu Jul 14 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-38
+- Fix segfault in EVP_PKEY_Q_keygen() when OpenSSL was not previously
+  initialized.
+  Resolves: rhbz#2107530
+- Improve AES-GCM performance on Power9 and Power10 ppc64le
+  Resolves: rhbz#2103044
+- Improve ChaCha20 performance on Power10 ppc64le
+  Resolves: rhbz#2103044
+
+* Tue Jul 05 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-37
+- CVE-2022-2097: AES OCB fails to encrypt some bytes on 32-bit x86
+  Resolves: CVE-2022-2097
+
+* Thu Jun 16 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-36
+- Ciphersuites with RSAPSK KX should be filterd in FIPS mode
+- Related: rhbz#2091994
+- FIPS provider should block RSA encryption for key transport.
+- Other RSA encryption options should still be available if key length is enough
+- Related: rhbz#2091977
+- Improve diagnostics when passing unsupported groups in TLS
+- Related: rhbz#2086554
+- Fix PPC64 Montgomery multiplication bug
+- Related: rhbz#2101346
+- Strict certificates validation shouldn't allow explicit EC parameters
+- Related: rhbz#2085521
+- CVE-2022-2068: the c_rehash script allows command injection
+- Related: rhbz#2098276
+
+* Wed Jun 08 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-35
+- Add explicit indicators for signatures in FIPS mode and mark signature
+  primitives as unapproved.
+  Resolves: rhbz#2087234
+
+* Fri Jun 03 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-34
+- Some OpenSSL test certificates are expired, updating
+- Resolves: rhbz#2095696
+
+* Thu May 26 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-33
+- CVE-2022-1473 openssl: OPENSSL_LH_flush() breaks reuse of memory
+- Resolves: rhbz#2089443
+- CVE-2022-1343 openssl: Signer certificate verification returned
+  inaccurate response when using OCSP_NOCHECKS
+- Resolves: rhbz#2089439
+- CVE-2022-1292 openssl: c_rehash script allows command injection
+- Resolves: rhbz#2090361
+- Revert "Disable EVP_PKEY_sign/EVP_PKEY_verify in FIPS mode"
+  Related: rhbz#2087234
+- Use KAT for ECDSA signature tests, s390 arch
+- Resolves: rhbz#2086866
+
+* Thu May 19 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-32
+- `openssl ecparam -list_curves` lists only FIPS-approved curves in FIPS mode
+- Resolves: rhbz#2091929
+- Ciphersuites with RSA KX should be filterd in FIPS mode
+- Related: rhbz#2091994
+- In FIPS mode, signature verification works with keys of arbitrary size
+  above 2048 bit, and only with 1024, 1280, 1536, 1792 bits for keys
+  below 2048 bits
+- Resolves: rhbz#2091938
+
+* Wed May 18 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-31
+- Disable SHA-1 signature verification in FIPS mode
+- Disable EVP_PKEY_sign/EVP_PKEY_verify in FIPS mode
+  Resolves: rhbz#2087234
+
+* Mon May 16 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-30
+- Use KAT for ECDSA signature tests
+- Resolves: rhbz#2086866
+
+* Thu May 12 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-29
+- `-config` argument of openssl app should work properly in FIPS mode
+- Resolves: rhbz#2085500
+- openssl req defaults on PKCS#8 encryption changed to AES-256-CBC
+- Resolves: rhbz#2085499
+
+* Fri May 06 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-28
+- OpenSSL should not accept custom elliptic curve parameters
+- Resolves rhbz#2085508
+- OpenSSL should not accept explicit curve parameters in FIPS mode
+- Resolves rhbz#2085521
+
+* Fri May 06 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-27
+- Change FIPS module version to include hash of specfile, patches and sources
+  Resolves: rhbz#2082585
+
+* Thu May 05 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-26
+- OpenSSL FIPS module should not build in non-approved algorithms
+  Resolves: rhbz#2082584
+
+* Mon May 02 2022 Dmitry Belyavskiy <dbelyavs@redhat.com> - 1:3.0.1-25
+- FIPS provider should block RSA encryption for key transport.
+- Other RSA encryption options should still be available
+- Resolves: rhbz#2053289
+
+* Mon May 02 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-24
+- Fix occasional internal error in TLS when DHE is used
+  Resolves: rhbz#2080323
+
 * Tue Apr 26 2022 Clemens Lang <cllang@redhat.com> - 1:3.0.1-23
 - Update missing initialization patch with feedback from upstream
   Resolves: rhbz#2076654