[openssl] master update

shane.lontis at oracle.com shane.lontis at oracle.com
Wed Jun 17 01:54:32 UTC 2020


The branch master has been updated
       via  4f2271d58a36b2aee125062ffb9626c6208fa394 (commit)
      from  5a147abd790075cdc97b36ff5084e2eb1d779b95 (commit)


- Log -----------------------------------------------------------------
commit 4f2271d58a36b2aee125062ffb9626c6208fa394
Author: Shane Lontis <shane.lontis at oracle.com>
Date:   Wed Jun 17 11:33:16 2020 +1000

    Add ACVP fips module tests
    
    For FIPS validation purposes - Automated Cryptographic Validation Protocol (ACVP) tests need to be
    performed. (See https://github.com/usnistgov/ACVP). These tests are very similiar to the old CAVS tests.
    
    This PR uses a hardwired subset of these test vectors to perform similiar operations,
    to show the usage and prove that the API's are able to perform the required operations.
    It may also help with communication with the lab (i.e- The lab could add a test here to show
    a unworking use case - which we can then address).
    
    The EVP layer performs these tests instead of calling lower level API's
    as was done in the old FOM.
    Some of these tests require access to internals that are not normally allowed/required.
    
    The config option 'acvp_tests' (enabled by default) has been added so that this
    access may be removed.
    
    The mechanism has been implemented as additional OSSL_PARAM values that can be set and get.
    A callback mechanism did not seem to add any additional benefit.
    These params will not be added to the gettables lists.
    
    Reviewed-by: Matt Caswell <matt at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/11572)

-----------------------------------------------------------------------

Summary of changes:
 Configure                                      |    1 +
 INSTALL.md                                     |   10 +
 crypto/dh/dh_check.c                           |    4 +-
 crypto/dh/dh_gen.c                             |   15 +-
 crypto/dh/dh_pmeth.c                           |   17 +-
 crypto/dsa/dsa_check.c                         |    4 +-
 crypto/dsa/dsa_gen.c                           |   27 +-
 crypto/dsa/dsa_pmeth.c                         |    6 +-
 crypto/ffc/ffc_backend.c                       |   22 +
 crypto/ffc/ffc_params.c                        |   59 +
 crypto/ffc/ffc_params_generate.c               |  208 +--
 crypto/ffc/ffc_params_validate.c               |   24 +-
 crypto/rsa/build.info                          |    4 +
 crypto/rsa/rsa_acvp_test_params.c              |  167 ++
 crypto/rsa/rsa_backend.c                       |    8 +-
 crypto/rsa/rsa_gen.c                           |    4 +-
 crypto/rsa/rsa_lib.c                           |    5 +
 crypto/rsa/rsa_local.h                         |   38 +-
 crypto/rsa/rsa_sp800_56b_gen.c                 |   74 +-
 doc/man7/EVP_PKEY-RSA.pod                      |   53 +
 include/crypto/dh.h                            |    4 +-
 include/crypto/dsa.h                           |    4 +-
 include/crypto/rsa.h                           |   16 +-
 include/internal/ffc.h                         |   55 +-
 include/openssl/core_names.h                   |   44 +-
 providers/implementations/keymgmt/dh_kmgmt.c   |   29 +-
 providers/implementations/keymgmt/dsa_kmgmt.c  |   29 +-
 providers/implementations/keymgmt/ec_kmgmt.c   |   47 +-
 providers/implementations/keymgmt/rsa_kmgmt.c  |   23 +-
 providers/implementations/signature/build.info |    4 +-
 providers/implementations/signature/dsa.c      |   18 +-
 providers/implementations/signature/ecdsa.c    |   25 +-
 providers/implementations/signature/rsa.c      |   19 +-
 test/acvp_test.c                               | 1367 ++++++++++++++++
 test/acvp_test.inc                             | 1984 ++++++++++++++++++++++++
 test/build.info                                |    7 +
 test/ffc_internal_test.c                       |  149 +-
 test/recipes/30-test_acvp.t                    |   41 +
 test/rsa_sp800_56b_test.c                      |  128 --
 39 files changed, 4236 insertions(+), 507 deletions(-)
 create mode 100644 crypto/rsa/rsa_acvp_test_params.c
 create mode 100644 test/acvp_test.c
 create mode 100644 test/acvp_test.inc
 create mode 100644 test/recipes/30-test_acvp.t

diff --git a/Configure b/Configure
index 1a22f47822..a0b9c22b6d 100755
--- a/Configure
+++ b/Configure
@@ -360,6 +360,7 @@ my @dtls = qw(dtls1 dtls1_2);
 # For developers: keep it sorted alphabetically
 
 my @disablables = (
+    "acvp_tests",
     "afalgeng",
     "aria",
     "asan",
diff --git a/INSTALL.md b/INSTALL.md
index 88961aa74b..981a86af04 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -501,6 +501,16 @@ never be used in production environments.  It will only work when used with
 gcc or clang and should be used in conjunction with the [no-shared](#no-shared)
 option.
 
+### no-acvp_tests
+
+Do not build support for Automated Cryptographic Validation Protocol (ACVP)
+tests.
+
+This is required for FIPS validation purposes. Certain ACVP tests require
+access to algorithm internals that are not normally accessible.
+Additional information related to ACVP can be found at
+<https://github.com/usnistgov/ACVP>.
+
 ### no-asm
 
 Do not use assembler code.
diff --git a/crypto/dh/dh_check.c b/crypto/dh/dh_check.c
index 9dd595ae12..a223121cd0 100644
--- a/crypto/dh/dh_check.c
+++ b/crypto/dh/dh_check.c
@@ -62,8 +62,8 @@ int DH_check_params(const DH *dh, int *ret)
      * (2b) FFC domain params conform to FIPS-186-4 explicit domain param
      * validity tests.
      */
-    return ffc_params_FIPS186_4_validate(&dh->params, FFC_PARAM_TYPE_DH, NULL,
-                                         FFC_PARAMS_VALIDATE_ALL, ret, NULL);
+    return ffc_params_FIPS186_4_validate(dh->libctx, &dh->params,
+                                         FFC_PARAM_TYPE_DH, ret, NULL);
 }
 #else
 int DH_check_params(const DH *dh, int *ret)
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
index 8c1518ad9b..52f3151bc8 100644
--- a/crypto/dh/dh_gen.c
+++ b/crypto/dh/dh_gen.c
@@ -35,28 +35,21 @@ static int dh_builtin_genparams(DH *ret, int prime_len, int generator,
                                 BN_GENCB *cb);
 #endif /* FIPS_MODULE */
 
-int dh_generate_ffc_parameters(DH *dh, int type, int pbits,
-                               int qbits, EVP_MD *md, BN_GENCB *cb)
+int dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits,
+                               BN_GENCB *cb)
 {
     int ret, res;
 
-    if (qbits <= 0) {
-        if (md != NULL)
-            qbits = EVP_MD_size(md) * 8;
-        else
-            qbits = (pbits >= 2048 ? SHA256_DIGEST_LENGTH :
-                                     SHA_DIGEST_LENGTH) * 8;
-    }
 #ifndef FIPS_MODULE
     if (type == DH_PARAMGEN_TYPE_FIPS_186_2)
         ret = ffc_params_FIPS186_2_generate(dh->libctx, &dh->params,
                                             FFC_PARAM_TYPE_DH,
-                                            pbits, qbits, md, &res, cb);
+                                            pbits, qbits, &res, cb);
     else
 #endif
         ret = ffc_params_FIPS186_4_generate(dh->libctx, &dh->params,
                                             FFC_PARAM_TYPE_DH,
-                                            pbits, qbits, md, &res, cb);
+                                            pbits, qbits, &res, cb);
     if (ret > 0)
         dh->dirty_cnt++;
     return ret;
diff --git a/crypto/dh/dh_pmeth.c b/crypto/dh/dh_pmeth.c
index 23527acf04..39b79ffb36 100644
--- a/crypto/dh/dh_pmeth.c
+++ b/crypto/dh/dh_pmeth.c
@@ -286,7 +286,6 @@ static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx,
     int res;
     int prime_len = dctx->prime_len;
     int subprime_len = dctx->subprime_len;
-    const EVP_MD *md = dctx->md;
 
     if (dctx->paramgen_type > DH_PARAMGEN_TYPE_FIPS_186_4)
         return NULL;
@@ -300,26 +299,22 @@ static DH *ffc_params_generate(OPENSSL_CTX *libctx, DH_PKEY_CTX *dctx,
         else
             subprime_len = 160;
     }
-    if (md == NULL) {
-        if (prime_len >= 2048)
-            md = EVP_sha256();
-        else
-            md = EVP_sha1();
-    }
+
+    if (dctx->md != NULL)
+        ffc_set_digest(&ret->params, EVP_MD_name(dctx->md), NULL);
+
 # ifndef FIPS_MODULE
     if (dctx->paramgen_type == DH_PARAMGEN_TYPE_FIPS_186_2)
         rv = ffc_params_FIPS186_2_generate(libctx, &ret->params,
                                            FFC_PARAM_TYPE_DH,
-                                           prime_len, subprime_len, md, &res,
-                                           pcb);
+                                           prime_len, subprime_len, &res, pcb);
     else
 # endif
     /* For FIPS we always use the DH_PARAMGEN_TYPE_FIPS_186_4 generator */
     if (dctx->paramgen_type >= DH_PARAMGEN_TYPE_FIPS_186_2)
         rv = ffc_params_FIPS186_4_generate(libctx, &ret->params,
                                            FFC_PARAM_TYPE_DH,
-                                           prime_len, subprime_len, md, &res,
-                                           pcb);
+                                           prime_len, subprime_len, &res, pcb);
     if (rv <= 0) {
         DH_free(ret);
         return NULL;
diff --git a/crypto/dsa/dsa_check.c b/crypto/dsa/dsa_check.c
index dc42ec5f5f..01cf0f6341 100644
--- a/crypto/dsa/dsa_check.c
+++ b/crypto/dsa/dsa_check.c
@@ -19,8 +19,8 @@ int dsa_check_params(const DSA *dsa, int *ret)
      * (2b) FFC domain params conform to FIPS-186-4 explicit domain param
      * validity tests.
      */
-    return ffc_params_FIPS186_4_validate(&dsa->params, FFC_PARAM_TYPE_DSA, NULL,
-                                         FFC_PARAMS_VALIDATE_ALL, ret, NULL);
+    return ffc_params_FIPS186_4_validate(dsa->libctx, &dsa->params,
+                                         FFC_PARAM_TYPE_DSA, ret, NULL);
 }
 
 /*
diff --git a/crypto/dsa/dsa_gen.c b/crypto/dsa/dsa_gen.c
index acd088ee79..9d5e91de29 100644
--- a/crypto/dsa/dsa_gen.c
+++ b/crypto/dsa/dsa_gen.c
@@ -23,29 +23,21 @@
 #include "crypto/dsa.h"
 #include "dsa_local.h"
 
-int dsa_generate_ffc_parameters(DSA *dsa, int type,
-                                int pbits, int qbits,
-                                EVP_MD *md, BN_GENCB *cb)
+int dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits,
+                                BN_GENCB *cb)
 {
     int ret = 0, res;
 
-    if (qbits <= 0) {
-        if (md != NULL)
-            qbits = EVP_MD_size(md) * 8;
-        else
-            qbits = (pbits >= 2048 ? SHA256_DIGEST_LENGTH :
-                                     SHA_DIGEST_LENGTH) * 8;
-    }
 #ifndef FIPS_MODULE
     if (type == DSA_PARAMGEN_TYPE_FIPS_186_2)
         ret = ffc_params_FIPS186_2_generate(dsa->libctx, &dsa->params,
                                             FFC_PARAM_TYPE_DSA,
-                                            pbits, qbits, md, &res, cb);
+                                            pbits, qbits, &res, cb);
     else
 #endif
         ret = ffc_params_FIPS186_4_generate(dsa->libctx, &dsa->params,
                                             FFC_PARAM_TYPE_DSA,
-                                            pbits, qbits, md, &res, cb);
+                                            pbits, qbits, &res, cb);
     if (ret > 0)
         dsa->dirty_cnt++;
     return ret;
@@ -57,26 +49,21 @@ int DSA_generate_parameters_ex(DSA *dsa, int bits,
                                int *counter_ret, unsigned long *h_ret,
                                BN_GENCB *cb)
 {
-#ifndef FIPS_MODULE
     if (dsa->meth->dsa_paramgen)
         return dsa->meth->dsa_paramgen(dsa, bits, seed_in, seed_len,
                                        counter_ret, h_ret, cb);
-#endif
     if (seed_in != NULL
         && !ffc_params_set_validate_params(&dsa->params, seed_in, seed_len, -1))
         return 0;
 
-#ifndef FIPS_MODULE
     /* The old code used FIPS 186-2 DSA Parameter generation */
     if (bits <= 1024 && seed_len == 20) {
         if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_2,
-                                         bits, 160, NULL, cb))
+                                         bits, 160, cb))
             return 0;
-    } else
-#endif
-    {
+    } else {
         if (!dsa_generate_ffc_parameters(dsa, DSA_PARAMGEN_TYPE_FIPS_186_4,
-                                         bits, -1, NULL, cb))
+                                         bits, -1, cb))
             return 0;
     }
 
diff --git a/crypto/dsa/dsa_pmeth.c b/crypto/dsa/dsa_pmeth.c
index 7f7f57f6d3..7b364059e7 100644
--- a/crypto/dsa/dsa_pmeth.c
+++ b/crypto/dsa/dsa_pmeth.c
@@ -217,9 +217,11 @@ static int pkey_dsa_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
         BN_GENCB_free(pcb);
         return 0;
     }
+    if (dctx->md != NULL)
+        ffc_set_digest(&dsa->params, EVP_MD_name(dctx->md), NULL);
+
     ret = ffc_params_FIPS186_4_generate(NULL, &dsa->params, FFC_PARAM_TYPE_DSA,
-                                        dctx->nbits, dctx->qbits, dctx->pmd,
-                                        &res, pcb);
+                                        dctx->nbits, dctx->qbits, &res, pcb);
     BN_GENCB_free(pcb);
     if (ret > 0)
         EVP_PKEY_assign_DSA(pkey, dsa);
diff --git a/crypto/ffc/ffc_backend.c b/crypto/ffc/ffc_backend.c
index c34e79bf4f..49f42d70d0 100644
--- a/crypto/ffc/ffc_backend.c
+++ b/crypto/ffc/ffc_backend.c
@@ -78,6 +78,28 @@ int ffc_params_fromdata(FFC_PARAMS *ffc, const OSSL_PARAM params[])
         if (!ffc_params_set_seed(ffc, prm->data, prm->data_size))
             goto err;
     }
+    prm  = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE);
+    if (prm != NULL) {
+        if (prm->data_type != OSSL_PARAM_UTF8_STRING)
+            goto err;
+        ffc_params_set_flags(ffc, ffc_params_flags_from_name(prm->data));
+    }
+    prm = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
+    if (prm != NULL) {
+        const OSSL_PARAM *p1;
+        const char *props = NULL;
+
+        if (prm->data_type != OSSL_PARAM_UTF8_STRING)
+            goto err;
+        p1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
+        if (p1 != NULL) {
+            if (p1->data_type != OSSL_PARAM_UTF8_STRING)
+                goto err;
+        }
+        if (!ffc_set_digest(ffc, prm->data, props))
+            goto err;
+    }
+
     ffc_params_set0_pqg(ffc, p, q, g);
     ffc_params_set0_j(ffc, j);
     return 1;
diff --git a/crypto/ffc/ffc_params.c b/crypto/ffc/ffc_params.c
index a95a2fa12b..0796d34337 100644
--- a/crypto/ffc/ffc_params.c
+++ b/crypto/ffc/ffc_params.c
@@ -11,6 +11,8 @@
 #include <openssl/core_names.h>
 #include "internal/ffc.h"
 #include "internal/param_build_set.h"
+#include "internal/nelem.h"
+#include "e_os.h" /* strcasecmp */
 
 #ifndef FIPS_MODULE
 # include <openssl/asn1.h> /* ffc_params_print */
@@ -21,6 +23,7 @@ void ffc_params_init(FFC_PARAMS *params)
     memset(params, 0, sizeof(*params));
     params->pcounter = -1;
     params->gindex = FFC_UNVERIFIABLE_GINDEX;
+    params->flags = FFC_PARAM_FLAG_VALIDATE_ALL;
 }
 
 void ffc_params_cleanup(FFC_PARAMS *params)
@@ -109,6 +112,18 @@ void ffc_params_set_h(FFC_PARAMS *params, int index)
     params->h = index;
 }
 
+void ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags)
+{
+    params->flags = flags;
+}
+
+int ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props)
+{
+    params->mdname = alg;
+    params->mdprops = props;
+    return 1;
+}
+
 int ffc_params_set_validate_params(FFC_PARAMS *params,
                                    const unsigned char *seed, size_t seedlen,
                                    int counter)
@@ -182,6 +197,36 @@ int ffc_params_cmp(const FFC_PARAMS *a, const FFC_PARAMS *b, int ignore_q)
            && (ignore_q || BN_cmp(a->q, b->q) == 0); /* Note: q may be NULL */
 }
 
+static const OSSL_ITEM flag_map[] = {
+    { FFC_PARAM_FLAG_VALIDATE_PQ, OSSL_FFC_PARAM_VALIDATE_PQ },
+    { FFC_PARAM_FLAG_VALIDATE_G, OSSL_FFC_PARAM_VALIDATE_G },
+    { FFC_PARAM_FLAG_VALIDATE_ALL, OSSL_FFC_PARAM_VALIDATE_PQG },
+    { 0, "" }
+};
+
+int ffc_params_flags_from_name(const char *name)
+{
+    size_t i;
+
+    for (i = 0; i < OSSL_NELEM(flag_map); ++i) {
+        if (strcasecmp(flag_map[i].ptr, name) == 0)
+            return flag_map[i].id;
+    }
+    return NID_undef;
+}
+
+const char *ffc_params_flags_to_name(int flags)
+{
+    size_t i;
+
+    flags &= FFC_PARAM_FLAG_VALIDATE_ALL;
+    for (i = 0; i < OSSL_NELEM(flag_map); ++i) {
+        if ((int)flag_map[i].id == flags)
+            return flag_map[i].ptr;
+    }
+    return "";
+}
+
 int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld,
                       OSSL_PARAM params[])
 {
@@ -228,6 +273,20 @@ int ffc_params_todata(const FFC_PARAMS *ffc, OSSL_PARAM_BLD *bld,
         return 0;
 #endif
     }
+    if (!ossl_param_build_set_utf8_string(bld, params,
+                                          OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE,
+                                          ffc_params_flags_to_name(ffc->flags)))
+        return 0;
+    if (ffc->mdname != NULL
+        && !ossl_param_build_set_utf8_string(bld, params,
+                                             OSSL_PKEY_PARAM_FFC_DIGEST,
+                                             ffc->mdname))
+       return 0;
+    if (ffc->mdprops != NULL
+        && !ossl_param_build_set_utf8_string(bld, params,
+                                             OSSL_PKEY_PARAM_FFC_DIGEST_PROPS,
+                                             ffc->mdprops))
+        return 0;
     return 1;
 }
 
diff --git a/crypto/ffc/ffc_params_generate.c b/crypto/ffc/ffc_params_generate.c
index 624c24dd21..b3ab476f3f 100644
--- a/crypto/ffc/ffc_params_generate.c
+++ b/crypto/ffc/ffc_params_generate.c
@@ -413,18 +413,15 @@ err:
     return ret;
 }
 
-static EVP_MD *fetch_default_md(OPENSSL_CTX *libctx, size_t N)
+static const char *default_mdname(size_t N)
 {
-    char *name = NULL;
-
     if (N == 160)
-        name = "SHA1";
+        return "SHA1";
     else if (N == 224)
-        name = "SHA-224";
+        return "SHA-224";
     else if (N == 256)
-        name = "SHA-256";
-
-    return name !=  NULL ?  EVP_MD_fetch(libctx, name, "") : NULL;
+        return "SHA-256";
+    return NULL;
 }
 
 /*
@@ -446,6 +443,13 @@ static EVP_MD *fetch_default_md(OPENSSL_CTX *libctx, size_t N)
  * the seed and index used during generation as input.
  *
  * params: used to pass in values for generation and validation.
+ * params->md: is the digest to use, If this value is NULL, then the digest is
+ *   chosen using the value of N.
+ * params->flags:
+ *  For validation one of:
+ *   -FFC_PARAM_FLAG_VALIDATE_PQ
+ *   -FFC_PARAM_FLAG_VALIDATE_G
+ *   -FFC_PARAM_FLAG_VALIDATE_ALL
  *  For generation of p & q:
  *   - This is skipped if p & q are passed in.
  *   - If the seed is passed in then generation of p & q uses this seed (and if
@@ -462,48 +466,58 @@ static EVP_MD *fetch_default_md(OPENSSL_CTX *libctx, size_t N)
  *   - For a partial validation : p, q and g are required.
  *   - For a canonical validation : the gindex and seed used for generation are
  *     also required.
+ * mode: The mode - either FFC_PARAM_MODE_GENERATE or FFC_PARAM_MODE_VERIFY.
  * type: The key type - FFC_PARAM_TYPE_DSA or FFC_PARAM_TYPE_DH.
  * L: is the size of the prime p in bits (e.g 2048)
  * N: is the size of the prime q in bits (e.g 256)
- * evpmd: is the digest to use, If this value is NULL, then the digest is chosen
- *        using the value of N.
- * validate_flags:
- *  or generation: FFC_PARAMS_GENERATE.
- *  For validation one of:
- *   -FFC_PARAMS_VALIDATE_PQ
- *   -FFC_PARAMS_VALIDATE_G
- *   -FFC_PARAMS_VALIDATE_ALL
  * res: A returned failure reason (One of FFC_CHECK_XXXX),
  *      or 0 for general failures.
  * cb: A callback (can be NULL) that is called during different phases
  *
  * Returns:
- *   - FFC_PARAMS_RET_STATUS_FAILED: if there was an error, or validation failed.
- *   - FFC_PARAMS_RET_STATUS_SUCCESS if the generation or validation succeeded.
- *   - FFC_PARAMS_RET_STATUS_UNVERIFIABLE_G if the validation of G succeeded,
+ *   - FFC_PARAM_RET_STATUS_FAILED: if there was an error, or validation failed.
+ *   - FFC_PARAM_RET_STATUS_SUCCESS if the generation or validation succeeded.
+ *   - FFC_PARAM_RET_STATUS_UNVERIFIABLE_G if the validation of G succeeded,
  *     but G is unverifiable.
  */
 int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
-                                    int type, size_t L, size_t N,
-                                    const EVP_MD *evpmd, int validate_flags,
+                                    int mode, int type, size_t L, size_t N,
                                     int *res, BN_GENCB *cb)
 {
-    int ok = FFC_PARAMS_RET_STATUS_FAILED;
+    int ok = FFC_PARAM_RET_STATUS_FAILED;
     unsigned char *seed = NULL, *seed_tmp = NULL;
     int mdsize, counter = 0, pcounter = 0, r = 0;
     size_t seedlen = 0;
     BIGNUM *tmp, *pm1, *e, *test;
     BIGNUM *g = NULL, *q = NULL, *p = NULL;
     BN_MONT_CTX *mont = NULL;
-    int n = 0, m = 0, qsize = N >> 3;
+    int n = 0, m = 0, qsize;
     int canonical_g = 0, hret = 0;
     BN_CTX *ctx = NULL;
     EVP_MD_CTX *mctx = NULL;
-    int generate = (validate_flags == 0);
-    EVP_MD *evpmd_fetch = NULL;
+    EVP_MD *md = NULL;
+    int verify = (mode == FFC_PARAM_MODE_VERIFY);
+    unsigned int flags = verify ? params->flags : 0;
 
     *res = 0;
 
+    if (params->mdname != NULL) {
+        md = EVP_MD_fetch(libctx, params->mdname, params->mdprops);
+    } else {
+        if (N <= 0)
+            N = (L >= 2048 ? SHA256_DIGEST_LENGTH : SHA_DIGEST_LENGTH) * 8;
+        md = EVP_MD_fetch(libctx, default_mdname(N), NULL);
+    }
+    if (md == NULL)
+        goto err;
+    mdsize = EVP_MD_size(md);
+    if (mdsize <= 0)
+        goto err;
+
+    if (N <= 0)
+        N = mdsize * 8;
+    qsize = N >> 3;
+
     /*
      * A.1.1.2 Step (1) AND
      * A.1.1.3 Step (3)
@@ -518,15 +532,6 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
     if (mctx == NULL)
         goto err;
 
-    if (evpmd == NULL) {
-        evpmd_fetch = fetch_default_md(libctx, N);
-        evpmd = evpmd_fetch;
-    }
-
-    mdsize = EVP_MD_size(evpmd);
-    if (mdsize <= 0)
-        goto err;
-
     if ((ctx = BN_CTX_new_ex(libctx)) == NULL)
         goto err;
 
@@ -546,7 +551,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
     if (params->seed != NULL)
         seed = params->seed;
 
-    if (generate) {
+    if (!verify) {
         /* For generation: p & q must both be NULL or NON-NULL */
         if ((params->p == NULL) != (params->q == NULL)) {
             *res = FFC_CHECK_INVALID_PQ;
@@ -554,13 +559,13 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
         }
     } else {
         /* Validation of p,q requires seed and counter to be valid */
-        if ((validate_flags & FFC_PARAMS_VALIDATE_PQ) != 0) {
+        if ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0) {
             if (seed == NULL || params->pcounter < 0) {
                 *res = FFC_CHECK_MISSING_SEED_OR_COUNTER;
                 goto err;
             }
         }
-        if ((validate_flags & FFC_PARAMS_VALIDATE_G) != 0) {
+        if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) {
             /* validation of g also requires g to be set */
             if (params->g == NULL) {
                 *res = FFC_CHECK_INVALID_G;
@@ -574,7 +579,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
      *   validate_flags = 0 then skip the generation of PQ.
      *   validate_flags = VALIDATE_G then also skip the validation of PQ.
      */
-    if (params->p != NULL && ((validate_flags & FFC_PARAMS_VALIDATE_PQ) == 0)) {
+    if (params->p != NULL && ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) == 0)) {
         /* p and q already exists so only generate g */
         p = params->p;
         q = params->q;
@@ -604,7 +609,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
 
     if (seed == NULL) {
         /* Validation requires the seed to be supplied */
-        if (validate_flags) {
+        if (verify) {
             *res = FFC_CHECK_MISSING_SEED_OR_COUNTER;
             goto err;
         }
@@ -617,7 +622,7 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
     /* A.1.1.2 Step (11): max loop count = 4L - 1 */
     counter = 4 * L - 1;
     /* Validation requires the counter to be supplied */
-    if (validate_flags) {
+    if (verify) {
         /* A.1.1.3 Step (4) : if (counter > (4L -1)) return INVALID */
         if (params->pcounter > counter) {
             *res = FFC_CHECK_INVALID_COUNTER;
@@ -638,11 +643,11 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
         goto err;
 
     for (;;) {
-        if (!generate_q_fips186_4(ctx, q, evpmd, qsize, seed, seedlen,
+        if (!generate_q_fips186_4(ctx, q, md, qsize, seed, seedlen,
                                   seed != params->seed, &m, res, cb))
             goto err;
         /* A.1.1.3 Step (9): Verify that q matches the expected value */
-        if (validate_flags && (BN_cmp(q, params->q) != 0)) {
+        if (verify && (BN_cmp(q, params->q) != 0)) {
             *res = FFC_CHECK_Q_MISMATCH;
             goto err;
         }
@@ -652,8 +657,8 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
             goto err;
 
         memcpy(seed_tmp, seed, seedlen);
-        r = generate_p(ctx, evpmd, counter, n, seed_tmp, seedlen, q, p, L, cb,
-                       &pcounter, res);
+        r = generate_p(ctx, md, counter, n, seed_tmp, seedlen, q, p, L,
+                       cb, &pcounter, res);
         if (r > 0)
             break; /* found p */
         if (r < 0)
@@ -674,11 +679,11 @@ int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
      * Gets here if we found p.
      * A.1.1.3 Step (14): return error if i != counter OR computed_p != known_p.
      */
-    if (validate_flags && (pcounter != counter || (BN_cmp(p, params->p) != 0)))
+    if (verify && (pcounter != counter || (BN_cmp(p, params->p) != 0)))
         goto err;
 
     /* If validating p & q only then skip the g validation test */
-    if ((validate_flags & FFC_PARAMS_VALIDATE_ALL) == FFC_PARAMS_VALIDATE_PQ)
+    if ((flags & FFC_PARAM_FLAG_VALIDATE_ALL) == FFC_PARAM_FLAG_VALIDATE_PQ)
         goto pass;
 g_only:
     if ((mont = BN_MONT_CTX_new()) == NULL)
@@ -686,7 +691,7 @@ g_only:
     if (!BN_MONT_CTX_set(mont, p, ctx))
         goto err;
 
-    if (((validate_flags & FFC_PARAMS_VALIDATE_G) != 0)
+    if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0)
         && !ffc_params_validate_unverifiable_g(ctx, mont, p, q, params->g,
                                                tmp, res))
         goto err;
@@ -703,17 +708,17 @@ g_only:
     /* Canonical g requires a seed and index to be set */
     if ((seed != NULL) && (params->gindex != FFC_UNVERIFIABLE_GINDEX)) {
         canonical_g = 1;
-        if (!generate_canonical_g(ctx, mont, evpmd, g, tmp, p, e,
+        if (!generate_canonical_g(ctx, mont, md, g, tmp, p, e,
                                   params->gindex, seed, seedlen)) {
             *res = FFC_CHECK_INVALID_G;
             goto err;
         }
         /* A.2.4 Step (13): Return valid if computed_g == g */
-        if (validate_flags && BN_cmp(g, params->g) != 0) {
+        if (verify && BN_cmp(g, params->g) != 0) {
             *res = FFC_CHECK_G_MISMATCH;
             goto err;
         }
-    } else if (generate) {
+    } else if (!verify) {
         if (!generate_unverifiable_g(ctx, mont, g, tmp, p, e, pm1, &hret))
             goto err;
     }
@@ -721,7 +726,7 @@ g_only:
     if (!BN_GENCB_call(cb, 3, 1))
         goto err;
 
-    if (generate) {
+    if (!verify) {
         if (p != params->p) {
             BN_free(params->p);
             params->p = BN_dup(p);
@@ -741,11 +746,11 @@ g_only:
         params->h = hret;
     }
 pass:
-    if ((validate_flags & FFC_PARAMS_VALIDATE_G) != 0 && (canonical_g == 0))
+    if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0 && (canonical_g == 0))
         /* Return for the case where g is partially valid */
-        ok = FFC_PARAMS_RET_STATUS_UNVERIFIABLE_G;
+        ok = FFC_PARAM_RET_STATUS_UNVERIFIABLE_G;
     else
-        ok = FFC_PARAMS_RET_STATUS_SUCCESS;
+        ok = FFC_PARAM_RET_STATUS_SUCCESS;
 err:
     if (seed != params->seed)
         OPENSSL_free(seed);
@@ -754,33 +759,47 @@ err:
         BN_CTX_end(ctx);
     BN_CTX_free(ctx);
     BN_MONT_CTX_free(mont);
-    EVP_MD_free(evpmd_fetch);
     EVP_MD_CTX_free(mctx);
+    EVP_MD_free(md);
     return ok;
 }
 
 int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
-                                    int type, size_t L, size_t N,
-                                    const EVP_MD *evpmd, int validate_flags,
+                                    int mode, int type, size_t L, size_t N,
                                     int *res, BN_GENCB *cb)
 {
-    int ok = FFC_PARAMS_RET_STATUS_FAILED;
+    int ok = FFC_PARAM_RET_STATUS_FAILED;
     unsigned char seed[SHA256_DIGEST_LENGTH];
     unsigned char buf[SHA256_DIGEST_LENGTH];
     BIGNUM *r0, *test, *tmp, *g = NULL, *q = NULL, *p = NULL;
     BN_MONT_CTX *mont = NULL;
-    size_t qsize = N >> 3;
+    EVP_MD *md = NULL;
+    size_t qsize;
     int n = 0, m = 0;
     int counter = 0, pcounter = 0, use_random_seed;
     int rv;
     BN_CTX *ctx = NULL;
     int hret = -1;
-    int generate = (validate_flags == 0);
     unsigned char *seed_in = params->seed;
     size_t seed_len = params->seedlen;
-    EVP_MD *evpmd_fetch = NULL;
+    int verify = (mode == FFC_PARAM_MODE_VERIFY);
+    unsigned int flags = verify ? params->flags : 0;
 
     *res = 0;
+
+    if (params->mdname != NULL) {
+        md = EVP_MD_fetch(libctx, params->mdname, params->mdprops);
+    } else {
+        if (N <= 0)
+            N = (L >= 2048 ? SHA256_DIGEST_LENGTH : SHA_DIGEST_LENGTH) * 8;
+        md = EVP_MD_fetch(libctx, default_mdname(N), NULL);
+    }
+    if (md == NULL)
+        goto err;
+    if (N <= 0)
+        N = EVP_MD_size(md) * 8;
+    qsize = N >> 3;
+
 #ifdef FIPS_MODULE
     /*
      * FIPS 186-4 states that validation can only be done for this pair.
@@ -788,7 +807,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
      */
     if (L != 1024 || N != 160) {
         *res = FFC_CHECK_BAD_LN_PAIR;
-        return FFC_PARAMS_RET_STATUS_FAILED;
+        goto err;
     }
 #endif
     if (qsize != SHA_DIGEST_LENGTH
@@ -796,17 +815,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
         && qsize != SHA256_DIGEST_LENGTH) {
         /* invalid q size */
         *res = FFC_CHECK_INVALID_Q_VALUE;
-        return FFC_PARAMS_RET_STATUS_FAILED;
-    }
-
-    if (evpmd == NULL) {
-        evpmd_fetch = fetch_default_md(libctx, qsize * 8);
-        evpmd = evpmd_fetch;
-    } else {
-        rv = EVP_MD_size(evpmd);
-        if (rv <= 0)
-            return 0;
-        qsize = (size_t)rv;
+        goto err;
     }
 
     if (L < 512)
@@ -817,12 +826,11 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
     if (seed_in != NULL) {
         if (seed_len < qsize) {
             *res = FFC_CHECK_INVALID_SEED_SIZE;
-            return 0;
+            goto err;
         }
-        if (seed_len > qsize) {
-            /* Only consume as much seed as is expected. */
+        /* Only consume as much seed as is expected. */
+        if (seed_len > qsize)
             seed_len = qsize;
-        }
         memcpy(seed, seed_in, seed_len);
     }
 
@@ -844,21 +852,21 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
     if (!BN_lshift(test, BN_value_one(), L - 1))
         goto err;
 
-    if (generate) {
+    if (!verify) {
         /* For generation: p & q must both be NULL or NON-NULL */
         if ((params->p != NULL) != (params->q != NULL)) {
             *res = FFC_CHECK_INVALID_PQ;
             goto err;
         }
     } else {
-        if ((validate_flags & FFC_PARAMS_VALIDATE_PQ) != 0) {
+        if ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) != 0) {
             /* Validation of p,q requires seed and counter to be valid */
             if (seed_in == NULL || params->pcounter < 0) {
                 *res = FFC_CHECK_MISSING_SEED_OR_COUNTER;
                 goto err;
             }
         }
-        if ((validate_flags & FFC_PARAMS_VALIDATE_G) != 0) {
+        if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0) {
             /* validation of g also requires g to be set */
             if (params->g == NULL) {
                 *res = FFC_CHECK_INVALID_G;
@@ -867,7 +875,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
         }
     }
 
-    if (params->p != NULL && ((validate_flags & FFC_PARAMS_VALIDATE_PQ) == 0)) {
+    if (params->p != NULL && ((flags & FFC_PARAM_FLAG_VALIDATE_PQ) == 0)) {
         /* p and q already exists so only generate g */
         p = params->p;
         q = params->q;
@@ -877,7 +885,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
 
     use_random_seed = (seed_in == NULL);
     for (;;) {
-        if (!generate_q_fips186_2(ctx, q, evpmd, buf, seed, qsize,
+        if (!generate_q_fips186_2(ctx, q, md, buf, seed, qsize,
                                   use_random_seed, &m, res, cb))
             goto err;
 
@@ -890,7 +898,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
         n = (L - 1) / 160;
         counter = 4 * L - 1; /* Was 4096 */
         /* Validation requires the counter to be supplied */
-        if (validate_flags) {
+        if (verify) {
             if (params->pcounter > counter) {
                 *res = FFC_CHECK_INVALID_COUNTER;
                 goto err;
@@ -898,7 +906,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
             counter = params->pcounter;
         }
 
-        rv = generate_p(ctx, evpmd, counter, n, buf, qsize, q, p, L, cb,
+        rv = generate_p(ctx, md, counter, n, buf, qsize, q, p, L, cb,
                         &pcounter, res);
         if (rv > 0)
             break; /* found it */
@@ -911,7 +919,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
     if (!BN_GENCB_call(cb, 2, 1))
         goto err;
 
-    if (validate_flags) {
+    if (verify) {
         if (pcounter != counter) {
             *res = FFC_CHECK_COUNTER_MISMATCH;
             goto err;
@@ -922,7 +930,7 @@ int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
         }
     }
     /* If validating p & q only then skip the g validation test */
-    if ((validate_flags & FFC_PARAMS_VALIDATE_ALL) == FFC_PARAMS_VALIDATE_PQ)
+    if ((flags & FFC_PARAM_FLAG_VALIDATE_ALL) == FFC_PARAM_FLAG_VALIDATE_PQ)
         goto pass;
 g_only:
     if ((mont = BN_MONT_CTX_new()) == NULL)
@@ -930,7 +938,7 @@ g_only:
     if (!BN_MONT_CTX_set(mont, p, ctx))
         goto err;
 
-    if (generate) {
+    if (!verify) {
         /* We now need to generate g */
         /* set test = p - 1 */
         if (!BN_sub(test, p, BN_value_one()))
@@ -940,7 +948,7 @@ g_only:
             goto err;
         if (!generate_unverifiable_g(ctx, mont, g, tmp, p, r0, test, &hret))
             goto err;
-    } else if (((validate_flags & FFC_PARAMS_VALIDATE_G) != 0)
+    } else if (((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0)
                && !ffc_params_validate_unverifiable_g(ctx, mont, p, q,
                                                       params->g, tmp, res)) {
         goto err;
@@ -949,7 +957,7 @@ g_only:
     if (!BN_GENCB_call(cb, 3, 1))
         goto err;
 
-    if (generate) {
+    if (!verify) {
         if (p != params->p) {
             BN_free(params->p);
             params->p = BN_dup(p);
@@ -969,32 +977,34 @@ g_only:
         params->h = hret;
     }
 pass:
-    if ((validate_flags & FFC_PARAMS_VALIDATE_G) != 0)
-        ok = FFC_PARAMS_RET_STATUS_UNVERIFIABLE_G;
+    if ((flags & FFC_PARAM_FLAG_VALIDATE_G) != 0)
+        ok = FFC_PARAM_RET_STATUS_UNVERIFIABLE_G;
     else
-        ok = FFC_PARAMS_RET_STATUS_SUCCESS;
+        ok = FFC_PARAM_RET_STATUS_SUCCESS;
 err:
     if (ctx != NULL)
         BN_CTX_end(ctx);
     BN_CTX_free(ctx);
-    EVP_MD_free(evpmd_fetch);
     BN_MONT_CTX_free(mont);
+    EVP_MD_free(md);
     return ok;
 }
 
 int ffc_params_FIPS186_4_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params,
                                   int type, size_t L, size_t N,
-                                  const EVP_MD *evpmd, int *res, BN_GENCB *cb)
+                                  int *res, BN_GENCB *cb)
 {
-    return ffc_params_FIPS186_4_gen_verify(libctx, params, type, L, N, evpmd, 0,
-                                           res, cb);
+    return ffc_params_FIPS186_4_gen_verify(libctx, params,
+                                           FFC_PARAM_MODE_GENERATE,
+                                           type, L, N, res, cb);
 }
 
 /* This should no longer be used in FIPS mode */
 int ffc_params_FIPS186_2_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params,
                                   int type, size_t L, size_t N,
-                                  const EVP_MD *evpmd, int *res, BN_GENCB *cb)
+                                  int *res, BN_GENCB *cb)
 {
-    return ffc_params_FIPS186_2_gen_verify(libctx, params, type, L, N, evpmd,
-                                           0, res, cb);
+    return ffc_params_FIPS186_2_gen_verify(libctx, params,
+                                           FFC_PARAM_MODE_GENERATE,
+                                           type, L, N, res, cb);
 }
diff --git a/crypto/ffc/ffc_params_validate.c b/crypto/ffc/ffc_params_validate.c
index 4d0a4d837f..f3df0c2b39 100644
--- a/crypto/ffc/ffc_params_validate.c
+++ b/crypto/ffc/ffc_params_validate.c
@@ -44,37 +44,37 @@ int ffc_params_validate_unverifiable_g(BN_CTX *ctx, BN_MONT_CTX *mont,
     return 1;
 }
 
-int ffc_params_FIPS186_4_validate(const FFC_PARAMS *params, int type,
-                                  const EVP_MD *evpmd, int validate_flags,
-                                  int *res, BN_GENCB *cb)
+int ffc_params_FIPS186_4_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params,
+                                  int type, int *res, BN_GENCB *cb)
 {
     size_t L, N;
 
     if (params == NULL || params->p == NULL || params->q == NULL)
-        return FFC_PARAMS_RET_STATUS_FAILED;
+        return FFC_PARAM_RET_STATUS_FAILED;
 
     /* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */
     L = BN_num_bits(params->p);
     N = BN_num_bits(params->q);
-    return ffc_params_FIPS186_4_gen_verify(NULL, (FFC_PARAMS *)params, type, L, N,
-                                           evpmd, validate_flags, res, cb);
+    return ffc_params_FIPS186_4_gen_verify(libctx, (FFC_PARAMS *)params,
+                                           FFC_PARAM_MODE_VERIFY, type,
+                                           L, N, res, cb);
 }
 
 /* This may be used in FIPS mode to validate deprecated FIPS-186-2 Params */
-int ffc_params_FIPS186_2_validate(const FFC_PARAMS *params, int type,
-                                  const EVP_MD *evpmd, int validate_flags,
-                                  int *res, BN_GENCB *cb)
+int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params,
+                                  int type, int *res, BN_GENCB *cb)
 {
     size_t L, N;
 
     if (params->p == NULL || params->q == NULL) {
         *res = FFC_CHECK_INVALID_PQ;
-        return FFC_PARAMS_RET_STATUS_FAILED;
+        return FFC_PARAM_RET_STATUS_FAILED;
     }
 
     /* A.1.1.3 Step (1..2) : L = len(p), N = len(q) */
     L = BN_num_bits(params->p);
     N = BN_num_bits(params->q);
-    return ffc_params_FIPS186_2_gen_verify(NULL, (FFC_PARAMS *)params, type, L, N,
-                                           evpmd, validate_flags, res, cb);
+    return ffc_params_FIPS186_2_gen_verify(libctx, (FFC_PARAMS *)params,
+                                           FFC_PARAM_MODE_VERIFY, type,
+                                           L, N, res, cb);
 }
diff --git a/crypto/rsa/build.info b/crypto/rsa/build.info
index 984ad775d5..1614996049 100644
--- a/crypto/rsa/build.info
+++ b/crypto/rsa/build.info
@@ -13,3 +13,7 @@ IF[{- !$disabled{'deprecated-0.9.8'} -}]
 ENDIF
 
 SOURCE[../../providers/libfips.a]=$COMMON
+
+IF[{- !$disabled{'acvp-tests'} -}]
+  SOURCE[../../providers/libfips.a]=rsa_acvp_test_params.c
+ENDIF
\ No newline at end of file
diff --git a/crypto/rsa/rsa_acvp_test_params.c b/crypto/rsa/rsa_acvp_test_params.c
new file mode 100644
index 0000000000..c1d07cb334
--- /dev/null
+++ b/crypto/rsa/rsa_acvp_test_params.c
@@ -0,0 +1,167 @@
+/*
+ * Copyright 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
+ */
+
+#include <string.h> /* memcpy */
+#include <openssl/core_names.h>
+#include <openssl/param_build.h>
+#include "crypto/rsa.h"
+#include "rsa_local.h"
+
+int rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[])
+{
+    const OSSL_PARAM *p, *s;
+    OSSL_PARAM *d, *alloc = NULL;
+    int ret = 1;
+
+    static const OSSL_PARAM settable[] = {
+        OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP, NULL, 0),
+        OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP1, NULL, 0),
+        OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XP2, NULL, 0),
+        OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ, NULL, 0),
+        OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ1, NULL, 0),
+        OSSL_PARAM_BN(OSSL_PKEY_PARAM_RSA_TEST_XQ2, NULL, 0),
+        OSSL_PARAM_END
+    };
+
+    /* Assume the first element is a required field if this feature is used */
+    p = OSSL_PARAM_locate_const(src, settable[0].key);
+    if (p == NULL)
+        return 1;
+
+    /* Zeroing here means the terminator is always set at the end */
+    alloc = OPENSSL_zalloc(sizeof(settable));
+    if (alloc == NULL)
+        return 0;
+
+    d = alloc;
+    for (s = settable; s->key != NULL; ++s) {
+        /* If src contains a key from settable then copy the src to the dest */
+        p = OSSL_PARAM_locate_const(src, s->key);
+        if (p != NULL) {
+            *d = *s; /* shallow copy from the static settable[] */
+            d->data_size = p->data_size;
+            d->data = OPENSSL_memdup(p->data, p->data_size);
+            if (d->data == NULL)
+                ret = 0;
+            ++d;
+        }
+    }
+    if (ret == 0) {
+        rsa_acvp_test_gen_params_free(alloc);
+        alloc = NULL;
+    }
+    if (*dst != NULL)
+        rsa_acvp_test_gen_params_free(*dst);
+    *dst = alloc;
+    return ret;
+}
+
+void rsa_acvp_test_gen_params_free(OSSL_PARAM *dst)
+{
+    OSSL_PARAM *p;
+
+    if (dst == NULL)
+        return;
+
+    for (p = dst; p->key != NULL; ++p) {
+        OPENSSL_free(p->data);
+        p->data = NULL;
+    }
+    OPENSSL_free(dst);
+}
+
+int rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[])
+{
+    RSA_ACVP_TEST *t;
+    const OSSL_PARAM *p;
+
+    if (r->acvp_test != NULL) {
+        rsa_acvp_test_free(r->acvp_test);
+        r->acvp_test = NULL;
+    }
+
+    t = OPENSSL_zalloc(sizeof(*t));
+    if (t == NULL)
+        return 0;
+
+    /* Set the input parameters */
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP1)) != NULL
+         && !OSSL_PARAM_get_BN(p, &t->Xp1))
+        goto err;
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP2)) != NULL
+         && !OSSL_PARAM_get_BN(p, &t->Xp2))
+        goto err;
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XP)) != NULL
+         && !OSSL_PARAM_get_BN(p, &t->Xp))
+        goto err;
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ1)) != NULL
+         && !OSSL_PARAM_get_BN(p, &t->Xq1))
+        goto err;
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ2)) != NULL
+         && !OSSL_PARAM_get_BN(p, &t->Xq2))
+        goto err;
+    if ((p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_RSA_TEST_XQ)) != NULL
+         && !OSSL_PARAM_get_BN(p, &t->Xq))
+        goto err;
+
+    /* Setup the output parameters */
+    t->p1 = BN_new();
+    t->p2 = BN_new();
+    t->q1 = BN_new();
+    t->q2 = BN_new();
+    r->acvp_test = t;
+    return 1;
+err:
+    rsa_acvp_test_free(t);
+    return 0;
+}
+
+int rsa_acvp_test_get_params(RSA *r, OSSL_PARAM params[])
+{
+    RSA_ACVP_TEST *t;
+    OSSL_PARAM *p;
+
+    if (r == NULL)
+        return 0;
+
+    t = r->acvp_test;
+    if (t != NULL) {
+        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_P1)) != NULL
+             && !OSSL_PARAM_set_BN(p, t->p1))
+                    return 0;
+        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_P2)) != NULL
+             && !OSSL_PARAM_set_BN(p, t->p2))
+                    return 0;
+        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_Q1)) != NULL
+             && !OSSL_PARAM_set_BN(p, t->q1))
+                    return 0;
+        if ((p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_RSA_TEST_Q2)) != NULL
+             && !OSSL_PARAM_set_BN(p, t->q2))
+                    return 0;
+    }
+    return 1;
+}
+
+void rsa_acvp_test_free(RSA_ACVP_TEST *t)
+{
+    if (t != NULL) {
+        BN_free(t->Xp1);
+        BN_free(t->Xp2);
+        BN_free(t->Xp);
+        BN_free(t->Xq1);
+        BN_free(t->Xq2);
+        BN_free(t->Xq);
+        BN_free(t->p1);
+        BN_free(t->p2);
+        BN_free(t->q1);
+        BN_free(t->q2);
+        OPENSSL_free(t);
+    }
+}
+
diff --git a/crypto/rsa/rsa_backend.c b/crypto/rsa/rsa_backend.c
index 7497a8579c..985a21127a 100644
--- a/crypto/rsa/rsa_backend.c
+++ b/crypto/rsa/rsa_backend.c
@@ -88,6 +88,7 @@ int rsa_fromdata(RSA *rsa, const OSSL_PARAM params[])
             goto err;
     }
 
+
     sk_BIGNUM_free(factors);
     sk_BIGNUM_free(exps);
     sk_BIGNUM_free(coeffs);
@@ -126,7 +127,7 @@ int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
         int numcoeffs = sk_BIGNUM_const_num(coeffs);
 
         /*
-         * It's permisssible to have zero primes, i.e. no CRT params.
+         * It's permissible to have zero primes, i.e. no CRT params.
          * Otherwise, there must be at least two, as many exponents,
          * and one coefficient less.
          */
@@ -145,6 +146,11 @@ int rsa_todata(RSA *rsa, OSSL_PARAM_BLD *bld, OSSL_PARAM params[])
         || !ossl_param_build_set_multi_key_bn(bld, params, rsa_mp_coeff_names,
                                               coeffs))
         goto err;
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    /* The acvp test results are not meant for export so check for bld == NULL */
+    if (bld == NULL)
+        rsa_acvp_test_get_params(rsa, params);
+#endif
     ret = 1;
  err:
     sk_BIGNUM_const_free(factors);
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index e52bce6355..1495cefa83 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -66,8 +66,8 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes,
         else
             return 0;
     }
-#endif /* FIPS_MODULE */
-    return rsa_keygen(NULL, rsa, bits, primes, e_value, cb, 0);
+#endif /* FIPS_MODUKE */
+    return rsa_keygen(rsa->libctx, rsa, bits, primes, e_value, cb, 0);
 }
 
 #ifndef FIPS_MODULE
diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c
index e80416ed3f..428cd145fa 100644
--- a/crypto/rsa/rsa_lib.c
+++ b/crypto/rsa/rsa_lib.c
@@ -162,6 +162,11 @@ void RSA_free(RSA *r)
     BN_clear_free(r->dmp1);
     BN_clear_free(r->dmq1);
     BN_clear_free(r->iqmp);
+
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    rsa_acvp_test_free(r->acvp_test);
+#endif
+
 #ifndef FIPS_MODULE
     RSA_PSS_PARAMS_free(r->pss);
     sk_RSA_PRIME_INFO_pop_free(r->prime_infos, rsa_multip_info_free);
diff --git a/crypto/rsa/rsa_local.h b/crypto/rsa/rsa_local.h
index 65fd6022f7..666e18ec65 100644
--- a/crypto/rsa/rsa_local.h
+++ b/crypto/rsa/rsa_local.h
@@ -10,7 +10,7 @@
 #ifndef OSSL_CRYPTO_RSA_LOCAL_H
 #define OSSL_CRYPTO_RSA_LOCAL_H
 
-#include <openssl/rsa.h>
+#include "crypto/rsa.h"
 #include "internal/refcount.h"
 #include "crypto/rsa.h"
 
@@ -29,6 +29,24 @@ typedef struct rsa_prime_info_st {
 DECLARE_ASN1_ITEM(RSA_PRIME_INFO)
 DEFINE_STACK_OF(RSA_PRIME_INFO)
 
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+struct rsa_acvp_test_st {
+    /* optional inputs */
+    BIGNUM *Xp1;
+    BIGNUM *Xp2;
+    BIGNUM *Xq1;
+    BIGNUM *Xq2;
+    BIGNUM *Xp;
+    BIGNUM *Xq;
+
+    /* optional outputs */
+    BIGNUM *p1;
+    BIGNUM *p2;
+    BIGNUM *q1;
+    BIGNUM *q2;
+};
+#endif
+
 struct rsa_st {
     /*
      * #legacy
@@ -58,12 +76,14 @@ struct rsa_st {
      */
     /* This is used uniquely by OpenSSL provider implementations. */
     RSA_PSS_PARAMS_30 pss_params;
-#ifndef FIPS_MODULE
-    /* This is used uniquely by rsa_ameth.c and rsa_pmeth.c. */
-    RSA_PSS_PARAMS *pss;
+
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    RSA_ACVP_TEST *acvp_test;
 #endif
 
 #ifndef FIPS_MODULE
+    /* This is used uniquely by rsa_ameth.c and rsa_pmeth.c. */
+    RSA_PSS_PARAMS *pss;
     /* for multi-prime RSA, defined in RFC 8017 */
     STACK_OF(RSA_PRIME_INFO) *prime_infos;
     /* Be careful using this if the RSA structure is shared */
@@ -172,13 +192,9 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed,
 
 int rsa_sp800_56b_derive_params_from_pq(RSA *rsa, int nbits,
                                         const BIGNUM *e, BN_CTX *ctx);
-int rsa_fips186_4_gen_prob_primes(RSA *rsa, BIGNUM *p1, BIGNUM *p2,
-                                  BIGNUM *Xpout, const BIGNUM *Xp,
-                                  const BIGNUM *Xp1, const BIGNUM *Xp2,
-                                  BIGNUM *q1, BIGNUM *q2, BIGNUM *Xqout,
-                                  const BIGNUM *Xq, const BIGNUM *Xq1,
-                                  const BIGNUM *Xq2, int nbits,
-                                  const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb);
+int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test,
+                                  int nbits, const BIGNUM *e, BN_CTX *ctx,
+                                  BN_GENCB *cb);
 
 int rsa_padding_add_SSLv23_with_libctx(OPENSSL_CTX *libctx, unsigned char *to,
                                        int tlen, const unsigned char *from,
diff --git a/crypto/rsa/rsa_sp800_56b_gen.c b/crypto/rsa/rsa_sp800_56b_gen.c
index d1673d5c98..9d7e1f1ebf 100644
--- a/crypto/rsa/rsa_sp800_56b_gen.c
+++ b/crypto/rsa/rsa_sp800_56b_gen.c
@@ -10,6 +10,7 @@
 
 #include <openssl/err.h>
 #include <openssl/bn.h>
+#include <openssl/core.h>
 #include "crypto/bn.h"
 #include "crypto/security_bits.h"
 #include "rsa_local.h"
@@ -25,20 +26,23 @@
  *
  * Params:
  *     rsa  Object used to store primes p & q.
- *     p1, p2 The returned auxiliary primes for p. If NULL they are not returned.
- *     Xpout An optionally returned random number used during generation of p.
- *     Xp An optional passed in value (that is random number used during
- *        generation of p).
- *     Xp1, Xp2 Optionally passed in randomly generated numbers from which
- *              auxiliary primes p1 & p2 are calculated. If NULL these values
- *              are generated internally.
- *     q1, q2 The returned auxiliary primes for q. If NULL they are not returned.
- *     Xqout An optionally returned random number used during generation of q.
- *     Xq An optional passed in value (that is random number used during
- *        generation of q).
- *     Xq1, Xq2 Optionally passed in randomly generated numbers from which
- *              auxiliary primes q1 & q2 are calculated. If NULL these values
- *              are generated internally.
+ *     test Object used for CAVS testing only.that contains..
+ *       p1, p2 The returned auxiliary primes for p.
+ *              If NULL they are not returned.
+ *       Xpout An optionally returned random number used during generation of p.
+ *       Xp An optional passed in value (that is random number used during
+ *          generation of p).
+ *       Xp1, Xp2 Optionally passed in randomly generated numbers from which
+ *                auxiliary primes p1 & p2 are calculated. If NULL these values
+ *                are generated internally.
+ *       q1, q2 The returned auxiliary primes for q.
+ *              If NULL they are not returned.
+ *       Xqout An optionally returned random number used during generation of q.
+ *       Xq An optional passed in value (that is random number used during
+ *          generation of q).
+ *       Xq1, Xq2 Optionally passed in randomly generated numbers from which
+ *                auxiliary primes q1 & q2 are calculated. If NULL these values
+ *                are generated internally.
  *     nbits The key size in bits (The size of the modulus n).
  *     e The public exponent.
  *     ctx A BN_CTX object.
@@ -49,16 +53,34 @@
  *     Xp, Xp1, Xp2, Xq, Xq1, Xq2 are optionally passed in.
  *     (Required for CAVS testing).
  */
-int rsa_fips186_4_gen_prob_primes(RSA *rsa, BIGNUM *p1, BIGNUM *p2,
-                                  BIGNUM *Xpout, const BIGNUM *Xp,
-                                  const BIGNUM *Xp1, const BIGNUM *Xp2,
-                                  BIGNUM *q1, BIGNUM *q2, BIGNUM *Xqout,
-                                  const BIGNUM *Xq, const BIGNUM *Xq1,
-                                  const BIGNUM *Xq2, int nbits,
+int rsa_fips186_4_gen_prob_primes(RSA *rsa, RSA_ACVP_TEST *test, int nbits,
                                   const BIGNUM *e, BN_CTX *ctx, BN_GENCB *cb)
 {
     int ret = 0, ok;
+    /* Temp allocated BIGNUMS */
     BIGNUM *Xpo = NULL, *Xqo = NULL, *tmp = NULL;
+    /* Intermediate BIGNUMS that can be returned for testing */
+    BIGNUM *p1 = NULL, *p2 = NULL;
+    BIGNUM *q1 = NULL, *q2 = NULL;
+    /* Intermediate BIGNUMS that can be input for testing */
+    BIGNUM *Xpout = NULL, *Xqout = NULL;
+    BIGNUM *Xp = NULL, *Xp1 = NULL, *Xp2 = NULL;
+    BIGNUM *Xq = NULL, *Xq1 = NULL, *Xq2 = NULL;
+
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    if (test != NULL) {
+        Xp1 = test->Xp1;
+        Xp2 = test->Xp2;
+        Xq1 = test->Xq1;
+        Xq2 = test->Xq2;
+        Xp = test->Xp;
+        Xq = test->Xq;
+        p1 = test->p1;
+        p2 = test->p2;
+        q1 = test->q1;
+        q2 = test->q2;
+    }
+#endif
 
     /* (Step 1) Check key length
      * NOTE: SP800-131A Rev1 Disallows key lengths of < 2048 bits for RSA
@@ -294,6 +316,11 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed,
     int ok;
     BN_CTX *ctx = NULL;
     BIGNUM *e = NULL;
+    RSA_ACVP_TEST *info = NULL;
+
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    info = rsa->acvp_test;
+#endif
 
     /* (Steps 1a-1b) : Currently ignores the strength check */
     if (!rsa_sp800_56b_validate_strength(nbits, -1))
@@ -311,13 +338,12 @@ int rsa_sp800_56b_generate_key(RSA *rsa, int nbits, const BIGNUM *efixed,
     } else {
         e = (BIGNUM *)efixed;
     }
-    /* (Step 1c) fixed exponent is checked later . */
+    /* (Step 1c) fixed exponent is checked later .*/
 
     for (;;) {
         /* (Step 2) Generate prime factors */
-        if (!rsa_fips186_4_gen_prob_primes(rsa, NULL, NULL, NULL, NULL, NULL,
-                                           NULL, NULL, NULL, NULL, NULL, NULL,
-                                           NULL, nbits, e, ctx, cb))
+        if (!rsa_fips186_4_gen_prob_primes(rsa, info, nbits, e, ctx,
+                                           cb))
             goto err;
         /* (Steps 3-5) Compute params d, n, dP, dQ, qInv */
         ok = rsa_sp800_56b_derive_params_from_pq(rsa, nbits, e, ctx);
diff --git a/doc/man7/EVP_PKEY-RSA.pod b/doc/man7/EVP_PKEY-RSA.pod
index 28f61e4066..428aa613a2 100644
--- a/doc/man7/EVP_PKEY-RSA.pod
+++ b/doc/man7/EVP_PKEY-RSA.pod
@@ -131,10 +131,63 @@ For legacy reasons a value of 3 is currently accepted but is deprecated.
 
 =back
 
+=head2 RSA key generation parameters for FIPS module testing
+
+When generating RSA keys, the following additional key generation parameters may
+be used for algorithm testing purposes only. Do not use these to generate
+RSA keys for a production environment.
+
+=over 4
+
+=item "xp" (B<OSSL_PKEY_PARAM_RSA_TEST_XP>) <unsigned integer>
+
+=item "xq" (B<OSSL_PKEY_PARAM_RSA_TEST_XQ>) <unsigned integer>
+
+These 2 fields are normally randomly generated and are used to generate "p" and
+"q".
+
+=item "xp1" (B<OSSL_PKEY_PARAM_RSA_TEST_XP1>) <unsigned integer>
+
+=item "xp2" (B<OSSL_PKEY_PARAM_RSA_TEST_XP2>) <unsigned integer>
+
+=item "xq1" (B<OSSL_PKEY_PARAM_RSA_TEST_XQ1>) <unsigned integer>
+
+=item "xq2" (B<OSSL_PKEY_PARAM_RSA_TEST_XQ2>) <unsigned integer>
+
+These 4 fields are normally randomly generated. The prime factors "p1", "p2",
+"q1" and "q2" are determined from these values.
+
+=back
+
+=head2 RSA key parameters for FIPS module testing
+
+The following intermediate values can be retrieved only if the values
+specified in L</"RSA key generation parameters for FIPS module testing"> are set.
+These should not be accessed in a production environment.
+
+=over 4
+
+=item "p1" (B<OSSL_PKEY_PARAM_RSA_TEST_P1>) <unsigned integer>
+
+=item "p2" (B<OSSL_PKEY_PARAM_RSA_TEST_P2>) <unsigned integer>
+
+=item "q1" (B<OSSL_PKEY_PARAM_RSA_TEST_Q1>) <unsigned integer>
+
+=item "q2" (B<OSSL_PKEY_PARAM_RSA_TEST_Q2>) <unsigned integer>
+
+The auxiliary probable primes.
+
+=back
+
 =head1 CONFORMING TO
 
 =over 4
 
+=item FIPS186-4
+
+Section B.3.6  Generation of Probable Primes with Conditions Based on
+Auxiliary Probable Primes
+
 =item RFC 8017, excluding RSA-PSS and RSA-OAEP
 
 =for comment RSA-PSS, and probably also RSA-OAEP, need separate keytypes,
diff --git a/include/crypto/dh.h b/include/crypto/dh.h
index f67b4e01cd..22847dd1e0 100644
--- a/include/crypto/dh.h
+++ b/include/crypto/dh.h
@@ -14,8 +14,8 @@
 DH *dh_new_by_nid_with_libctx(OPENSSL_CTX *libctx, int nid);
 DH *dh_new_with_libctx(OPENSSL_CTX *libctx);
 
-int dh_generate_ffc_parameters(DH *dh, int type, int pbits,
-                               int qbits, EVP_MD *md, BN_GENCB *cb);
+int dh_generate_ffc_parameters(DH *dh, int type, int pbits, int qbits,
+                               BN_GENCB *cb);
 int dh_generate_public_key(BN_CTX *ctx, DH *dh, const BIGNUM *priv_key,
                            BIGNUM *pub_key);
 int dh_get_named_group_uid_from_size(int pbits);
diff --git a/include/crypto/dsa.h b/include/crypto/dsa.h
index 1a278fecf2..59c94a1740 100644
--- a/include/crypto/dsa.h
+++ b/include/crypto/dsa.h
@@ -16,8 +16,8 @@
 
 DSA *dsa_new_with_ctx(OPENSSL_CTX *libctx);
 
-int dsa_generate_ffc_parameters(DSA *dsa, int type,
-                                int pbits, int qbits, EVP_MD *md, BN_GENCB *cb);
+int dsa_generate_ffc_parameters(DSA *dsa, int type, int pbits, int qbits,
+                                BN_GENCB *cb);
 
 int dsa_sign_int(int type, const unsigned char *dgst,
                  int dlen, unsigned char *sig, unsigned int *siglen, DSA *dsa);
diff --git a/include/crypto/rsa.h b/include/crypto/rsa.h
index 5d7a6e515d..9469ec9233 100644
--- a/include/crypto/rsa.h
+++ b/include/crypto/rsa.h
@@ -10,8 +10,8 @@
 #ifndef OSSL_INTERNAL_RSA_H
 # define OSSL_INTERNAL_RSA_H
 
-#include <openssl/core.h>
-#include <openssl/rsa.h>
+# include <openssl/core.h>
+# include <openssl/rsa.h>
 
 typedef struct rsa_pss_params_30_st {
     int hash_algorithm_nid;
@@ -93,4 +93,16 @@ extern const char *rsa_mp_factor_names[];
 extern const char *rsa_mp_exp_names[];
 extern const char *rsa_mp_coeff_names[];
 
+# if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+int rsa_acvp_test_gen_params_new(OSSL_PARAM **dst, const OSSL_PARAM src[]);
+void rsa_acvp_test_gen_params_free(OSSL_PARAM *dst);
+
+int rsa_acvp_test_set_params(RSA *r, const OSSL_PARAM params[]);
+int rsa_acvp_test_get_params(RSA *r, OSSL_PARAM params[]);
+typedef struct rsa_acvp_test_st RSA_ACVP_TEST;
+void rsa_acvp_test_free(RSA_ACVP_TEST *t);
+# else
+# define RSA_ACVP_TEST void
+# endif
+
 #endif
diff --git a/include/internal/ffc.h b/include/internal/ffc.h
index e4c4dce8fa..2ed5d72c5c 100644
--- a/include/internal/ffc.h
+++ b/include/internal/ffc.h
@@ -16,6 +16,7 @@
 # include <openssl/dh.h> /* Uses Error codes from DH */
 # include <openssl/params.h>
 # include <openssl/param_build.h>
+# include "internal/sizes.h"
 
 /* Default value for gindex when canonical generation of g is not used */
 # define FFC_UNVERIFIABLE_GINDEX -1
@@ -24,17 +25,24 @@
 # define FFC_PARAM_TYPE_DSA  0
 # define FFC_PARAM_TYPE_DH   1
 
+/*
+ * The mode used by functions that share code for both generation and
+ * verification. See ffc_params_FIPS186_4_gen_verify().
+ */
+#define FFC_PARAM_MODE_VERIFY   0
+#define FFC_PARAM_MODE_GENERATE 1
+
 /* Return codes for generation and validation of FFC parameters */
-#define FFC_PARAMS_RET_STATUS_FAILED         0
-#define FFC_PARAMS_RET_STATUS_SUCCESS        1
+#define FFC_PARAM_RET_STATUS_FAILED         0
+#define FFC_PARAM_RET_STATUS_SUCCESS        1
 /* Returned if validating and g is only partially verifiable */
-#define FFC_PARAMS_RET_STATUS_UNVERIFIABLE_G 2
+#define FFC_PARAM_RET_STATUS_UNVERIFIABLE_G 2
 
 /* Validation flags */
-# define FFC_PARAMS_GENERATE     0x00
-# define FFC_PARAMS_VALIDATE_PQ  0x01
-# define FFC_PARAMS_VALIDATE_G   0x02
-# define FFC_PARAMS_VALIDATE_ALL (FFC_PARAMS_VALIDATE_PQ | FFC_PARAMS_VALIDATE_G)
+# define FFC_PARAM_FLAG_VALIDATE_PQ  0x01
+# define FFC_PARAM_FLAG_VALIDATE_G   0x02
+# define FFC_PARAM_FLAG_VALIDATE_ALL                                           \
+    (FFC_PARAM_FLAG_VALIDATE_PQ | FFC_PARAM_FLAG_VALIDATE_G)
 
 /*
  * NB: These values must align with the equivalently named macros in
@@ -94,6 +102,14 @@ typedef struct ffc_params_st {
      */
     int gindex;
     int h; /* loop counter for unverifiable g */
+
+    unsigned int flags; /* See FFC_PARAM_FLAG_VALIDATE_ALL */
+    /*
+     * The digest to use for generation or validation. If this value is NULL,
+     * then the digest is chosen using the value of N.
+     */
+    const char *mdname;
+    const char *mdprops;
 } FFC_PARAMS;
 
 void ffc_params_init(FFC_PARAMS *params);
@@ -107,6 +123,8 @@ int ffc_params_set_seed(FFC_PARAMS *params,
 void ffc_params_set_gindex(FFC_PARAMS *params, int index);
 void ffc_params_set_pcounter(FFC_PARAMS *params, int index);
 void ffc_params_set_h(FFC_PARAMS *params, int index);
+void ffc_params_set_flags(FFC_PARAMS *params, unsigned int flags);
+int ffc_set_digest(FFC_PARAMS *params, const char *alg, const char *props);
 
 int ffc_params_set_validate_params(FFC_PARAMS *params,
                                    const unsigned char *seed, size_t seedlen,
@@ -125,27 +143,22 @@ int ffc_params_print(BIO *bp, const FFC_PARAMS *ffc, int indent);
 
 int ffc_params_FIPS186_4_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params,
                                   int type, size_t L, size_t N,
-                                  const EVP_MD *evpmd, int *res, BN_GENCB *cb);
+                                  int *res, BN_GENCB *cb);
 int ffc_params_FIPS186_2_generate(OPENSSL_CTX *libctx, FFC_PARAMS *params,
                                   int type, size_t L, size_t N,
-                                  const EVP_MD *evpmd, int *res, BN_GENCB *cb);
+                                  int *res, BN_GENCB *cb);
 
 int ffc_params_FIPS186_4_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
-                                    int type, size_t L, size_t N,
-                                    const EVP_MD *evpmd, int validate_flags,
+                                    int mode, int type, size_t L, size_t N,
                                     int *res, BN_GENCB *cb);
 int ffc_params_FIPS186_2_gen_verify(OPENSSL_CTX *libctx, FFC_PARAMS *params,
-                                    int type, size_t L, size_t N,
-                                    const EVP_MD *evpmd, int validate_flags,
+                                    int mode, int type, size_t L, size_t N,
                                     int *res, BN_GENCB *cb);
 
-int ffc_params_FIPS186_4_validate(const FFC_PARAMS *params, int type,
-                                  const EVP_MD *evpmd, int validate_flags,
-                                  int *res, BN_GENCB *cb);
-int ffc_params_FIPS186_2_validate(const FFC_PARAMS *params, int type,
-                                  const EVP_MD *evpmd, int validate_flags,
-                                  int *res, BN_GENCB *cb);
-
+int ffc_params_FIPS186_4_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params,
+                                  int type, int *res, BN_GENCB *cb);
+int ffc_params_FIPS186_2_validate(OPENSSL_CTX *libctx, const FFC_PARAMS *params,
+                                  int type, int *res, BN_GENCB *cb);
 
 int ffc_generate_private_key(BN_CTX *ctx, const FFC_PARAMS *params,
                              int N, int s, BIGNUM *priv);
@@ -168,5 +181,7 @@ int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name);
 int ffc_named_group_to_uid(const char *name);
 const char *ffc_named_group_from_uid(int nid);
 int ffc_set_group_pqg(FFC_PARAMS *ffc, const char *group_name);
+const char *ffc_params_flags_to_name(int flags);
+int ffc_params_flags_from_name(const char *name);
 
 #endif /* OSSL_INTERNAL_FFC_H */
diff --git a/include/openssl/core_names.h b/include/openssl/core_names.h
index f04168e819..fa6b7a9547 100644
--- a/include/openssl/core_names.h
+++ b/include/openssl/core_names.h
@@ -201,22 +201,30 @@ extern "C" {
 #define OSSL_PKEY_PARAM_PRIV_KEY            "priv"
 
 /* Diffie-Hellman/DSA Parameters */
-#define OSSL_PKEY_PARAM_FFC_P        "p"
-#define OSSL_PKEY_PARAM_FFC_G        "g"
-#define OSSL_PKEY_PARAM_FFC_Q        "q"
-#define OSSL_PKEY_PARAM_FFC_GINDEX   "gindex"
-#define OSSL_PKEY_PARAM_FFC_PCOUNTER "pcounter"
-#define OSSL_PKEY_PARAM_FFC_SEED     "seed"
-#define OSSL_PKEY_PARAM_FFC_COFACTOR "j"
-#define OSSL_PKEY_PARAM_FFC_H        "hindex"
+#define OSSL_PKEY_PARAM_FFC_P               "p"
+#define OSSL_PKEY_PARAM_FFC_G               "g"
+#define OSSL_PKEY_PARAM_FFC_Q               "q"
+#define OSSL_PKEY_PARAM_FFC_GINDEX          "gindex"
+#define OSSL_PKEY_PARAM_FFC_PCOUNTER        "pcounter"
+#define OSSL_PKEY_PARAM_FFC_SEED            "seed"
+#define OSSL_PKEY_PARAM_FFC_COFACTOR        "j"
+#define OSSL_PKEY_PARAM_FFC_H               "hindex"
+#define OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE   "valid-type"
+
+/* Diffie-Hellman/DSA Parameters parameter validation types */
+#define OSSL_FFC_PARAM_VALIDATE_PQ          "validate-pq"
+#define OSSL_FFC_PARAM_VALIDATE_G           "validate-g"
+#define OSSL_FFC_PARAM_VALIDATE_PQG         "validate-pqg"
 
 /* Diffie-Hellman params */
-#define OSSL_PKEY_PARAM_DH_GROUP     "group"
-#define OSSL_PKEY_PARAM_DH_GENERATOR "safeprime-generator"
-#define OSSL_PKEY_PARAM_DH_PRIV_LEN   "priv_len"
+#define OSSL_PKEY_PARAM_DH_GROUP            "group"
+#define OSSL_PKEY_PARAM_DH_GENERATOR        "safeprime-generator"
+#define OSSL_PKEY_PARAM_DH_PRIV_LEN         "priv_len"
 
 /* Elliptic Curve Domain Parameters */
 #define OSSL_PKEY_PARAM_EC_NAME      "curve-name"
+#define OSSL_PKEY_PARAM_EC_PUB_X     "qx"
+#define OSSL_PKEY_PARAM_EC_PUB_Y     "qy"
 
 /* Elliptic Curve Key Parameters */
 #define OSSL_PKEY_PARAM_USE_COFACTOR_FLAG "use-cofactor-flag"
@@ -334,7 +342,6 @@ extern "C" {
 #define OSSL_SIGNATURE_PARAM_MGF1_PROPERTIES    \
     OSSL_PKEY_PARAM_MGF1_PROPERTIES
 #define OSSL_SIGNATURE_PARAM_DIGEST_SIZE        OSSL_PKEY_PARAM_DIGEST_SIZE
-#define OSSL_SIGNATURE_PARAM_KAT                "kat"
 
 /* Asym cipher parameters */
 #define OSSL_ASYM_CIPHER_PARAM_PAD_MODE                 OSSL_PKEY_PARAM_PAD_MODE
@@ -364,6 +371,19 @@ extern "C" {
 #define OSSL_GEN_PARAM_POTENTIAL            "potential" /* integer */
 #define OSSL_GEN_PARAM_ITERATION            "iteration" /* integer */
 
+/* ACVP Test parameters : These should not be used normally */
+#define OSSL_PKEY_PARAM_RSA_TEST_XP1 "xp1"
+#define OSSL_PKEY_PARAM_RSA_TEST_XP2 "xp2"
+#define OSSL_PKEY_PARAM_RSA_TEST_XP  "xp"
+#define OSSL_PKEY_PARAM_RSA_TEST_XQ1 "xq1"
+#define OSSL_PKEY_PARAM_RSA_TEST_XQ2 "xq2"
+#define OSSL_PKEY_PARAM_RSA_TEST_XQ  "xq"
+#define OSSL_PKEY_PARAM_RSA_TEST_P1  "p1"
+#define OSSL_PKEY_PARAM_RSA_TEST_P2  "p2"
+#define OSSL_PKEY_PARAM_RSA_TEST_Q1  "q1"
+#define OSSL_PKEY_PARAM_RSA_TEST_Q2  "q2"
+#define OSSL_SIGNATURE_PARAM_KAT "kat"
+
 # ifdef __cplusplus
 }
 # endif
diff --git a/providers/implementations/keymgmt/dh_kmgmt.c b/providers/implementations/keymgmt/dh_kmgmt.c
index 0dd1796dc0..c81d437dae 100644
--- a/providers/implementations/keymgmt/dh_kmgmt.c
+++ b/providers/implementations/keymgmt/dh_kmgmt.c
@@ -59,7 +59,6 @@ struct dh_gen_ctx {
     int group_nid;
     size_t pbits;
     size_t qbits;
-    EVP_MD *md;
     unsigned char *seed; /* optional FIPS186-4 param for testing */
     size_t seedlen;
     int gindex; /* optional  FIPS186-4 generator index (ignored if -1) */
@@ -69,6 +68,8 @@ struct dh_gen_ctx {
     int hindex;
     int priv_len;
 
+    const char *mdname;
+    const char *mdprops;
     OSSL_CALLBACK *cb;
     void *cbarg;
 };
@@ -411,7 +412,7 @@ static void *dh_gen_init(void *provctx, int selection)
         gctx->libctx = libctx;
         gctx->pbits = 2048;
         gctx->qbits = 224;
-        gctx->md = NULL;
+        gctx->mdname = NULL;
         gctx->gen_type = DH_PARAMGEN_TYPE_FIPS_186_4;
         gctx->gindex = -1;
         gctx->hindex = 0;
@@ -498,20 +499,15 @@ static int dh_gen_set_params(void *genctx, const OSSL_PARAM params[])
         return 0;
     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
     if (p != NULL) {
-        const OSSL_PARAM *p1;
-        char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' };
-        char *str = mdprops;
-
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
-        p1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
-        if (p1 != NULL
-            && !OSSL_PARAM_get_utf8_string(p1, &str, sizeof(mdprops)))
-            return 0;
-        EVP_MD_free(gctx->md);
-        gctx->md = EVP_MD_fetch(gctx->libctx, p->data, mdprops);
-        if (gctx->md == NULL)
+        gctx->mdname = p->data;
+    }
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
+    if (p != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
+        gctx->mdprops = p->data;
     }
     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_DH_PRIV_LEN);
     if (p != NULL && !OSSL_PARAM_get_int(p, &gctx->priv_len))
@@ -592,6 +588,10 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
         } else if (gctx->hindex != 0) {
             ffc_params_set_h(ffc, gctx->hindex);
         }
+        if (gctx->mdname != NULL) {
+            if (!ffc_set_digest(ffc, gctx->mdname, gctx->mdprops))
+                goto end;
+        }
         gctx->cb = osslcb;
         gctx->cbarg = cbarg;
         gencb = BN_GENCB_new();
@@ -609,7 +609,7 @@ static void *dh_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
                                                 gctx->generator, gencb);
             else
                 ret = dh_generate_ffc_parameters(dh, gctx->gen_type, gctx->pbits,
-                                                 gctx->qbits, gctx->md, gencb);
+                                                 gctx->qbits, gencb);
             if (ret <= 0)
                 goto end;
         }
@@ -641,7 +641,6 @@ static void dh_gen_cleanup(void *genctx)
         return;
 
     OPENSSL_clear_free(gctx->seed, gctx->seedlen);
-    EVP_MD_free(gctx->md);
     OPENSSL_free(gctx);
 }
 
diff --git a/providers/implementations/keymgmt/dsa_kmgmt.c b/providers/implementations/keymgmt/dsa_kmgmt.c
index af8361fb28..5fa3e08af9 100644
--- a/providers/implementations/keymgmt/dsa_kmgmt.c
+++ b/providers/implementations/keymgmt/dsa_kmgmt.c
@@ -56,13 +56,14 @@ struct dsa_gen_ctx {
     /* All these parameters are used for parameter generation only */
     size_t pbits;
     size_t qbits;
-    EVP_MD *md;
     unsigned char *seed; /* optional FIPS186-4 param for testing */
     size_t seedlen;
     int gindex; /* optional  FIPS186-4 generator index (ignored if -1) */
     int gen_type; /* DSA_PARAMGEN_TYPE_FIPS_186_2 or DSA_PARAMGEN_TYPE_FIPS_186_4 */
     int pcounter;
     int hindex;
+    const char *mdname;
+    const char *mdprops;
     OSSL_CALLBACK *cb;
     void *cbarg;
 };
@@ -364,7 +365,6 @@ static void *dsa_gen_init(void *provctx, int selection)
         gctx->libctx = libctx;
         gctx->pbits = 2048;
         gctx->qbits = 224;
-        gctx->md = NULL;
         gctx->gen_type = DSA_PARAMGEN_TYPE_FIPS_186_4;
         gctx->gindex = -1;
         gctx->pcounter = -1;
@@ -440,21 +440,15 @@ static int dsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
         return 0;
     p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST);
     if (p != NULL) {
-        const OSSL_PARAM *p1;
-        char mdprops[OSSL_MAX_PROPQUERY_SIZE] = { '\0' };
-        char *str = mdprops;
-
         if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
-        p1 = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
-        if (p1 != NULL) {
-            if (!OSSL_PARAM_get_utf8_string(p1, &str, sizeof(mdprops)))
-                return 0;
-        }
-        EVP_MD_free(gctx->md);
-        gctx->md = EVP_MD_fetch(gctx->libctx, p->data, mdprops);
-        if (gctx->md == NULL)
+        gctx->mdname = p->data;
+    }
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_FFC_DIGEST_PROPS);
+    if (p != NULL) {
+        if (p->data_type != OSSL_PARAM_UTF8_STRING)
             return 0;
+        gctx->mdprops = p->data;
     }
     return 1;
 }
@@ -523,10 +517,14 @@ static void *dsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
     } else if (gctx->hindex != 0) {
         ffc_params_set_h(ffc, gctx->hindex);
     }
+    if (gctx->mdname != NULL) {
+        if (!ffc_set_digest(ffc, gctx->mdname, gctx->mdprops))
+            goto end;
+    }
     if ((gctx->selection & OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS) != 0) {
 
          if (dsa_generate_ffc_parameters(dsa, gctx->gen_type,
-                                         gctx->pbits, gctx->qbits, gctx->md,
+                                         gctx->pbits, gctx->qbits,
                                          gencb) <= 0)
              goto end;
     }
@@ -556,7 +554,6 @@ static void dsa_gen_cleanup(void *genctx)
         return;
 
     OPENSSL_clear_free(gctx->seed, gctx->seedlen);
-    EVP_MD_free(gctx->md);
     OPENSSL_free(gctx);
 }
 
diff --git a/providers/implementations/keymgmt/ec_kmgmt.c b/providers/implementations/keymgmt/ec_kmgmt.c
index 7e3220739f..d926ec2bd2 100644
--- a/providers/implementations/keymgmt/ec_kmgmt.c
+++ b/providers/implementations/keymgmt/ec_kmgmt.c
@@ -110,6 +110,7 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
                   OSSL_PARAM params[], int include_private,
                   unsigned char **pub_key)
 {
+    BIGNUM *x = NULL, *y = NULL;
     const BIGNUM *priv_key = NULL;
     const EC_POINT *pub_point = NULL;
     const EC_GROUP *ecg = NULL;
@@ -125,6 +126,7 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
     pub_point = EC_KEY_get0_public_key(eckey);
 
     if (pub_point != NULL) {
+        OSSL_PARAM *p = NULL, *px = NULL, *py = NULL;
         /*
          * EC_POINT_point2buf() can generate random numbers in some
          * implementations so we need to ensure we use the correct libctx.
@@ -133,14 +135,41 @@ int key_to_params(const EC_KEY *eckey, OSSL_PARAM_BLD *tmpl,
         if (bnctx == NULL)
             goto err;
 
-        /* convert pub_point to a octet string according to the SECG standard */
-        if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
-                                              POINT_CONVERSION_COMPRESSED,
-                                              pub_key, bnctx)) == 0
-            || !ossl_param_build_set_octet_string(tmpl, params,
-                                                  OSSL_PKEY_PARAM_PUB_KEY,
-                                                  *pub_key, pub_key_len))
-            goto err;
+
+        /* If we are doing a get then check first before decoding the point */
+        if (tmpl == NULL) {
+            p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PUB_KEY);
+            px = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_X);
+            py = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_EC_PUB_Y);
+        }
+
+        if (p != NULL || tmpl != NULL) {
+            /* convert pub_point to a octet string according to the SECG standard */
+            if ((pub_key_len = EC_POINT_point2buf(ecg, pub_point,
+                                                  POINT_CONVERSION_COMPRESSED,
+                                                  pub_key, bnctx)) == 0
+                || !ossl_param_build_set_octet_string(tmpl, p,
+                                                      OSSL_PKEY_PARAM_PUB_KEY,
+                                                      *pub_key, pub_key_len))
+                goto err;
+        }
+        if (px != NULL || py != NULL) {
+            if (px != NULL)
+                x = BN_CTX_get(bnctx);
+            if (py != NULL)
+                y = BN_CTX_get(bnctx);
+
+            if (!EC_POINT_get_affine_coordinates(ecg, pub_point, x, y, bnctx))
+                goto err;
+            if (px != NULL
+                && !ossl_param_build_set_bn(tmpl, px,
+                                            OSSL_PKEY_PARAM_EC_PUB_X, x))
+                goto err;
+            if (py != NULL
+                && !ossl_param_build_set_bn(tmpl, py,
+                                            OSSL_PKEY_PARAM_EC_PUB_Y, y))
+                goto err;
+        }
     }
 
     if (priv_key != NULL && include_private) {
@@ -532,6 +561,8 @@ static const OSSL_PARAM ec_known_gettable_params[] = {
     OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_TLS_ENCODED_PT, NULL, 0),
     EC_IMEXPORTABLE_DOM_PARAMETERS,
     EC_IMEXPORTABLE_PUBLIC_KEY,
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_X, NULL, 0),
+    OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_EC_PUB_Y, NULL, 0),
     EC_IMEXPORTABLE_PRIVATE_KEY,
     EC_IMEXPORTABLE_OTHER_PARAMETERS,
     OSSL_PARAM_END
diff --git a/providers/implementations/keymgmt/rsa_kmgmt.c b/providers/implementations/keymgmt/rsa_kmgmt.c
index 3091c1dee0..313b9c292d 100644
--- a/providers/implementations/keymgmt/rsa_kmgmt.c
+++ b/providers/implementations/keymgmt/rsa_kmgmt.c
@@ -380,6 +380,11 @@ struct rsa_gen_ctx {
     /* For generation callback */
     OSSL_CALLBACK *cb;
     void *cbarg;
+
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    /* ACVP test parameters */
+    OSSL_PARAM *acvp_test_params;
+#endif
 };
 
 static int rsa_gencb(int p, int n, BN_GENCB *cb)
@@ -389,7 +394,6 @@ static int rsa_gencb(int p, int n, BN_GENCB *cb)
 
     params[0] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_POTENTIAL, &p);
     params[1] = OSSL_PARAM_construct_int(OSSL_GEN_PARAM_ITERATION, &n);
-
     return gctx->cb(params, gctx->cbarg);
 }
 
@@ -451,6 +455,11 @@ static int rsa_gen_set_params(void *genctx, const OSSL_PARAM params[])
         && !pss_params_fromdata(&gctx->pss_params, params, gctx->rsa_type,
                                 gctx->libctx))
         return 0;
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    /* Any ACVP test related parameters are copied into a params[] */
+    if (!rsa_acvp_test_gen_params_new(&gctx->acvp_test_params, params))
+        return 0;
+#endif
     return 1;
 }
 
@@ -525,6 +534,13 @@ static void *rsa_gen(void *genctx, OSSL_CALLBACK *osslcb, void *cbarg)
     if (gencb != NULL)
         BN_GENCB_set(gencb, rsa_gencb, genctx);
 
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    if (gctx->acvp_test_params != NULL) {
+        if (!rsa_acvp_test_set_params(rsa_tmp, gctx->acvp_test_params))
+            goto err;
+    }
+#endif
+
     if (!RSA_generate_multi_prime_key(rsa_tmp,
                                       (int)gctx->nbits, (int)gctx->primes,
                                       gctx->pub_exp, gencb))
@@ -551,7 +567,10 @@ static void rsa_gen_cleanup(void *genctx)
 
     if (gctx == NULL)
         return;
-
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    rsa_acvp_test_gen_params_free(gctx->acvp_test_params);
+    gctx->acvp_test_params = NULL;
+#endif
     BN_clear_free(gctx->pub_exp);
     OPENSSL_free(gctx);
 }
diff --git a/providers/implementations/signature/build.info b/providers/implementations/signature/build.info
index dbe0876a0e..0e7765ae24 100644
--- a/providers/implementations/signature/build.info
+++ b/providers/implementations/signature/build.info
@@ -3,7 +3,6 @@
 
 $DSA_GOAL=../../libimplementations.a
 $EC_GOAL=../../libimplementations.a
-$ECDSA_GOAL=../../libimplementations.a
 
 IF[{- !$disabled{dsa} -}]
   SOURCE[$DSA_GOAL]=dsa.c
@@ -11,7 +10,8 @@ ENDIF
 
 IF[{- !$disabled{ec} -}]
   SOURCE[$EC_GOAL]=eddsa.c
-  SOURCE[$ECDSA_GOAL]=ecdsa.c
+  SOURCE[../../libfips.a]=ecdsa.c
+  SOURCE[../../libnonfips.a]=ecdsa.c
 ENDIF
 
 SOURCE[../../libfips.a]=rsa.c
diff --git a/providers/implementations/signature/dsa.c b/providers/implementations/signature/dsa.c
index de6aac670b..a4902babcb 100644
--- a/providers/implementations/signature/dsa.c
+++ b/providers/implementations/signature/dsa.c
@@ -338,13 +338,17 @@ int dsa_digest_verify_final(void *vpdsactx, const unsigned char *sig,
 
 static void dsa_freectx(void *vpdsactx)
 {
-    PROV_DSA_CTX *pdsactx = (PROV_DSA_CTX *)vpdsactx;
-
-    DSA_free(pdsactx->dsa);
-    EVP_MD_CTX_free(pdsactx->mdctx);
-    EVP_MD_free(pdsactx->md);
-
-    OPENSSL_free(pdsactx);
+    PROV_DSA_CTX *ctx = (PROV_DSA_CTX *)vpdsactx;
+
+    OPENSSL_free(ctx->propq);
+    EVP_MD_CTX_free(ctx->mdctx);
+    EVP_MD_free(ctx->md);
+    ctx->propq = NULL;
+    ctx->mdctx = NULL;
+    ctx->md = NULL;
+    ctx->mdsize = 0;
+    DSA_free(ctx->dsa);
+    OPENSSL_free(ctx);
 }
 
 static void *dsa_dupctx(void *vpdsactx)
diff --git a/providers/implementations/signature/ecdsa.c b/providers/implementations/signature/ecdsa.c
index d96f597a92..61a13f4f2f 100644
--- a/providers/implementations/signature/ecdsa.c
+++ b/providers/implementations/signature/ecdsa.c
@@ -72,14 +72,6 @@ typedef struct {
 
     EVP_MD *md;
     EVP_MD_CTX *mdctx;
-    /*
-     * This indicates that KAT (CAVS) test is running. Externally an app will
-     * override the random callback such that the generated private key and k
-     * are known.
-     * Normal operation will loop to choose a new k if the signature is not
-     * valid - but for this mode of operation it forces a failure instead.
-     */
-    unsigned int kattest;
     /*
      * Internally used to cache the results of calling the EC group
      * sign_setup() methods which are then passed to the sign operation.
@@ -89,6 +81,16 @@ typedef struct {
      */
     BIGNUM *kinv;
     BIGNUM *r;
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
+    /*
+     * This indicates that KAT (CAVS) test is running. Externally an app will
+     * override the random callback such that the generated private key and k
+     * are known.
+     * Normal operation will loop to choose a new k if the signature is not
+     * valid - but for this mode of operation it forces a failure instead.
+     */
+    unsigned int kattest;
+#endif
 } PROV_ECDSA_CTX;
 
 static void *ecdsa_newctx(void *provctx, const char *propq)
@@ -131,8 +133,10 @@ static int ecdsa_sign(void *vctx, unsigned char *sig, size_t *siglen,
         return 1;
     }
 
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
     if (ctx->kattest && !ECDSA_sign_setup(ctx->ec, NULL, &ctx->kinv, &ctx->r))
         return 0;
+#endif
 
     if (sigsize < (size_t)ecsize)
         return 0;
@@ -201,8 +205,10 @@ static int get_md_nid(const EVP_MD *md)
 
 static void free_md(PROV_ECDSA_CTX *ctx)
 {
+    OPENSSL_free(ctx->propq);
     EVP_MD_CTX_free(ctx->mdctx);
     EVP_MD_free(ctx->md);
+    ctx->propq = NULL;
     ctx->mdctx = NULL;
     ctx->md = NULL;
     ctx->mdsize = 0;
@@ -414,10 +420,11 @@ static int ecdsa_set_ctx_params(void *vctx, const OSSL_PARAM params[])
          */
         return 1;
     }
-
+#if defined(FIPS_MODULE) && !defined(OPENSSL_NO_ACVP_TESTS)
     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_KAT);
     if (p != NULL && !OSSL_PARAM_get_uint(p, &ctx->kattest))
         return 0;
+#endif
 
     p = OSSL_PARAM_locate_const(params, OSSL_SIGNATURE_PARAM_DIGEST_SIZE);
     if (p != NULL && !OSSL_PARAM_get_size_t(p, &ctx->mdsize))
diff --git a/providers/implementations/signature/rsa.c b/providers/implementations/signature/rsa.c
index 81611bb4f0..5af64d2a90 100644
--- a/providers/implementations/signature/rsa.c
+++ b/providers/implementations/signature/rsa.c
@@ -594,13 +594,15 @@ static int rsa_verify_recover(void *vprsactx,
             }
 
             *routlen = ret;
-            if (routsize < (size_t)ret) {
-                ERR_raise_data(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL,
-                               "buffer size is %d, should be %d",
-                               routsize, ret);
-                return 0;
+            if (rout != prsactx->tbuf) {
+                if (routsize < (size_t)ret) {
+                    ERR_raise_data(ERR_LIB_PROV, PROV_R_OUTPUT_BUFFER_TOO_SMALL,
+                                   "buffer size is %d, should be %d",
+                                   routsize, ret);
+                    return 0;
+                }
+                memcpy(rout, prsactx->tbuf, ret);
             }
-            memcpy(rout, prsactx->tbuf, ret);
             break;
 
         case RSA_PKCS1_PADDING:
@@ -655,7 +657,10 @@ static int rsa_verify(void *vprsactx, const unsigned char *sig, size_t siglen,
             }
             return 1;
         case RSA_X931_PADDING:
-            if (rsa_verify_recover(prsactx, NULL, &rslen, 0, sig, siglen) <= 0)
+            if (!setup_tbuf(prsactx))
+                return 0;
+            if (rsa_verify_recover(prsactx, prsactx->tbuf, &rslen, 0,
+                                   sig, siglen) <= 0)
                 return 0;
             break;
         case RSA_PKCS1_PSS_PADDING:
diff --git a/test/acvp_test.c b/test/acvp_test.c
new file mode 100644
index 0000000000..0e3e117133
--- /dev/null
+++ b/test/acvp_test.c
@@ -0,0 +1,1367 @@
+/*
+ * Copyright 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
+ */
+
+/*
+ * A set of tests demonstrating uses cases for CAVS/ACVP testing.
+ *
+ * For examples of testing KDF's, Digests, KeyAgreement & DRBG's refer to
+ * providers/fips/self_test_kats.c
+ */
+
+#include <openssl/opensslconf.h> /* To see if OPENSSL_NO_EC is defined */
+#include <openssl/core_names.h>
+#include <openssl/evp.h>
+#include <openssl/ec.h>
+#include <openssl/dh.h>
+#include <openssl/dsa.h>
+#include <openssl/rsa.h>
+#include <openssl/param_build.h>
+#include <openssl/provider.h>
+#include "testutil.h"
+#include "testutil/output.h"
+#include "acvp_test.inc"
+#include "internal/nelem.h"
+
+static OSSL_PROVIDER *prov_null = NULL;
+static OPENSSL_CTX *libctx = NULL;
+
+typedef enum OPTION_choice {
+    OPT_ERR = -1,
+    OPT_EOF = 0,
+    OPT_CONFIG_FILE,
+    OPT_TEST_ENUM
+} OPTION_CHOICE;
+
+const OPTIONS *test_get_options(void)
+{
+    static const OPTIONS test_options[] = {
+        OPT_TEST_OPTIONS_DEFAULT_USAGE,
+        { "config", OPT_CONFIG_FILE, '<',
+          "The configuration file to use for the libctx" },
+        { NULL }
+    };
+    return test_options;
+}
+
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DSA)                       \
+    || !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_RSA)
+static int pkey_get_bn_bytes(EVP_PKEY *pkey, const char *name,
+                             unsigned char **out, size_t *out_len)
+{
+    unsigned char *buf = NULL;
+    BIGNUM *bn = NULL;
+    int sz;
+
+    if (!EVP_PKEY_get_bn_param(pkey, name, &bn))
+        goto err;
+    sz = BN_num_bytes(bn);
+    buf = OPENSSL_zalloc(sz);
+    if (buf == NULL)
+        goto err;
+    if (!BN_bn2binpad(bn, buf, sz))
+        goto err;
+
+    *out_len = sz;
+    *out = buf;
+    BN_free(bn);
+    return 1;
+err:
+    OPENSSL_free(buf);
+    BN_free(bn);
+    return 0;
+}
+#endif
+
+#if !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_DSA)                        \
+    || !defined(OPENSSL_NO_RSA)
+static int sig_gen(EVP_PKEY *pkey, OSSL_PARAM *params, const char *digest_name,
+                   const unsigned char *msg, size_t msg_len,
+                   unsigned char **sig_out, size_t *sig_out_len)
+{
+    int ret = 0;
+    EVP_MD_CTX *md_ctx = NULL;
+    unsigned char *sig = NULL;
+    size_t sig_len;
+    size_t sz = EVP_PKEY_size(pkey);
+
+    if (!TEST_ptr(sig = OPENSSL_malloc(sz))
+        || !TEST_ptr(md_ctx = EVP_MD_CTX_new())
+        || !TEST_int_eq(EVP_DigestSignInit_ex(md_ctx, NULL, digest_name, NULL,
+                                              pkey, libctx), 1)
+        || !TEST_int_gt(EVP_DigestSign(md_ctx, sig, &sig_len, msg, msg_len), 0))
+        goto err;
+    *sig_out = sig;
+    *sig_out_len = sig_len;
+    sig = NULL;
+    ret = 1;
+err:
+    OPENSSL_free(sig);
+    EVP_MD_CTX_free(md_ctx);
+    return ret;
+}
+#endif
+
+#ifndef OPENSSL_NO_EC
+static int ecdsa_keygen_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    unsigned char *priv = NULL;
+    unsigned char *pubx = NULL, *puby = NULL;
+    size_t priv_len = 0, pubx_len = 0, puby_len = 0;
+    const struct ecdsa_keygen_st *tst = &ecdsa_keygen_data[id];
+
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL))
+        || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)
+        || !TEST_true(EVP_PKEY_CTX_set_ec_paramgen_curve_name(ctx,
+                                                              tst->curve_name))
+        || !TEST_int_gt(EVP_PKEY_keygen(ctx, &pkey), 0)
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_PRIV_KEY, &priv,
+                                        &priv_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_EC_PUB_X, &pubx,
+                                        &pubx_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_EC_PUB_Y, &puby,
+                                        &puby_len)))
+        goto err;
+
+    test_output_memory("qy", puby, puby_len);
+    test_output_memory("qx", pubx, pubx_len);
+    test_output_memory("d", priv, priv_len);
+    ret = 1;
+err:
+    OPENSSL_clear_free(priv, priv_len);
+    OPENSSL_free(pubx);
+    OPENSSL_free(puby);
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(ctx);
+    return ret;
+}
+
+static int ecdsa_create_pkey(EVP_PKEY **pkey, const char *curve_name,
+                             const unsigned char *pub, size_t pub_len,
+                             int expected)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *params = NULL;
+
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
+        || (curve_name != NULL
+            && !TEST_true(OSSL_PARAM_BLD_push_utf8_string(
+                              bld, OSSL_PKEY_PARAM_EC_NAME, curve_name, 0) > 0))
+        || !TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
+                                                       OSSL_PKEY_PARAM_PUB_KEY,
+                                                       pub, pub_len) > 0)
+        || !TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
+        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL))
+        || !TEST_true(EVP_PKEY_key_fromdata_init(ctx))
+        || !TEST_int_eq(EVP_PKEY_fromdata(ctx, pkey, params), expected))
+    goto err;
+
+    ret = 1;
+err:
+    OSSL_PARAM_BLD_free_params(params);
+    OSSL_PARAM_BLD_free(bld);
+    EVP_PKEY_CTX_free(ctx);
+    return ret;
+}
+
+static int ecdsa_pub_verify_test(int id)
+{
+    const struct ecdsa_pub_verify_st *tst = &ecdsa_pv_data[id];
+
+    int ret = 0;
+    EVP_PKEY_CTX *key_ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+
+    if (!TEST_true(ecdsa_create_pkey(&pkey, tst->curve_name,
+                                     tst->pub, tst->pub_len, tst->pass)))
+        goto err;
+
+    if (tst->pass) {
+        if (!TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, ""))
+            || !TEST_int_eq(EVP_PKEY_public_check(key_ctx), tst->pass))
+            goto err;
+    }
+    ret = 1;
+err:
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(key_ctx);
+    return ret;
+}
+
+/* Extract r and s  from a ecdsa signature */
+static int get_ecdsa_sig_rs_bytes(const unsigned char *sig, size_t sig_len,
+                                  unsigned char **r, unsigned char **s,
+                                  size_t *rlen, size_t *slen)
+{
+    int ret = 0;
+    unsigned char *rbuf = NULL, *sbuf = NULL;
+    size_t r1_len, s1_len;
+    const BIGNUM *r1, *s1;
+    ECDSA_SIG *sign = d2i_ECDSA_SIG(NULL, &sig, sig_len);
+
+    if (sign == NULL)
+        return 0;
+    r1 = ECDSA_SIG_get0_r(sign);
+    s1 = ECDSA_SIG_get0_s(sign);
+    if (r1 == NULL || s1 == NULL)
+        return 0;
+
+    r1_len = BN_num_bytes(r1);
+    s1_len = BN_num_bytes(s1);
+    rbuf = OPENSSL_zalloc(r1_len);
+    sbuf = OPENSSL_zalloc(s1_len);
+    if (rbuf == NULL || sbuf == NULL)
+        goto err;
+    if (BN_bn2binpad(r1, rbuf, r1_len) <= 0)
+        goto err;
+    if (BN_bn2binpad(s1, sbuf, s1_len) <= 0)
+        goto err;
+    *r = rbuf;
+    *s = sbuf;
+    *rlen = r1_len;
+    *slen = s1_len;
+    ret = 1;
+err:
+    if (ret == 0) {
+        OPENSSL_free(rbuf);
+        OPENSSL_free(sbuf);
+    }
+    ECDSA_SIG_free(sign);
+    return ret;
+}
+
+static int ecdsa_siggen_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL, *key_ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    size_t sig_len = 0, rlen = 0, slen = 0;
+    unsigned char *sig = NULL;
+    unsigned char *r = NULL, *s = NULL;
+    const struct ecdsa_siggen_st *tst = &ecdsa_siggen_data[id];
+
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "EC", NULL))
+        || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)
+        || !TEST_true(EVP_PKEY_CTX_set_ec_paramgen_curve_name(ctx,
+                                                              tst->curve_name))
+        || !TEST_int_gt(EVP_PKEY_keygen(ctx, &pkey), 0))
+        goto err;
+
+    if (!TEST_true(sig_gen(pkey, NULL, tst->digest_alg, tst->msg, tst->msg_len,
+                           &sig, &sig_len))
+        || !TEST_true(get_ecdsa_sig_rs_bytes(sig, sig_len, &r, &s, &rlen, &slen)))
+        goto err;
+    test_output_memory("r", r, rlen);
+    test_output_memory("s", s, slen);
+    ret = 1;
+err:
+    OPENSSL_free(r);
+    OPENSSL_free(s);
+    OPENSSL_free(sig);
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(key_ctx);
+    EVP_PKEY_CTX_free(ctx);
+    return ret;
+}
+
+static int ecdsa_sigver_test(int id)
+{
+    int ret = 0;
+    EVP_MD_CTX *md_ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    ECDSA_SIG *sign = NULL;
+    size_t sig_len;
+    unsigned char *sig = NULL;
+    BIGNUM *rbn = NULL, *sbn = NULL;
+    const struct ecdsa_sigver_st *tst = &ecdsa_sigver_data[id];
+
+    if (!TEST_true(ecdsa_create_pkey(&pkey, tst->curve_name,
+                                     tst->pub, tst->pub_len, 1)))
+        goto err;
+
+    if (!TEST_ptr(sign = ECDSA_SIG_new())
+        || !TEST_ptr(rbn = BN_bin2bn(tst->r, tst->r_len, NULL))
+        || !TEST_ptr(sbn = BN_bin2bn(tst->s, tst->s_len, NULL))
+        || !TEST_true(ECDSA_SIG_set0(sign, rbn, sbn)))
+        goto err;
+    rbn = sbn = NULL;
+
+    ret = TEST_int_gt((sig_len = i2d_ECDSA_SIG(sign, &sig)), 0)
+          && TEST_ptr(md_ctx = EVP_MD_CTX_new())
+          && TEST_true(EVP_DigestVerifyInit_ex(md_ctx, NULL, tst->digest_alg,
+                                               NULL, pkey, libctx)
+          && TEST_int_eq(EVP_DigestVerify(md_ctx, sig, sig_len,
+                                          tst->msg, tst->msg_len), tst->pass));
+err:
+    BN_free(rbn);
+    BN_free(sbn);
+    OPENSSL_free(sig);
+    ECDSA_SIG_free(sign);
+    EVP_PKEY_free(pkey);
+    EVP_MD_CTX_free(md_ctx);
+    return ret;
+
+}
+#endif /* OPENSSL_NO_EC */
+
+#ifndef OPENSSL_NO_DSA
+static int pkey_get_octet_bytes(EVP_PKEY *pkey, const char *name,
+                                unsigned char **out, size_t *out_len)
+{
+    size_t len = 0;
+    unsigned char *buf = NULL;
+
+    if (!EVP_PKEY_get_octet_string_param(pkey, name, NULL, 0, &len))
+        goto err;
+
+    buf = OPENSSL_zalloc(len);
+    if (buf == NULL)
+        goto err;
+
+    if (!EVP_PKEY_get_octet_string_param(pkey, name, buf, len, out_len))
+        goto err;
+    *out = buf;
+    return 1;
+err:
+    OPENSSL_free(buf);
+    return 0;
+}
+
+static EVP_PKEY *dsa_paramgen(int L, int N)
+{
+    EVP_PKEY_CTX *paramgen_ctx = NULL;
+    EVP_PKEY *param_key = NULL;
+
+    if (!TEST_ptr(paramgen_ctx = EVP_PKEY_CTX_new_from_name(libctx, "DSA", NULL))
+        || !TEST_true(EVP_PKEY_paramgen_init(paramgen_ctx))
+        || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(paramgen_ctx, L))
+        || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_q_bits(paramgen_ctx, N))
+        || !TEST_true(EVP_PKEY_paramgen(paramgen_ctx, &param_key)))
+        return NULL;
+    EVP_PKEY_CTX_free(paramgen_ctx);
+    return param_key;
+}
+
+static EVP_PKEY *dsa_keygen(int L, int N)
+{
+    EVP_PKEY *param_key = NULL, *key = NULL;
+    EVP_PKEY_CTX *keygen_ctx = NULL;
+
+    if (!TEST_ptr(param_key = dsa_paramgen(L, N))
+        || !TEST_ptr(keygen_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, param_key,
+                                                             NULL))
+        || !TEST_int_gt(EVP_PKEY_keygen_init(keygen_ctx), 0)
+        || !TEST_int_gt(EVP_PKEY_keygen(keygen_ctx, &key), 0))
+        goto err;
+err:
+    EVP_PKEY_free(param_key);
+    EVP_PKEY_CTX_free(keygen_ctx);
+    return key;
+}
+
+static int dsa_keygen_test(int id)
+{
+    int ret = 0, i;
+    EVP_PKEY_CTX *paramgen_ctx = NULL, *keygen_ctx = NULL;
+    EVP_PKEY *param_key = NULL, *key = NULL;
+    unsigned char *priv = NULL, *pub = NULL;
+    size_t priv_len = 0, pub_len = 0;
+    const struct dsa_paramgen_st *tst = &dsa_keygen_data[id];
+
+    if (!TEST_ptr(param_key = dsa_paramgen(tst->L, tst->N))
+        || !TEST_ptr(keygen_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, param_key,
+                                                             NULL))
+        || !TEST_int_gt(EVP_PKEY_keygen_init(keygen_ctx), 0))
+        goto err;
+    for (i = 0; i < 2; ++i) {
+        if (!TEST_int_gt(EVP_PKEY_keygen(keygen_ctx, &key), 0)
+            || !TEST_true(pkey_get_bn_bytes(key, OSSL_PKEY_PARAM_PRIV_KEY,
+                                            &priv, &priv_len))
+            || !TEST_true(pkey_get_bn_bytes(key, OSSL_PKEY_PARAM_PUB_KEY,
+                                            &pub, &pub_len)))
+            goto err;
+        test_output_memory("y", pub, pub_len);
+        test_output_memory("x", priv, priv_len);
+        EVP_PKEY_free(key);
+        OPENSSL_clear_free(priv, priv_len);
+        OPENSSL_free(pub);
+        key = NULL;
+        pub = priv = NULL;
+    }
+    ret = 1;
+err:
+    OPENSSL_clear_free(priv, priv_len);
+    OPENSSL_free(pub);
+    EVP_PKEY_free(param_key);
+    EVP_PKEY_free(key);
+    EVP_PKEY_CTX_free(keygen_ctx);
+    EVP_PKEY_CTX_free(paramgen_ctx);
+    return ret;
+}
+
+static int dsa_paramgen_test(int id)
+{
+    int ret = 0, counter = 0;
+    EVP_PKEY_CTX *paramgen_ctx = NULL;
+    EVP_PKEY *param_key = NULL;
+    unsigned char *p = NULL, *q = NULL, *seed = NULL;
+    size_t plen = 0, qlen = 0, seedlen = 0;
+    const struct dsa_paramgen_st *tst = &dsa_paramgen_data[id];
+
+    if (!TEST_ptr(paramgen_ctx = EVP_PKEY_CTX_new_from_name(libctx, "DSA", NULL))
+        || !TEST_true(EVP_PKEY_paramgen_init(paramgen_ctx))
+        || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_bits(paramgen_ctx, tst->L))
+        || !TEST_true(EVP_PKEY_CTX_set_dsa_paramgen_q_bits(paramgen_ctx, tst->N))
+        || !TEST_true(EVP_PKEY_paramgen(paramgen_ctx, &param_key))
+        || !TEST_true(pkey_get_bn_bytes(param_key, OSSL_PKEY_PARAM_FFC_P,
+                                        &p, &plen))
+        || !TEST_true(pkey_get_bn_bytes(param_key, OSSL_PKEY_PARAM_FFC_Q,
+                                        &q, &qlen))
+        || !TEST_true(pkey_get_octet_bytes(param_key, OSSL_PKEY_PARAM_FFC_SEED,
+                                           &seed, &seedlen))
+        || !TEST_true(EVP_PKEY_get_int_param(param_key,
+                                             OSSL_PKEY_PARAM_FFC_PCOUNTER,
+                                             &counter)))
+        goto err;
+
+    test_output_memory("p", p, plen);
+    test_output_memory("q", q, qlen);
+    test_output_memory("domainSeed", seed, seedlen);
+    test_printf_stderr("%s: %d\n", "counter", counter);
+    ret = 1;
+err:
+    OPENSSL_free(p);
+    OPENSSL_free(q);
+    OPENSSL_free(seed);
+    EVP_PKEY_free(param_key);
+    EVP_PKEY_CTX_free(paramgen_ctx);
+    return ret;
+}
+
+static int dsa_create_pkey(EVP_PKEY **pkey,
+                           const unsigned char *p, size_t p_len,
+                           const unsigned char *q, size_t q_len,
+                           const unsigned char *g, size_t g_len,
+                           const unsigned char *seed, size_t seed_len,
+                           int counter,
+                           const char *validate_type,
+                           const unsigned char *pub, size_t pub_len,
+                           BN_CTX *bn_ctx)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *params = NULL;
+    BIGNUM *p_bn = NULL, *q_bn = NULL, *g_bn = NULL, *pub_bn = NULL;
+
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
+        || !TEST_ptr(p_bn = BN_CTX_get(bn_ctx))
+        || !TEST_ptr(BN_bin2bn(p, p_len, p_bn))
+        || !TEST_true(OSSL_PARAM_BLD_push_utf8_string(bld,
+                         OSSL_PKEY_PARAM_FFC_VALIDATE_TYPE,
+                         validate_type, 0))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_P, p_bn))
+        || !TEST_ptr(q_bn = BN_CTX_get(bn_ctx))
+        || !TEST_ptr(BN_bin2bn(q, q_len, q_bn))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_FFC_Q, q_bn)))
+        goto err;
+
+     if (g != NULL) {
+         if (!TEST_ptr(g_bn = BN_CTX_get(bn_ctx))
+             || !TEST_ptr(BN_bin2bn(g, g_len, g_bn))
+             || !TEST_true(OSSL_PARAM_BLD_push_BN(bld,
+                                                  OSSL_PKEY_PARAM_FFC_G, g_bn)))
+             goto err;
+     }
+     if (seed != NULL) {
+         if (!TEST_true(OSSL_PARAM_BLD_push_octet_string(bld,
+                            OSSL_PKEY_PARAM_FFC_SEED, seed, seed_len)))
+             goto err;
+     }
+     if (counter != -1) {
+         if (!TEST_true(OSSL_PARAM_BLD_push_int(bld,
+                                                OSSL_PKEY_PARAM_FFC_PCOUNTER,
+                                                counter)))
+             goto err;
+     }
+     if (pub != NULL) {
+         if (!TEST_ptr(pub_bn = BN_CTX_get(bn_ctx))
+             || !TEST_ptr(BN_bin2bn(pub, pub_len, pub_bn))
+             || !TEST_true(OSSL_PARAM_BLD_push_BN(bld,
+                                                  OSSL_PKEY_PARAM_PUB_KEY,
+                                                  pub_bn)))
+             goto err;
+     }
+     if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
+         || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "DSA", NULL))
+         || !TEST_true(EVP_PKEY_key_fromdata_init(ctx))
+         || !TEST_true(EVP_PKEY_fromdata(ctx, pkey, params)))
+         goto err;
+
+    ret = 1;
+err:
+    OSSL_PARAM_BLD_free_params(params);
+    OSSL_PARAM_BLD_free(bld);
+    EVP_PKEY_CTX_free(ctx);
+    return ret;
+}
+
+static int dsa_pqver_test(int id)
+{
+    int ret = 0;
+    BN_CTX *bn_ctx = NULL;
+    EVP_PKEY_CTX *key_ctx = NULL;
+    EVP_PKEY *param_key = NULL;
+    const struct dsa_pqver_st *tst = &dsa_pqver_data[id];
+
+    if (!TEST_ptr(bn_ctx = BN_CTX_new_ex(libctx))
+        || !TEST_true(dsa_create_pkey(&param_key, tst->p, tst->p_len,
+                                      tst->q, tst->q_len, NULL, 0,
+                                      tst->seed, tst->seed_len, tst->counter,
+                                      OSSL_FFC_PARAM_VALIDATE_PQ,
+                                      NULL, 0,
+                                      bn_ctx))
+        || !TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, param_key,
+                                                          NULL))
+        || !TEST_int_eq(EVP_PKEY_param_check(key_ctx), tst->pass))
+        goto err;
+
+    ret = 1;
+err:
+    BN_CTX_free(bn_ctx);
+    EVP_PKEY_free(param_key);
+    EVP_PKEY_CTX_free(key_ctx);
+    return ret;
+}
+
+/* Extract r and s from a dsa signature */
+static int get_dsa_sig_rs_bytes(const unsigned char *sig, size_t sig_len,
+                                unsigned char **r, unsigned char **s,
+                                size_t *r_len, size_t *s_len)
+{
+    int ret = 0;
+    unsigned char *rbuf = NULL, *sbuf = NULL;
+    size_t r1_len, s1_len;
+    const BIGNUM *r1, *s1;
+    DSA_SIG *sign = d2i_DSA_SIG(NULL, &sig, sig_len);
+
+    if (sign == NULL)
+        return 0;
+    DSA_SIG_get0(sign, &r1, &s1);
+    if (r1 == NULL || s1 == NULL)
+        return 0;
+
+    r1_len = BN_num_bytes(r1);
+    s1_len = BN_num_bytes(s1);
+    rbuf = OPENSSL_zalloc(r1_len);
+    sbuf = OPENSSL_zalloc(s1_len);
+    if (rbuf == NULL || sbuf == NULL)
+        goto err;
+    if (BN_bn2binpad(r1, rbuf, r1_len) <= 0)
+        goto err;
+    if (BN_bn2binpad(s1, sbuf, s1_len) <= 0)
+        goto err;
+    *r = rbuf;
+    *s = sbuf;
+    *r_len = r1_len;
+    *s_len = s1_len;
+    ret = 1;
+err:
+    if (ret == 0) {
+        OPENSSL_free(rbuf);
+        OPENSSL_free(sbuf);
+    }
+    DSA_SIG_free(sign);
+    return ret;
+}
+
+static int dsa_siggen_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY *pkey = NULL;
+    unsigned char *sig = NULL, *r = NULL, *s = NULL;
+    size_t sig_len = 0, rlen = 0, slen = 0;
+    const struct dsa_siggen_st *tst = &dsa_siggen_data[id];
+
+    if (!TEST_ptr(pkey = dsa_keygen(tst->L, tst->N)))
+        goto err;
+
+    if (!TEST_true(sig_gen(pkey, NULL, tst->digest_alg, tst->msg, tst->msg_len,
+                           &sig, &sig_len))
+        || !TEST_true(get_dsa_sig_rs_bytes(sig, sig_len, &r, &s, &rlen, &slen)))
+        goto err;
+    test_output_memory("r", r, rlen);
+    test_output_memory("s", s, slen);
+    ret = 1;
+err:
+    OPENSSL_free(r);
+    OPENSSL_free(s);
+    OPENSSL_free(sig);
+    EVP_PKEY_free(pkey);
+    return ret;
+}
+
+static int dsa_sigver_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    DSA_SIG *sign = NULL;
+    size_t sig_len;
+    unsigned char *sig = NULL;
+    BIGNUM *rbn = NULL, *sbn = NULL;
+    EVP_MD *md = NULL;
+    unsigned char digest[EVP_MAX_MD_SIZE];
+    unsigned int digest_len;
+    BN_CTX *bn_ctx = NULL;
+    const struct dsa_sigver_st *tst  = &dsa_sigver_data[id];
+
+    if (!TEST_ptr(bn_ctx = BN_CTX_new())
+        || !TEST_true(dsa_create_pkey(&pkey, tst->p, tst->p_len,
+                                      tst->q, tst->q_len, tst->g, tst->g_len,
+                                      NULL, 0, 0, "", tst->pub, tst->pub_len,
+                                      bn_ctx)))
+        goto err;
+
+    if (!TEST_ptr(sign = DSA_SIG_new())
+        || !TEST_ptr(rbn = BN_bin2bn(tst->r, tst->r_len, NULL))
+        || !TEST_ptr(sbn = BN_bin2bn(tst->s, tst->s_len, NULL))
+        || !TEST_true(DSA_SIG_set0(sign, rbn, sbn)))
+        goto err;
+    rbn = sbn = NULL;
+
+    if (!TEST_ptr(md = EVP_MD_fetch(libctx, tst->digest_alg, ""))
+        || !TEST_true(EVP_Digest(tst->msg, tst->msg_len,
+                                 digest, &digest_len, md, NULL)))
+        goto err;
+
+    if (!TEST_int_gt((sig_len = i2d_DSA_SIG(sign, &sig)), 0)
+        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, ""))
+        || !TEST_int_gt(EVP_PKEY_verify_init(ctx), 0)
+        || !TEST_int_eq(EVP_PKEY_verify(ctx, sig, sig_len, digest, digest_len),
+                        tst->pass))
+        goto err;
+    ret = 1;
+err:
+    EVP_PKEY_CTX_free(ctx);
+    OPENSSL_free(sig);
+    EVP_MD_free(md);
+    DSA_SIG_free(sign);
+    EVP_PKEY_free(pkey);
+    BN_free(rbn);
+    BN_free(sbn);
+    BN_CTX_free(bn_ctx);
+    return ret;
+}
+#endif /* OPENSSL_NO_DSA */
+
+
+/* cipher encrypt/decrypt */
+static int cipher_enc(const char *alg,
+                      const unsigned char *pt, size_t pt_len,
+                      const unsigned char *key, size_t key_len,
+                      const unsigned char *iv, size_t iv_len,
+                      const unsigned char *ct, size_t ct_len,
+                      int enc)
+{
+    int ret = 0, out_len = 0, len = 0;
+    EVP_CIPHER_CTX *ctx = NULL;
+    EVP_CIPHER *cipher = NULL;
+    unsigned char out[256] = { 0 };
+
+    TEST_note("%s : %s", alg, enc ? "encrypt" : "decrypt");
+    if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
+        || !TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, alg, ""))
+        || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc))
+        || !TEST_true(EVP_CIPHER_CTX_set_padding(ctx, 0))
+        || !TEST_true(EVP_CipherUpdate(ctx, out, &len, pt, pt_len))
+        || !TEST_true(EVP_CipherFinal_ex(ctx, out + len, &out_len)))
+        goto err;
+    out_len += len;
+    if (!TEST_mem_eq(out, out_len, ct, ct_len))
+        goto err;
+    ret = 1;
+err:
+    EVP_CIPHER_free(cipher);
+    EVP_CIPHER_CTX_free(ctx);
+    return ret;
+}
+
+static int cipher_enc_dec_test(int id)
+{
+    const struct cipher_st *tst = &cipher_enc_data[id];
+    const int enc = 1;
+
+    return TEST_true(cipher_enc(tst->alg, tst->pt, tst->pt_len,
+                                tst->key, tst->key_len,
+                                tst->iv, tst->iv_len,
+                                tst->ct, tst->ct_len, enc))
+           && TEST_true(cipher_enc(tst->alg, tst->ct, tst->ct_len,
+                                   tst->key, tst->key_len,
+                                   tst->iv, tst->iv_len,
+                                   tst->pt, tst->pt_len, !enc));
+}
+
+static int aes_ccm_enc_dec(const char *alg,
+                           const unsigned char *pt, size_t pt_len,
+                           const unsigned char *key, size_t key_len,
+                           const unsigned char *iv, size_t iv_len,
+                           const unsigned char *aad, size_t aad_len,
+                           const unsigned char *ct, size_t ct_len,
+                           const unsigned char *tag, size_t tag_len,
+                           int enc, int pass)
+{
+    int ret = 0;
+    EVP_CIPHER_CTX *ctx;
+    EVP_CIPHER *cipher = NULL;
+    int out_len, len;
+    unsigned char out[1024];
+
+    TEST_note("%s : %s : expected to %s", alg, enc ? "encrypt" : "decrypt",
+              pass ? "pass" : "fail");
+
+    if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
+        || !TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, alg, ""))
+        || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len,
+                                          NULL))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len,
+                                          enc ? NULL : (void *)tag))
+        || !TEST_true(EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
+        || !TEST_true(EVP_CIPHER_CTX_set_padding(ctx, 0))
+        || !TEST_true(EVP_CipherUpdate(ctx, NULL, &len, NULL, pt_len))
+        || !TEST_true(EVP_CipherUpdate(ctx, NULL, &len, aad, aad_len))
+        || !TEST_int_eq(EVP_CipherUpdate(ctx, out, &len, pt, pt_len), pass))
+        goto err;
+
+    if (!pass) {
+        ret = 1;
+        goto err;
+    }
+    if (!TEST_true(EVP_CipherFinal_ex(ctx, out + len, &out_len)))
+        goto err;
+    if (enc) {
+        out_len += len;
+        if (!TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
+                                           tag_len, out + out_len))
+            || !TEST_mem_eq(out, out_len, ct, ct_len)
+            || !TEST_mem_eq(out + out_len, tag_len, tag, tag_len))
+            goto err;
+    } else {
+        if (!TEST_mem_eq(out, out_len + len, ct, ct_len))
+            goto err;
+    }
+
+    ret = 1;
+err:
+    EVP_CIPHER_free(cipher);
+    EVP_CIPHER_CTX_free(ctx);
+    return ret;
+}
+
+static int aes_ccm_enc_dec_test(int id)
+{
+    const struct cipher_ccm_st *tst = &aes_ccm_enc_data[id];
+
+    /* The tag is on the end of the cipher text */
+    const size_t tag_len = tst->ct_len - tst->pt_len;
+    const size_t ct_len = tst->ct_len - tag_len;
+    const unsigned char *tag = tst->ct + ct_len;
+    const int enc = 1;
+    const int pass = 1;
+
+    if (ct_len < 1)
+        return 0;
+
+    return aes_ccm_enc_dec(tst->alg, tst->pt, tst->pt_len,
+                           tst->key, tst->key_len,
+                           tst->iv, tst->iv_len, tst->aad, tst->aad_len,
+                           tst->ct, ct_len, tag, tag_len, enc, pass)
+            && aes_ccm_enc_dec(tst->alg, tst->ct, ct_len,
+                               tst->key, tst->key_len,
+                               tst->iv, tst->iv_len, tst->aad, tst->aad_len,
+                               tst->pt, tst->pt_len, tag, tag_len, !enc, pass)
+            /* test that it fails if the tag is incorrect */
+            && aes_ccm_enc_dec(tst->alg, tst->ct, ct_len,
+                               tst->key, tst->key_len,
+                               tst->iv, tst->iv_len, tst->aad, tst->aad_len,
+                               tst->pt, tst->pt_len,
+                               tag - 1, tag_len, !enc, !pass);
+}
+
+static int aes_gcm_enc_dec(const char *alg,
+                           const unsigned char *pt, size_t pt_len,
+                           const unsigned char *key, size_t key_len,
+                           const unsigned char *iv, size_t iv_len,
+                           const unsigned char *aad, size_t aad_len,
+                           const unsigned char *ct, size_t ct_len,
+                           const unsigned char *tag, size_t tag_len,
+                           int enc, int pass)
+{
+    int ret = 0;
+    EVP_CIPHER_CTX *ctx;
+    EVP_CIPHER *cipher = NULL;
+    int out_len, len;
+    unsigned char out[1024];
+
+    TEST_note("%s : %s : expected to %s", alg, enc ? "encrypt" : "decrypt",
+              pass ? "pass" : "fail");
+
+    if (!TEST_ptr(ctx = EVP_CIPHER_CTX_new())
+        || !TEST_ptr(cipher = EVP_CIPHER_fetch(libctx, alg, ""))
+        || !TEST_true(EVP_CipherInit_ex(ctx, cipher, NULL, NULL, NULL, enc))
+        || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_IVLEN, iv_len,
+                                          NULL)))
+        goto err;
+
+    if (!enc) {
+        if (!TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_SET_TAG, tag_len,
+                                           (void *)tag)))
+            goto err;
+    }
+    /*
+     * TODO(3.0): The IV should not be set outside the boundary as it is now.
+     * It needs to be fed in via a dummy entropy source for this test.
+     */
+    if (!TEST_true(EVP_CipherInit_ex(ctx, NULL, NULL, key, iv, enc))
+        || !TEST_true(EVP_CIPHER_CTX_set_padding(ctx, 0))
+        || !TEST_true(EVP_CipherUpdate(ctx, NULL, &len, aad, aad_len))
+        || !TEST_true(EVP_CipherUpdate(ctx, out, &len, pt, pt_len)))
+        goto err;
+
+    if (!TEST_int_eq(EVP_CipherFinal_ex(ctx, out + len, &out_len), pass))
+        goto err;
+    if (!pass) {
+        ret = 1;
+        goto err;
+    }
+    out_len += len;
+    if (enc) {
+        if (!TEST_mem_eq(out, out_len, ct, ct_len)
+            || !TEST_true(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG,
+                                              tag_len, out + out_len))
+            || !TEST_mem_eq(out + out_len, tag_len, tag, tag_len))
+                    goto err;
+    } else {
+        if (!TEST_mem_eq(out, out_len, ct, ct_len))
+            goto err;
+    }
+
+    ret = 1;
+err:
+    EVP_CIPHER_free(cipher);
+    EVP_CIPHER_CTX_free(ctx);
+    return ret;
+}
+
+static int aes_gcm_enc_dec_test(int id)
+{
+    const struct cipher_gcm_st *tst = &aes_gcm_enc_data[id];
+    int enc = 1;
+    int pass = 1;
+
+    return aes_gcm_enc_dec(tst->alg, tst->pt, tst->pt_len,
+                           tst->key, tst->key_len,
+                           tst->iv, tst->iv_len, tst->aad, tst->aad_len,
+                           tst->ct, tst->ct_len, tst->tag, tst->tag_len,
+                           enc, pass)
+            && aes_gcm_enc_dec(tst->alg, tst->ct, tst->ct_len,
+                               tst->key, tst->key_len,
+                               tst->iv, tst->iv_len, tst->aad, tst->aad_len,
+                               tst->pt, tst->pt_len, tst->tag, tst->tag_len,
+                               !enc, pass)
+            /* Fail if incorrect tag passed to decrypt */
+            && aes_gcm_enc_dec(tst->alg, tst->ct, tst->ct_len,
+                               tst->key, tst->key_len,
+                               tst->iv, tst->iv_len, tst->aad, tst->aad_len,
+                               tst->pt, tst->pt_len, tst->aad, tst->tag_len,
+                               !enc, !pass);
+}
+
+#ifndef OPENSSL_NO_DH
+static int dh_create_pkey(EVP_PKEY **pkey, const char *group_name,
+                          const unsigned char *pub, size_t pub_len,
+                          const unsigned char *priv, size_t priv_len,
+                          BN_CTX *bn_ctx, int pass)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *params = NULL;
+    BIGNUM *pub_bn = NULL, *priv_bn = NULL;
+
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
+        || (group_name != NULL
+            && !TEST_int_gt(OSSL_PARAM_BLD_push_utf8_string(
+                              bld, OSSL_PKEY_PARAM_DH_GROUP,
+                              group_name, 0), 0)))
+        goto err;
+
+    if (pub != NULL) {
+        if (!TEST_ptr(pub_bn = BN_CTX_get(bn_ctx))
+            || !TEST_ptr(BN_bin2bn(pub, pub_len, pub_bn))
+            || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PUB_KEY,
+                                                 pub_bn)))
+            goto err;
+    }
+    if (priv != NULL) {
+        if (!TEST_ptr(priv_bn = BN_CTX_get(bn_ctx))
+            || !TEST_ptr(BN_bin2bn(priv, priv_len, priv_bn))
+            || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_PRIV_KEY,
+                                                 priv_bn)))
+            goto err;
+    }
+
+    if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
+        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "DH", NULL))
+        || !TEST_true(EVP_PKEY_key_fromdata_init(ctx))
+        || !TEST_int_eq(EVP_PKEY_fromdata(ctx, pkey, params), pass))
+    goto err;
+
+    ret = 1;
+err:
+    OSSL_PARAM_BLD_free_params(params);
+    OSSL_PARAM_BLD_free(bld);
+    EVP_PKEY_CTX_free(ctx);
+    return ret;
+}
+
+static int dh_safe_prime_keygen_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    unsigned char *priv = NULL;
+    unsigned char *pub = NULL;
+    size_t priv_len = 0, pub_len = 0;
+    OSSL_PARAM params[2];
+    const struct dh_safe_prime_keygen_st *tst = &dh_safe_prime_keygen_data[id];
+
+    params[0] = OSSL_PARAM_construct_utf8_string(OSSL_PKEY_PARAM_DH_GROUP,
+                                                 (char *)tst->group_name, 0);
+    params[1] = OSSL_PARAM_construct_end();
+
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "DH", NULL))
+        || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)
+        || !TEST_true(EVP_PKEY_CTX_set_params(ctx, params))
+        || !TEST_int_gt(EVP_PKEY_keygen(ctx, &pkey), 0)
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_PRIV_KEY,
+                                        &priv, &priv_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_PUB_KEY,
+                                        &pub, &pub_len)))
+        goto err;
+
+    test_output_memory("x", priv, priv_len);
+    test_output_memory("y", pub, pub_len);
+    ret = 1;
+err:
+    OPENSSL_clear_free(priv, priv_len);
+    OPENSSL_free(pub);
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(ctx);
+    return ret;
+}
+
+static int dh_safe_prime_keyver_test(int id)
+{
+    int ret = 0;
+    BN_CTX *bn_ctx = NULL;
+    EVP_PKEY_CTX *key_ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    const struct dh_safe_prime_keyver_st *tst = &dh_safe_prime_keyver_data[id];
+
+    if (!TEST_ptr(bn_ctx = BN_CTX_new_ex(libctx))
+        || !TEST_true(dh_create_pkey(&pkey, tst->group_name,
+                                     tst->pub, tst->pub_len,
+                                     tst->priv, tst->priv_len, bn_ctx, 1))
+        || !TEST_ptr(key_ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, ""))
+        || !TEST_int_eq(EVP_PKEY_check(key_ctx), tst->pass))
+        goto err;
+
+    ret = 1;
+err:
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(key_ctx);
+    BN_CTX_free(bn_ctx);
+    return ret;
+}
+#endif /* OPENSSL_NO_DH */
+
+
+#ifndef OPENSSL_NO_RSA
+static EVP_PKEY *rsa_keygen(int bits)
+{
+    EVP_PKEY *key = NULL;
+    EVP_PKEY_CTX *keygen_ctx = NULL;
+
+    if (!TEST_ptr(keygen_ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", NULL))
+        || !TEST_int_gt(EVP_PKEY_keygen_init(keygen_ctx), 0)
+        || !TEST_true(EVP_PKEY_CTX_set_rsa_keygen_bits(keygen_ctx, bits))
+        || !TEST_int_gt(EVP_PKEY_keygen(keygen_ctx, &key), 0))
+        goto err;
+err:
+    EVP_PKEY_CTX_free(keygen_ctx);
+    return key;
+}
+
+static int rsa_create_pkey(EVP_PKEY **pkey,
+                           const unsigned char *n, size_t n_len,
+                           const unsigned char *e, size_t e_len,
+                           const unsigned char *d, size_t d_len,
+                           BN_CTX *bn_ctx)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *params = NULL;
+    BIGNUM *e_bn = NULL, *d_bn = NULL, *n_bn = NULL;
+
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
+        || !TEST_ptr(n_bn = BN_CTX_get(bn_ctx))
+        || !TEST_ptr(BN_bin2bn(n, n_len, n_bn))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_N, n_bn)))
+        goto err;
+
+    if (e != NULL) {
+        if (!TEST_ptr(e_bn = BN_CTX_get(bn_ctx))
+            || !TEST_ptr(BN_bin2bn(e, e_len, e_bn))
+            || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_E,
+                          e_bn)))
+            goto err;
+    }
+    if (d != NULL) {
+        if (!TEST_ptr(d_bn = BN_CTX_get(bn_ctx))
+            || !TEST_ptr(BN_bin2bn(d, d_len, d_bn))
+            || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_D,
+                          d_bn)))
+            goto err;
+    }
+    if (!TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld))
+        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", NULL))
+        || !TEST_true(EVP_PKEY_key_fromdata_init(ctx))
+        || !TEST_true(EVP_PKEY_fromdata(ctx, pkey, params)))
+        goto err;
+
+    ret = 1;
+err:
+    OSSL_PARAM_BLD_free_params(params);
+    OSSL_PARAM_BLD_free(bld);
+    EVP_PKEY_CTX_free(ctx);
+    return ret;
+}
+
+static int rsa_keygen_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    BIGNUM *e_bn = NULL;
+    BIGNUM *xp1_bn = NULL, *xp2_bn = NULL, *xp_bn = NULL;
+    BIGNUM *xq1_bn = NULL, *xq2_bn = NULL, *xq_bn = NULL;
+    unsigned char *n = NULL, *d = NULL;
+    unsigned char *p = NULL, *p1 = NULL, *p2 = NULL;
+    unsigned char *q = NULL, *q1 = NULL, *q2 = NULL;
+    size_t n_len = 0, d_len = 0;
+    size_t p_len = 0, p1_len = 0, p2_len = 0;
+    size_t q_len = 0, q1_len = 0, q2_len = 0;
+    OSSL_PARAM_BLD *bld = NULL;
+    OSSL_PARAM *params = NULL;
+    const struct rsa_keygen_st *tst = &rsa_keygen_data[id];
+
+    if (!TEST_ptr(bld = OSSL_PARAM_BLD_new())
+        || !TEST_ptr(xp1_bn = BN_bin2bn(tst->xp1, tst->xp1_len, NULL))
+        || !TEST_ptr(xp2_bn = BN_bin2bn(tst->xp2, tst->xp2_len, NULL))
+        || !TEST_ptr(xp_bn = BN_bin2bn(tst->xp, tst->xp_len, NULL))
+        || !TEST_ptr(xq1_bn = BN_bin2bn(tst->xq1, tst->xq1_len, NULL))
+        || !TEST_ptr(xq2_bn = BN_bin2bn(tst->xq2, tst->xq2_len, NULL))
+        || !TEST_ptr(xq_bn = BN_bin2bn(tst->xq, tst->xq_len, NULL))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_TEST_XP1,
+                                             xp1_bn))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_TEST_XP2,
+                                             xp2_bn))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_TEST_XP,
+                                             xp_bn))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_TEST_XQ1,
+                                             xq1_bn))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_TEST_XQ2,
+                                             xq2_bn))
+        || !TEST_true(OSSL_PARAM_BLD_push_BN(bld, OSSL_PKEY_PARAM_RSA_TEST_XQ,
+                                             xq_bn))
+        || !TEST_ptr(params = OSSL_PARAM_BLD_to_param(bld)))
+        goto err;
+
+    if (!TEST_ptr(ctx = EVP_PKEY_CTX_new_from_name(libctx, "RSA", NULL))
+        || !TEST_ptr(e_bn = BN_bin2bn(tst->e, tst->e_len, NULL))
+        || !TEST_int_gt(EVP_PKEY_keygen_init(ctx), 0)
+        || !TEST_true(EVP_PKEY_CTX_set_params(ctx, params))
+        || !TEST_true(EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, tst->mod))
+        || !TEST_true(EVP_PKEY_CTX_set_rsa_keygen_pubexp(ctx, e_bn))
+        || !TEST_int_gt(EVP_PKEY_keygen(ctx, &pkey), 0)
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_TEST_P1,
+                                        &p1, &p1_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_TEST_P2,
+                                        &p2, &p2_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_TEST_Q1,
+                                        &q1, &q1_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_TEST_Q2,
+                                        &q2, &q2_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_FACTOR1,
+                                        &p, &p_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_FACTOR2,
+                                        &q, &q_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_N,
+                                        &n, &n_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_D,
+                                        &d, &d_len)))
+        goto err;
+
+    if (!TEST_mem_eq(tst->p1, tst->p1_len, p1, p1_len)
+        || !TEST_mem_eq(tst->p2, tst->p2_len, p2, p2_len)
+        || !TEST_mem_eq(tst->p, tst->p_len, p, p_len)
+        || !TEST_mem_eq(tst->q1, tst->q1_len, q1, q1_len)
+        || !TEST_mem_eq(tst->q2, tst->q2_len, q2, q2_len)
+        || !TEST_mem_eq(tst->q, tst->q_len, q, q_len)
+        || !TEST_mem_eq(tst->n, tst->n_len, n, n_len)
+        || !TEST_mem_eq(tst->d, tst->d_len, d, d_len))
+        goto err;
+
+    test_output_memory("p1", p1, p1_len);
+    test_output_memory("p2", p2, p2_len);
+    test_output_memory("p", p, p_len);
+    test_output_memory("q1", q1, q1_len);
+    test_output_memory("q2", q2, q2_len);
+    test_output_memory("q", q, q_len);
+    test_output_memory("n", n, n_len);
+    test_output_memory("d", d, d_len);
+    ret = 1;
+err:
+    BN_free(xp1_bn);
+    BN_free(xp2_bn);
+    BN_free(xp_bn);
+    BN_free(xq1_bn);
+    BN_free(xq2_bn);
+    BN_free(xq_bn);
+    BN_free(e_bn);
+    OPENSSL_free(p1);
+    OPENSSL_free(p2);
+    OPENSSL_free(q1);
+    OPENSSL_free(q2);
+    OPENSSL_free(p);
+    OPENSSL_free(q);
+    OPENSSL_free(n);
+    OPENSSL_free(d);
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(ctx);
+    OSSL_PARAM_BLD_free_params(params);
+    OSSL_PARAM_BLD_free(bld);
+    return ret;
+}
+
+static int rsa_siggen_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY *pkey = NULL;
+    unsigned char *sig = NULL, *n = NULL, *e = NULL;
+    size_t sig_len = 0, n_len = 0, e_len = 0;
+    OSSL_PARAM params[4], *p;
+    const struct rsa_siggen_st *tst = &rsa_siggen_data[id];
+
+    TEST_note("RSA %s signature generation", tst->sig_pad_mode);
+
+    p = params;
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE,
+                                            (char *)tst->sig_pad_mode, 0);
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
+                                            (char *)tst->digest_alg, 0);
+    if (tst->pss_salt_len >= 0) {
+        int salt_len = tst->pss_salt_len;
+
+        *p++ = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN,
+                                        &salt_len);
+    }
+    *p++ = OSSL_PARAM_construct_end();
+
+    if (!TEST_ptr(pkey = rsa_keygen(tst->mod))
+       || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_N, &n, &n_len))
+       || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_E, &e, &e_len))
+       || !TEST_true(sig_gen(pkey, params, tst->digest_alg,
+                             tst->msg, tst->msg_len,
+                             &sig, &sig_len)))
+        goto err;
+    test_output_memory("n", n, n_len);
+    test_output_memory("e", e, e_len);
+    test_output_memory("sig", sig, sig_len);
+    ret = 1;
+err:
+    OPENSSL_free(n);
+    OPENSSL_free(e);
+    OPENSSL_free(sig);
+    EVP_PKEY_free(pkey);
+    return ret;
+}
+
+static int rsa_sigver_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *pkey_ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    EVP_MD_CTX *md_ctx = NULL;
+    BN_CTX *bn_ctx = NULL;
+    OSSL_PARAM params[4], *p;
+    const struct rsa_sigver_st *tst  = &rsa_sigver_data[id];
+
+    TEST_note("RSA %s Signature Verify : expected to %s ", tst->sig_pad_mode,
+               tst->pass == PASS ? "pass" : "fail");
+
+    p = params;
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_PAD_MODE,
+                                            (char *)tst->sig_pad_mode, 0);
+    *p++ = OSSL_PARAM_construct_utf8_string(OSSL_SIGNATURE_PARAM_DIGEST,
+                                            (char *)tst->digest_alg, 0);
+    if (tst->pss_salt_len >= 0) {
+        int salt_len = tst->pss_salt_len;
+
+        *p++ = OSSL_PARAM_construct_int(OSSL_SIGNATURE_PARAM_PSS_SALTLEN,
+                                        &salt_len);
+    }
+    *p++ = OSSL_PARAM_construct_end();
+
+    if (!TEST_ptr(bn_ctx = BN_CTX_new())
+        || !TEST_true(rsa_create_pkey(&pkey, tst->n, tst->n_len,
+                                      tst->e, tst->e_len, NULL, 0, bn_ctx))
+        || !TEST_ptr(md_ctx = EVP_MD_CTX_new())
+        || !TEST_true(EVP_DigestVerifyInit_ex(md_ctx, &pkey_ctx, tst->digest_alg,
+                                              NULL, pkey, libctx)
+        || !TEST_true(EVP_PKEY_CTX_set_params(pkey_ctx, params))
+        || !TEST_int_eq(EVP_DigestVerify(md_ctx, tst->sig, tst->sig_len,
+                                         tst->msg, tst->msg_len), tst->pass)))
+        goto err;
+    ret = 1;
+err:
+    EVP_PKEY_free(pkey);
+    BN_CTX_free(bn_ctx);
+    EVP_MD_CTX_free(md_ctx);
+    return ret;
+}
+
+static int rsa_decryption_primitive_test(int id)
+{
+    int ret = 0;
+    EVP_PKEY_CTX *ctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    unsigned char pt[2048];
+    size_t pt_len = sizeof(pt);
+    unsigned char *n = NULL, *e = NULL;
+    size_t n_len = 0, e_len = 0;
+    BN_CTX *bn_ctx = NULL;
+    const struct rsa_decrypt_prim_st *tst  = &rsa_decrypt_prim_data[id];
+
+    if (!TEST_ptr(pkey = rsa_keygen(2048))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_N, &n, &n_len))
+        || !TEST_true(pkey_get_bn_bytes(pkey, OSSL_PKEY_PARAM_RSA_E, &e, &e_len))
+        || !TEST_ptr(ctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, ""))
+        || !TEST_int_gt(EVP_PKEY_decrypt_init(ctx), 0)
+        || !TEST_int_gt(EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_NO_PADDING), 0))
+        goto err;
+
+    test_output_memory("n", n, n_len);
+    test_output_memory("e", e, e_len);
+    if (!EVP_PKEY_decrypt(ctx, pt, &pt_len, tst->ct, tst->ct_len))
+        TEST_note("Decryption Failed");
+    else
+        test_output_memory("pt", pt, pt_len);
+    ret = 1;
+err:
+    OPENSSL_free(n);
+    OPENSSL_free(e);
+    EVP_PKEY_CTX_free(ctx);
+    EVP_PKEY_free(pkey);
+    BN_CTX_free(bn_ctx);
+    return ret;
+}
+#endif /* OPENSSL_NO_RSA */
+
+
+int setup_tests(void)
+{
+    char *config_file = NULL;
+
+    OPTION_CHOICE o;
+
+    while ((o = opt_next()) != OPT_EOF) {
+        switch (o) {
+        case OPT_CONFIG_FILE:
+            config_file = opt_arg();
+            break;
+        case OPT_TEST_CASES:
+           break;
+        default:
+        case OPT_ERR:
+            return 0;
+        }
+    }
+
+    prov_null = OSSL_PROVIDER_load(NULL, "null");
+    if (prov_null == NULL) {
+        opt_printf_stderr("Failed to load null provider into default libctx\n");
+        return 0;
+    }
+
+    libctx = OPENSSL_CTX_new();
+    if (libctx == NULL
+        || !OPENSSL_CTX_load_config(libctx, config_file)) {
+        opt_printf_stderr("Failed to load config\n");
+        return 0;
+    }
+
+    ADD_ALL_TESTS(cipher_enc_dec_test, OSSL_NELEM(cipher_enc_data));
+    ADD_ALL_TESTS(aes_ccm_enc_dec_test, OSSL_NELEM(aes_ccm_enc_data));
+    ADD_ALL_TESTS(aes_gcm_enc_dec_test, OSSL_NELEM(aes_gcm_enc_data));
+
+#ifndef OPENSSL_NO_RSA
+    ADD_ALL_TESTS(rsa_keygen_test, OSSL_NELEM(rsa_keygen_data));
+    ADD_ALL_TESTS(rsa_siggen_test, OSSL_NELEM(rsa_siggen_data));
+    ADD_ALL_TESTS(rsa_sigver_test, OSSL_NELEM(rsa_sigver_data));
+    ADD_ALL_TESTS(rsa_decryption_primitive_test,
+                  OSSL_NELEM(rsa_decrypt_prim_data));
+#endif /* OPENSSL_NO_RSA */
+
+#ifndef OPENSSL_NO_DH
+    ADD_ALL_TESTS(dh_safe_prime_keygen_test,
+                  OSSL_NELEM(dh_safe_prime_keygen_data));
+    ADD_ALL_TESTS(dh_safe_prime_keyver_test,
+                  OSSL_NELEM(dh_safe_prime_keyver_data));
+#endif /* OPENSSL_NO_DH */
+
+#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));
+    ADD_ALL_TESTS(dsa_pqver_test, OSSL_NELEM(dsa_pqver_data));
+    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 */
+
+#ifndef OPENSSL_NO_EC
+    ADD_ALL_TESTS(ecdsa_keygen_test, OSSL_NELEM(ecdsa_keygen_data));
+    ADD_ALL_TESTS(ecdsa_pub_verify_test, OSSL_NELEM(ecdsa_pv_data));
+    ADD_ALL_TESTS(ecdsa_siggen_test, OSSL_NELEM(ecdsa_siggen_data));
+    ADD_ALL_TESTS(ecdsa_sigver_test, OSSL_NELEM(ecdsa_sigver_data));
+#endif /* OPENSSL_NO_EC */
+    return 1;
+}
+
+void cleanup_tests(void)
+{
+    OSSL_PROVIDER_unload(prov_null);
+    OPENSSL_CTX_free(libctx);
+}
diff --git a/test/acvp_test.inc b/test/acvp_test.inc
new file mode 100644
index 0000000000..01f6d0d668
--- /dev/null
+++ b/test/acvp_test.inc
@@ -0,0 +1,1984 @@
+/*
+ * Copyright 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
+ */
+
+#define PASS 1
+#define FAIL 0
+#define ITM(x) x, sizeof(x)
+
+#ifndef OPENSSL_NO_EC
+
+struct ecdsa_keygen_st {
+    const char *curve_name;
+};
+
+struct ecdsa_pub_verify_st {
+    const char *curve_name;
+    const unsigned char *pub;
+    size_t pub_len;
+    int pass;
+};
+
+struct ecdsa_siggen_st {
+    const char *digest_alg;
+    const char *curve_name;
+    const unsigned char *msg;
+    size_t msg_len;
+};
+
+struct ecdsa_sigver_st {
+    const char *digest_alg;
+    const char *curve_name;
+    const unsigned char *msg;
+    size_t msg_len;
+    const unsigned char *pub;
+    size_t pub_len;
+    const unsigned char *r;
+    size_t r_len;
+    const unsigned char *s;
+    size_t s_len;
+    int pass;
+};
+
+static const struct ecdsa_keygen_st ecdsa_keygen_data[] = {
+    { "P-224" },
+};
+
+static const unsigned char ecdsa_pv_pub0[] = {
+    POINT_CONVERSION_UNCOMPRESSED,
+    0x50, 0x0F, 0x05, 0x86, 0xD3, 0xAA, 0x8A, 0x48,
+    0x46, 0x63, 0x0D, 0xD7, 0xC7, 0x5D, 0x5F, 0x1D,
+    0xB2, 0xA7, 0x9B, 0xE8, 0xC8, 0xBB, 0xBE, 0x2C,
+    0x93, 0x33, 0xDC, 0xCB, 0xBB, 0x2F, 0xB3, 0xCF,
+    0x55, 0x88, 0x7A, 0x97, 0xD1, 0x75, 0x73, 0xFE,
+    0x92, 0x02, 0x5C, 0xC8, 0xE3, 0xF4, 0x35, 0x4B,
+    0x08, 0x7E, 0xF4, 0xD3, 0x7D, 0x86, 0x06, 0x92,
+    0xBA, 0x15, 0x3F, 0xCF, 0x0C, 0xC4, 0xBF, 0xBC,
+};
+static const unsigned char ecdsa_pv_pub1[] = {
+    POINT_CONVERSION_UNCOMPRESSED,
+    0x1F, 0x74, 0xD6, 0x99, 0xEB, 0x1D, 0x4F, 0x26,
+    0x25, 0x5E, 0xD4, 0x6A, 0xA6, 0xD5, 0x23, 0xB3,
+    0xF5, 0x5D, 0x14, 0x38, 0xE0, 0x4D, 0x23, 0x7F,
+    0x9A, 0xE5, 0xB7, 0x1B, 0xF9, 0x7F, 0xAD, 0x7E,
+    0x0E, 0x1C, 0x06, 0xF4, 0x20, 0xF3, 0x8E, 0x93,
+    0x79, 0x11, 0x15, 0xD6, 0x82, 0x12, 0x14, 0xC2,
+    0xF9, 0x30, 0x61, 0x9A, 0xC3, 0x12, 0xE3, 0x88,
+    0x4E, 0xB1, 0x1A, 0x4B, 0x54, 0x6D, 0xEA, 0xCF,
+};
+static const struct ecdsa_pub_verify_st ecdsa_pv_data[] = {
+    {
+        "P-256",
+        ITM(ecdsa_pv_pub0),
+        PASS
+    },
+    {
+        "P-256",
+        ITM(ecdsa_pv_pub1),
+        FAIL
+    },
+};
+
+static const unsigned char ecdsa_siggen_msg0[] = {
+    0xB8, 0x65, 0x55, 0x9D, 0x54, 0x5C, 0xD2, 0xC7,
+    0xC2, 0xCA, 0x96, 0xDF, 0xF3, 0x9B, 0x26, 0xED,
+    0xF8, 0x16, 0x99, 0x05, 0x94, 0xA9, 0x3F, 0x69,
+    0x5F, 0xE8, 0x73, 0xC5, 0xFE, 0x78, 0x28, 0x84,
+    0xC0, 0xA7, 0xFA, 0x29, 0xBE, 0x37, 0x82, 0xC0,
+    0x56, 0x41, 0x49, 0xAF, 0xF3, 0x59, 0xBB, 0x96,
+    0xF6, 0x4B, 0x87, 0x45, 0xAB, 0x1F, 0xB2, 0xB3,
+    0x8F, 0x14, 0xD4, 0xD7, 0x1C, 0x29, 0x08, 0x0C,
+    0x79, 0x8A, 0x38, 0xAE, 0x32, 0x1C, 0x38, 0x80,
+    0x5B, 0x45, 0x25, 0x46, 0x5D, 0xCE, 0x7D, 0x34,
+    0xC0, 0x90, 0xEF, 0x06, 0x84, 0xA1, 0x0F, 0xF8,
+    0x56, 0x2D, 0x46, 0xF7, 0xB7, 0xDE, 0x06, 0x7C,
+    0x87, 0xA6, 0x7E, 0x71, 0x8D, 0x7B, 0x27, 0xE5,
+    0x51, 0x0C, 0xE7, 0xBA, 0x18, 0x08, 0xE0, 0xD5,
+    0x0B, 0x8C, 0xB6, 0x22, 0xA5, 0x8F, 0xB3, 0xF7,
+    0xFB, 0xC6, 0x2A, 0x59, 0x02, 0x8A, 0x8C, 0x42,
+};
+static const struct ecdsa_siggen_st ecdsa_siggen_data[] = {
+     {
+        "SHA2-256",
+        "P-384",
+        ITM(ecdsa_siggen_msg0),
+     },
+};
+
+static const unsigned char ecdsa_sigver_msg0[] = {
+    0x0b, 0x00, 0xc4, 0x3f, 0xb9, 0xcb, 0x92, 0xd3,
+    0x56, 0x83, 0xc6, 0x97, 0x23, 0xf8, 0xf1, 0x0b,
+    0x0a, 0xa6, 0x60, 0xca, 0x3a, 0xed, 0xba, 0x38,
+    0xf7, 0x86, 0xc2, 0x6d, 0xa1, 0xb6, 0x40, 0x2c,
+    0x92, 0xfe, 0x44, 0x1a, 0x19, 0x61, 0x5c, 0x02,
+    0xfa, 0xd3, 0x79, 0x99, 0xb8, 0x99, 0xe8, 0x70,
+    0xaa, 0x26, 0x01, 0xf2, 0xe7, 0xdc, 0x69, 0xce,
+    0x9a, 0xd2, 0xaa, 0x02, 0x15, 0xab, 0x0d, 0xcb,
+    0x77, 0xaf, 0xe0, 0x81, 0x6d, 0x92, 0x6e, 0x09,
+    0xcd, 0x93, 0xd6, 0x22, 0x67, 0xc2, 0xd3, 0x7c,
+    0x58, 0x11, 0xc8, 0x77, 0x4e, 0x97, 0x92, 0x87,
+    0xcd, 0xe4, 0xc9, 0x2a, 0x77, 0xb2, 0xf0, 0xe7,
+    0xd3, 0x5a, 0x20, 0x36, 0x91, 0x75, 0x23, 0xa8,
+    0xcb, 0x4a, 0xd0, 0xe5, 0x95, 0x3b, 0x24, 0x2a,
+    0x86, 0xa0, 0xaa, 0xbe, 0xac, 0x59, 0xd7, 0xd0,
+    0xfb, 0xdf, 0x33, 0xc9, 0x73, 0xaf, 0x8a, 0x06,
+};
+static const unsigned char ecdsa_sigver_msg1[] = {
+    0x45, 0xBB, 0x9D, 0xDC, 0x1D, 0x0A, 0xF2, 0xD7,
+    0x56, 0x07, 0x1F, 0x47, 0x2A, 0x17, 0xCE, 0x38,
+    0xA8, 0x7E, 0x75, 0xED, 0x4F, 0xE4, 0x17, 0x65,
+    0x11, 0x69, 0xDF, 0x04, 0xF0, 0x39, 0x28, 0xD0,
+    0x75, 0xD5, 0xF0, 0x1C, 0x32, 0x84, 0x16, 0x74,
+    0x7D, 0x61, 0x57, 0xDB, 0x92, 0x24, 0x60, 0xBA,
+    0x58, 0x7B, 0x48, 0xB4, 0x44, 0xFB, 0xD7, 0x35,
+    0xD7, 0xCF, 0x61, 0x34, 0x7F, 0x70, 0x38, 0xAE,
+    0xE2, 0xB2, 0x6C, 0x8A, 0xD1, 0x27, 0xB4, 0xF0,
+    0x33, 0xB9, 0xE9, 0x27, 0x1A, 0xEE, 0x34, 0x72,
+    0x9D, 0x5E, 0x74, 0x28, 0xE7, 0x0B, 0x82, 0xE1,
+    0x60, 0xC2, 0x43, 0xE6, 0x75, 0x4A, 0x2E, 0x66,
+    0x88, 0x72, 0xCA, 0xC7, 0x97, 0xFE, 0x19, 0xCD,
+    0xA4, 0x30, 0xBF, 0xC7, 0xDC, 0x37, 0xF8, 0x1B,
+    0xB6, 0xD7, 0x7E, 0xAD, 0xD6, 0xC1, 0x20, 0xAC,
+    0x79, 0x03, 0x89, 0xEA, 0xF4, 0x59, 0x21, 0xF2,
+};
+
+static const unsigned char ecdsa_sigver_pub0[] = {
+    POINT_CONVERSION_UNCOMPRESSED,
+    0x2c, 0xdf, 0x6f, 0x23, 0x3d, 0x73, 0x86, 0x25,
+    0x1a, 0x29, 0xd6, 0xde, 0x98, 0xcf, 0x85, 0xf7,
+    0x6a, 0x55, 0xba, 0xdb, 0x0f, 0x35, 0x94, 0x92,
+    0xb3, 0x58, 0xf3, 0x89, 0x7f, 0x6c, 0x22, 0x10,
+    0xd9, 0xd3, 0x54, 0xd2, 0x74, 0x9f, 0x64, 0x0d,
+    0xd2, 0xf8, 0x3e, 0xfc, 0x7f, 0xb7, 0x16, 0x36,
+};
+static const unsigned char ecdsa_sigver_pub1[] = {
+    POINT_CONVERSION_UNCOMPRESSED,
+    0x00, 0xD4, 0x79, 0x9F, 0xD9, 0x99, 0xEC, 0x21,
+    0x1E, 0xE6, 0x06, 0x58, 0xB7, 0xFB, 0x76, 0xFC,
+    0xF5, 0x9A, 0xE1, 0x1E, 0x5A, 0x87, 0xD7, 0x0E,
+    0x21, 0x7B, 0xDE, 0x21, 0x52, 0xE6, 0xE4, 0x09,
+    0x2C, 0xB8, 0x5D, 0x99, 0xE2, 0x6A, 0xB1, 0xE5,
+    0x79, 0x11, 0x49, 0xBD, 0x3D, 0xC7, 0x1C, 0x48,
+    0xF5, 0x83, 0xFC, 0x9E, 0xF3, 0xAB, 0x2D, 0x30,
+    0x64, 0xEC, 0x22, 0xCB, 0xEB, 0x95, 0xBF, 0xF2,
+    0x2D, 0xCE,
+
+    0x01, 0xB9, 0xFE, 0xBD, 0x4C, 0x4B, 0xDA, 0x1F,
+    0x30, 0xC3, 0x5C, 0x0F, 0x5D, 0x3E, 0x36, 0x51,
+    0xF2, 0xC0, 0xF7, 0xFC, 0x79, 0x25, 0x98, 0xF2,
+    0x4B, 0x2B, 0x61, 0xFC, 0xD9, 0xC4, 0x5C, 0xC0,
+    0x13, 0xA2, 0x4F, 0x2E, 0x34, 0xD4, 0x15, 0xC4,
+    0x25, 0x13, 0xA9, 0x30, 0x35, 0x56, 0xB7, 0xCD,
+    0xD0, 0xC4, 0x65, 0x5D, 0xFB, 0xB2, 0xE4, 0xBF,
+    0x22, 0x67, 0xEF, 0xA1, 0x2E, 0xA2, 0x1B, 0x33,
+    0xE4, 0x3D,
+};
+static const unsigned char ecdsa_sigver_r0[] = {
+    0x6b, 0x35, 0x62, 0x67, 0xa3, 0xbd, 0x76, 0xc8,
+    0xa3, 0xdc, 0x93, 0x18, 0x82, 0x6f, 0xd2, 0x43,
+    0x52, 0x18, 0x93, 0x21, 0x8e, 0xce, 0x12, 0x65,
+};
+static const unsigned char ecdsa_sigver_r1[] = {
+    0x01, 0xBF, 0xA6, 0x46, 0x6D, 0x4E, 0x1C, 0x42,
+    0x18, 0x7D, 0x46, 0xC6, 0x5F, 0xA5, 0x05, 0xEA,
+    0x1A, 0xEF, 0xDB, 0x46, 0xD1, 0x79, 0x3F, 0x2B,
+    0xE2, 0x70, 0x0F, 0x14, 0x26, 0x30, 0x7F, 0x2D,
+    0x1A, 0x41, 0xFD, 0x11, 0xC0, 0xBB, 0xD0, 0xD5,
+    0x09, 0xAA, 0xE0, 0x1A, 0xFE, 0x59, 0x23, 0x7D,
+    0x1B, 0x5C, 0xB9, 0x51, 0xCD, 0x3A, 0xA1, 0x32,
+    0xC6, 0x92, 0xB0, 0x7D, 0x91, 0xC6, 0x30, 0xC0,
+    0xA4, 0x2A,
+};
+static const unsigned char ecdsa_sigver_s0[] = {
+    0x7b, 0x92, 0x4a, 0x13, 0x8d, 0x74, 0x87, 0xb2,
+    0xd4, 0xc7, 0x21, 0x73, 0x2c, 0x8a, 0x09, 0x25,
+    0xac, 0x19, 0xcf, 0x9c, 0xbc, 0xd7, 0x7b, 0xf8,
+};
+static const unsigned char ecdsa_sigver_s1[] = {
+    0x00, 0x8D, 0x56, 0xBA, 0x60, 0x38, 0x23, 0x47,
+    0xB8, 0x32, 0x73, 0x29, 0x40, 0x84, 0xF0, 0x2C,
+    0x90, 0xB2, 0x1D, 0x56, 0xFF, 0x38, 0x68, 0xAA,
+    0x42, 0xBA, 0x48, 0xA1, 0x52, 0x8C, 0xB4, 0xD6,
+    0x15, 0xB7, 0x88, 0xB3, 0x71, 0xC6, 0x69, 0x60,
+    0x6C, 0xEB, 0x4B, 0xF6, 0x19, 0x6A, 0x95, 0x8F,
+    0x01, 0x09, 0xC6, 0x13, 0xE6, 0x17, 0x38, 0xC8,
+    0x10, 0x49, 0x4F, 0x87, 0x43, 0x63, 0x62, 0x98,
+    0xB1, 0xAC,
+};
+static const struct ecdsa_sigver_st ecdsa_sigver_data[] = {
+    {
+        "SHA-1",
+        "P-192",
+        ITM(ecdsa_sigver_msg0),
+        ITM(ecdsa_sigver_pub0),
+        ITM(ecdsa_sigver_r0),
+        ITM(ecdsa_sigver_s0),
+        PASS,
+    },
+    {
+        "SHA2-512",
+        "P-521",
+        ITM(ecdsa_sigver_msg1),
+        ITM(ecdsa_sigver_pub1),
+        ITM(ecdsa_sigver_r1),
+        ITM(ecdsa_sigver_s1),
+        FAIL,
+    },
+};
+
+#endif /* OPENSSL_NO_EC */
+
+
+#ifndef OPENSSL_NO_DSA
+
+struct dsa_paramgen_st {
+    size_t L;
+    size_t N;
+};
+
+struct dsa_pqver_st {
+    const unsigned char *p;
+    size_t p_len;
+    const unsigned char *q;
+    size_t q_len;
+    const unsigned char *seed;
+    size_t seed_len;
+    int counter;
+    int pass;
+};
+
+struct dsa_siggen_st {
+    const char *digest_alg;
+    size_t L;
+    size_t N;
+    const unsigned char *msg;
+    size_t msg_len;
+};
+
+struct dsa_sigver_st {
+    const char *digest_alg;
+    const unsigned char *p;
+    size_t p_len;
+    const unsigned char *q;
+    size_t q_len;
+    const unsigned char *g;
+    size_t g_len;
+    const unsigned char *pub;
+    size_t pub_len;
+    const unsigned char *msg;
+    size_t msg_len;
+    const unsigned char *r;
+    size_t r_len;
+    const unsigned char *s;
+    size_t s_len;
+    int pass;
+};
+
+static const struct dsa_paramgen_st dsa_keygen_data[] = {
+    { 2048, 224 },
+};
+
+static const struct dsa_paramgen_st dsa_paramgen_data[] = {
+    { 2048, 256 },
+};
+
+/* dsa_pqver */
+static const unsigned char dsa_pqver_p0[] = {
+    0xEF, 0xC7, 0x95, 0xEB, 0x1E, 0x1C, 0x8F, 0x5E,
+    0x4A, 0x85, 0xCD, 0x20, 0x66, 0xC7, 0xB9, 0x6C,
+    0x4E, 0xC4, 0xE7, 0x3B, 0x7B, 0x8E, 0x0E, 0x8C,
+    0x00, 0xF5, 0x2E, 0x68, 0xF5, 0xC2, 0x89, 0x47,
+    0xA5, 0x7B, 0xA6, 0xA3, 0x30, 0xBC, 0xFA, 0x25,
+    0x29, 0xBD, 0xE2, 0x4D, 0x05, 0x0B, 0x6D, 0x2D,
+    0x49, 0x50, 0x53, 0xEF, 0x8C, 0xBE, 0xC3, 0xEC,
+    0x92, 0xC1, 0x45, 0xE3, 0x95, 0x39, 0x72, 0x58,
+    0xFD, 0x93, 0x23, 0x06, 0x37, 0xD6, 0x56, 0x1F,
+    0x75, 0x92, 0xAD, 0x15, 0xA9, 0x88, 0x25, 0x3F,
+    0xD6, 0x47, 0xB5, 0xB1, 0x32, 0x01, 0x2D, 0x70,
+    0x55, 0xB9, 0x5D, 0xED, 0x1B, 0x40, 0x39, 0x78,
+    0x74, 0xA6, 0xDF, 0x4B, 0xE4, 0x86, 0x8B, 0x56,
+    0x46, 0x1E, 0xDB, 0x04, 0xD2, 0xD2, 0x50, 0xE9,
+    0x5D, 0x88, 0xA8, 0x84, 0x55, 0xE3, 0xF3, 0xB7,
+    0x07, 0x54, 0x9E, 0x98, 0x03, 0x9F, 0x31, 0x86,
+    0xEB, 0x0D, 0x26, 0x97, 0x30, 0x31, 0x34, 0x64,
+    0x35, 0x56, 0x40, 0x35, 0xEA, 0xE5, 0x00, 0x90,
+    0xBD, 0x20, 0x93, 0xFC, 0xAD, 0x70, 0x9A, 0xF5,
+    0xB8, 0xA4, 0xAD, 0xEC, 0xFE, 0x64, 0xF4, 0x2C,
+    0x11, 0x25, 0x68, 0x27, 0x0E, 0x5C, 0x81, 0x57,
+    0x64, 0x9A, 0x50, 0x86, 0xA3, 0x69, 0x61, 0x1E,
+    0x0D, 0x62, 0xE9, 0x4D, 0x44, 0x1E, 0x1E, 0xE1,
+    0x6D, 0x8F, 0x10, 0x67, 0x82, 0xB6, 0x6A, 0xD0,
+    0x08, 0x59, 0xF3, 0xBA, 0xE8, 0x29, 0xE0, 0x60,
+    0x1F, 0x3E, 0xBA, 0xAB, 0x6E, 0xB6, 0x5B, 0xAF,
+    0xCC, 0x76, 0x5D, 0x70, 0x7F, 0x3A, 0xAA, 0x7E,
+    0x27, 0x23, 0x6F, 0x8E, 0xF8, 0x06, 0xC1, 0x3E,
+    0xAE, 0xBE, 0x22, 0x71, 0x93, 0xEC, 0x9A, 0x33,
+    0x3C, 0xA4, 0x77, 0xD4, 0x76, 0x79, 0x10, 0x5A,
+    0xF4, 0x07, 0x52, 0x66, 0x9D, 0xC5, 0xFD, 0xDA,
+    0xA1, 0xE7, 0xA2, 0x45, 0x27, 0x08, 0x54, 0xB9,
+    0x3B, 0xEC, 0x07, 0xFB, 0xE0, 0xF4, 0x4B, 0x7C,
+    0xB1, 0x04, 0x2B, 0x0E, 0x65, 0x3A, 0xF7, 0x65,
+    0x57, 0x65, 0xCF, 0x36, 0x28, 0x2A, 0x1C, 0x57,
+    0x10, 0x28, 0x02, 0x26, 0xF7, 0x45, 0xAA, 0x1B,
+    0x2E, 0xE3, 0x25, 0xEA, 0x28, 0xA1, 0x84, 0x1E,
+    0xA1, 0xA3, 0xAB, 0x52, 0x25, 0xD4, 0x64, 0xB2,
+    0xA8, 0xA5, 0xFD, 0x2F, 0x48, 0x90, 0x28, 0x8F,
+    0x8B, 0x10, 0x7F, 0x6F, 0x80, 0xA9, 0x4B, 0xB3,
+    0xC0, 0x5B, 0x27, 0xE9, 0x90, 0x90, 0x53, 0xA8,
+    0x30, 0x88, 0xD4, 0x9B, 0x09, 0x62, 0xCD, 0x99,
+    0x61, 0x63, 0x14, 0xDF, 0xC3, 0x5A, 0x60, 0xBE,
+    0xA3, 0x40, 0xAB, 0x29, 0x3E, 0xB2, 0x02, 0x19,
+    0x9D, 0x97, 0x75, 0x34, 0x0D, 0x71, 0x3B, 0xEC,
+    0xF1, 0x13, 0x23, 0xE6, 0xCA, 0x35, 0x84, 0xFF,
+    0x27, 0x4A, 0xE0, 0x11, 0x59, 0xEB, 0x1D, 0x8C,
+    0xFF, 0xF3, 0x91, 0x90, 0x3C, 0xE9, 0x43, 0x31,
+};
+static const unsigned char dsa_pqver_p1[] = {
+    0x83, 0xA6, 0x8F, 0xE5, 0xFE, 0xF0, 0x9D, 0x9E,
+    0x8A, 0x80, 0x9C, 0x47, 0xEF, 0xBE, 0x1A, 0xD0,
+    0x7F, 0xEA, 0x6D, 0x08, 0x59, 0x2D, 0x04, 0xB6,
+    0xAC, 0x2A, 0x54, 0x47, 0x42, 0xB2, 0x5F, 0x28,
+    0xF6, 0x30, 0x36, 0xE3, 0xDA, 0x4E, 0xDC, 0xC1,
+    0x6E, 0x61, 0xCE, 0x45, 0x1C, 0x73, 0x87, 0x3E,
+    0xB7, 0x94, 0xDB, 0x68, 0xEE, 0xFD, 0x8D, 0x93,
+    0x5E, 0x5D, 0xAB, 0x77, 0xA2, 0xF0, 0xD6, 0x60,
+    0xCD, 0x9D, 0x13, 0xE0, 0xA6, 0xE7, 0xEC, 0x45,
+    0xBA, 0xD8, 0xB0, 0x3D, 0x4F, 0x75, 0x30, 0xB7,
+    0x89, 0x96, 0x2B, 0x48, 0xFC, 0x73, 0xB8, 0x5C,
+    0x59, 0xDC, 0x41, 0xEF, 0xCE, 0xC6, 0x7F, 0x66,
+    0x4F, 0xB6, 0x1F, 0x9C, 0x91, 0xB4, 0xEE, 0xAA,
+    0x2C, 0x4A, 0x7F, 0x1F, 0xBF, 0xE2, 0x9A, 0xF2,
+    0x9F, 0x52, 0x83, 0x30, 0x97, 0x86, 0x7F, 0xA2,
+    0x85, 0x20, 0x75, 0x75, 0xAD, 0x01, 0xE2, 0x40,
+    0x3A, 0x82, 0xD8, 0x52, 0x91, 0x15, 0x67, 0x1B,
+    0x00, 0x78, 0xFD, 0x3E, 0x61, 0x8A, 0xA8, 0x1D,
+    0x1A, 0x07, 0x8E, 0x87, 0x48, 0x64, 0x1E, 0x5B,
+    0x05, 0x34, 0x7E, 0x5D, 0xD6, 0x11, 0xC4, 0xB7,
+    0x0E, 0xF3, 0x91, 0xC7, 0x2B, 0xAD, 0x22, 0x96,
+    0xA3, 0xF7, 0x4E, 0xEB, 0xE4, 0x9F, 0x67, 0x91,
+    0x9D, 0x65, 0x45, 0x8F, 0x92, 0x2F, 0x8B, 0x46,
+    0xCC, 0x4B, 0xB9, 0xC5, 0xD0, 0x00, 0xFF, 0xBB,
+    0x37, 0xD6, 0x20, 0x36, 0x7D, 0x4A, 0xC3, 0x75,
+    0xAC, 0x58, 0xE5, 0x24, 0x54, 0x47, 0x80, 0x2C,
+    0x83, 0xBD, 0xC8, 0xA7, 0x87, 0x20, 0x3D, 0xA8,
+    0x78, 0xE2, 0xC5, 0x4E, 0xE8, 0x4E, 0x3C, 0xFA,
+    0x75, 0xA0, 0x8D, 0x35, 0x8E, 0xF2, 0x61, 0x19,
+    0x84, 0x9C, 0x71, 0x95, 0x5B, 0x09, 0xE1, 0xB6,
+    0xC6, 0x6A, 0x7C, 0x34, 0x39, 0x67, 0x14, 0xAB,
+    0xA7, 0x6B, 0x45, 0x01, 0xF0, 0x0F, 0x52, 0xB5,
+    0x23, 0xD9, 0x67, 0x57, 0x91, 0x9F, 0xC2, 0xA9,
+    0xB6, 0x7C, 0x15, 0x59, 0x3E, 0x22, 0x89, 0xD6,
+    0x0B, 0x83, 0xB4, 0x29, 0xEF, 0x0B, 0x66, 0x30,
+    0x2D, 0xE7, 0xC5, 0x04, 0x1F, 0x28, 0x7D, 0x9F,
+    0xC9, 0x87, 0x05, 0xC6, 0x1B, 0x18, 0x1F, 0x3B,
+    0x90, 0x00, 0x31, 0x5B, 0xDC, 0x19, 0x7D, 0x71,
+    0xE4, 0xA4, 0x21, 0xB5, 0x37, 0xE7, 0x9B, 0xA4,
+    0xBC, 0x04, 0xF8, 0x0A, 0x95, 0x3F, 0xDB, 0x30,
+    0xA5, 0xC9, 0xC2, 0xD7, 0x19, 0x9D, 0x57, 0x77,
+    0x44, 0xB7, 0x47, 0xBD, 0xA1, 0x01, 0xEB, 0x51,
+    0xA4, 0xB2, 0x8B, 0x1A, 0x51, 0xA4, 0xCC, 0x07,
+    0x57, 0x19, 0xFB, 0xFC, 0xAA, 0x42, 0xCC, 0x2A,
+    0xCE, 0xF8, 0xFD, 0xF8, 0x92, 0xC4, 0xDC, 0x7B,
+    0x0B, 0x92, 0x9A, 0xD7, 0xC5, 0xBC, 0x6D, 0x74,
+    0x13, 0x0E, 0xD2, 0x8F, 0x86, 0xEB, 0x8D, 0xD7,
+    0xC6, 0xAC, 0x43, 0xD8, 0x00, 0x80, 0x53, 0x57,
+};
+static const unsigned char dsa_pqver_q0[] = {
+    0xCB, 0x74, 0xE6, 0x57, 0x37, 0x0F, 0x7A, 0x61,
+    0x0B, 0x09, 0xCE, 0x91, 0x78, 0x06, 0x3C, 0x7F,
+    0x20, 0xF5, 0xD1, 0x1E, 0x1D, 0xC2, 0x43, 0xBA,
+    0x89, 0xC8, 0x4A, 0x49, 0x83, 0x38, 0xE1, 0x2D,
+};
+static const unsigned char dsa_pqver_q1[] = {
+    0x85, 0x2B, 0x77, 0x9B, 0x1B, 0x70, 0x6F, 0x8C,
+    0x10, 0xF3, 0x2F, 0xA9, 0xC2, 0xEE, 0xF6, 0x74,
+    0x78, 0x5F, 0xD5, 0x5E, 0x2C, 0x34, 0xAF, 0xD1,
+    0x25, 0x63, 0x96, 0x6D, 0x6D, 0x84, 0x68, 0x3F,
+};
+static const unsigned char dsa_pqver_seed0[] = {
+    0x33, 0xDC, 0x43, 0xAF, 0xC4, 0x51, 0x5C, 0x3B,
+    0x8B, 0x8A, 0x0D, 0x5D, 0xA2, 0x84, 0xDE, 0x6D,
+    0xCC, 0x6C, 0xFD, 0x42, 0x37, 0x98, 0xFB, 0x66,
+    0xAB, 0xD3, 0x73, 0x96, 0x1F, 0xC5, 0xD1, 0x46,
+};
+static const unsigned char dsa_pqver_seed1[] = {
+    0xEE, 0xA4, 0x02, 0x70, 0x0B, 0x89, 0xB7, 0x96,
+    0x52, 0x5C, 0x00, 0xC4, 0x8E, 0x14, 0x45, 0x0F,
+    0x6A, 0x18, 0x00, 0xF7, 0x24, 0x52, 0x41, 0x0E,
+    0x33, 0x41, 0xD2, 0x91, 0xC3, 0x16, 0x7D, 0x5D,
+};
+static const struct dsa_pqver_st dsa_pqver_data[] = {
+    {
+        ITM(dsa_pqver_p0),
+        ITM(dsa_pqver_q0),
+        ITM(dsa_pqver_seed0),
+        1956,
+        PASS
+    },
+    {
+        ITM(dsa_pqver_p1),
+        ITM(dsa_pqver_q1),
+        ITM(dsa_pqver_seed1),
+        685,
+        FAIL
+    },
+};
+
+/* dsa_siggen */
+static const unsigned char dsa_siggen_msg0[]= {
+    0x85, 0x01, 0x2F, 0x61, 0x1C, 0x36, 0xA8, 0xE1,
+    0x54, 0x55, 0x13, 0xFA, 0x00, 0x58, 0x1E, 0xD4,
+    0xF2, 0x4C, 0x54, 0x67, 0xB3, 0xEA, 0x48, 0x2C,
+    0xD1, 0x27, 0xBE, 0x5F, 0x26, 0x35, 0xD4, 0x00,
+    0xDD, 0x6C, 0xD8, 0xE8, 0x3C, 0x6D, 0x2D, 0x50,
+    0x01, 0x53, 0xC7, 0xB5, 0xA3, 0x8E, 0x9A, 0x85,
+    0xA6, 0x53, 0x8C, 0x46, 0x55, 0x02, 0xA1, 0x5E,
+    0xEA, 0x6C, 0xCF, 0x4A, 0x86, 0xA9, 0x34, 0x1B,
+    0x0B, 0xB6, 0x88, 0x9A, 0xDE, 0xC4, 0x27, 0x7F,
+    0x93, 0xAA, 0x69, 0x54, 0x48, 0x33, 0x98, 0xA0,
+    0x71, 0x45, 0x09, 0x5A, 0x51, 0xDF, 0xB6, 0x66,
+    0x06, 0xB7, 0xAD, 0x64, 0xED, 0xC1, 0xFA, 0x6B,
+    0xA8, 0x0F, 0xE8, 0x3C, 0x2E, 0x0C, 0xCB, 0xB0,
+    0xAE, 0xDE, 0x25, 0x0C, 0x68, 0xA8, 0x15, 0x97,
+    0xD0, 0xBC, 0x0B, 0x81, 0x15, 0xDC, 0x2B, 0xF3,
+    0xF2, 0xB7, 0xA7, 0xA9, 0x74, 0xD6, 0x5D, 0xB8,
+    0xB7, 0xD1, 0xFC, 0x5D, 0xCA, 0x69, 0x5D, 0x7D,
+    0xC6, 0x1E, 0x37, 0x7D, 0xD3, 0xA9, 0x1E, 0xAE,
+    0x60, 0x22, 0x3A, 0x4B, 0x7A, 0xB1, 0x3D, 0xA4,
+    0x6D, 0xB3, 0xA5, 0x8C, 0x89, 0x91, 0xCF, 0xE6,
+    0x5B, 0xF9, 0xB6, 0x87, 0x56, 0x75, 0xB9, 0x0B,
+    0x08, 0x85, 0x32, 0x52, 0x81, 0x99, 0xA7, 0x98,
+    0x44, 0x30, 0x3B, 0x44, 0xBC, 0xB8, 0xB2, 0x6D,
+    0x59, 0x52, 0xD3, 0x84, 0x74, 0x65, 0x02, 0xF9,
+    0x71, 0xB9, 0x16, 0x7A, 0x42, 0x62, 0xDE, 0x9B,
+    0x66, 0xF6, 0x04, 0x2C, 0x1F, 0x96, 0xF7, 0x41,
+    0x38, 0x1A, 0xF1, 0x8C, 0x8A, 0x40, 0x9F, 0x72,
+    0x73, 0xF9, 0xE9, 0x35, 0x11, 0x1F, 0x02, 0x0C,
+    0xB1, 0x51, 0xE8, 0x78, 0xDB, 0xE0, 0xB2, 0x35,
+    0xBD, 0xC5, 0x84, 0x5B, 0x2B, 0x25, 0x66, 0x42,
+    0x87, 0xE5, 0xA4, 0x77, 0x71, 0xB4, 0x4A, 0x59,
+    0x31, 0xF1, 0x5A, 0xF5, 0x98, 0x9C, 0x61, 0xEA,
+    0x52, 0x2F, 0x51, 0x85, 0xD9, 0x7F, 0x26, 0xDD,
+    0x91, 0x63, 0x41, 0xD5, 0x99, 0xD1, 0x64, 0xCE,
+    0xEE, 0x82, 0xD1, 0x73, 0x0A, 0x54, 0x3B, 0x03,
+    0xD7, 0xC1, 0xF7, 0x01, 0xBD, 0x44, 0x99, 0xFE,
+    0x9B, 0x1E, 0x2C, 0x8F, 0xF4, 0x55, 0xC5, 0x59,
+    0x58, 0xAF, 0xCB, 0xAD, 0xB8, 0x22, 0x1A, 0x29,
+    0xF3, 0x18, 0x39, 0x31, 0x9B, 0xFC, 0x08, 0x7E,
+    0xBE, 0x45, 0xDA, 0x9E, 0xD8, 0x7F, 0x8C, 0x5D,
+    0x10, 0xF9, 0xF8, 0xB4, 0xFA, 0x58, 0xE6, 0x28,
+    0xB4, 0x6C, 0x70, 0x12, 0xD2, 0xFA, 0x49, 0xB2,
+    0x5F, 0xD0, 0x81, 0x4A, 0xA1, 0xAA, 0xF8, 0x93,
+    0xD2, 0x26, 0xE7, 0xDA, 0x7D, 0x79, 0xC5, 0xC8,
+    0xC2, 0x9E, 0xA7, 0x01, 0xD5, 0x7A, 0xF9, 0x75,
+    0x62, 0xDB, 0xDC, 0x93, 0x90, 0xDA, 0xA5, 0xA6,
+    0x20, 0x58, 0x17, 0x9E, 0x47, 0x4E, 0xFB, 0xB8,
+    0xFB, 0xCD, 0x2E, 0xF4, 0xCD, 0x49, 0x03, 0x90,
+};
+static struct dsa_siggen_st dsa_siggen_data[] = {
+    {
+        "SHA2-384",
+        3072,
+        256,
+        ITM(dsa_siggen_msg0),
+    },
+};
+
+/* dsa_sigver */
+static const unsigned char dsa_sigver_p0[] = {
+    0xD2, 0x90, 0x2E, 0x38, 0xA5, 0x32, 0xBB, 0x63,
+    0xE0, 0xC3, 0x20, 0xD9, 0x26, 0x06, 0x21, 0x06,
+    0x85, 0x3A, 0x4C, 0xE3, 0x13, 0x83, 0xCA, 0x43,
+    0x8C, 0x9C, 0x76, 0xC0, 0x65, 0x60, 0x27, 0x7E,
+    0x7C, 0xA0, 0x83, 0x9F, 0x65, 0x91, 0xF9, 0x16,
+    0x5F, 0xE8, 0x60, 0x0C, 0xC6, 0x91, 0x20, 0x35,
+    0xE7, 0xF1, 0x83, 0xE6, 0xF8, 0x8C, 0xBB, 0x4C,
+    0xFF, 0xF5, 0x4D, 0x09, 0x8E, 0x83, 0x72, 0xCB,
+    0x22, 0x5F, 0xD0, 0x85, 0xA9, 0x60, 0x3C, 0x4A,
+    0xA6, 0xDD, 0x73, 0x1F, 0xCF, 0xD0, 0xD7, 0x42,
+    0xB8, 0x72, 0x61, 0xDB, 0x91, 0xE3, 0xBB, 0x5C,
+    0x21, 0x41, 0xFD, 0x97, 0xD0, 0x81, 0x72, 0x53,
+    0x77, 0xE0, 0x15, 0x9E, 0xC0, 0xD0, 0x6A, 0xB4,
+    0x7F, 0xF8, 0x63, 0x39, 0x1A, 0x25, 0x63, 0x84,
+    0x4D, 0xBA, 0x2C, 0x29, 0x94, 0x28, 0xCE, 0x5B,
+    0x9A, 0xC3, 0x14, 0xAD, 0x9D, 0x82, 0x1D, 0x8F,
+    0xF3, 0xE9, 0x60, 0x65, 0x28, 0x0B, 0x0E, 0x48,
+    0x6B, 0xCC, 0x05, 0x9D, 0x3B, 0x1F, 0x1D, 0x0A,
+    0xA7, 0xF8, 0x22, 0xB0, 0xE1, 0x52, 0xB0, 0x25,
+    0x8F, 0xEA, 0x25, 0x28, 0xC9, 0x6F, 0x44, 0xCD,
+    0xA4, 0x16, 0x13, 0xE8, 0xD0, 0xDB, 0x43, 0x6E,
+    0xCE, 0xEC, 0x0B, 0xA8, 0x3E, 0x53, 0x10, 0xA2,
+    0x52, 0x0E, 0xBB, 0x63, 0x63, 0x84, 0x2C, 0x12,
+    0x93, 0x29, 0x98, 0xAF, 0x38, 0x8F, 0x0B, 0x86,
+    0x16, 0x99, 0x0E, 0x39, 0xA8, 0x4A, 0x0B, 0xCD,
+    0xAA, 0x66, 0x8F, 0x4C, 0x15, 0xB7, 0xA5, 0xBB,
+    0x22, 0x77, 0x8D, 0xE8, 0x05, 0x35, 0x2D, 0xAA,
+    0x8D, 0x83, 0xDE, 0xBC, 0x15, 0x3D, 0xC2, 0x95,
+    0x0E, 0x47, 0x85, 0x41, 0xAD, 0xE3, 0xB1, 0x70,
+    0x76, 0x1B, 0x62, 0x9E, 0x96, 0x8B, 0x18, 0xD7,
+    0xE3, 0xB5, 0xF8, 0x6E, 0x85, 0x67, 0x61, 0x54,
+    0x7C, 0x85, 0x08, 0x91, 0xF4, 0x46, 0x3F, 0x01,
+    0x99, 0x48, 0x18, 0x3C, 0x0D, 0xC7, 0x2D, 0xEC,
+    0xA4, 0x11, 0x1D, 0x4F, 0x7F, 0xBF, 0x3A, 0xE8,
+    0x9C, 0x1C, 0xAE, 0x9E, 0x30, 0x32, 0x1F, 0x81,
+    0xEF, 0x14, 0xFE, 0x5C, 0xC2, 0x5C, 0xD0, 0x6A,
+    0x7C, 0x18, 0x88, 0x9F, 0xC4, 0x97, 0x7D, 0x4B,
+    0x3B, 0x01, 0xEB, 0x59, 0x58, 0x1C, 0x00, 0x6B,
+    0x3E, 0xD6, 0x80, 0x80, 0x86, 0x06, 0x39, 0x88,
+    0x0D, 0x23, 0x1E, 0xD6, 0x5E, 0x1F, 0x92, 0x3B,
+    0xEC, 0x50, 0x0B, 0xA0, 0x83, 0x4F, 0x10, 0xDE,
+    0xAF, 0x7B, 0x19, 0xBC, 0xBD, 0x72, 0xE6, 0x42,
+    0xFE, 0xD7, 0xEF, 0x22, 0xD3, 0x83, 0x6B, 0x30,
+    0xA3, 0x95, 0x0D, 0x3E, 0x61, 0x9E, 0xBC, 0x0E,
+    0x14, 0x7E, 0x61, 0x05, 0x3D, 0xBA, 0x4E, 0xEF,
+    0x31, 0x75, 0x5D, 0x10, 0x1E, 0xBA, 0xBD, 0xBA,
+    0x89, 0x4D, 0x3A, 0x5B, 0x03, 0xB1, 0xAE, 0x27,
+    0x47, 0x2D, 0x03, 0xB1, 0x8A, 0x74, 0x1B, 0xF3,
+};
+static const unsigned char dsa_sigver_q0[] = {
+    0xAC, 0x71, 0x8D, 0x81, 0x05, 0x2F, 0xAB, 0x72,
+    0xB9, 0x96, 0x94, 0x98, 0xB5, 0x19, 0x2B, 0xE2,
+    0x78, 0x06, 0xAA, 0x32, 0xFC, 0xB9, 0xD2, 0xFD,
+    0x26, 0xC4, 0x50, 0x6F, 0x81, 0xD8, 0x04, 0xAB,
+};
+static const unsigned char dsa_sigver_g0[] = {
+    0x3D, 0x0B, 0x46, 0x39, 0x13, 0xFF, 0x67, 0xA8,
+    0x8C, 0xE8, 0x8A, 0x46, 0x46, 0x9A, 0xE6, 0x70,
+    0xA1, 0xF5, 0x48, 0xF5, 0x84, 0xF8, 0x93, 0x57,
+    0x9A, 0x4F, 0x2C, 0xD4, 0x26, 0x49, 0x1C, 0x83,
+    0x64, 0x14, 0x0B, 0x5B, 0xEF, 0x6F, 0x6F, 0x91,
+    0x14, 0xC5, 0x4D, 0xE8, 0x86, 0x47, 0x5C, 0xFC,
+    0xAE, 0xBF, 0xD8, 0x32, 0xE2, 0x96, 0xB9, 0x61,
+    0x70, 0x3F, 0x24, 0x29, 0xFA, 0x41, 0x5D, 0x8E,
+    0xD0, 0xB0, 0xF1, 0x26, 0xD5, 0x7C, 0xE6, 0x17,
+    0x48, 0xE5, 0x04, 0x0E, 0x58, 0x14, 0xEE, 0xBA,
+    0x64, 0xE9, 0xF1, 0x6A, 0x7C, 0x17, 0xAB, 0x7B,
+    0x28, 0xCF, 0x69, 0x7D, 0xDC, 0x54, 0xCA, 0xF2,
+    0x4C, 0x22, 0x17, 0xDD, 0xC3, 0x1A, 0x02, 0xE2,
+    0x8E, 0xE6, 0xA4, 0xFB, 0x84, 0x27, 0x2B, 0xE8,
+    0x14, 0xF3, 0x3D, 0xAC, 0x59, 0x0C, 0xAB, 0x69,
+    0x0E, 0x73, 0xDF, 0x82, 0xC1, 0xDE, 0xD7, 0xD9,
+    0xA7, 0xCA, 0x8F, 0x4B, 0xCE, 0x8A, 0x05, 0xBD,
+    0x07, 0xC8, 0x29, 0xBB, 0x46, 0x29, 0x2A, 0x4F,
+    0xA7, 0x12, 0x19, 0x91, 0x01, 0xA0, 0xAE, 0x16,
+    0xEF, 0xC1, 0xC5, 0x4B, 0x03, 0xF0, 0x53, 0xDC,
+    0xFC, 0x1C, 0xC4, 0x73, 0xB7, 0xBF, 0x53, 0xEB,
+    0x19, 0x63, 0xCA, 0x30, 0x53, 0x54, 0x12, 0x90,
+    0x0E, 0x43, 0xC7, 0x66, 0xFF, 0x29, 0xFC, 0xA4,
+    0xE8, 0xF6, 0x4B, 0x76, 0x3B, 0xA2, 0x65, 0x6B,
+    0x9E, 0xFA, 0xBA, 0x5B, 0x54, 0x94, 0x34, 0xF6,
+    0xD1, 0x20, 0x2A, 0xF7, 0x39, 0x72, 0xA3, 0xDB,
+    0xD1, 0x8F, 0xA6, 0x4D, 0x1B, 0xB1, 0x2D, 0xC5,
+    0x7F, 0xC5, 0x2C, 0x7E, 0x6D, 0xD9, 0xC8, 0xC2,
+    0x19, 0xC0, 0xC4, 0xC2, 0x77, 0xD9, 0x4C, 0x63,
+    0x77, 0x59, 0x0C, 0x5B, 0xFE, 0x69, 0xEF, 0xBF,
+    0x58, 0x47, 0x69, 0x3E, 0x49, 0xA7, 0x1B, 0x98,
+    0x6C, 0xE5, 0xA7, 0x42, 0x8B, 0x0E, 0x68, 0x05,
+    0x48, 0x80, 0x39, 0xF4, 0x02, 0x9E, 0xE2, 0x9F,
+    0x1C, 0xDA, 0x24, 0xC5, 0xB8, 0xEC, 0x03, 0xEA,
+    0x7A, 0x00, 0xDF, 0xCF, 0x58, 0xD0, 0xE7, 0xB7,
+    0xF3, 0xE7, 0x36, 0xDD, 0x1F, 0x65, 0xF9, 0x2D,
+    0x6F, 0xC3, 0xE4, 0x72, 0xFD, 0xBA, 0x58, 0x8D,
+    0xB5, 0xDF, 0x61, 0x3D, 0x3B, 0xB5, 0xF3, 0x08,
+    0xE7, 0x21, 0x5A, 0x7D, 0xFF, 0x02, 0x1E, 0x0E,
+    0x4E, 0xB5, 0x0D, 0x3D, 0x33, 0xF4, 0xA7, 0x6D,
+    0xF7, 0x96, 0xC2, 0x96, 0x85, 0x33, 0x9C, 0x58,
+    0x72, 0x5C, 0x97, 0x73, 0x0E, 0xDC, 0x5C, 0x6B,
+    0x3D, 0x68, 0xF7, 0xF0, 0x0F, 0xCC, 0x01, 0xBB,
+    0x47, 0x01, 0x3C, 0xB0, 0x52, 0x48, 0x70, 0xB8,
+    0x0C, 0x0F, 0x04, 0xB5, 0x8F, 0x70, 0x50, 0x12,
+    0x7C, 0x9D, 0xD1, 0xC1, 0x2B, 0xFE, 0x95, 0x31,
+    0x8F, 0x2D, 0xFA, 0xAC, 0xAE, 0x24, 0xDD, 0x13,
+    0xDA, 0x76, 0xC2, 0x34, 0xB9, 0x4A, 0x3E, 0xC3,
+};
+static const unsigned char dsa_sigver_pub0[] = {
+    0x91, 0x78, 0x1C, 0xBA, 0x8A, 0x2F, 0xF6, 0xEC,
+    0x9B, 0xD4, 0x73, 0x2C, 0x1F, 0xC0, 0xFE, 0x79,
+    0xCF, 0xAC, 0x0C, 0x3C, 0x0D, 0x81, 0x85, 0x3D,
+    0xCD, 0x67, 0x2B, 0x77, 0x99, 0x4A, 0x51, 0x48,
+    0x58, 0x03, 0xC9, 0x68, 0xE6, 0x19, 0x26, 0x28,
+    0xDC, 0x86, 0x9F, 0x8F, 0xCE, 0xDD, 0x1B, 0xCD,
+    0xDD, 0x63, 0x4E, 0xCE, 0x76, 0x4D, 0xD5, 0x0D,
+    0x71, 0x73, 0x04, 0x03, 0x9C, 0x35, 0xD0, 0x56,
+    0x98, 0x25, 0xA7, 0x06, 0xF2, 0x6B, 0xA9, 0x9F,
+    0x9A, 0xB1, 0x2A, 0xBD, 0xB7, 0x71, 0x62, 0x99,
+    0x06, 0x47, 0x77, 0x22, 0x57, 0xFA, 0x24, 0x21,
+    0x21, 0xB0, 0x78, 0x26, 0x7E, 0xEC, 0xB6, 0xEB,
+    0x82, 0x15, 0x53, 0x68, 0xAE, 0xAC, 0x5B, 0xDC,
+    0xA6, 0x7F, 0x6B, 0x26, 0xE6, 0x59, 0x22, 0x55,
+    0x1C, 0x3B, 0xFD, 0xD5, 0x90, 0xA9, 0x6F, 0xB3,
+    0xE6, 0x99, 0x8E, 0x26, 0x72, 0xA1, 0x02, 0xAA,
+    0x37, 0xF6, 0x89, 0x68, 0xF1, 0x5A, 0x6D, 0x54,
+    0xAD, 0x9D, 0xF3, 0x03, 0xBE, 0x3F, 0x9D, 0x85,
+    0x38, 0x25, 0xB8, 0xDF, 0xB8, 0x43, 0x21, 0xCA,
+    0xF8, 0xDC, 0x12, 0x40, 0x1E, 0xEF, 0x37, 0x40,
+    0xCE, 0x0E, 0x02, 0x88, 0x63, 0x98, 0x2E, 0x93,
+    0x89, 0xB0, 0x43, 0xAC, 0x0E, 0x62, 0x4C, 0x38,
+    0x14, 0xAC, 0x0C, 0xA3, 0x03, 0x10, 0x8E, 0xB4,
+    0x60, 0x10, 0x9B, 0xCC, 0x16, 0xA7, 0xB8, 0x1D,
+    0x73, 0x81, 0x26, 0x12, 0xA8, 0x9A, 0xFE, 0x17,
+    0xBB, 0x2D, 0x33, 0x5E, 0x8C, 0xA4, 0x80, 0xBF,
+    0x84, 0x37, 0xCA, 0x0F, 0x50, 0x23, 0x79, 0x20,
+    0x2A, 0x8E, 0xD1, 0x1F, 0x9F, 0x89, 0x98, 0x4F,
+    0xF5, 0xB6, 0x0F, 0xB9, 0x3C, 0xFC, 0x6C, 0x00,
+    0xBC, 0x76, 0x2F, 0xB4, 0xFD, 0x22, 0x13, 0x37,
+    0x26, 0xCD, 0x9B, 0xAF, 0x4C, 0x89, 0x16, 0xD0,
+    0x73, 0x44, 0xF9, 0x71, 0x60, 0xA2, 0x3E, 0xFE,
+    0x24, 0xFE, 0xFC, 0xFE, 0x90, 0x91, 0xED, 0x92,
+    0x57, 0x0A, 0xFA, 0xEB, 0x21, 0x99, 0xE3, 0x9A,
+    0xFF, 0x5C, 0x74, 0x85, 0xC2, 0x6D, 0x83, 0x90,
+    0xEE, 0x84, 0x05, 0x1A, 0x00, 0xAC, 0x87, 0xA7,
+    0x78, 0x87, 0xCA, 0x70, 0xFC, 0xB0, 0xF4, 0x3B,
+    0x61, 0x7C, 0xD0, 0x09, 0x63, 0x2B, 0x5E, 0xC2,
+    0xFE, 0x15, 0x41, 0xB3, 0x9F, 0xFC, 0x19, 0xE3,
+    0x4D, 0x3C, 0x6F, 0x89, 0xEB, 0x8A, 0x43, 0xEC,
+    0x8E, 0xFB, 0xEC, 0xCD, 0x99, 0x2E, 0x4B, 0x02,
+    0x99, 0xAC, 0xC6, 0x62, 0xAA, 0xC5, 0x0F, 0xA3,
+    0x0B, 0xBB, 0xCD, 0x51, 0x0C, 0x19, 0xA7, 0x7A,
+    0x43, 0x6C, 0xAA, 0x26, 0x28, 0x2A, 0xC9, 0x9D,
+    0x97, 0xAE, 0x83, 0x74, 0xDA, 0xC4, 0x03, 0x98,
+    0x94, 0x58, 0x28, 0xBC, 0x32, 0x1D, 0xD4, 0xF2,
+    0x6F, 0x89, 0x92, 0xD4, 0x80, 0x9B, 0xDE, 0x6B,
+    0xC5, 0x6F, 0xDB, 0x7A, 0x03, 0x1C, 0xF5, 0x55,
+};
+static const unsigned char dsa_sigver_msg0[] = {
+    0x32, 0xE9, 0x64, 0x47, 0xED, 0x3B, 0xF0, 0xC0,
+    0xCA, 0xC2, 0x90, 0xF5, 0x10, 0x60, 0x99, 0x82,
+    0x4D, 0x13, 0x44, 0xFA, 0x92, 0xD1, 0xFD, 0x50,
+    0x26, 0x80, 0xEA, 0x7B, 0x7D, 0xC5, 0xF0, 0xB7,
+};
+static const unsigned char dsa_sigver_msg1[] = {
+    0x31, 0xE9, 0x64, 0x47, 0xED, 0x3B, 0xF0, 0xC0,
+    0xCA, 0xC2, 0x90, 0xF5, 0x10, 0x60, 0x99, 0x82,
+    0x4D, 0x13, 0x44, 0xFA, 0x92, 0xD1, 0xFD, 0x50,
+    0x26, 0x80, 0xEA, 0x7B, 0x7D, 0xC5, 0xF0, 0xB7
+};
+static const unsigned char dsa_sigver_r0[] = {
+    0x2A, 0x24, 0x0F, 0xA7, 0x04, 0xF1, 0xE0, 0x60,
+    0x3B, 0x07, 0xDE, 0xB6, 0x5F, 0x01, 0x20, 0x81,
+    0xDD, 0x64, 0x22, 0x0F, 0x9F, 0x2E, 0x67, 0x33,
+    0xB7, 0x56, 0xDE, 0x17, 0xD0, 0xED, 0x9D, 0x30,
+};
+static const unsigned char dsa_sigver_s0[] = {
+    0x15, 0x93, 0x81, 0x6E, 0xC2, 0x07, 0x6E, 0x06,
+    0x6A, 0xBF, 0x62, 0xBF, 0x93, 0xA6, 0xCB, 0x6E,
+    0xBA, 0x1E, 0x72, 0x57, 0x27, 0x0E, 0x85, 0x9E,
+    0x8C, 0x42, 0x9A, 0x41, 0x63, 0x27, 0x74, 0x4F,
+};
+static const struct dsa_sigver_st dsa_sigver_data[] = {
+    {
+        "SHA2-512",
+        ITM(dsa_sigver_p0),
+        ITM(dsa_sigver_q0),
+        ITM(dsa_sigver_g0),
+        ITM(dsa_sigver_pub0),
+        ITM(dsa_sigver_msg0),
+        ITM(dsa_sigver_r0),
+        ITM(dsa_sigver_s0),
+        PASS,
+    },
+    {
+        "SHA2-512",
+        ITM(dsa_sigver_p0),
+        ITM(dsa_sigver_q0),
+        ITM(dsa_sigver_g0),
+        ITM(dsa_sigver_pub0),
+        ITM(dsa_sigver_msg1),
+        ITM(dsa_sigver_r0),
+        ITM(dsa_sigver_s0),
+        FAIL,
+    },
+};
+
+#endif /* OPENSSL_NO_DSA */
+
+struct cipher_st {
+    const char *alg;
+    const unsigned char *key;
+    size_t key_len;
+    const unsigned char *iv;
+    size_t iv_len;
+    const unsigned char *pt;
+    size_t pt_len;
+    const unsigned char *ct;
+    size_t ct_len;
+};
+
+struct cipher_ccm_st {
+    const char *alg;
+    const unsigned char *key;
+    size_t key_len;
+    const unsigned char *iv;
+    size_t iv_len;
+    const unsigned char *aad;
+    size_t aad_len;
+    const unsigned char *pt;
+    size_t pt_len;
+    const unsigned char *ct; /* includes the tag */
+    size_t ct_len;
+};
+
+struct cipher_gcm_st {
+    const char *alg;
+    const unsigned char *key;
+    size_t key_len;
+    const unsigned char *iv;
+    size_t iv_len;
+    const unsigned char *aad;
+    size_t aad_len;
+    const unsigned char *pt;
+    size_t pt_len;
+    const unsigned char *ct;
+    size_t ct_len;
+    const unsigned char *tag;
+    size_t tag_len;
+};
+
+
+static const unsigned char cipher_enc_pt0[] = {
+    0xF3, 0x44, 0x81, 0xEC, 0x3C, 0xC6, 0x27, 0xBA,
+    0xCD, 0x5D, 0xC3, 0xFB, 0x08, 0xF2, 0x73, 0xE6,
+};
+static const unsigned char cipher_enc_pt1[] = {
+    0x1B, 0x07, 0x7A, 0x6A, 0xF4, 0xB7, 0xF9, 0x82,
+    0x29, 0xDE, 0x78, 0x6D, 0x75, 0x16, 0xB6, 0x39,
+};
+static const unsigned char cipher_enc_pt2[] = {
+    0x91, 0x07, 0x41, 0x31, 0xF1, 0xF8, 0x6C, 0xCD,
+    0x54, 0x8D, 0x22, 0xA6, 0x93, 0x40, 0xFF, 0x39,
+};
+static const unsigned char cipher_enc_pt3[] = {
+    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+    0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+    0x10, 0x11, 0x12, 0x13
+};
+static const unsigned char cipher_enc_key0[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char cipher_enc_key1[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char cipher_enc_key2[] = {
+    0xE8, 0x70, 0x13, 0x1C, 0xE7, 0x03, 0xD6, 0x51,
+    0x4E, 0x76, 0x1F, 0x95, 0xE6, 0xEE, 0x9E, 0xFB,
+};
+static const unsigned char cipher_enc_key3[] = {
+    0xff, 0xfe, 0xfd, 0xfc, 0xfb, 0xfa, 0xf9, 0xf8,
+    0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf2, 0xf1, 0xf0,
+    0xbf, 0xbe, 0xbd, 0xbc, 0xbb, 0xba, 0xb9, 0xb8,
+    0xb7, 0xb6, 0xb5, 0xb4, 0xb3, 0xb2, 0xb1, 0xb0,
+};
+static const unsigned char cipher_enc_ct0[] = {
+    0x03, 0x36, 0x76, 0x3E, 0x96, 0x6D, 0x92, 0x59,
+    0x5A, 0x56, 0x7C, 0xC9, 0xCE, 0x53, 0x7F, 0x5E,
+};
+static const unsigned char cipher_enc_ct1[] = {
+    0x27, 0x5C, 0xFC, 0x04, 0x13, 0xD8, 0xCC, 0xB7,
+    0x05, 0x13, 0xC3, 0x85, 0x9B, 0x1D, 0x0F, 0x72,
+};
+static const unsigned char cipher_enc_ct2[] = {
+    0x3A, 0xF6, 0x4C, 0x70, 0x37, 0xEE, 0x48, 0x13,
+    0xD8, 0x5F, 0xE9, 0xB3, 0x7F, 0xE6, 0x6A, 0xD4,
+};
+static const unsigned char cipher_enc_ct3[] = {
+    0x9d, 0x84, 0xc8, 0x13, 0xf7, 0x19, 0xaa, 0x2c,
+    0x7b, 0xe3, 0xf6, 0x61, 0x71, 0xc7, 0xc5, 0xc2,
+    0xed, 0xbf, 0x9d, 0xac,
+};
+static const unsigned char cipher_enc_iv0[] = {
+    0x00,
+};
+static const unsigned char cipher_enc_iv1[] = {
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+static const unsigned char cipher_enc_iv2[] = {
+    0x53, 0xF2, 0x25, 0xD8, 0xDE, 0x97, 0xF1, 0x4B,
+    0xFE, 0x3E, 0xC6, 0x5E, 0xC3, 0xFF, 0xF7, 0xD3,
+};
+static const unsigned char cipher_enc_iv3[] = {
+    0x9a, 0x78, 0x56, 0x34, 0x12, 0x00, 0x00, 0x00,
+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
+static const struct cipher_st cipher_enc_data[] = {
+    {
+        "AES-128-ECB",
+        ITM(cipher_enc_key0),
+        NULL, 0,     /* iv */
+        ITM(cipher_enc_pt0),
+        ITM(cipher_enc_ct0),
+    },
+    {
+        "AES-192-CBC",
+        ITM(cipher_enc_key1),
+        ITM(cipher_enc_iv1),
+        ITM(cipher_enc_pt1),
+        ITM(cipher_enc_ct1),
+    },
+    {
+        "AES-128-CTR",
+        ITM(cipher_enc_key2),
+        ITM(cipher_enc_iv2),
+        ITM(cipher_enc_pt2),
+        ITM(cipher_enc_ct2),
+    },
+    {
+        "AES-128-XTS",
+         ITM(cipher_enc_key3),
+         ITM(cipher_enc_iv3),
+         ITM(cipher_enc_pt3),
+         ITM(cipher_enc_ct3),
+    }
+};
+
+static const unsigned char aes_ccm_enc_pt0[] = {
+    0xDA, 0x6A, 0xDC, 0xB2, 0xA5, 0xCC, 0xC3, 0xE7,
+    0xFC, 0x4C, 0xDF, 0x0A, 0xAB, 0xDC, 0x3B, 0x38,
+    0x26, 0x8B, 0x21, 0x82, 0xCA, 0x26, 0xE6, 0x2C,
+};
+static const unsigned char aes_ccm_enc_key0[] = {
+    0xDE, 0xF8, 0x67, 0xBC, 0x40, 0xB6, 0x7C, 0xAA,
+    0x4A, 0x00, 0xE8, 0x07, 0x24, 0x52, 0xAE, 0x72,
+};
+static const unsigned char aes_ccm_enc_aad0[] = {
+    0x29, 0x8D, 0x01, 0x92, 0x3B, 0x50, 0x1F, 0x66,
+    0xCE, 0xD3, 0x57, 0x4B, 0x7B, 0x4F, 0x07, 0x57,
+};
+static const unsigned char aes_ccm_enc_iv0[] = {
+    0x44, 0xEE, 0x48, 0x11, 0x4D, 0x3B, 0x71, 0x33,
+    0xF0, 0xF7, 0x12, 0xA2, 0xA5,
+};
+static const unsigned char aes_ccm_enc_ct0[] = {
+    0x30, 0x4D, 0x19, 0x31, 0x02, 0x66, 0x95, 0x2E,
+    0x23, 0x6D, 0xF4, 0xB9, 0xDF, 0xFE, 0xCA, 0x92,
+    0x04, 0x2A, 0x32, 0xB5, 0x08, 0x2C, 0x8B, 0x6F,
+    0x1B, 0x14, 0xB8, 0x62, 0x8B, 0xA0, 0x12, 0x4E,
+    0x6A, 0x6F, 0x85, 0x86, 0x24, 0x6A, 0x83, 0xE0,
+};
+static const struct cipher_ccm_st aes_ccm_enc_data[] = {
+    {
+        "AES-128-CCM",
+        ITM(aes_ccm_enc_key0),
+        ITM(aes_ccm_enc_iv0),
+        ITM(aes_ccm_enc_aad0),
+        ITM(aes_ccm_enc_pt0),
+        ITM(aes_ccm_enc_ct0),
+    },
+};
+
+static const unsigned char aes_gcm_enc_pt0[] = {
+    0x97,
+};
+static const unsigned char aes_gcm_enc_key0[] = {
+    0x3E, 0x77, 0x38, 0xA6, 0x0A, 0xB3, 0x95, 0x90,
+    0xFA, 0x8B, 0x3B, 0xCF, 0xE1, 0xA3, 0x8C, 0x7D,
+};
+static const unsigned char aes_gcm_enc_aad0[] = {
+    0xE7, 0xEF, 0xCB, 0x0F, 0x3D, 0x94, 0x1D, 0x0F,
+    0x3D, 0x65, 0x69, 0xFC, 0xDA, 0x77, 0x36, 0x5E,
+    0xB9, 0x20, 0xF8, 0xDA, 0x81, 0xDF, 0x6B, 0x4C,
+    0x2A, 0x70, 0x5E, 0xE3, 0x07, 0xCE, 0xCF, 0x62,
+    0x84,
+};
+static const unsigned char aes_gcm_enc_iv0[] = {
+    0x01, 0x02, 0x03, 0x04, 0xEB, 0xED, 0x2F, 0x4B,
+    0xD1, 0x20, 0x2C, 0xCD,
+};
+static const unsigned char aes_gcm_enc_ct0[] = {
+    0x63,
+};
+static const unsigned char aes_gcm_enc_tag0[] = {
+    0xA2, 0x8E, 0xA5, 0xF6, 0x6A, 0x1C, 0xE6, 0xD7,
+    0xFF, 0xCD, 0x7F, 0x49,
+};
+static const struct cipher_gcm_st aes_gcm_enc_data[] = {
+    {
+        "AES-128-GCM",
+        ITM(aes_gcm_enc_key0),
+        ITM(aes_gcm_enc_iv0),
+        ITM(aes_gcm_enc_aad0),
+        ITM(aes_gcm_enc_pt0),
+        ITM(aes_gcm_enc_ct0),
+        ITM(aes_gcm_enc_tag0),
+    },
+};
+
+#ifndef OPENSSL_NO_DH
+
+struct dh_safe_prime_keygen_st {
+    const char *group_name;
+};
+
+struct dh_safe_prime_keyver_st {
+    const char *group_name;
+    const unsigned char *pub;
+    size_t pub_len;
+    const unsigned char *priv;
+    size_t priv_len;
+    int pass;
+};
+
+static const struct dh_safe_prime_keygen_st dh_safe_prime_keygen_data[] = {
+    { "ffdhe2048" },
+};
+
+static const unsigned char dh_safe_prime_keyver_priv0[] = {
+    0x39, 0x9C, 0x08, 0x8E, 0x4A, 0x1E, 0x1A, 0x03,
+    0x18, 0x5A, 0x72, 0x4F, 0xCB, 0x13, 0xFB, 0x8F,
+    0x7F, 0x14, 0x12, 0x48, 0x9A, 0x18, 0x03, 0x1C,
+    0x03, 0x98, 0x7E, 0x3C, 0xEF, 0x57, 0xF2, 0x1E,
+    0xD5, 0x54, 0x5C, 0x0F, 0x36, 0x5E, 0xB0, 0xF8,
+    0xD1, 0x27, 0x79, 0x24, 0x69, 0xB5, 0x7C, 0xF1,
+    0x39, 0xFC, 0xE3, 0x79, 0xF0, 0xD6, 0xA0, 0xE1,
+    0xA5, 0xA7, 0x65, 0x01, 0xBA, 0xFE, 0xBB, 0x28,
+    0xF0, 0x9C, 0x49, 0x90, 0x68, 0xB4, 0xE7, 0xE2,
+    0xB6, 0xBF, 0xB9, 0xF8, 0x96, 0xAA, 0xF9, 0xE6,
+    0x0B, 0x8A, 0x86, 0x0D, 0x31, 0x2C, 0x90, 0xDA,
+    0x4E, 0xFB, 0xE3, 0x59, 0x3F, 0xFB, 0x14, 0x33,
+    0xF6, 0xBD, 0xDA, 0x5D, 0x27, 0xCC, 0x7C, 0x1C,
+    0x30, 0xC8, 0xB2, 0xAF, 0x2A, 0xA8, 0x25, 0x97,
+    0xDC, 0x5E, 0xEF, 0x22, 0xCB, 0xF6, 0x88, 0x83,
+    0xD0, 0x47, 0x3F, 0x5D, 0xF3, 0x2A, 0xE0, 0xCC,
+    0x86, 0x49, 0x5A, 0x8F, 0x67, 0xF6, 0xC4, 0xD8,
+    0x3F, 0x09, 0xE8, 0x49, 0x89, 0x2E, 0xC0, 0xB4,
+    0x9C, 0x06, 0x9C, 0x40, 0x10, 0xFB, 0x20, 0xC6,
+    0xF1, 0x5F, 0x52, 0x3F, 0x21, 0xBF, 0xBB, 0x13,
+    0x6A, 0x81, 0x1C, 0xFF, 0x19, 0x2A, 0x36, 0xD2,
+    0x13, 0x23, 0x33, 0xD1, 0xEF, 0x34, 0xF3, 0xA6,
+    0xD5, 0x56, 0xAF, 0x1A, 0x63, 0xFC, 0x95, 0x86,
+    0xD5, 0xEB, 0xBF, 0x49, 0x84, 0x73, 0x30, 0x1D,
+    0xE2, 0xA1, 0xAE, 0x6D, 0x20, 0x69, 0xAE, 0xB6,
+    0x1A, 0xB9, 0xF2, 0x7A, 0xE3, 0x17, 0x4E, 0x7C,
+    0x8F, 0xE8, 0x34, 0x02, 0x59, 0xB4, 0x54, 0x9A,
+    0x8D, 0x19, 0x04, 0x2A, 0x8E, 0xF8, 0x05, 0xA3,
+    0x98, 0x5B, 0xBD, 0xB4, 0x6A, 0xDA, 0xAA, 0x1F,
+    0xFC, 0x56, 0xA0, 0x4D, 0x22, 0x66, 0x31, 0xEA,
+    0x8A, 0xC8, 0x61, 0x12, 0x40, 0xF0, 0x38, 0x0B,
+    0xA3, 0x23, 0x40, 0x97, 0x7A, 0x18, 0xE3, 0x42,
+};
+static const unsigned char dh_safe_prime_keyver_pub0[] = {
+    0xFA, 0xDA, 0x86, 0x67, 0xE9, 0x12, 0x67, 0x79,
+    0x50, 0xAE, 0x64, 0x0B, 0x07, 0x47, 0x8F, 0xA5,
+    0xD1, 0x27, 0x6C, 0xFC, 0x10, 0xD8, 0x90, 0x8D,
+    0x93, 0x75, 0xAD, 0x31, 0xBD, 0x97, 0xBE, 0xD5,
+    0xB5, 0x59, 0x2F, 0x37, 0x52, 0x32, 0x30, 0x75,
+    0xD3, 0xA5, 0x36, 0x10, 0x62, 0x4C, 0x82, 0x06,
+    0xB9, 0x29, 0xAE, 0x14, 0xD1, 0xB0, 0xD0, 0x23,
+    0x7A, 0xE6, 0xEA, 0x7E, 0x8E, 0xE3, 0xC7, 0xEB,
+    0x43, 0x78, 0xFA, 0x9A, 0x40, 0x9A, 0x6F, 0xF5,
+    0x42, 0x8A, 0xF7, 0xF3, 0x92, 0xE6, 0x5D, 0x68,
+    0x9B, 0x2A, 0x91, 0xB5, 0x37, 0x33, 0x3F, 0x35,
+    0xA5, 0xFB, 0x54, 0xD1, 0x3C, 0x46, 0xC6, 0x3C,
+    0x16, 0x3A, 0xD7, 0xF8, 0x55, 0x48, 0x9A, 0xB7,
+    0xB1, 0x40, 0xBF, 0xAF, 0x26, 0x1B, 0x07, 0x0F,
+    0x11, 0x04, 0x63, 0x06, 0xDA, 0x2D, 0x45, 0x0E,
+    0x7F, 0x17, 0xA4, 0x38, 0xBD, 0x68, 0x5A, 0xA9,
+    0xC4, 0x7F, 0x7E, 0xC7, 0xF0, 0xFC, 0x74, 0x87,
+    0x55, 0xCD, 0x35, 0xA8, 0xAA, 0x59, 0xA7, 0xFA,
+    0xC1, 0x34, 0x67, 0x04, 0xD8, 0xCC, 0xE1, 0x77,
+    0x60, 0xE1, 0xBE, 0xC0, 0xA5, 0x52, 0xA4, 0x72,
+    0x3A, 0x19, 0xFA, 0x76, 0xC8, 0x67, 0x60, 0x5E,
+    0x1C, 0x43, 0xF4, 0x50, 0xA0, 0xCB, 0x33, 0x77,
+    0x2D, 0x2D, 0x3B, 0x5D, 0x7D, 0x72, 0x2E, 0x38,
+    0xCD, 0x71, 0xB1, 0xBF, 0xB5, 0x10, 0x80, 0xCD,
+    0xA4, 0x5D, 0x70, 0x6E, 0xD5, 0x7E, 0xA2, 0xAA,
+    0xDC, 0xA4, 0x7C, 0x7A, 0x7D, 0x21, 0x09, 0x6A,
+    0x14, 0xB2, 0x21, 0x24, 0xA4, 0xF4, 0x6C, 0xD2,
+    0xBA, 0x76, 0x99, 0xD7, 0x69, 0x44, 0xA8, 0x66,
+    0x85, 0x08, 0x50, 0xBA, 0x42, 0x37, 0xA2, 0xC2,
+    0xD5, 0x45, 0x7E, 0x7B, 0xE9, 0x4A, 0xAE, 0xEE,
+    0x84, 0x2A, 0xEB, 0xA9, 0x4A, 0x69, 0x40, 0x83,
+    0xBA, 0xCC, 0x1E, 0x1B, 0x25, 0x56, 0x13, 0x88,
+};
+static const struct dh_safe_prime_keyver_st dh_safe_prime_keyver_data[] = {
+    {
+        "ffdhe2048",
+        ITM(dh_safe_prime_keyver_pub0),
+        ITM(dh_safe_prime_keyver_priv0),
+        PASS
+    },
+};
+
+#endif /* OPENSSL_NO_DH */
+
+#ifndef OPENSSL_NO_RSA
+struct rsa_keygen_st {
+    size_t mod;
+    const unsigned char *e;
+    size_t e_len;
+    const unsigned char *xp1;
+    size_t xp1_len;
+    const unsigned char *xp2;
+    size_t xp2_len;
+    const unsigned char *xp;
+    size_t xp_len;
+    const unsigned char *xq1;
+    size_t xq1_len;
+    const unsigned char *xq2;
+    size_t xq2_len;
+    const unsigned char *xq;
+    size_t xq_len;
+
+    const unsigned char *p1;
+    size_t p1_len;
+    const unsigned char *p2;
+    size_t p2_len;
+    const unsigned char *q1;
+    size_t q1_len;
+    const unsigned char *q2;
+    size_t q2_len;
+    const unsigned char *p;
+    size_t p_len;
+    const unsigned char *q;
+    size_t q_len;
+    const unsigned char *n;
+    size_t n_len;
+    const unsigned char *d;
+    size_t d_len;
+};
+
+static const unsigned char rsa_keygen0_e[] = {
+    0x01,0x00,0x01
+};
+static const unsigned char rsa_keygen0_xp[] = {
+    0xcf,0x72,0x1b,0x9a,0xfd,0x0d,0x22,0x1a,0x74,0x50,0x97,0x22,0x76,0xd8,0xc0,
+    0xc2,0xfd,0x08,0x81,0x05,0xdd,0x18,0x21,0x99,0x96,0xd6,0x5c,0x79,0xe3,0x02,
+    0x81,0xd7,0x0e,0x3f,0x3b,0x34,0xda,0x61,0xc9,0x2d,0x84,0x86,0x62,0x1e,0x3d,
+    0x5d,0xbf,0x92,0x2e,0xcd,0x35,0x3d,0x6e,0xb9,0x59,0x16,0xc9,0x82,0x50,0x41,
+    0x30,0x45,0x67,0xaa,0xb7,0xbe,0xec,0xea,0x4b,0x9e,0xa0,0xc3,0x05,0xb3,0x88,
+    0xd4,0x4c,0xac,0xeb,0xe4,0x03,0xc6,0xca,0xcb,0xd9,0xd3,0x4e,0xf6,0x7f,0x2c,
+    0x27,0x1e,0x08,0x6c,0xc2,0xd6,0x45,0x1f,0x84,0xe4,0x3c,0x97,0x19,0xde,0xb8,
+    0x55,0xaf,0x0e,0xcf,0x9e,0xb0,0x9c,0x20,0xd3,0x1f,0xa8,0xd7,0x52,0xc2,0x95,
+    0x1c,0x80,0x15,0x42,0x4d,0x4f,0x19,0x16
+};
+static const unsigned char rsa_keygen0_xp1[] = {
+    0xac,0x5f,0x7f,0x6e,0x33,0x3e,0x97,0x3a,0xb3,0x17,0x44,0xa9,0x0f,0x7a,0x54,
+    0x70,0x27,0x06,0x93,0xd5,0x49,0xde,0x91,0x83,0xbc,0x8a,0x7b,0x95
+};
+static const unsigned char rsa_keygen0_xp2[] = {
+    0x0b,0xf6,0xe8,0x79,0x5a,0x81,0xae,0x90,0x1d,0xa4,0x38,0x74,0x9c,0x0e,0x6f,
+    0xe0,0x03,0xcf,0xc4,0x53,0x16,0x32,0x17,0xf7,0x09,0x5f,0xd9
+};
+static const unsigned char rsa_keygen0_xq[] = {
+    0xfe,0xab,0xf2,0x7c,0x16,0x4a,0xf0,0x8d,0x31,0xc6,0x0a,0x82,0xe2,0xae,0xbb,
+    0x03,0x7e,0x7b,0x20,0x4e,0x64,0xb0,0x16,0xad,0x3c,0x01,0x1a,0xd3,0x54,0xbf,
+    0x2b,0xa4,0x02,0x9e,0xc3,0x0d,0x60,0x3d,0x1f,0xb9,0xc0,0x0d,0xe6,0x97,0x68,
+    0xbb,0x8c,0x81,0xd5,0xc1,0x54,0x96,0x0f,0x99,0xf0,0xa8,0xa2,0xf3,0xc6,0x8e,
+    0xec,0xbc,0x31,0x17,0x70,0x98,0x24,0xa3,0x36,0x51,0xa8,0x54,0xbd,0x9a,0x89,
+    0x99,0x6e,0x57,0x5e,0xd0,0x39,0x86,0xc3,0xa3,0x1b,0xc7,0xcf,0xc4,0x4f,0x47,
+    0x25,0x9e,0x2c,0x79,0xe1,0x2c,0xcc,0xe4,0x63,0xf4,0x02,0x84,0xf8,0xf6,0xa1,
+    0x5c,0x93,0x14,0xf2,0x68,0x5f,0x3a,0x90,0x2f,0x4e,0x5e,0xf9,0x16,0x05,0xcf,
+    0x21,0x63,0xca,0xfa,0xb0,0x08,0x02,0xc0
+};
+static const unsigned char rsa_keygen0_xq1[] = {
+    0x9b,0x02,0xd4,0xba,0xf0,0xaa,0x14,0x99,0x6d,0xc0,0xb7,0xa5,0xe1,0xd3,0x70,
+    0xb6,0x5a,0xa2,0x9b,0x59,0xd5,0x8c,0x1e,0x9f,0x3f,0x9a,0xde,0xeb,0x9e,0x9c,
+    0x61,0xd6,0x5a,0xe1
+};
+static const unsigned char rsa_keygen0_xq2[] = {
+    0x06,0x81,0x53,0xfd,0xa8,0x7b,0xa3,0x85,0x90,0x15,0x2c,0x97,0xb2,0xa0,0x17,
+    0x48,0xb0,0x7f,0x0a,0x01,0x6d
+};
+/* expected values */
+static const unsigned char rsa_keygen0_p1[] = {
+    0xac,0x5f,0x7f,0x6e,0x33,0x3e,0x97,0x3a,0xb3,0x17,0x44,0xa9,0x0f,0x7a,0x54,
+    0x70,0x27,0x06,0x93,0xd5,0x49,0xde,0x91,0x83,0xbc,0x8a,0x7b,0xc3
+};
+static const unsigned char rsa_keygen0_p2[] = {
+    0x0b,0xf6,0xe8,0x79,0x5a,0x81,0xae,0x90,0x1d,0xa4,0x38,0x74,0x9c,0x0e,0x6f,
+    0xe0,0x03,0xcf,0xc4,0x53,0x16,0x32,0x17,0xf7,0x09,0x5f,0xd9
+};
+static const unsigned char rsa_keygen0_q1[] = {
+    0x9b,0x02,0xd4,0xba,0xf0,0xaa,0x14,0x99,0x6d,0xc0,0xb7,0xa5,0xe1,0xd3,0x70,
+    0xb6,0x5a,0xa2,0x9b,0x59,0xd5,0x8c,0x1e,0x9f,0x3f,0x9a,0xde,0xeb,0x9e,0x9c,
+    0x61,0xd6,0x5d,0x47
+};
+static const unsigned char rsa_keygen0_q2[] = {
+    0x06,0x81,0x53,0xfd,0xa8,0x7b,0xa3,0x85,0x90,0x15,0x2c,0x97,0xb2,0xa0,0x17,
+    0x48,0xb0,0x7f,0x0a,0x01,0x8f
+};
+static const unsigned char rsa_keygen0_p[] = {
+    0xcf,0x72,0x1b,0x9a,0xfd,0x0d,0x22,0x1a,0x74,0x50,0x97,0x22,0x76,0xd8,0xc0,
+    0xc2,0xfd,0x08,0x81,0x05,0xdd,0x18,0x21,0x99,0x96,0xd6,0x5c,0x79,0xe3,0x02,
+    0x81,0xd7,0x0e,0x3f,0x3b,0x34,0xda,0x61,0xc9,0x2d,0x84,0x86,0x62,0x1e,0x3d,
+    0x5d,0xbf,0x92,0x2e,0xcd,0x35,0x3d,0x6e,0xb9,0x59,0x16,0xc9,0x82,0x50,0x41,
+    0x30,0x45,0x67,0xaa,0xb7,0xbe,0xec,0xea,0x4b,0x9e,0xa0,0xc3,0x05,0xbc,0x4c,
+    0x01,0xa5,0x4b,0xbd,0xa4,0x20,0xb5,0x20,0xd5,0x59,0x6f,0x82,0x5c,0x8f,0x4f,
+    0xe0,0x3a,0x4e,0x7e,0xfe,0x44,0xf3,0x3c,0xc0,0x0e,0x14,0x2b,0x32,0xe6,0x28,
+    0x8b,0x63,0x87,0x00,0xc3,0x53,0x4a,0x5b,0x71,0x7a,0x5b,0x28,0x40,0xc4,0x18,
+    0xb6,0x77,0x0b,0xab,0x59,0xa4,0x96,0x7d
+};
+static const unsigned char rsa_keygen0_q[] = {
+    0xfe,0xab,0xf2,0x7c,0x16,0x4a,0xf0,0x8d,0x31,0xc6,0x0a,0x82,0xe2,0xae,0xbb,
+    0x03,0x7e,0x7b,0x20,0x4e,0x64,0xb0,0x16,0xad,0x3c,0x01,0x1a,0xd3,0x54,0xbf,
+    0x2b,0xa4,0x02,0x9e,0xc3,0x0d,0x60,0x3d,0x1f,0xb9,0xc0,0x0d,0xe6,0x97,0x68,
+    0xbb,0x8c,0x81,0xd5,0xc1,0x54,0x96,0x0f,0x99,0xf0,0xa8,0xa2,0xf3,0xc6,0x8e,
+    0xec,0xbc,0x31,0x17,0x70,0x98,0x24,0xa3,0x36,0x51,0xa8,0x54,0xc4,0x44,0xdd,
+    0xf7,0x7e,0xda,0x47,0x4a,0x67,0x44,0x5d,0x4e,0x75,0xf0,0x4d,0x00,0x68,0xe1,
+    0x4a,0xec,0x1f,0x45,0xf9,0xe6,0xca,0x38,0x95,0x48,0x6f,0xdc,0x9d,0x1b,0xa3,
+    0x4b,0xfd,0x08,0x4b,0x54,0xcd,0xeb,0x3d,0xef,0x33,0x11,0x6e,0xce,0xe4,0x5d,
+    0xef,0xa9,0x58,0x5c,0x87,0x4d,0xc8,0xcf
+};
+static const unsigned char rsa_keygen0_n[] = {
+    0xce,0x5e,0x8d,0x1a,0xa3,0x08,0x7a,0x2d,0xb4,0x49,0x48,0xf0,0x06,0xb6,0xfe,
+    0xba,0x2f,0x39,0x7c,0x7b,0xe0,0x5d,0x09,0x2d,0x57,0x4e,0x54,0x60,0x9c,0xe5,
+    0x08,0x4b,0xe1,0x1a,0x73,0xc1,0x5e,0x2f,0xb6,0x46,0xd7,0x81,0xca,0xbc,0x98,
+    0xd2,0xf9,0xef,0x1c,0x92,0x8c,0x8d,0x99,0x85,0x28,0x52,0xd6,0xd5,0xab,0x70,
+    0x7e,0x9e,0xa9,0x87,0x82,0xc8,0x95,0x64,0xeb,0xf0,0x6c,0x0f,0x3f,0xe9,0x02,
+    0x29,0x2e,0x6d,0xa1,0xec,0xbf,0xdc,0x23,0xdf,0x82,0x4f,0xab,0x39,0x8d,0xcc,
+    0xac,0x21,0x51,0x14,0xf8,0xef,0xec,0x73,0x80,0x86,0xa3,0xcf,0x8f,0xd5,0xcf,
+    0x22,0x1f,0xcc,0x23,0x2f,0xba,0xcb,0xf6,0x17,0xcd,0x3a,0x1f,0xd9,0x84,0xb9,
+    0x88,0xa7,0x78,0x0f,0xaa,0xc9,0x04,0x01,0x20,0x72,0x5d,0x2a,0xfe,0x5b,0xdd,
+    0x16,0x5a,0xed,0x83,0x02,0x96,0x39,0x46,0x37,0x30,0xc1,0x0d,0x87,0xc2,0xc8,
+    0x33,0x38,0xed,0x35,0x72,0xe5,0x29,0xf8,0x1f,0x23,0x60,0xe1,0x2a,0x5b,0x1d,
+    0x6b,0x53,0x3f,0x07,0xc4,0xd9,0xbb,0x04,0x0c,0x5c,0x3f,0x0b,0xc4,0xd4,0x61,
+    0x96,0x94,0xf1,0x0f,0x4a,0x49,0xac,0xde,0xd2,0xe8,0x42,0xb3,0x4a,0x0b,0x64,
+    0x7a,0x32,0x5f,0x2b,0x5b,0x0f,0x8b,0x8b,0xe0,0x33,0x23,0x34,0x64,0xf8,0xb5,
+    0x7f,0x69,0x60,0xb8,0x71,0xe9,0xff,0x92,0x42,0xb1,0xf7,0x23,0xa8,0xa7,0x92,
+    0x04,0x3d,0x6b,0xff,0xf7,0xab,0xbb,0x14,0x1f,0x4c,0x10,0x97,0xd5,0x6b,0x71,
+    0x12,0xfd,0x93,0xa0,0x4a,0x3b,0x75,0x72,0x40,0x96,0x1c,0x5f,0x40,0x40,0x57,
+    0x13
+};
+static const unsigned char rsa_keygen0_d[] = {
+    0x47,0x47,0x49,0x1d,0x66,0x2a,0x4b,0x68,0xf5,0xd8,0x4a,0x24,0xfd,0x6c,0xbf,
+    0x56,0xb7,0x70,0xf7,0x9a,0x21,0xc8,0x80,0x9e,0xf4,0x84,0xcd,0x88,0x01,0x28,
+    0xea,0x50,0xab,0x13,0x63,0xdf,0xea,0x14,0x38,0xb5,0x07,0x42,0x81,0x2f,0xda,
+    0xe9,0x24,0x02,0x7e,0xaf,0xef,0x74,0x09,0x0e,0x80,0xfa,0xfb,0xd1,0x19,0x41,
+    0xe5,0xba,0x0f,0x7c,0x0a,0xa4,0x15,0x55,0xa2,0x58,0x8c,0x3a,0x48,0x2c,0xc6,
+    0xde,0x4a,0x76,0xfb,0x72,0xb6,0x61,0xe6,0xd2,0x10,0x44,0x4c,0x33,0xb8,0xd2,
+    0x74,0xb1,0x9d,0x3b,0xcd,0x2f,0xb1,0x4f,0xc3,0x98,0xbd,0x83,0xb7,0x7e,0x75,
+    0xe8,0xa7,0x6a,0xee,0xcc,0x51,0x8c,0x99,0x17,0x67,0x7f,0x27,0xf9,0x0d,0x6a,
+    0xb7,0xd4,0x80,0x17,0x89,0x39,0x9c,0xf3,0xd7,0x0f,0xdf,0xb0,0x55,0x80,0x1d,
+    0xaf,0x57,0x2e,0xd0,0xf0,0x4f,0x42,0x69,0x55,0xbc,0x83,0xd6,0x97,0x83,0x7a,
+    0xe6,0xc6,0x30,0x6d,0x3d,0xb5,0x21,0xa7,0xc4,0x62,0x0a,0x20,0xce,0x5e,0x5a,
+    0x17,0x98,0xb3,0x6f,0x6b,0x9a,0xeb,0x6b,0xa3,0xc4,0x75,0xd8,0x2b,0xdc,0x5c,
+    0x6f,0xec,0x5d,0x49,0xac,0xa8,0xa4,0x2f,0xb8,0x8c,0x4f,0x2e,0x46,0x21,0xee,
+    0x72,0x6a,0x0e,0x22,0x80,0x71,0xc8,0x76,0x40,0x44,0x61,0x16,0xbf,0xa5,0xf8,
+    0x89,0xc7,0xe9,0x87,0xdf,0xbd,0x2e,0x4b,0x4e,0xc2,0x97,0x53,0xe9,0x49,0x1c,
+    0x05,0xb0,0x0b,0x9b,0x9f,0x21,0x19,0x41,0xe9,0xf5,0x61,0xd7,0x33,0x2e,0x2c,
+    0x94,0xb8,0xa8,0x9a,0x3a,0xcc,0x6a,0x24,0x8d,0x19,0x13,0xee,0xb9,0xb0,0x48,
+    0x61
+};
+
+static const struct rsa_keygen_st rsa_keygen_data[] = {
+    {
+        2048,
+        ITM(rsa_keygen0_e),
+        ITM(rsa_keygen0_xp1),
+        ITM(rsa_keygen0_xp2),
+        ITM(rsa_keygen0_xp),
+        ITM(rsa_keygen0_xq1),
+        ITM(rsa_keygen0_xq2),
+        ITM(rsa_keygen0_xq),
+
+        ITM(rsa_keygen0_p1),
+        ITM(rsa_keygen0_p2),
+        ITM(rsa_keygen0_q1),
+        ITM(rsa_keygen0_q2),
+
+        ITM(rsa_keygen0_p),
+        ITM(rsa_keygen0_q),
+        ITM(rsa_keygen0_n),
+        ITM(rsa_keygen0_d),
+    },
+};
+
+#define NO_PSS_SALT_LEN -1
+struct rsa_siggen_st {
+    const char *sig_pad_mode;
+    size_t mod;
+    const char *digest_alg;
+    const unsigned char *msg;
+    size_t msg_len;
+    int pss_salt_len;
+};
+static const unsigned char rsa_siggen0_msg[] = {
+    0xa3, 0x76, 0x35, 0xc2, 0x6d, 0x6b, 0xa0, 0xe1,
+    0x2e, 0x0b, 0x58, 0x33, 0x0d, 0x30, 0xdd, 0x07,
+    0xa9, 0x53, 0xd6, 0x37, 0x07, 0xad, 0xa8, 0x67,
+};
+static const struct rsa_siggen_st rsa_siggen_data[] = {
+    {
+        "pkcs1", /* pkcs1v1.5 */
+        2048,
+        "SHA384",
+        ITM(rsa_siggen0_msg),
+        NO_PSS_SALT_LEN,
+    },
+    {
+        "x931",
+        2048,
+        "SHA384",
+        ITM(rsa_siggen0_msg),
+        NO_PSS_SALT_LEN,
+    },
+    {
+        "pss",
+        2048,
+        "SHA384",
+        ITM(rsa_siggen0_msg),
+        62
+    },
+};
+
+struct rsa_sigver_st {
+    const char *sig_pad_mode;
+    size_t mod;
+    const char *digest_alg;
+    const unsigned char *msg;
+    size_t msg_len;
+    const unsigned char *n;
+    size_t n_len;
+    const unsigned char *e;
+    size_t e_len;
+    const unsigned char *sig;
+    size_t sig_len;
+    int pss_salt_len;
+    int pass;
+};
+
+static const unsigned char rsa_sigver15_0_n[] = {
+    0xbb, 0xbc, 0xf3, 0x35, 0x6f, 0x8e, 0x2e, 0x4f,
+    0x32, 0xb5, 0xbb, 0x47, 0x9d, 0x02, 0x2a, 0xac,
+    0x93, 0x9e, 0x70, 0x50, 0x0f, 0x59, 0x0d, 0x38,
+    0x1c, 0xe5, 0xda, 0x87, 0x61, 0x6b, 0xbf, 0xa8,
+    0x2c, 0x2f, 0x97, 0xbc, 0x4b, 0xd4, 0xae, 0x21,
+    0xed, 0xbe, 0x7a, 0x98, 0x15, 0xa8, 0xe2, 0xf0,
+    0x5f, 0x4d, 0xf8, 0xe2, 0x7c, 0x7e, 0x87, 0x52,
+    0x8e, 0xbf, 0xb6, 0x3f, 0x1a, 0x12, 0x96, 0x87,
+    0x2c, 0xd2, 0xac, 0x85, 0x87, 0xe5, 0xcd, 0x4c,
+    0x31, 0x2b, 0x98, 0x16, 0x9f, 0xcf, 0x3e, 0xef,
+    0x50, 0xaa, 0xee, 0xc0, 0x6c, 0x80, 0x94, 0xc5,
+    0xb1, 0xc7, 0x0d, 0xd4, 0x24, 0x94, 0x44, 0x3a,
+    0x44, 0xdb, 0x10, 0xdc, 0x21, 0x57, 0xe0, 0x77,
+    0xe5, 0x9c, 0xc4, 0x49, 0x06, 0xe3, 0x5a, 0xea,
+    0x64, 0xf4, 0x54, 0xca, 0xfc, 0x5a, 0x2b, 0x92,
+    0x76, 0xe1, 0x86, 0x6f, 0x3b, 0x4e, 0x7d, 0xe7,
+    0xb9, 0x62, 0xc4, 0x63, 0x12, 0x65, 0x16, 0x58,
+    0x11, 0x23, 0xba, 0x1b, 0x95, 0x06, 0x1c, 0xdd,
+    0xdc, 0x49, 0x0b, 0x67, 0x7c, 0xb0, 0xdb, 0x45,
+    0x88, 0x6e, 0x42, 0xdd, 0x67, 0xbf, 0xec, 0x0e,
+    0xfa, 0x64, 0x06, 0x3e, 0xb9, 0x40, 0xee, 0xc6,
+    0x56, 0xdf, 0xe7, 0xd8, 0xed, 0xf1, 0xf7, 0x53,
+    0xec, 0xd6, 0x1e, 0xb1, 0x66, 0x66, 0x80, 0x16,
+    0x5b, 0xba, 0x8c, 0x75, 0xe2, 0x6c, 0x19, 0xe7,
+    0xf9, 0xc8, 0xae, 0x75, 0xc9, 0xc4, 0x19, 0xe6,
+    0xba, 0xfd, 0x3e, 0x12, 0xf0, 0x88, 0x90, 0xee,
+    0x39, 0xf8, 0x85, 0x3c, 0x20, 0x3b, 0xfe, 0xb9,
+    0xa0, 0x07, 0x93, 0x6d, 0x20, 0x78, 0xf2, 0xc2,
+    0xa5, 0x49, 0x51, 0xa3, 0xb7, 0x13, 0x83, 0xeb,
+    0x19, 0x55, 0x08, 0x4f, 0x28, 0x32, 0x1a, 0x9b,
+    0xab, 0x05, 0x9a, 0xaa, 0x28, 0xdc, 0xfa, 0xbf,
+    0xf3, 0x52, 0x40, 0x0c, 0x4a, 0xb3, 0xd6, 0xb5,
+};
+static const unsigned char rsa_sigver15_0_e[] = {
+    0x01, 0x00, 0x01,
+};
+static const unsigned char rsa_sigver15_0_msg[] = {
+    0xba, 0x1a, 0x03, 0xda, 0x95, 0xd4, 0x36, 0x60,
+    0xe6, 0x77, 0xc7, 0x80, 0x49, 0x42, 0xc7, 0x98,
+    0xf6, 0x9e, 0xcf, 0x6f, 0xe5, 0xaf, 0x41, 0x6c,
+    0x36, 0x29, 0xd0, 0x06, 0xcf, 0x65, 0x43, 0x7c,
+    0x47, 0xb4, 0x75, 0xc6, 0x03, 0xf3, 0xa1, 0xcb,
+    0x9e, 0x5f, 0xdc, 0xd4, 0x8e, 0xab, 0xe3, 0x41,
+    0x05, 0x50, 0x17, 0x7b, 0x16, 0x25, 0xc6, 0x29,
+    0x19, 0x2f, 0xac, 0xa7, 0x50, 0xba, 0xba, 0xb3,
+    0xcb, 0xa8, 0x16, 0x6a, 0x88, 0x0a, 0x62, 0x74,
+    0xdf, 0xed, 0x41, 0x7b, 0x1d, 0x76, 0x17, 0xe1,
+    0x70, 0x32, 0x11, 0xb2, 0x03, 0xa7, 0x66, 0xd7,
+    0x69, 0x2f, 0xdc, 0x8d, 0x3f, 0x06, 0x8d, 0x16,
+    0x0d, 0xa1, 0xeb, 0xae, 0x6e, 0x41, 0x02, 0xc1,
+    0x71, 0xc9, 0xfd, 0x5b, 0x3e, 0xcc, 0xec, 0xe0,
+    0xfd, 0xeb, 0xc4, 0xfd, 0xf3, 0x5e, 0xa7, 0xde,
+    0xee, 0xd0, 0x66, 0xa2, 0xe4, 0x70, 0x45, 0x0c,
+};
+static const unsigned char rsa_sigver15_0_sig[] = {
+    0x4a, 0x8a, 0xcb, 0x88, 0x89, 0xd3, 0xa9, 0x48,
+    0x84, 0x09, 0x2e, 0x2c, 0x50, 0x02, 0xb9, 0xad,
+    0xe5, 0x10, 0xac, 0x27, 0x8f, 0x2d, 0x36, 0x7e,
+    0x6e, 0x32, 0x5c, 0x1d, 0xcb, 0xfa, 0xb8, 0xc7,
+    0x1a, 0x27, 0x11, 0x2b, 0x34, 0xf4, 0xa9, 0xda,
+    0xa0, 0x99, 0x86, 0xbe, 0x81, 0xd0, 0xd9, 0x2a,
+    0x88, 0x25, 0x99, 0xb3, 0x02, 0x50, 0xf1, 0xa5,
+    0x4f, 0x3a, 0x1d, 0x7f, 0xcf, 0x7d, 0x76, 0x00,
+    0x06, 0x87, 0x9f, 0x39, 0x3a, 0x3c, 0xc0, 0xc6,
+    0x46, 0x7a, 0x65, 0x0d, 0x85, 0x06, 0xd8, 0x51,
+    0xbe, 0xc5, 0x00, 0x80, 0xeb, 0x73, 0xbb, 0x71,
+    0x8c, 0xcc, 0x72, 0x83, 0x1f, 0x9d, 0x73, 0x75,
+    0xb8, 0xc8, 0x4c, 0x07, 0x5b, 0xda, 0x8c, 0x9b,
+    0x6f, 0x65, 0x8c, 0x2e, 0x23, 0x62, 0x6c, 0x8d,
+    0x94, 0x54, 0x5b, 0x7f, 0xe6, 0x5c, 0x90, 0xa3,
+    0x07, 0xe2, 0x14, 0x4d, 0xe7, 0x71, 0x6c, 0xfd,
+    0x64, 0x12, 0x14, 0x12, 0x14, 0x00, 0x1b, 0xc4,
+    0x65, 0xe7, 0x28, 0x5c, 0x34, 0x2d, 0xda, 0x94,
+    0xfd, 0x71, 0xcb, 0x27, 0xa6, 0x0e, 0x63, 0xd4,
+    0xd6, 0x14, 0x65, 0xc0, 0xe3, 0x65, 0x94, 0x61,
+    0x59, 0xb8, 0xc9, 0x3b, 0x9b, 0xc2, 0x82, 0xe2,
+    0x76, 0xe7, 0x17, 0xf1, 0xef, 0x32, 0x9e, 0x8a,
+    0x04, 0xf3, 0x1e, 0xcc, 0x16, 0xb4, 0x45, 0x0e,
+    0x77, 0xdb, 0x8b, 0x38, 0x6c, 0xcc, 0x98, 0xf4,
+    0xf8, 0xb5, 0x45, 0x2c, 0xde, 0x23, 0x36, 0xe7,
+    0x83, 0xf0, 0xb4, 0xb5, 0xe3, 0xd3, 0xd4, 0x59,
+    0xf1, 0x46, 0x7f, 0x0f, 0x55, 0x58, 0xff, 0x75,
+    0xc7, 0x7f, 0xee, 0xf8, 0xe0, 0xb2, 0x52, 0xd8,
+    0xba, 0x37, 0x4f, 0x7b, 0xba, 0xa3, 0xf0, 0x13,
+    0xa7, 0x3a, 0x21, 0xac, 0xdc, 0x9e, 0x63, 0x36,
+    0x38, 0xe7, 0x90, 0xeb, 0xea, 0x7f, 0x83, 0xf4,
+    0x9d, 0xf3, 0x6b, 0x31, 0x44, 0x47, 0x27, 0x8e,
+};
+
+#define rsa_sigver15_1_n rsa_sigver15_0_n
+#define rsa_sigver15_1_e rsa_sigver15_0_e
+static const unsigned char rsa_sigver15_1_msg[] = {
+    0x52, 0x68, 0x35, 0xd6, 0x4a, 0x95, 0xaa, 0xbd,
+    0x02, 0x69, 0x7f, 0x92, 0xc7, 0x8c, 0x04, 0x71,
+    0x17, 0x10, 0x5a, 0x0d, 0xab, 0x5e, 0x91, 0x45,
+    0xb5, 0x70, 0x0d, 0xf8, 0x66, 0x41, 0x2e, 0x19,
+    0xb3, 0x82, 0x30, 0x06, 0x59, 0x8f, 0x4f, 0x15,
+    0x1e, 0xa1, 0x2f, 0x70, 0x5a, 0x45, 0x7c, 0x24,
+    0xb7, 0x0d, 0xcd, 0x74, 0x35, 0x85, 0xcf, 0x73,
+    0x71, 0x68, 0x9f, 0xd2, 0x26, 0x14, 0x77, 0xf6,
+    0xf4, 0x3c, 0x8d, 0x4d, 0x60, 0xdd, 0x38, 0xe3,
+    0x1d, 0x73, 0x55, 0x30, 0x8a, 0x6c, 0xe9, 0x35,
+    0x7b, 0xdd, 0x08, 0xc7, 0x3c, 0x74, 0xf5, 0x2a,
+    0xd3, 0xae, 0x8a, 0xe1, 0x86, 0x49, 0xda, 0xc5,
+    0x9d, 0xfd, 0x16, 0x55, 0x69, 0x67, 0xad, 0x4d,
+    0x85, 0x46, 0xb7, 0x7a, 0x5c, 0xe9, 0x94, 0xcc,
+    0xeb, 0xe8, 0xd0, 0xad, 0xc9, 0x13, 0x4a, 0x91,
+    0x64, 0xa8, 0x96, 0xce, 0x8d, 0xc9, 0x9f, 0xaf,
+};
+static const unsigned char rsa_sigver15_1_sig[] = {
+    0x81, 0x96, 0xdb, 0x65, 0x66, 0x5d, 0xec, 0x14,
+    0xb3, 0x42, 0xf6, 0x93, 0x89, 0xae, 0x49, 0x81,
+    0x98, 0xda, 0x71, 0x6d, 0x72, 0x9b, 0xcb, 0x39,
+    0xe4, 0x85, 0xd1, 0x9f, 0xbe, 0xb8, 0x69, 0x0e,
+    0xbe, 0xc0, 0x07, 0x88, 0xee, 0xbf, 0xf9, 0x5d,
+    0x20, 0x0f, 0x90, 0x48, 0x93, 0x53, 0xbb, 0xc6,
+    0x2f, 0xf8, 0xb7, 0x1d, 0xd2, 0x15, 0x0f, 0x1f,
+    0x25, 0xab, 0x5b, 0xae, 0x52, 0xe6, 0x8e, 0x06,
+    0x43, 0xe1, 0xd9, 0x4a, 0x4c, 0xee, 0x24, 0x0e,
+    0xeb, 0x4f, 0x9b, 0x1a, 0xcb, 0x6d, 0x22, 0x93,
+    0xa8, 0xa8, 0xcd, 0x4b, 0xa2, 0xf6, 0x88, 0x1a,
+    0xaf, 0x3b, 0x2b, 0xdf, 0x04, 0x2d, 0x2b, 0x27,
+    0x54, 0x90, 0x41, 0xb0, 0x4a, 0xda, 0xb1, 0xdf,
+    0xce, 0x39, 0xda, 0xd7, 0xda, 0x00, 0x97, 0x89,
+    0x9a, 0xaf, 0x4c, 0xc3, 0x0b, 0x6d, 0xb3, 0xce,
+    0x59, 0x0b, 0xd9, 0x91, 0x17, 0x31, 0x6a, 0xe7,
+    0x92, 0xec, 0x62, 0xe1, 0xe9, 0x73, 0xc7, 0x14,
+    0x06, 0x16, 0x42, 0x8a, 0x68, 0xb1, 0x7c, 0xb8,
+    0xa1, 0x45, 0xf0, 0x06, 0xf6, 0x85, 0xb5, 0x93,
+    0xf1, 0x45, 0xc4, 0xe5, 0xf1, 0x76, 0x71, 0xb4,
+    0xdc, 0x03, 0x55, 0xde, 0xb1, 0xd3, 0x5a, 0x0f,
+    0x1f, 0x4f, 0xdd, 0xaa, 0x87, 0x8e, 0x46, 0x4d,
+    0xe3, 0xd0, 0x5b, 0x28, 0x01, 0xc4, 0x94, 0xf7,
+    0x00, 0x93, 0xae, 0xa3, 0xb5, 0x64, 0x65, 0xa1,
+    0x16, 0x29, 0x2e, 0xc7, 0xbb, 0xeb, 0x71, 0x02,
+    0xf9, 0x26, 0xb6, 0xa6, 0x24, 0xdc, 0x6a, 0x0e,
+    0x0d, 0xad, 0x50, 0xf5, 0x4b, 0xe7, 0x0e, 0x9a,
+    0x39, 0x20, 0x70, 0xe2, 0xdf, 0x3b, 0x6f, 0x9d,
+    0xe3, 0x8f, 0x15, 0x6d, 0x5a, 0xaf, 0x12, 0xf7,
+    0xf7, 0x85, 0x6f, 0x0e, 0xe4, 0x6e, 0x27, 0xf7,
+    0xb3, 0x44, 0x38, 0x73, 0x45, 0x80, 0x7a, 0x72,
+    0x82, 0xf3, 0xc8, 0x32, 0xb8, 0x25, 0xef, 0xdc,
+};
+
+static const unsigned char rsa_sigverpss_0_n[] = {
+    0xb2, 0xee, 0xdd, 0xdf, 0xa0, 0x35, 0x92, 0x21,
+    0xf4, 0x8e, 0xc3, 0x24, 0x39, 0xed, 0xe2, 0x38,
+    0xc0, 0xaa, 0xff, 0x35, 0x75, 0x27, 0x05, 0xd4,
+    0x84, 0x78, 0x23, 0x50, 0xa5, 0x64, 0x1e, 0x11,
+    0x45, 0x2a, 0xb1, 0xeb, 0x97, 0x07, 0x0b, 0xff,
+    0xb3, 0x1f, 0xc4, 0xa4, 0x80, 0xae, 0x1c, 0x8c,
+    0x66, 0x71, 0x95, 0x80, 0x60, 0xea, 0x4d, 0xde,
+    0x90, 0x98, 0xe8, 0xe2, 0x96, 0xa7, 0x0e, 0x5f,
+    0x00, 0x74, 0xed, 0x79, 0xc3, 0xe2, 0xc2, 0x4e,
+    0xbe, 0x07, 0xbd, 0xb1, 0xb2, 0xeb, 0x6c, 0x29,
+    0x9a, 0x59, 0x29, 0x81, 0xa3, 0x83, 0xa3, 0x00,
+    0x24, 0xa8, 0xfd, 0x45, 0xbb, 0xca, 0x1e, 0x44,
+    0x47, 0xbb, 0x82, 0x4a, 0x5b, 0x71, 0x46, 0xc0,
+    0xb4, 0xcc, 0x1b, 0x5e, 0x88, 0x9c, 0x89, 0x69,
+    0xb4, 0xb0, 0x7c, 0x8e, 0xea, 0x24, 0xc0, 0x2f,
+    0xc8, 0x3f, 0x9d, 0x9f, 0x43, 0xd3, 0xf0, 0x25,
+    0x67, 0xf1, 0xf0, 0x9b, 0xd4, 0xff, 0x17, 0x9f,
+    0xc3, 0x41, 0x2f, 0x53, 0x33, 0xdd, 0x73, 0x8a,
+    0x5c, 0x74, 0x04, 0x3b, 0x60, 0xcc, 0x9f, 0xca,
+    0x01, 0xb0, 0x0d, 0xe0, 0xcf, 0xb2, 0xf0, 0x08,
+    0x73, 0xb6, 0x67, 0x6c, 0x54, 0x9e, 0x1c, 0x01,
+    0xb5, 0x34, 0xab, 0xcf, 0x77, 0xfe, 0x04, 0x01,
+    0xc1, 0xd2, 0x4d, 0x47, 0x60, 0x5c, 0x68, 0x47,
+    0x8a, 0x47, 0x3c, 0x3a, 0xa3, 0xb2, 0x75, 0x87,
+    0x6e, 0x01, 0x7b, 0xdb, 0xe9, 0x6e, 0x63, 0xb2,
+    0x65, 0xab, 0xc6, 0xed, 0x0d, 0xa6, 0x84, 0xff,
+    0xf3, 0xcf, 0xd3, 0x9a, 0x96, 0x9b, 0x5c, 0x22,
+    0xf8, 0x07, 0x7d, 0x63, 0x75, 0x50, 0x91, 0x5b,
+    0xc4, 0x1f, 0x29, 0x1f, 0x5d, 0xb0, 0x6e, 0xfa,
+    0x9b, 0x16, 0xf0, 0xe4, 0xda, 0x2c, 0x94, 0x20,
+    0x9b, 0x44, 0x51, 0x38, 0xd0, 0xe4, 0x86, 0xc9,
+    0x76, 0x12, 0x04, 0x1a, 0x25, 0x14, 0xb7, 0x14,
+    0xdb, 0x6e, 0xd2, 0xc3, 0x57, 0x2c, 0x4c, 0xec,
+    0xfe, 0x25, 0xed, 0x3e, 0xe3, 0x26, 0xa8, 0xd4,
+    0xd0, 0x21, 0xbc, 0x09, 0x7e, 0xb0, 0x02, 0x3c,
+    0xa3, 0x43, 0xa4, 0x1f, 0x73, 0x54, 0x5f, 0xa3,
+    0xe2, 0x49, 0x4e, 0x25, 0xe8, 0xfc, 0xfb, 0xa9,
+    0x29, 0xc0, 0x7d, 0xd0, 0x06, 0xd5, 0x5c, 0x52,
+    0x68, 0x3c, 0xf8, 0xc5, 0xdb, 0x92, 0x27, 0x7c,
+    0xd8, 0x56, 0x1a, 0x7d, 0xe3, 0x32, 0xe5, 0x08,
+    0xc9, 0x36, 0x9d, 0x7e, 0xd2, 0x2d, 0xc2, 0x53,
+    0xf2, 0x7e, 0xce, 0x8a, 0x10, 0x5c, 0xf7, 0xe9,
+    0x99, 0xa6, 0xa8, 0xf5, 0x8d, 0x6c, 0xed, 0xf3,
+    0xa1, 0xc8, 0x2a, 0x75, 0x77, 0x99, 0x18, 0xe1,
+    0x32, 0xdb, 0x35, 0x4a, 0x8b, 0x4a, 0xec, 0xc2,
+    0x15, 0xe9, 0x4b, 0x89, 0x13, 0x81, 0xfb, 0x0c,
+    0xf9, 0xb4, 0xd8, 0xee, 0xb5, 0xba, 0x45, 0xa1,
+    0xea, 0x01, 0xf9, 0xbb, 0xd5, 0xa1, 0x73, 0xa1,
+    0x5b, 0xef, 0x98, 0xa8, 0xcf, 0x74, 0xf4, 0xd5,
+    0x1a, 0xe2, 0xa7, 0xb9, 0x37, 0x43, 0xb1, 0x29,
+    0x94, 0xc3, 0x71, 0x74, 0x34, 0x7d, 0x6f, 0xac,
+    0x97, 0xb3, 0x5b, 0x3a, 0x0a, 0x3c, 0xe2, 0x94,
+    0x6c, 0x39, 0xb8, 0xe9, 0x2c, 0xf9, 0xc3, 0x8b,
+    0xd1, 0x80, 0x4d, 0x22, 0x64, 0x63, 0x20, 0x1b,
+    0xeb, 0xf9, 0x09, 0x14, 0x86, 0x6e, 0xf4, 0x6d,
+    0xfc, 0xe5, 0x1b, 0xf7, 0xf2, 0xe0, 0x4d, 0xc8,
+    0xeb, 0x24, 0x35, 0x16, 0x0a, 0x81, 0x9f, 0x9e,
+    0x47, 0xd8, 0xea, 0x85, 0xda, 0x77, 0x6c, 0x3d,
+    0xd4, 0xa9, 0x15, 0xbd, 0xda, 0x5d, 0xf0, 0x72,
+    0x8d, 0xb5, 0x12, 0x72, 0xb1, 0x62, 0xa0, 0xad,
+    0xc8, 0x0e, 0x5b, 0x47, 0x4c, 0x69, 0xf7, 0x07,
+    0xe8, 0xd9, 0x9b, 0xc7, 0x2f, 0xd5, 0x68, 0x1e,
+    0x1c, 0xe0, 0x8f, 0x40, 0x45, 0x5f, 0x08, 0xc8,
+    0x95, 0x57, 0xb7, 0x35, 0x92, 0x97, 0xf9, 0x7d,
+};
+static const unsigned char rsa_sigverpss_0_e[] = {
+    0x01, 0x00, 0x01,
+};
+static const unsigned char rsa_sigverpss_0_msg[] = {
+    0x32, 0x03, 0x0c, 0x2e, 0x06, 0xfc, 0x0f, 0xa5,
+    0x65, 0xcd, 0x0f, 0x88, 0x52, 0x80, 0xc3, 0x43,
+    0xda, 0x01, 0x36, 0x48, 0xf5, 0x76, 0xc8, 0x03,
+    0xae, 0xce, 0x76, 0x0f, 0x83, 0x9d, 0x5c, 0xaa,
+    0x0f, 0x27, 0x78, 0x66, 0xe6, 0xba, 0xb1, 0x22,
+    0xc1, 0x42, 0x18, 0x39, 0xdb, 0x17, 0x6d, 0xf9,
+    0x9a, 0x19, 0xe5, 0x57, 0x72, 0xff, 0x2a, 0xe0,
+    0x07, 0xec, 0xa4, 0xf3, 0x91, 0x43, 0xf7, 0x2e,
+    0x85, 0xbd, 0xcd, 0x26, 0x72, 0xb9, 0xd5, 0x5b,
+    0x28, 0xd3, 0x0c, 0x6b, 0x20, 0xb7, 0x3b, 0x85,
+    0x18, 0x38, 0xc0, 0x21, 0xfe, 0x9c, 0x92, 0xee,
+    0x0f, 0x3a, 0x80, 0x0c, 0x40, 0x48, 0xb9, 0x7c,
+    0xdd, 0xee, 0x91, 0xd5, 0x70, 0x9e, 0x82, 0x38,
+    0xe4, 0xa8, 0x71, 0x85, 0xea, 0x09, 0x33, 0xcf,
+    0x9c, 0x84, 0x50, 0x0e, 0x60, 0xf5, 0x07, 0x14,
+    0x10, 0xe1, 0x92, 0xc3, 0x58, 0x51, 0xab, 0x7c,
+};
+static const unsigned char rsa_sigverpss_0_sig[] = {
+    0x43, 0xb2, 0x4a, 0x50, 0xa7, 0xe2, 0x6c, 0x5d,
+    0x50, 0xc5, 0x39, 0xc1, 0xc1, 0x35, 0xbd, 0x66,
+    0xbd, 0x86, 0x54, 0xc5, 0x2e, 0x65, 0xfc, 0x19,
+    0x19, 0x6a, 0x22, 0x43, 0x22, 0x11, 0x26, 0xae,
+    0x51, 0x78, 0xfa, 0xfa, 0xc1, 0xf0, 0x77, 0x1b,
+    0xd6, 0x5b, 0x93, 0xbd, 0x84, 0xe4, 0x35, 0xbd,
+    0x8d, 0x91, 0xb2, 0x7c, 0xb2, 0xb1, 0xda, 0xd7,
+    0x72, 0x62, 0x88, 0x3e, 0xe9, 0x40, 0x27, 0x4e,
+    0xa5, 0x17, 0x94, 0xf1, 0xe9, 0xdd, 0x8c, 0x6c,
+    0x5b, 0xc0, 0x0b, 0xe3, 0x7c, 0x8b, 0xc8, 0x10,
+    0x57, 0x35, 0x69, 0xb7, 0x56, 0xe0, 0x2f, 0x61,
+    0x2e, 0x13, 0x11, 0x79, 0xfa, 0x60, 0x8f, 0x2a,
+    0x65, 0x73, 0xf5, 0x17, 0x34, 0x74, 0x72, 0x22,
+    0xff, 0x22, 0x5b, 0x97, 0x59, 0x44, 0xf4, 0xfb,
+    0x4a, 0x2b, 0x7e, 0x28, 0xe3, 0x79, 0x84, 0x24,
+    0x63, 0xeb, 0xde, 0x63, 0x88, 0xe0, 0xbd, 0x28,
+    0xef, 0x49, 0x6d, 0xd4, 0x2a, 0x87, 0x53, 0xba,
+    0x5f, 0xde, 0xe3, 0xd4, 0xb2, 0xc2, 0x6f, 0x49,
+    0x10, 0xae, 0x5e, 0x15, 0xdd, 0x0f, 0x91, 0xe2,
+    0xeb, 0x1e, 0xc5, 0x36, 0x8e, 0xdf, 0xa6, 0x17,
+    0x25, 0x21, 0x16, 0x06, 0x72, 0x37, 0x77, 0x19,
+    0xe5, 0x88, 0x1b, 0x0b, 0x5b, 0x80, 0x44, 0x8f,
+    0x13, 0xef, 0xbb, 0xfa, 0xf6, 0x4a, 0x11, 0x6a,
+    0x6a, 0x0c, 0xe0, 0x42, 0x6b, 0x7d, 0xfd, 0xad,
+    0xb0, 0x4b, 0xff, 0x3f, 0x20, 0xca, 0x5f, 0x64,
+    0xcc, 0xc9, 0x5b, 0x89, 0xc2, 0x05, 0x33, 0xf9,
+    0xa5, 0x31, 0x55, 0xfb, 0xdc, 0xeb, 0xd1, 0x24,
+    0xbf, 0x17, 0x0f, 0xc8, 0xfd, 0xe9, 0x6a, 0xc1,
+    0xa7, 0x94, 0x36, 0x72, 0x22, 0x29, 0x2c, 0x1c,
+    0xd1, 0x8b, 0x7b, 0x37, 0x42, 0x25, 0x8d, 0xe3,
+    0xcc, 0x06, 0x5f, 0x3c, 0x15, 0xfa, 0x74, 0x8a,
+    0x83, 0xf0, 0xcc, 0xf5, 0x30, 0xd1, 0xa8, 0x88,
+    0x9f, 0x4e, 0x1d, 0xd8, 0xe3, 0x1b, 0xb5, 0xe3,
+    0xdb, 0xce, 0xbc, 0x03, 0xfe, 0xe6, 0xa2, 0xb4,
+    0x94, 0x76, 0xd1, 0xb7, 0xce, 0xae, 0x6a, 0x7c,
+    0xbd, 0x4f, 0xd6, 0xfe, 0x60, 0xd0, 0x78, 0xd4,
+    0x04, 0x3f, 0xe0, 0x17, 0x2a, 0x41, 0x26, 0x5a,
+    0x81, 0x80, 0xcd, 0x40, 0x7c, 0x4f, 0xd6, 0xd6,
+    0x1d, 0x1f, 0x58, 0x59, 0xaf, 0xa8, 0x00, 0x91,
+    0x69, 0xb1, 0xf8, 0x3b, 0xef, 0x59, 0x7e, 0x83,
+    0x4e, 0xca, 0x1d, 0x33, 0x35, 0xb6, 0xa5, 0x9a,
+    0x0e, 0xc5, 0xe5, 0x11, 0xdd, 0x5d, 0xb7, 0x32,
+    0x66, 0x23, 0x63, 0x08, 0xbc, 0x2e, 0x9c, 0x10,
+    0x30, 0xa4, 0x13, 0x38, 0xee, 0xc7, 0x10, 0xf6,
+    0xed, 0xe9, 0xe1, 0xd1, 0x89, 0x8b, 0x94, 0x21,
+    0xde, 0x76, 0x72, 0x90, 0xc4, 0xbc, 0x59, 0x31,
+    0x1b, 0x1b, 0xd7, 0xa0, 0xd0, 0x3d, 0xaa, 0x43,
+    0x66, 0xfa, 0x43, 0x8d, 0xcc, 0x37, 0xdc, 0x60,
+    0x59, 0xaf, 0x02, 0x98, 0xe5, 0xe0, 0x17, 0xd6,
+    0xc3, 0x84, 0xf2, 0xaa, 0x5d, 0x88, 0xa8, 0x78,
+    0xbf, 0xbd, 0x18, 0x34, 0x9f, 0x5c, 0x6d, 0x22,
+    0x0c, 0x77, 0x4f, 0x16, 0xf2, 0x85, 0x88, 0x2e,
+    0x9a, 0x2b, 0x30, 0x1e, 0x17, 0xc8, 0xc7, 0xd4,
+    0x20, 0x93, 0x47, 0x0d, 0x32, 0x7d, 0xcb, 0x77,
+    0x85, 0x82, 0xc3, 0x80, 0x75, 0x10, 0x83, 0x33,
+    0xd5, 0xde, 0x47, 0xd4, 0x22, 0x55, 0x4d, 0xca,
+    0x4f, 0x90, 0xd2, 0x9f, 0x80, 0x58, 0x22, 0x4c,
+    0x5a, 0xaa, 0x53, 0x9e, 0xeb, 0xde, 0x62, 0x8a,
+    0xfb, 0xd7, 0x4b, 0x28, 0xd5, 0xe1, 0x02, 0xf9,
+    0x61, 0x74, 0x42, 0x12, 0x32, 0x5d, 0x1b, 0x10,
+    0x8f, 0x51, 0x8d, 0x7c, 0x59, 0xc5, 0xb7, 0x5a,
+    0x68, 0xe7, 0xdd, 0xb0, 0xc0, 0x22, 0xbc, 0xf1,
+    0x37, 0xcc, 0x63, 0xa2, 0x85, 0xb9, 0x11, 0x91,
+    0x43, 0xb9, 0x7b, 0xfb, 0x4a, 0x21, 0xc9, 0xd5,
+};
+
+#define rsa_sigverpss_1_n rsa_sigverpss_0_n
+#define rsa_sigverpss_1_e rsa_sigverpss_0_e
+static const unsigned char rsa_sigverpss_1_msg[] = {
+    0x29, 0xdc, 0x70, 0xd8, 0xa5, 0xde, 0x41, 0x1d,
+    0xed, 0x05, 0x16, 0x04, 0x48, 0x05, 0x21, 0x05,
+    0x1c, 0x40, 0x8a, 0xbb, 0x6c, 0x3c, 0x11, 0xf3,
+    0x9f, 0x55, 0xf4, 0x03, 0x83, 0xaf, 0x13, 0x5d,
+    0x91, 0x6f, 0x52, 0x63, 0x73, 0x2b, 0x3f, 0x7d,
+    0xc3, 0x9e, 0xf5, 0x69, 0x16, 0xa1, 0x40, 0xd3,
+    0x39, 0x57, 0x01, 0x26, 0xba, 0xa7, 0xd4, 0xa1,
+    0xaa, 0xef, 0xf1, 0xad, 0xa2, 0xf6, 0x50, 0x6e,
+    0x04, 0x23, 0x11, 0x98, 0x83, 0xed, 0x1a, 0x84,
+    0xe6, 0x93, 0x02, 0x83, 0x08, 0x0d, 0x2e, 0x72,
+    0x24, 0x42, 0x39, 0x8e, 0x4f, 0x7b, 0x99, 0x8a,
+    0x46, 0x18, 0x80, 0xdf, 0x6a, 0x82, 0x01, 0x64,
+    0x09, 0x60, 0x74, 0x1e, 0xdf, 0x0e, 0x1b, 0x59,
+    0xdd, 0x4a, 0x06, 0xf7, 0x29, 0x31, 0x33, 0x09,
+    0x65, 0x6b, 0xfa, 0x9c, 0x34, 0xa2, 0xa8, 0xd5,
+    0xfa, 0x38, 0x6b, 0x41, 0xe4, 0x39, 0x6e, 0x66,
+};
+static const unsigned char rsa_sigverpss_1_sig[] = {
+    0x48, 0x7f, 0x71, 0x82, 0x63, 0x1d, 0xf2, 0xee,
+    0xe8, 0x79, 0xeb, 0x3a, 0xaf, 0x41, 0x8a, 0x7c,
+    0xab, 0x0b, 0xd4, 0x57, 0xb6, 0x62, 0x9f, 0x6f,
+    0xec, 0xc1, 0xd4, 0xef, 0x55, 0x51, 0xd1, 0x0a,
+    0x0e, 0x1d, 0x8a, 0x64, 0x69, 0x08, 0x57, 0xf5,
+    0x04, 0xa8, 0x6c, 0xde, 0x76, 0x4d, 0x81, 0xf4,
+    0x95, 0x7e, 0x95, 0x6d, 0x41, 0x31, 0x2f, 0x9d,
+    0xe7, 0x47, 0x45, 0x45, 0x9f, 0xa8, 0xf8, 0xe3,
+    0x30, 0xa6, 0x41, 0x0f, 0x12, 0x05, 0x6d, 0x2b,
+    0x1a, 0xae, 0xef, 0xd4, 0x6b, 0xc6, 0xf4, 0x61,
+    0xa5, 0x07, 0xfe, 0xe8, 0xd0, 0xfd, 0xa3, 0x93,
+    0x58, 0xb4, 0x22, 0x37, 0x1b, 0x84, 0xcb, 0xef,
+    0xae, 0x24, 0xec, 0x62, 0xe2, 0x7d, 0xf4, 0x09,
+    0x5a, 0xc3, 0x0f, 0x4b, 0x49, 0xb7, 0xe7, 0xb2,
+    0x9b, 0x01, 0x2c, 0x8a, 0x39, 0xdd, 0x10, 0xec,
+    0x30, 0xb9, 0x7e, 0x39, 0x98, 0x94, 0x2a, 0xa4,
+    0xb3, 0x97, 0x7f, 0x85, 0x6e, 0x19, 0x75, 0x9e,
+    0x91, 0x94, 0xaa, 0xb5, 0xb0, 0x1f, 0x72, 0x50,
+    0xb5, 0x6d, 0x7a, 0xff, 0x90, 0xcc, 0x24, 0x80,
+    0x20, 0x23, 0x1c, 0xf3, 0xbd, 0x01, 0xc7, 0x82,
+    0x63, 0x04, 0xcc, 0xbd, 0xfb, 0x41, 0x9a, 0xb8,
+    0xeb, 0x6d, 0x78, 0x02, 0xee, 0x4a, 0x6d, 0xbb,
+    0xf7, 0xb7, 0xcf, 0x91, 0xca, 0x11, 0xf2, 0x62,
+    0xec, 0x18, 0x14, 0xcd, 0x10, 0xd8, 0x60, 0xe5,
+    0x20, 0x86, 0x74, 0x84, 0xd5, 0x35, 0x34, 0x69,
+    0x65, 0x93, 0x31, 0x99, 0xb6, 0x2d, 0x43, 0x23,
+    0x1d, 0x73, 0x55, 0xfa, 0x03, 0x76, 0x22, 0xcc,
+    0x66, 0xbc, 0x20, 0x2f, 0x7f, 0x4f, 0x78, 0xdd,
+    0xd1, 0x1f, 0xb6, 0x79, 0x6b, 0x58, 0x58, 0x57,
+    0x56, 0x87, 0xbc, 0x72, 0x6c, 0x81, 0x0a, 0xe2,
+    0xae, 0xb2, 0x4b, 0x66, 0x5b, 0x65, 0x35, 0x2b,
+    0x89, 0x0b, 0xa8, 0x5c, 0x34, 0xb3, 0x5f, 0xb0,
+    0x21, 0x5d, 0x4c, 0x60, 0x57, 0x73, 0xb6, 0x16,
+    0x94, 0xa7, 0x55, 0x52, 0x2a, 0x87, 0x10, 0xc9,
+    0x7c, 0x86, 0xb9, 0xdd, 0xf5, 0xb9, 0x30, 0xc0,
+    0xe6, 0x2a, 0xc9, 0x08, 0x3a, 0x88, 0xdc, 0x27,
+    0xea, 0x2f, 0xd9, 0x37, 0x06, 0x36, 0xd8, 0xe5,
+    0x66, 0x11, 0x54, 0x72, 0x4c, 0xc8, 0xa2, 0xc1,
+    0xed, 0xf5, 0x17, 0x3b, 0x06, 0x2b, 0x4c, 0xc9,
+    0x49, 0x2b, 0x98, 0x6f, 0xb8, 0x77, 0x96, 0x0c,
+    0x6b, 0x47, 0x81, 0x6c, 0xf3, 0x94, 0x3d, 0x3b,
+    0x24, 0x2d, 0x26, 0x9c, 0x40, 0xc1, 0x1f, 0xa7,
+    0xb2, 0xb4, 0x29, 0xb6, 0x05, 0xe5, 0x6e, 0x3c,
+    0xab, 0xd4, 0xaa, 0x3d, 0x78, 0x63, 0x3e, 0xf2,
+    0x75, 0x0d, 0xc3, 0x46, 0x0e, 0x68, 0xd7, 0x3d,
+    0xb9, 0xcb, 0x9a, 0x0a, 0xce, 0xec, 0x6f, 0x21,
+    0x8c, 0x86, 0xaa, 0xeb, 0x7b, 0x56, 0x41, 0xa6,
+    0x7a, 0xd3, 0x03, 0x02, 0x5c, 0x76, 0x01, 0xf7,
+    0x5d, 0x5e, 0x8e, 0x7d, 0xac, 0x35, 0x84, 0x11,
+    0xc6, 0xbc, 0x9a, 0x53, 0xcc, 0x3b, 0x4f, 0x5b,
+    0x23, 0x79, 0x30, 0x52, 0xc3, 0x73, 0x5d, 0xc8,
+    0xf1, 0xec, 0x2e, 0x0d, 0xda, 0x64, 0x90, 0x50,
+    0x62, 0xcf, 0x18, 0xc5, 0x52, 0x45, 0xe7, 0x38,
+    0x1a, 0xec, 0x01, 0x18, 0xbb, 0x85, 0x97, 0x7f,
+    0x68, 0x2b, 0x6f, 0xfc, 0xcd, 0x08, 0xc8, 0xe2,
+    0xca, 0x7e, 0xa6, 0x4f, 0xca, 0x5d, 0xdd, 0xf8,
+    0xfa, 0x52, 0x1c, 0x91, 0x82, 0x56, 0x07, 0xb2,
+    0x03, 0x3e, 0xa2, 0x8d, 0x60, 0xff, 0x78, 0x05,
+    0x1a, 0xfc, 0x6e, 0x27, 0x80, 0xbd, 0x90, 0x98,
+    0x83, 0x46, 0xba, 0xec, 0xee, 0x89, 0xe3, 0x1b,
+    0xc0, 0xcd, 0x2f, 0x05, 0x37, 0x18, 0xb5, 0xfa,
+    0xc3, 0x91, 0x85, 0x0f, 0xb7, 0x74, 0x1c, 0x64,
+    0xf0, 0xf8, 0x56, 0x35, 0xb8, 0x1d, 0xc3, 0x39,
+    0x5c, 0xea, 0x8a, 0x92, 0x31, 0xd2, 0x11, 0x4b,
+};
+
+static const unsigned char rsa_sigverx931_0_n[] = {
+    0xa0, 0x16, 0x14, 0x80, 0x8b, 0x17, 0x2b, 0xad,
+    0xd7, 0x07, 0x31, 0x6d, 0xfc, 0xba, 0x25, 0x83,
+    0x09, 0xa0, 0xf7, 0x71, 0xc6, 0x06, 0x22, 0x87,
+    0xd6, 0xbd, 0x13, 0xd9, 0xfe, 0x7c, 0xf7, 0xe6,
+    0x48, 0xdb, 0x27, 0xd8, 0xa5, 0x49, 0x8e, 0x8c,
+    0xea, 0xbe, 0xe0, 0x04, 0x6f, 0x3d, 0x3b, 0x73,
+    0xdc, 0xc5, 0xd4, 0xdc, 0x85, 0xef, 0xea, 0x10,
+    0x46, 0xf3, 0x88, 0xb9, 0x93, 0xbc, 0xa0, 0xb6,
+    0x06, 0x02, 0x82, 0xb4, 0x2d, 0x54, 0xec, 0x79,
+    0x50, 0x8a, 0xfc, 0xfa, 0x62, 0x45, 0xbb, 0xd7,
+    0x26, 0xcd, 0x88, 0xfa, 0xe8, 0x0f, 0x26, 0x5b,
+    0x1f, 0x21, 0x3f, 0x3b, 0x5d, 0x98, 0x3f, 0x02,
+    0x8c, 0xa1, 0xbf, 0xc0, 0x70, 0x4d, 0xd1, 0x41,
+    0xfd, 0xb9, 0x55, 0x12, 0x90, 0xc8, 0x6e, 0x0f,
+    0x19, 0xa8, 0x5c, 0x31, 0xd6, 0x16, 0x0e, 0xdf,
+    0x08, 0x84, 0xcd, 0x4b, 0xfd, 0x28, 0x8d, 0x7d,
+    0x6e, 0xea, 0xc7, 0x95, 0x4a, 0xc3, 0x84, 0x54,
+    0x7f, 0xb0, 0x20, 0x29, 0x96, 0x39, 0x4c, 0x3e,
+    0x85, 0xec, 0x22, 0xdd, 0xb9, 0x14, 0xbb, 0x04,
+    0x2f, 0x4c, 0x0c, 0xe3, 0xfa, 0xae, 0x47, 0x79,
+    0x59, 0x8e, 0x4e, 0x7d, 0x4a, 0x17, 0xae, 0x16,
+    0x38, 0x66, 0x4e, 0xff, 0x45, 0x7f, 0xac, 0x5e,
+    0x75, 0x9f, 0x51, 0x18, 0xe6, 0xad, 0x6b, 0x8b,
+    0x3d, 0x08, 0x4d, 0x9a, 0xd2, 0x11, 0xba, 0xa8,
+    0xc3, 0xb5, 0x17, 0xb5, 0xdf, 0xe7, 0x39, 0x89,
+    0x27, 0x7b, 0xeb, 0xf4, 0xe5, 0x7e, 0xa9, 0x7b,
+    0x39, 0x40, 0x6f, 0xe4, 0x82, 0x14, 0x3d, 0x62,
+    0xb6, 0xd4, 0x43, 0xd0, 0x0a, 0x2f, 0xc1, 0x73,
+    0x3d, 0x99, 0x37, 0xbe, 0x62, 0x13, 0x6a, 0x8b,
+    0xeb, 0xc5, 0x64, 0xd5, 0x2a, 0x8b, 0x4f, 0x7f,
+    0x82, 0x48, 0x69, 0x3e, 0x08, 0x1b, 0xb5, 0x77,
+    0xd3, 0xdc, 0x1b, 0x2c, 0xe5, 0x59, 0xf6, 0x33,
+    0x47, 0xa0, 0x0f, 0xff, 0x8a, 0x6a, 0x1d, 0x66,
+    0x24, 0x67, 0x36, 0x7d, 0x21, 0xda, 0xc1, 0xd4,
+    0x11, 0x6c, 0xe8, 0x5f, 0xd7, 0x8a, 0x53, 0x5c,
+    0xb2, 0xe2, 0xf9, 0x14, 0x29, 0x0f, 0xcf, 0x28,
+    0x32, 0x4f, 0xc6, 0x17, 0xf6, 0xbc, 0x0e, 0xb8,
+    0x99, 0x7c, 0x14, 0xa3, 0x40, 0x3f, 0xf3, 0xe4,
+    0x31, 0xbe, 0x54, 0x64, 0x5a, 0xad, 0x1d, 0xb0,
+    0x37, 0xcc, 0xd9, 0x0b, 0xa4, 0xbc, 0xe0, 0x07,
+    0x37, 0xd1, 0xe1, 0x65, 0xc6, 0x53, 0xfe, 0x60,
+    0x6a, 0x64, 0xa4, 0x01, 0x00, 0xf3, 0x5b, 0x9a,
+    0x28, 0x61, 0xde, 0x7a, 0xd7, 0x0d, 0x56, 0x1e,
+    0x4d, 0xa8, 0x6a, 0xb5, 0xf2, 0x86, 0x2a, 0x4e,
+    0xaa, 0x37, 0x23, 0x5a, 0x3b, 0x69, 0x66, 0x81,
+    0xc8, 0x8e, 0x1b, 0x31, 0x0f, 0x28, 0x31, 0x9a,
+    0x2d, 0xe5, 0x79, 0xcc, 0xa4, 0xca, 0x60, 0x45,
+    0xf7, 0x83, 0x73, 0x5a, 0x01, 0x29, 0xda, 0xf7,
+
+};
+static const unsigned char rsa_sigverx931_0_e[] = {
+    0x01, 0x00, 0x01,
+};
+static const unsigned char rsa_sigverx931_0_msg[] = {
+    0x82, 0x2e, 0x41, 0x70, 0x9d, 0x1f, 0xe9, 0x47,
+    0xec, 0xf1, 0x79, 0xcc, 0x05, 0xef, 0xdb, 0xcd,
+    0xca, 0x8b, 0x8e, 0x61, 0x45, 0xad, 0xa6, 0xd9,
+    0xd7, 0x4b, 0x15, 0xf4, 0x92, 0x3a, 0x2a, 0x52,
+    0xe3, 0x44, 0x57, 0x2b, 0x74, 0x7a, 0x37, 0x41,
+    0x50, 0xcb, 0xcf, 0x13, 0x49, 0xd6, 0x15, 0x54,
+    0x97, 0xfd, 0xae, 0x9b, 0xc1, 0xbb, 0xfc, 0x5c,
+    0xc1, 0x37, 0x58, 0x17, 0x63, 0x19, 0x9c, 0xcf,
+    0xee, 0x9c, 0xe5, 0xbe, 0x06, 0xe4, 0x97, 0x47,
+    0xd1, 0x93, 0xa1, 0x2c, 0x59, 0x97, 0x02, 0x01,
+    0x31, 0x45, 0x8c, 0xe1, 0x5c, 0xac, 0xe7, 0x5f,
+    0x6a, 0x23, 0xda, 0xbf, 0xe4, 0x25, 0xc6, 0x67,
+    0xea, 0x5f, 0x73, 0x90, 0x1b, 0x06, 0x0f, 0x41,
+    0xb5, 0x6e, 0x74, 0x7e, 0xfd, 0xd9, 0xaa, 0xbd,
+    0xe2, 0x8d, 0xad, 0x99, 0xdd, 0x29, 0x70, 0xca,
+    0x1b, 0x38, 0x21, 0x55, 0xde, 0x07, 0xaf, 0x00,
+
+};
+static const unsigned char rsa_sigverx931_0_sig[] = {
+    0x29, 0xa9, 0x3a, 0x8e, 0x9e, 0x90, 0x1b, 0xdb,
+    0xaf, 0x0b, 0x47, 0x5b, 0xb5, 0xc3, 0x8c, 0xc3,
+    0x70, 0xbe, 0x73, 0xf9, 0x65, 0x8e, 0xc6, 0x1e,
+    0x95, 0x0b, 0xdb, 0x24, 0x76, 0x79, 0xf1, 0x00,
+    0x71, 0xcd, 0xc5, 0x6a, 0x7b, 0xd2, 0x8b, 0x18,
+    0xc4, 0xdd, 0xf1, 0x2a, 0x31, 0x04, 0x3f, 0xfc,
+    0x36, 0x06, 0x20, 0x71, 0x3d, 0x62, 0xf2, 0xb5,
+    0x79, 0x0a, 0xd5, 0xd2, 0x81, 0xf1, 0xb1, 0x4f,
+    0x9a, 0x17, 0xe8, 0x67, 0x64, 0x48, 0x09, 0x75,
+    0xff, 0x2d, 0xee, 0x36, 0xca, 0xca, 0x1d, 0x74,
+    0x99, 0xbe, 0x5c, 0x94, 0x31, 0xcc, 0x12, 0xf4,
+    0x59, 0x7e, 0x17, 0x00, 0x4f, 0x7b, 0xa4, 0xb1,
+    0xda, 0xdb, 0x3e, 0xa4, 0x34, 0x10, 0x4a, 0x19,
+    0x0a, 0xd2, 0xa7, 0xa0, 0xc5, 0xe6, 0xef, 0x82,
+    0xd4, 0x2e, 0x21, 0xbe, 0x15, 0x73, 0xac, 0xef,
+    0x05, 0xdb, 0x6a, 0x8a, 0x1a, 0xcb, 0x8e, 0xa5,
+    0xee, 0xfb, 0x28, 0xbf, 0x96, 0xa4, 0x2b, 0xd2,
+    0x85, 0x2b, 0x20, 0xc3, 0xaf, 0x9a, 0x32, 0x04,
+    0xa0, 0x49, 0x24, 0x47, 0xd0, 0x09, 0xf7, 0xcf,
+    0x73, 0xb6, 0xf6, 0x70, 0xda, 0x3b, 0xf8, 0x5a,
+    0x28, 0x2e, 0x14, 0x6c, 0x52, 0xbd, 0x2a, 0x7c,
+    0x8e, 0xc1, 0xa8, 0x0e, 0xb1, 0x1e, 0x6b, 0x8d,
+    0x76, 0xea, 0x70, 0x81, 0xa0, 0x02, 0x63, 0x74,
+    0xbc, 0x7e, 0xb9, 0xac, 0x0e, 0x7b, 0x1b, 0x75,
+    0x82, 0xe2, 0x98, 0x4e, 0x24, 0x55, 0xd4, 0xbd,
+    0x14, 0xde, 0x58, 0x56, 0x3a, 0x5d, 0x4e, 0x57,
+    0x0d, 0x54, 0x74, 0xe8, 0x86, 0x8c, 0xcb, 0x07,
+    0x9f, 0x0b, 0xfb, 0xc2, 0x08, 0x5c, 0xd7, 0x05,
+    0x3b, 0xc8, 0xd2, 0x15, 0x68, 0x8f, 0x3d, 0x3c,
+    0x4e, 0x85, 0xa9, 0x25, 0x6f, 0xf5, 0x2e, 0xca,
+    0xca, 0xa8, 0x27, 0x89, 0x61, 0x4e, 0x1f, 0x57,
+    0x2d, 0x99, 0x10, 0x3f, 0xbc, 0x9e, 0x96, 0x5e,
+    0x2f, 0x0a, 0x25, 0xa7, 0x5c, 0xea, 0x65, 0x2a,
+    0x22, 0x35, 0xa3, 0xf9, 0x13, 0x89, 0x05, 0x2e,
+    0x19, 0x73, 0x1d, 0x70, 0x74, 0x98, 0x15, 0x4b,
+    0xab, 0x56, 0x52, 0xe0, 0x01, 0x42, 0x95, 0x6a,
+    0x46, 0x2c, 0x78, 0xff, 0x26, 0xbc, 0x48, 0x10,
+    0x38, 0x25, 0xab, 0x32, 0x7c, 0x79, 0x7c, 0x5d,
+    0x6f, 0x45, 0x54, 0x74, 0x2d, 0x93, 0x56, 0x52,
+    0x11, 0x34, 0x1e, 0xe3, 0x4b, 0x6a, 0x17, 0x4f,
+    0x37, 0x14, 0x75, 0xac, 0xa3, 0xa1, 0xca, 0xda,
+    0x38, 0x06, 0xa9, 0x78, 0xb9, 0x5d, 0xd0, 0x59,
+    0x1b, 0x5d, 0x1e, 0xc2, 0x0b, 0xfb, 0x39, 0x37,
+    0x44, 0x85, 0xb6, 0x36, 0x06, 0x95, 0xbc, 0x15,
+    0x35, 0xb9, 0xe6, 0x27, 0x42, 0xe3, 0xc8, 0xec,
+    0x30, 0x37, 0x20, 0x26, 0x9a, 0x11, 0x61, 0xc0,
+    0xdb, 0xb2, 0x5a, 0x26, 0x78, 0x27, 0xb9, 0x13,
+    0xc9, 0x1a, 0xa7, 0x67, 0x93, 0xe8, 0xbe, 0xcb,
+};
+
+#define rsa_sigverx931_1_n rsa_sigverx931_0_n
+#define rsa_sigverx931_1_e rsa_sigverx931_0_e
+static const unsigned char rsa_sigverx931_1_msg[] = {
+    0x79, 0x02, 0xb9, 0xd2, 0x3e, 0x84, 0x02, 0xc8,
+    0x2a, 0x94, 0x92, 0x14, 0x8d, 0xd5, 0xd3, 0x8d,
+    0xb2, 0xf6, 0x00, 0x8b, 0x61, 0x2c, 0xd2, 0xf9,
+    0xa8, 0xe0, 0x5d, 0xac, 0xdc, 0xa5, 0x34, 0xf3,
+    0xda, 0x6c, 0xd4, 0x70, 0x92, 0xfb, 0x40, 0x26,
+    0xc7, 0x9b, 0xe8, 0xd2, 0x10, 0x11, 0xcf, 0x7f,
+    0x23, 0xd0, 0xed, 0x55, 0x52, 0x6d, 0xd3, 0xb2,
+    0x56, 0x53, 0x8d, 0x7c, 0x4c, 0xb8, 0xcc, 0xb5,
+    0xfd, 0xd0, 0x45, 0x4f, 0x62, 0x40, 0x54, 0x42,
+    0x68, 0xd5, 0xe5, 0xdd, 0xf0, 0x76, 0x94, 0x59,
+    0x1a, 0x57, 0x13, 0xb4, 0xc3, 0x70, 0xcc, 0xbd,
+    0x4c, 0x2e, 0xc8, 0x6b, 0x9d, 0x68, 0xd0, 0x72,
+    0x6a, 0x94, 0xd2, 0x18, 0xb5, 0x3b, 0x86, 0x45,
+    0x95, 0xaa, 0x50, 0xda, 0x35, 0xeb, 0x69, 0x44,
+    0x1f, 0xf3, 0x3a, 0x51, 0xbb, 0x1d, 0x08, 0x42,
+    0x12, 0xd7, 0xd6, 0x21, 0xd8, 0x9b, 0x87, 0x55,
+};
+
+static const unsigned char rsa_sigverx931_1_sig[] = {
+    0x3b, 0xba, 0xb3, 0xb1, 0xb2, 0x6a, 0x29, 0xb5,
+    0xf9, 0x94, 0xf1, 0x00, 0x5c, 0x16, 0x67, 0x67,
+    0x73, 0xd3, 0xde, 0x7e, 0x07, 0xfa, 0xaa, 0x95,
+    0xeb, 0x5a, 0x55, 0xdc, 0xb2, 0xa9, 0x70, 0x5a,
+    0xee, 0x8f, 0x8d, 0x69, 0x85, 0x2b, 0x00, 0xe3,
+    0xdc, 0xe2, 0x73, 0x9b, 0x68, 0xeb, 0x93, 0x69,
+    0x08, 0x03, 0x17, 0xd6, 0x50, 0x21, 0x14, 0x23,
+    0x8c, 0xe6, 0x54, 0x3a, 0xd9, 0xfc, 0x8b, 0x14,
+    0x81, 0xb1, 0x8b, 0x9d, 0xd2, 0xbe, 0x58, 0x75,
+    0x94, 0x74, 0x93, 0xc9, 0xbb, 0x4e, 0xf6, 0x1f,
+    0x73, 0x7d, 0x1a, 0x5f, 0xbd, 0xbf, 0x59, 0x37,
+    0x5b, 0x98, 0x54, 0xad, 0x3a, 0xef, 0xa0, 0xef,
+    0xcb, 0xc3, 0xe8, 0x84, 0xd8, 0x3d, 0xf5, 0x60,
+    0xb8, 0xc3, 0x8d, 0x1e, 0x78, 0xa0, 0x91, 0x94,
+    0xb7, 0xd7, 0xb1, 0xd4, 0xe2, 0xee, 0x81, 0x93,
+    0xfc, 0x41, 0xf0, 0x31, 0xbb, 0x03, 0x52, 0xde,
+    0x80, 0x20, 0x3a, 0x68, 0xe6, 0xc5, 0x50, 0x1b,
+    0x08, 0x3f, 0x40, 0xde, 0xb3, 0xe5, 0x81, 0x99,
+    0x7f, 0xdb, 0xb6, 0x5d, 0x61, 0x27, 0xd4, 0xfb,
+    0xcd, 0xc5, 0x7a, 0xea, 0xde, 0x7a, 0x66, 0xef,
+    0x55, 0x3f, 0x85, 0xea, 0x84, 0xc5, 0x0a, 0xf6,
+    0x3c, 0x40, 0x38, 0xf7, 0x6c, 0x66, 0xe5, 0xbe,
+    0x61, 0x41, 0xd3, 0xb1, 0x08, 0xe1, 0xb4, 0xf9,
+    0x6e, 0xf6, 0x0e, 0x4a, 0x72, 0x6c, 0x61, 0x63,
+    0x3e, 0x41, 0x33, 0x94, 0xd6, 0x27, 0xa4, 0xd9,
+    0x3a, 0x20, 0x2b, 0x39, 0xea, 0xe5, 0x82, 0x48,
+    0xd6, 0x5b, 0x58, 0x85, 0x44, 0xb0, 0xd2, 0xfd,
+    0xfb, 0x3e, 0xeb, 0x78, 0xac, 0xbc, 0xba, 0x16,
+    0x92, 0x0e, 0x20, 0xc1, 0xb2, 0xd1, 0x92, 0xa8,
+    0x00, 0x88, 0xc0, 0x41, 0x46, 0x38, 0xb6, 0x54,
+    0x70, 0x0c, 0x00, 0x62, 0x97, 0x6a, 0x8e, 0x66,
+    0x5a, 0xa1, 0x6c, 0xf7, 0x6d, 0xc2, 0x27, 0x56,
+    0x60, 0x5b, 0x0c, 0x52, 0xac, 0x5c, 0xae, 0x99,
+    0x55, 0x11, 0x62, 0x52, 0x09, 0x48, 0x53, 0x90,
+    0x3c, 0x0b, 0xd4, 0xdc, 0x7b, 0xe3, 0x4c, 0xe3,
+    0xa8, 0x6d, 0xc5, 0xdf, 0xc1, 0x5c, 0x59, 0x25,
+    0x99, 0x30, 0xde, 0x57, 0x6a, 0x84, 0x25, 0x34,
+    0x3e, 0x64, 0x11, 0xdb, 0x7a, 0x82, 0x8e, 0x70,
+    0xd2, 0x5c, 0x0e, 0x81, 0xa0, 0x24, 0x53, 0x75,
+    0x98, 0xd6, 0x10, 0x01, 0x6a, 0x14, 0xed, 0xc3,
+    0x6f, 0xc4, 0x18, 0xb8, 0xd2, 0x9f, 0x59, 0x53,
+    0x81, 0x3a, 0x86, 0x31, 0xfc, 0x9e, 0xbf, 0x6c,
+    0x52, 0x93, 0x86, 0x9c, 0xaa, 0x6c, 0x6f, 0x07,
+    0x8a, 0x40, 0x33, 0x64, 0xb2, 0x70, 0x48, 0x85,
+    0x05, 0x59, 0x65, 0x2d, 0x6b, 0x9a, 0xad, 0xab,
+    0x20, 0x7e, 0x02, 0x6d, 0xde, 0xcf, 0x22, 0x0b,
+    0xea, 0x6e, 0xbd, 0x1c, 0x39, 0x3a, 0xfd, 0xa4,
+    0xde, 0x54, 0xae, 0xde, 0x5e, 0xf7, 0xb0, 0x6d,
+};
+
+static const struct rsa_sigver_st rsa_sigver_data[] = {
+    {
+        "pkcs1", /* pkcs1v1.5 */
+        2048,
+        "SHA224",
+        ITM(rsa_sigver15_0_msg),
+        ITM(rsa_sigver15_0_n),
+        ITM(rsa_sigver15_0_e),
+        ITM(rsa_sigver15_0_sig),
+        NO_PSS_SALT_LEN,
+        PASS
+    },
+    {
+        "pkcs1", /* pkcs1v1.5 */
+        2048,
+        "SHA224",
+        ITM(rsa_sigver15_1_msg),
+        ITM(rsa_sigver15_1_n),
+        ITM(rsa_sigver15_1_e),
+        ITM(rsa_sigver15_1_sig),
+        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,
+        "SHA256",
+        ITM(rsa_sigverx931_1_msg),
+        ITM(rsa_sigverx931_1_n),
+        ITM(rsa_sigverx931_1_e),
+        ITM(rsa_sigverx931_1_sig),
+        NO_PSS_SALT_LEN,
+        FAIL
+    },
+    {
+        "pss",
+        4096,
+        "SHA384",
+        ITM(rsa_sigverpss_0_msg),
+        ITM(rsa_sigverpss_0_n),
+        ITM(rsa_sigverpss_0_e),
+        ITM(rsa_sigverpss_0_sig),
+        62,
+        PASS
+    },
+    {
+        "pss",
+        4096,
+        "SHA384",
+        ITM(rsa_sigverpss_1_msg),
+        ITM(rsa_sigverpss_1_n),
+        ITM(rsa_sigverpss_1_e),
+        ITM(rsa_sigverpss_1_sig),
+        62,
+        FAIL
+    },
+};
+
+struct rsa_decrypt_prim_st {
+    const unsigned char *ct;
+    size_t ct_len;
+};
+
+static const unsigned char rsa_decrypt_prim_0_ct[] = {
+    0x09, 0x7e, 0x82, 0xfe, 0xc7, 0x24, 0x65, 0xe0,
+    0x49, 0x2e, 0x78, 0xed, 0xf4, 0x7d, 0x05, 0x0d,
+    0xff, 0x2f, 0x1a, 0x95, 0xeb, 0x74, 0x60, 0x3d,
+    0xd3, 0x3a, 0xec, 0x8a, 0x2c, 0x8b, 0x00, 0xa5,
+    0x75, 0x2c, 0x87, 0x7b, 0xa5, 0x76, 0x08, 0xee,
+    0x99, 0xab, 0x5b, 0x21, 0x69, 0x90, 0x72, 0x0d,
+    0x55, 0xe4, 0x7d, 0x1d, 0xcb, 0xaa, 0xeb, 0x32,
+    0x24, 0xf7, 0xce, 0x95, 0xb5, 0x3e, 0x0e, 0x57,
+    0xd4, 0x2a, 0x5b, 0xfc, 0x1f, 0xf7, 0x28, 0x3f,
+    0xd6, 0x31, 0x36, 0x92, 0xc5, 0x13, 0xe3, 0x4e,
+    0x28, 0x53, 0xbe, 0x60, 0x5f, 0x82, 0x12, 0x7a,
+    0x50, 0xe6, 0x91, 0x40, 0xcf, 0x52, 0x3a, 0xd2,
+    0x15, 0x20, 0xd5, 0x82, 0x6d, 0x5e, 0xab, 0x47,
+    0xd1, 0x2d, 0x00, 0xf5, 0xea, 0xf4, 0x68, 0x88,
+    0x38, 0x43, 0xd6, 0xcb, 0xaa, 0xd0, 0xd1, 0x75,
+    0xe6, 0x87, 0x5f, 0xd1, 0x89, 0xd3, 0x57, 0x1b,
+    0xf2, 0x45, 0x8a, 0x92, 0xe6, 0x95, 0xb8, 0x99,
+    0x80, 0xe9, 0xe6, 0x5f, 0x2b, 0x48, 0x2b, 0xb3,
+    0x2b, 0x80, 0x56, 0xf8, 0xd4, 0x96, 0x44, 0xb5,
+    0xae, 0x6d, 0x4a, 0x3d, 0x7b, 0x0a, 0x54, 0x3c,
+    0xa8, 0x21, 0x8b, 0x64, 0x96, 0xea, 0xc2, 0xef,
+    0x60, 0xbb, 0xd3, 0x4e, 0xaf, 0x6c, 0x5b, 0x06,
+    0x57, 0xe8, 0x5e, 0x2c, 0x87, 0x46, 0x12, 0xeb,
+    0xfb, 0xe2, 0xdb, 0x7b, 0xac, 0x09, 0x8b, 0xa0,
+    0x98, 0x6e, 0xc6, 0x3f, 0x98, 0xdd, 0x7d, 0xc6,
+    0xc6, 0x32, 0xc2, 0xcc, 0x73, 0xe2, 0x15, 0xde,
+    0xb2, 0x0f, 0x41, 0x08, 0x1e, 0x2e, 0xba, 0x93,
+    0x65, 0x94, 0xab, 0x84, 0x0e, 0x1e, 0xda, 0x1b,
+    0xf0, 0xe0, 0x13, 0x13, 0xe2, 0xa5, 0x31, 0xb8,
+    0x80, 0xc1, 0x38, 0xc5, 0x08, 0x09, 0x0a, 0xe2,
+    0x78, 0x7d, 0xd6, 0xcf, 0x8d, 0x6b, 0xe8, 0x1b,
+    0x47, 0x83, 0x80, 0x71, 0xe2, 0xd3, 0x01, 0xbc,
+};
+
+static const unsigned char rsa_decrypt_prim_1_ct[] = {
+    0xff, 0xd5, 0xaa, 0x3f, 0x0c, 0x7c, 0x78, 0x7e,
+    0xe3, 0x8a, 0x4f, 0xcc, 0x20, 0x3f, 0x51, 0xe5,
+    0xf4, 0x9c, 0xc5, 0x62, 0xcc, 0xa3, 0xcb, 0xce,
+    0x39, 0x80, 0x35, 0xef, 0xd5, 0x95, 0x56, 0xcb,
+    0xb2, 0x62, 0x8c, 0xe6, 0x8b, 0x20, 0xe4, 0x36,
+    0xae, 0xe8, 0x07, 0x07, 0xc2, 0x23, 0x6a, 0xfc,
+    0x83, 0xf0, 0x04, 0x88, 0x19, 0xf8, 0x9f, 0x5c,
+    0x59, 0x4d, 0xb3, 0x81, 0x86, 0x9d, 0x3b, 0x61,
+    0x73, 0x31, 0x03, 0xec, 0x9c, 0xdd, 0x75, 0xb7,
+    0x37, 0x0a, 0x8d, 0x94, 0xd9, 0x9f, 0x6d, 0x85,
+    0xb0, 0x5c, 0x08, 0xcc, 0xb4, 0x27, 0x8c, 0xf0,
+    0xe6, 0xd6, 0xe0, 0xc1, 0x57, 0x59, 0xaa, 0xc7,
+    0x8f, 0x5c, 0xa7, 0x4b, 0x3c, 0x81, 0x4a, 0xa3,
+    0x9b, 0x18, 0x88, 0x04, 0x98, 0x54, 0x3d, 0x87,
+    0x2a, 0x89, 0xb6, 0x41, 0xe8, 0xbd, 0x37, 0x17,
+    0x03, 0xa8, 0xf1, 0x37, 0xa5, 0x5e, 0x02, 0x13,
+    0x67, 0x08, 0xec, 0x9e, 0x97, 0xf5, 0xcc, 0x5f,
+    0x75, 0x37, 0xbe, 0xce, 0xe8, 0x5e, 0xa1, 0xca,
+    0x46, 0xa3, 0xda, 0xe4, 0x1f, 0xf8, 0xc4, 0xa3,
+    0x26, 0xbb, 0xed, 0xa2, 0x71, 0xb2, 0x44, 0x00,
+    0xd3, 0xe5, 0x06, 0xf1, 0xb4, 0xc1, 0xe0, 0x29,
+    0xca, 0xeb, 0xe0, 0xdf, 0xd1, 0x69, 0x5f, 0xa9,
+    0x03, 0x7c, 0x49, 0x93, 0xfb, 0xc2, 0xdf, 0x39,
+    0xbc, 0x2a, 0x6b, 0x59, 0x7d, 0xf4, 0x84, 0x93,
+    0xa2, 0x8b, 0x7a, 0x5a, 0x7a, 0xa9, 0xff, 0x41,
+    0x4c, 0x52, 0x5c, 0xf9, 0x59, 0xd2, 0x91, 0xc3,
+    0xa9, 0xe8, 0x23, 0x36, 0x5f, 0x2f, 0xb9, 0xbe,
+    0x22, 0xc4, 0xfd, 0x84, 0x5f, 0x81, 0x3d, 0x94,
+    0xf8, 0xa4, 0x9b, 0xae, 0xc0, 0xb5, 0x78, 0x4f,
+    0x91, 0x76, 0x02, 0x5d, 0x60, 0x71, 0x8b, 0xeb,
+    0x08, 0x42, 0xe3, 0xb3, 0x63, 0x05, 0x60, 0x59,
+    0x98, 0xc1, 0x6d, 0x66, 0xb3, 0xc5, 0x8a, 0xbc,
+};
+
+static const struct rsa_decrypt_prim_st rsa_decrypt_prim_data[] = {
+    {
+        ITM(rsa_decrypt_prim_0_ct),
+    },
+    {
+        ITM(rsa_decrypt_prim_1_ct),
+    },
+};
+
+#endif /* OPENSSL_NO_RSA */
diff --git a/test/build.info b/test/build.info
index de4f2fc270..6d7043208a 100644
--- a/test/build.info
+++ b/test/build.info
@@ -36,6 +36,7 @@ IF[{- !$disabled{tests} -}]
           destest mdc2test \
           enginetest exptest \
           evp_pkey_provided_test evp_test evp_extra_test evp_fetch_prov_test \
+          acvp_test \
           v3nametest v3ext \
           crltest danetest bad_dtls_test lhash_test sparse_array_test \
           conf_include_test params_api_test params_conversion_test \
@@ -145,6 +146,12 @@ IF[{- !$disabled{tests} -}]
   INCLUDE[evp_pkey_provided_test]=../include ../apps/include
   DEPEND[evp_pkey_provided_test]=../libcrypto.a libtestutil.a
 
+  IF[{- !$disabled{acvp-tests} -}]
+    SOURCE[acvp_test]=acvp_test.c
+    INCLUDE[acvp_test]=../include ../apps/include
+    DEPEND[acvp_test]=../libcrypto.a libtestutil.a
+  ENDIF
+
   IF[{- !$disabled{'deprecated-3.0'} -}]
     PROGRAMS{noinst}=igetest bftest casttest
 
diff --git a/test/ffc_internal_test.c b/test/ffc_internal_test.c
index c0b8e67871..632cead926 100644
--- a/test/ffc_internal_test.c
+++ b/test/ffc_internal_test.c
@@ -189,42 +189,40 @@ static int ffc_params_validate_g_unverified_test(void)
     ffc_params_set0_pqg(&params, p, q, NULL);
     p = NULL;
     q = NULL;
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha256(),
-                                                  FFC_PARAMS_VALIDATE_G, &res,
-                                                  NULL)))
+    ffc_params_set_flags(&params, FFC_PARAM_FLAG_VALIDATE_G);
+    ffc_set_digest(&params, "SHA256", NULL);
+
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     ffc_params_set0_pqg(&params, p, q, g);
     g = NULL;
-    if (!TEST_true(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                 EVP_sha256(),
-                                                 FFC_PARAMS_VALIDATE_G, &res,
-                                                 NULL)))
+    if (!TEST_true(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                 FFC_PARAM_TYPE_DSA,
+                                                 &res, NULL)))
         goto err;
 
     /* incorrect g */
     BN_add_word(g1, 1);
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha256(),
-                                                  FFC_PARAMS_VALIDATE_G, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     /* fail if g < 2 */
     BN_set_word(g1, 1);
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha256(),
-                                                  FFC_PARAMS_VALIDATE_G, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     BN_copy(g1, p1);
     /* Fail if g >= p */
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha256(),
-                                                  FFC_PARAMS_VALIDATE_G, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     ret = 1;
@@ -255,10 +253,12 @@ static int ffc_params_validate_pq_test(void)
     /* No p */
     ffc_params_set0_pqg(&params, NULL, q, NULL);
     q = NULL;
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha224(),
-                                                  FFC_PARAMS_VALIDATE_PQ, &res,
-                                                  NULL)))
+    ffc_params_set_flags(&params, FFC_PARAM_FLAG_VALIDATE_PQ);
+    ffc_set_digest(&params, "SHA224", NULL);
+
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     /* Test valid case */
@@ -267,40 +267,36 @@ static int ffc_params_validate_pq_test(void)
     ffc_params_set_validate_params(&params, dsa_2048_224_sha224_seed,
                                    sizeof(dsa_2048_224_sha224_seed),
                                    dsa_2048_224_sha224_counter);
-    if (!TEST_true(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                 EVP_sha224(),
-                                                 FFC_PARAMS_VALIDATE_PQ, &res,
-                                                 NULL)))
+    if (!TEST_true(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                 FFC_PARAM_TYPE_DSA,
+                                                 &res, NULL)))
         goto err;
 
     /* Bad counter - so p is not prime */
     ffc_params_set_validate_params(&params, dsa_2048_224_sha224_seed,
                                    sizeof(dsa_2048_224_sha224_seed),
                                    1);
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha224(),
-                                                  FFC_PARAMS_VALIDATE_PQ, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     /* seedlen smaller than N */
     ffc_params_set_validate_params(&params, dsa_2048_224_sha224_seed,
                                    sizeof(dsa_2048_224_sha224_seed)-1,
                                    dsa_2048_224_sha224_counter);
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha224(),
-                                                  FFC_PARAMS_VALIDATE_PQ, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     /* Provided seed doesnt produce a valid prime q */
     ffc_params_set_validate_params(&params, dsa_2048_224_sha224_bad_seed,
                                    sizeof(dsa_2048_224_sha224_bad_seed),
                                    dsa_2048_224_sha224_counter);
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha224(),
-                                                  FFC_PARAMS_VALIDATE_PQ, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     if (!TEST_ptr(p = BN_bin2bn(dsa_3072_256_sha512_p,
@@ -314,21 +310,20 @@ static int ffc_params_validate_pq_test(void)
 
     ffc_params_set0_pqg(&params, p, q, NULL);
     p = q  = NULL;
+    ffc_set_digest(&params, "SHA512", NULL);
     ffc_params_set_validate_params(&params, dsa_3072_256_sha512_seed,
                                    sizeof(dsa_3072_256_sha512_seed),
                                    dsa_3072_256_sha512_counter);
     /* Q doesn't div P-1 */
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  EVP_sha512(),
-                                                  FFC_PARAMS_VALIDATE_PQ, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
 
     /* Bad L/N for FIPS DH */
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DH,
-                                                  EVP_sha512(),
-                                                  FFC_PARAMS_VALIDATE_PQ, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DH,
+                                                  &res, NULL)))
         goto err;
 
     ret = 1;
@@ -347,13 +342,13 @@ static int ffc_params_gen_test(void)
     FFC_PARAMS params;
 
     ffc_params_init(&params);
-    if (!TEST_true(ffc_params_FIPS186_4_generate(NULL, &params, FFC_PARAM_TYPE_DH,
-                                                 2048, 256, NULL, &res, NULL)))
+    if (!TEST_true(ffc_params_FIPS186_4_generate(NULL, &params,
+                                                 FFC_PARAM_TYPE_DH,
+                                                 2048, 256, &res, NULL)))
         goto err;
-    if (!TEST_true(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DH,
-                                                 NULL,
-                                                 FFC_PARAMS_VALIDATE_ALL, &res,
-                                                 NULL)))
+    if (!TEST_true(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                 FFC_PARAM_TYPE_DH,
+                                                 &res, NULL)))
         goto err;
 
     ret = 1;
@@ -369,13 +364,13 @@ static int ffc_params_gen_canonicalg_test(void)
 
     ffc_params_init(&params);
     params.gindex = 1;
-    if (!TEST_true(ffc_params_FIPS186_4_generate(NULL, &params, FFC_PARAM_TYPE_DH,
-                                                 2048, 256, NULL, &res, NULL)))
+    if (!TEST_true(ffc_params_FIPS186_4_generate(NULL, &params,
+                                                 FFC_PARAM_TYPE_DH,
+                                                 2048, 256, &res, NULL)))
         goto err;
-    if (!TEST_true(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DH,
-                                                 NULL,
-                                                 FFC_PARAMS_VALIDATE_ALL, &res,
-                                                 NULL)))
+    if (!TEST_true(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                 FFC_PARAM_TYPE_DH,
+                                                 &res, NULL)))
         goto err;
 
     if (!TEST_true(ffc_params_print(bio_out, &params, 4)))
@@ -396,19 +391,18 @@ static int ffc_params_fips186_2_gen_validate_test(void)
     ffc_params_init(&params);
     if (!TEST_ptr(bn = BN_new()))
         goto err;
-    if (!TEST_true(ffc_params_FIPS186_2_generate(NULL, &params, FFC_PARAM_TYPE_DH,
-                                                 1024, 160, NULL, &res, NULL)))
+    if (!TEST_true(ffc_params_FIPS186_2_generate(NULL, &params,
+                                                 FFC_PARAM_TYPE_DH,
+                                                 1024, 160, &res, NULL)))
         goto err;
-    if (!TEST_true(ffc_params_FIPS186_2_validate(&params, FFC_PARAM_TYPE_DH,
-                                                 NULL,
-                                                 FFC_PARAMS_VALIDATE_ALL, &res,
-                                                 NULL)))
+    if (!TEST_true(ffc_params_FIPS186_2_validate(NULL, &params,
+                                                 FFC_PARAM_TYPE_DH,
+                                                 &res, NULL)))
         goto err;
     /* FIPS 186-4 L,N pair test will fail for DH */
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DH,
-                                                  NULL,
-                                                  FFC_PARAMS_VALIDATE_ALL, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DH,
+                                                  &res, NULL)))
         goto err;
     if (!TEST_int_eq(res, FFC_CHECK_BAD_LN_PAIR))
         goto err;
@@ -417,20 +411,19 @@ static int ffc_params_fips186_2_gen_validate_test(void)
      * The fips186-2 generation should produce a different q compared to
      * fips 186-4 given the same seed value. So validation of q will fail.
      */
-    if (!TEST_false(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                  NULL,
-                                                  FFC_PARAMS_VALIDATE_ALL, &res,
-                                                  NULL)))
+    if (!TEST_false(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                  FFC_PARAM_TYPE_DSA,
+                                                  &res, NULL)))
         goto err;
     /* As the params are randomly generated the error is one of the following */
     if (!TEST_true(res == FFC_CHECK_Q_MISMATCH || res == FFC_CHECK_Q_NOT_PRIME))
         goto err;
 
+    ffc_params_set_flags(&params, FFC_PARAM_FLAG_VALIDATE_G);
     /* Partially valid g test will still pass */
-    if (!TEST_int_eq(ffc_params_FIPS186_4_validate(&params, FFC_PARAM_TYPE_DSA,
-                                                 NULL,
-                                                 FFC_PARAMS_VALIDATE_G, &res,
-                                                 NULL), 2))
+    if (!TEST_int_eq(ffc_params_FIPS186_4_validate(NULL, &params,
+                                                   FFC_PARAM_TYPE_DSA,
+                                                   &res, NULL), 2))
         goto err;
 
     if (!TEST_true(ffc_params_print(bio_out, &params, 4)))
diff --git a/test/recipes/30-test_acvp.t b/test/recipes/30-test_acvp.t
new file mode 100644
index 0000000000..e2e40aaa76
--- /dev/null
+++ b/test/recipes/30-test_acvp.t
@@ -0,0 +1,41 @@
+#! /usr/bin/env perl
+# Copyright 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
+
+use strict;
+use warnings;
+
+use OpenSSL::Test qw(:DEFAULT bldtop_dir srctop_dir srctop_file bldtop_file);
+use OpenSSL::Test::Utils;
+
+BEGIN {
+setup("test_acvp");
+}
+
+my $no_fips = disabled('fips') || ($ENV{NO_FIPS} // 0);
+
+plan skip_all => "ACVP is not supported by this test"
+    if $no_fips || disabled("acvp_tests");
+
+use lib srctop_dir('Configurations');
+use lib bldtop_dir('.');
+use platform;
+
+my $infile = bldtop_file('providers', platform->dso('fips'));
+
+plan tests => 2;
+
+ok(run(app(['openssl', 'fipsinstall',
+           '-out', bldtop_file('providers', 'fipsmodule.cnf'),
+           '-module', $infile,
+           '-provider_name', 'fips', '-mac_name', 'HMAC',
+           '-macopt', 'digest:SHA256', '-macopt', 'hexkey:00',
+           '-section_name', 'fips_sect'])),
+   "fipsinstall");
+
+ok(run(test(["acvp_test", "-config", srctop_file("test","fips.cnf")])),
+   "running acvp_test");
diff --git a/test/rsa_sp800_56b_test.c b/test/rsa_sp800_56b_test.c
index b80df0137a..edcf4478fa 100644
--- a/test/rsa_sp800_56b_test.c
+++ b/test/rsa_sp800_56b_test.c
@@ -33,63 +33,6 @@ int setup_tests(void)
 static const unsigned char cav_e[] = {
     0x01,0x00,0x01
 };
-static const unsigned char cav_Xp[] = {
-    0xcf,0x72,0x1b,0x9a,0xfd,0x0d,0x22,0x1a,0x74,0x50,0x97,0x22,0x76,0xd8,0xc0,
-    0xc2,0xfd,0x08,0x81,0x05,0xdd,0x18,0x21,0x99,0x96,0xd6,0x5c,0x79,0xe3,0x02,
-    0x81,0xd7,0x0e,0x3f,0x3b,0x34,0xda,0x61,0xc9,0x2d,0x84,0x86,0x62,0x1e,0x3d,
-    0x5d,0xbf,0x92,0x2e,0xcd,0x35,0x3d,0x6e,0xb9,0x59,0x16,0xc9,0x82,0x50,0x41,
-    0x30,0x45,0x67,0xaa,0xb7,0xbe,0xec,0xea,0x4b,0x9e,0xa0,0xc3,0x05,0xb3,0x88,
-    0xd4,0x4c,0xac,0xeb,0xe4,0x03,0xc6,0xca,0xcb,0xd9,0xd3,0x4e,0xf6,0x7f,0x2c,
-    0x27,0x1e,0x08,0x6c,0xc2,0xd6,0x45,0x1f,0x84,0xe4,0x3c,0x97,0x19,0xde,0xb8,
-    0x55,0xaf,0x0e,0xcf,0x9e,0xb0,0x9c,0x20,0xd3,0x1f,0xa8,0xd7,0x52,0xc2,0x95,
-    0x1c,0x80,0x15,0x42,0x4d,0x4f,0x19,0x16
-};
-static const unsigned char cav_Xp1[] = {
-    0xac,0x5f,0x7f,0x6e,0x33,0x3e,0x97,0x3a,0xb3,0x17,0x44,0xa9,0x0f,0x7a,0x54,
-    0x70,0x27,0x06,0x93,0xd5,0x49,0xde,0x91,0x83,0xbc,0x8a,0x7b,0x95
-};
-static const unsigned char cav_Xp2[] = {
-    0x0b,0xf6,0xe8,0x79,0x5a,0x81,0xae,0x90,0x1d,0xa4,0x38,0x74,0x9c,0x0e,0x6f,
-    0xe0,0x03,0xcf,0xc4,0x53,0x16,0x32,0x17,0xf7,0x09,0x5f,0xd9
-};
-static const unsigned char cav_Xq[] = {
-    0xfe,0xab,0xf2,0x7c,0x16,0x4a,0xf0,0x8d,0x31,0xc6,0x0a,0x82,0xe2,0xae,0xbb,
-    0x03,0x7e,0x7b,0x20,0x4e,0x64,0xb0,0x16,0xad,0x3c,0x01,0x1a,0xd3,0x54,0xbf,
-    0x2b,0xa4,0x02,0x9e,0xc3,0x0d,0x60,0x3d,0x1f,0xb9,0xc0,0x0d,0xe6,0x97,0x68,
-    0xbb,0x8c,0x81,0xd5,0xc1,0x54,0x96,0x0f,0x99,0xf0,0xa8,0xa2,0xf3,0xc6,0x8e,
-    0xec,0xbc,0x31,0x17,0x70,0x98,0x24,0xa3,0x36,0x51,0xa8,0x54,0xbd,0x9a,0x89,
-    0x99,0x6e,0x57,0x5e,0xd0,0x39,0x86,0xc3,0xa3,0x1b,0xc7,0xcf,0xc4,0x4f,0x47,
-    0x25,0x9e,0x2c,0x79,0xe1,0x2c,0xcc,0xe4,0x63,0xf4,0x02,0x84,0xf8,0xf6,0xa1,
-    0x5c,0x93,0x14,0xf2,0x68,0x5f,0x3a,0x90,0x2f,0x4e,0x5e,0xf9,0x16,0x05,0xcf,
-    0x21,0x63,0xca,0xfa,0xb0,0x08,0x02,0xc0
-};
-static const unsigned char cav_Xq1[] = {
-    0x9b,0x02,0xd4,0xba,0xf0,0xaa,0x14,0x99,0x6d,0xc0,0xb7,0xa5,0xe1,0xd3,0x70,
-    0xb6,0x5a,0xa2,0x9b,0x59,0xd5,0x8c,0x1e,0x9f,0x3f,0x9a,0xde,0xeb,0x9e,0x9c,
-    0x61,0xd6,0x5a,0xe1
-};
-static const unsigned char cav_Xq2[] = {
-    0x06,0x81,0x53,0xfd,0xa8,0x7b,0xa3,0x85,0x90,0x15,0x2c,0x97,0xb2,0xa0,0x17,
-    0x48,0xb0,0x7f,0x0a,0x01,0x6d
-};
-/* expected values */
-static const unsigned char cav_p1[] = {
-    0xac,0x5f,0x7f,0x6e,0x33,0x3e,0x97,0x3a,0xb3,0x17,0x44,0xa9,0x0f,0x7a,0x54,
-    0x70,0x27,0x06,0x93,0xd5,0x49,0xde,0x91,0x83,0xbc,0x8a,0x7b,0xc3
-};
-static const unsigned char cav_p2[] = {
-    0x0b,0xf6,0xe8,0x79,0x5a,0x81,0xae,0x90,0x1d,0xa4,0x38,0x74,0x9c,0x0e,0x6f,
-    0xe0,0x03,0xcf,0xc4,0x53,0x16,0x32,0x17,0xf7,0x09,0x5f,0xd9
-};
-static const unsigned char cav_q1[] = {
-    0x9b,0x02,0xd4,0xba,0xf0,0xaa,0x14,0x99,0x6d,0xc0,0xb7,0xa5,0xe1,0xd3,0x70,
-    0xb6,0x5a,0xa2,0x9b,0x59,0xd5,0x8c,0x1e,0x9f,0x3f,0x9a,0xde,0xeb,0x9e,0x9c,
-    0x61,0xd6,0x5d,0x47
-};
-static const unsigned char cav_q2[] = {
-    0x06,0x81,0x53,0xfd,0xa8,0x7b,0xa3,0x85,0x90,0x15,0x2c,0x97,0xb2,0xa0,0x17,
-    0x48,0xb0,0x7f,0x0a,0x01,0x8f
-};
 static const unsigned char cav_p[] = {
     0xcf,0x72,0x1b,0x9a,0xfd,0x0d,0x22,0x1a,0x74,0x50,0x97,0x22,0x76,0xd8,0xc0,
     0xc2,0xfd,0x08,0x81,0x05,0xdd,0x18,0x21,0x99,0x96,0xd6,0x5c,0x79,0xe3,0x02,
@@ -162,15 +105,6 @@ static BIGNUM *bn_load_new(const unsigned char *data, int sz)
     return ret;
 }
 
-/* helper function */
-static BIGNUM *bn_load(BN_CTX *ctx, const unsigned char *data, int sz)
-{
-    BIGNUM *ret = BN_CTX_get(ctx);
-    if (ret != NULL)
-        BN_bin2bn(data, sz, ret);
-    return ret;
-}
-
 static int test_check_public_exponent(void)
 {
     int ret = 0;
@@ -502,67 +436,6 @@ end:
     return ret;
 }
 
-static int test_fips1864_keygen_kat(void)
-{
-    int ret = 0;
-    RSA *key = NULL;
-    BN_CTX *ctx = NULL;
-    BIGNUM *e, *Xp, *Xp1, *Xp2, *Xq, *Xq1, *Xq2;
-    BIGNUM *p1, *p2, *q1, *q2;
-    BIGNUM *p1_exp, *p2_exp, *q1_exp, *q2_exp;
-    BIGNUM *p_exp, *q_exp, *n_exp, *d_exp;
-    const BIGNUM *p, *q, *n, *d, *e2;
-
-    if (!(TEST_ptr(key = RSA_new()) && TEST_ptr(ctx = BN_CTX_new())))
-        goto err;
-    BN_CTX_start(ctx);
-
-    e = bn_load(ctx, cav_e, sizeof(cav_e));
-    Xp = bn_load(ctx, cav_Xp, sizeof(cav_Xp));
-    Xp1 = bn_load(ctx, cav_Xp1, sizeof(cav_Xp1));
-    Xp2 = bn_load(ctx, cav_Xp2, sizeof(cav_Xp2));
-    Xq = bn_load(ctx, cav_Xq, sizeof(cav_Xq));
-    Xq1 = bn_load(ctx, cav_Xq1, sizeof(cav_Xq1));
-    Xq2 = bn_load(ctx, cav_Xq2, sizeof(cav_Xq2));
-    p1_exp = bn_load(ctx, cav_p1, sizeof(cav_p1));
-    p2_exp = bn_load(ctx, cav_p2, sizeof(cav_p2));
-    q1_exp = bn_load(ctx, cav_q1, sizeof(cav_q1));
-    q2_exp = bn_load(ctx, cav_q2, sizeof(cav_q2));
-    p_exp = bn_load(ctx, cav_p, sizeof(cav_p));
-    q_exp = bn_load(ctx, cav_q, sizeof(cav_q));
-    n_exp = bn_load(ctx, cav_n, sizeof(cav_n));
-    d_exp = bn_load(ctx, cav_d, sizeof(cav_d));
-    p1 = BN_CTX_get(ctx);
-    p2 = BN_CTX_get(ctx);
-    q1 = BN_CTX_get(ctx);
-    q2 = BN_CTX_get(ctx);
-    ret = TEST_ptr(q2)
-          && TEST_true(rsa_fips186_4_gen_prob_primes(key, p1, p2, NULL, Xp, Xp1,
-                                                     Xp2, q1, q2, NULL, Xq, Xq1,
-                                                     Xq2, 2048, e, ctx, NULL))
-          && TEST_true(rsa_sp800_56b_derive_params_from_pq(key, 2048, e, ctx))
-          && TEST_BN_eq(p1_exp, p1)
-          && TEST_BN_eq(p2_exp, p2)
-          && TEST_BN_eq(q1_exp, q1)
-          && TEST_BN_eq(q2_exp, q2);
-    if (!ret)
-        goto err;
-
-    RSA_get0_key(key, &n, &e2, &d);
-    RSA_get0_factors(key, &p, &q);
-    ret = TEST_BN_eq(e, e2)
-          && TEST_BN_eq(p_exp, p)
-          && TEST_BN_eq(q_exp, q)
-          && TEST_BN_eq(n_exp, n)
-          && TEST_BN_eq(d_exp, d);
-err:
-    RSA_free(key);
-    BN_CTX_end(ctx);
-    BN_CTX_free(ctx);
-    return ret;
-}
-
-
 static int keygen_size[] =
 {
     2048, 3072
@@ -668,7 +541,6 @@ int setup_tests(void)
     ADD_TEST(test_check_public_key);
     ADD_TEST(test_invalid_keypair);
     ADD_TEST(test_pq_diff);
-    ADD_TEST(test_fips1864_keygen_kat);
     ADD_ALL_TESTS(test_sp80056b_keygen, (int)OSSL_NELEM(keygen_size));
     return 1;
 }


More information about the openssl-commits mailing list