]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Add EDDSA FIPS self tests.
authorslontis <shane.lontis@oracle.com>
Fri, 15 Sep 2023 02:40:39 +0000 (12:40 +1000)
committerTomas Mraz <tomas@openssl.org>
Wed, 14 Aug 2024 14:17:47 +0000 (16:17 +0200)
See FIPS 140-3 IG Section 10.3.A Part 11
Indicates ECDSA requires a sign and verify test.
Note 11 states that HashEdDSA is not required to be tested if PureEdDSA is tested.
Note 12 indicates that both ED25519 and X448 need to be tested.

Since ED uses the oneshot interface, additional API's needed to be exposed to the
FIPS provider using #ifdef FIPS_MODULE.

Changed ED25518 and ED448 to use fips=true in the FIPS provider.
Updated documentation for provider lists for EDDSA.

Reviewed-by: Paul Dale <ppzgs1@gmail.com>
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/22112)

crypto/evp/digest.c
crypto/evp/m_sigver.c
doc/man7/OSSL_PROVIDER-FIPS.pod
include/openssl/self_test.h
providers/fips/fipsprov.c
providers/fips/self_test_data.inc
providers/fips/self_test_kats.c

index a74e2fa42c5bbd27e11a6f18395f7ec28aabe695..9003af6d74ea60ea2afac7e23927a4ec0ae10f5a 100644 (file)
@@ -78,7 +78,6 @@ static int evp_md_ctx_reset_ex(EVP_MD_CTX *ctx, int keep_fetched)
     if (ctx == NULL)
         return 1;
 
-#ifndef FIPS_MODULE
     /*
      * pctx should be freed by the user of EVP_MD_CTX
      * if EVP_MD_CTX_FLAG_KEEP_PKEY_CTX is set
@@ -87,7 +86,6 @@ static int evp_md_ctx_reset_ex(EVP_MD_CTX *ctx, int keep_fetched)
         EVP_PKEY_CTX_free(ctx->pctx);
         ctx->pctx = NULL;
     }
-#endif
 
     evp_md_ctx_clear_digest(ctx, 0, keep_fetched);
     if (!keep_fetched)
index 3a979f4bd459213d7d14bc7b23419fb129494361..90bc1ed264cc5f77ffec72fce16cf1dd1528e1ea 100644 (file)
 #include "evp_local.h"
 
 #ifndef FIPS_MODULE
-
 static int update(EVP_MD_CTX *ctx, const void *data, size_t datalen)
 {
     ERR_raise(ERR_LIB_EVP, EVP_R_ONLY_ONESHOT_SUPPORTED);
     return 0;
 }
+#endif
 
 /*
  * If we get the "NULL" md then the name comes back as "UNDEF". We want to use
@@ -58,8 +58,10 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
         reinit = 0;
         if (e == NULL)
             ctx->pctx = EVP_PKEY_CTX_new_from_pkey(libctx, pkey, props);
+#ifndef FIPS_MODULE
         else
             ctx->pctx = EVP_PKEY_CTX_new(pkey, e);
+#endif
     }
     if (ctx->pctx == NULL)
         return 0;
@@ -241,6 +243,11 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
             if (ctx->fetched_digest != NULL) {
                 ctx->digest = ctx->reqdigest = ctx->fetched_digest;
             } else {
+#ifdef FIPS_MODULE
+                (void)ERR_clear_last_mark();
+                ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
+                goto err;
+#else
                 /* legacy engine support : remove the mark when this is deleted */
                 ctx->reqdigest = ctx->digest = EVP_get_digestbyname(mdname);
                 if (ctx->digest == NULL) {
@@ -248,6 +255,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                     ERR_raise(ERR_LIB_EVP, EVP_R_INITIALIZATION_ERROR);
                     goto err;
                 }
+#endif
             }
             (void)ERR_pop_to_mark();
         }
@@ -293,6 +301,9 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
     EVP_KEYMGMT_free(tmp_keymgmt);
     tmp_keymgmt = NULL;
 
+#ifdef FIPS_MODULE
+    return 0;
+#else
     if (type == NULL && mdname != NULL)
         type = evp_get_digestbyname_ex(locpctx->libctx, mdname);
 
@@ -355,7 +366,7 @@ static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
         ctx->pctx->flag_call_digest_custom = 1;
 
     ret = 1;
-
+#endif
  end:
 #ifndef FIPS_MODULE
     if (ret > 0)
@@ -375,12 +386,14 @@ int EVP_DigestSignInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                           params);
 }
 
+#ifndef FIPS_MODULE
 int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                        const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
 {
     return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 0,
                           NULL);
 }
+#endif
 
 int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                             const char *mdname, OSSL_LIB_CTX *libctx,
@@ -391,13 +404,14 @@ int EVP_DigestVerifyInit_ex(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                           params);
 }
 
+#ifndef FIPS_MODULE
 int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx,
                          const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey)
 {
     return do_sigver_init(ctx, pctx, type, NULL, NULL, NULL, e, pkey, 1,
                           NULL);
 }
-#endif /* FIPS_MDOE */
+#endif /* FIPS_MODULE */
 
 int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
 {
@@ -423,6 +437,10 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
                                                       data, dsize);
 
  legacy:
+#ifdef FIPS_MODULE
+    ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
+    return 0;
+#else
     if (pctx != NULL) {
         /* do_sigver_init() checked that |digest_custom| is non-NULL */
         if (pctx->flag_call_digest_custom
@@ -432,6 +450,7 @@ int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
     }
 
     return EVP_DigestUpdate(ctx, data, dsize);
+#endif
 }
 
 int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
@@ -458,6 +477,10 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
                                                         data, dsize);
 
  legacy:
+#ifdef FIPS_MODULE
+    ERR_raise(ERR_LIB_EVP, EVP_R_UPDATE_ERROR);
+    return 0;
+#else
     if (pctx != NULL) {
         /* do_sigver_init() checked that |digest_custom| is non-NULL */
         if (pctx->flag_call_digest_custom
@@ -467,6 +490,7 @@ int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t dsize)
     }
 
     return EVP_DigestUpdate(ctx, data, dsize);
+#endif
 }
 
 #ifndef FIPS_MODULE
@@ -575,6 +599,7 @@ int EVP_DigestSignFinal(EVP_MD_CTX *ctx, unsigned char *sigret,
     }
     return 1;
 }
+#endif
 
 int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
                    const unsigned char *tbs, size_t tbslen)
@@ -598,6 +623,11 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
                                                        sigret == NULL ? 0 : *siglen,
                                                        tbs, tbslen);
         }
+#ifdef FIPS_MODULE
+    }
+    ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
+    return 0;
+#else
     } else {
         /* legacy */
         if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestsign != NULL)
@@ -607,15 +637,17 @@ int EVP_DigestSign(EVP_MD_CTX *ctx, unsigned char *sigret, size_t *siglen,
     if (sigret != NULL && EVP_DigestSignUpdate(ctx, tbs, tbslen) <= 0)
         return 0;
     return EVP_DigestSignFinal(ctx, sigret, siglen);
+#endif
 }
 
+#ifndef FIPS_MODULE
 int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
                           size_t siglen)
 {
+    int vctx = 0;
+    unsigned int mdlen = 0;
     unsigned char md[EVP_MAX_MD_SIZE];
     int r = 0;
-    unsigned int mdlen = 0;
-    int vctx = 0;
     EVP_PKEY_CTX *dctx = NULL, *pctx = ctx->pctx;
 
     if ((ctx->flags & EVP_MD_CTX_FLAG_FINALISED) != 0) {
@@ -684,6 +716,7 @@ int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const unsigned char *sig,
         return r;
     return EVP_PKEY_verify(pctx, sig, siglen, md, mdlen);
 }
+#endif
 
 int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
                      size_t siglen, const unsigned char *tbs, size_t tbslen)
@@ -705,14 +738,18 @@ int EVP_DigestVerify(EVP_MD_CTX *ctx, const unsigned char *sigret,
                                                          sigret, siglen,
                                                          tbs, tbslen);
         }
+#ifdef FIPS_MODULE
+    }
+    ERR_raise(ERR_LIB_EVP, EVP_R_FINAL_ERROR);
+    return 0;
+#else
     } else {
         /* legacy */
         if (ctx->pctx->pmeth != NULL && ctx->pctx->pmeth->digestverify != NULL)
             return ctx->pctx->pmeth->digestverify(ctx, sigret, siglen, tbs, tbslen);
     }
-
     if (EVP_DigestVerifyUpdate(ctx, tbs, tbslen) <= 0)
         return -1;
     return EVP_DigestVerifyFinal(ctx, sigret, siglen);
+#endif
 }
-#endif /* FIPS_MODULE */
index ebdb2a8e764442727f3942e161fe29266ee0dd66..78b58115bcab3ba858bec237e6d89cff3e9a801d 100644 (file)
@@ -160,12 +160,8 @@ for signature generation, but may be used for verification for legacy use cases.
 
 =item ED25519, see L<EVP_SIGNATURE-ED25519(7)>
 
-This is an unapproved algorithm.
-
 =item ED448, see L<EVP_SIGNATURE-ED448(7)>
 
-This is an unapproved algorithm.
-
 =item ECDSA, see L<EVP_SIGNATURE-ECDSA(7)>
 
 =item HMAC, see L<EVP_SIGNATURE-HMAC(7)>
@@ -379,6 +375,8 @@ Digest tests used with the "KAT_Digest" type.
 
 =item "ECDSA" (B<OSSL_SELF_TEST_DESC_SIGN_ECDSA>)
 
+=item "EDDSA" (B<OSSL_SELF_TEST_DESC_SIGN_EDDSA>)
+
 Signature tests used with the "KAT_Signature" type.
 
 =item "ECDH" (B<OSSL_SELF_TEST_DESC_KA_ECDH>)
index 17822049acfb057d41f090d01f8862af200cc58d..7a204f5602787d14b5db16e8b67fb6d91ce8b95d 100644 (file)
@@ -59,6 +59,7 @@ extern "C" {
 # define OSSL_SELF_TEST_DESC_SIGN_DSA       "DSA"
 # define OSSL_SELF_TEST_DESC_SIGN_RSA       "RSA"
 # define OSSL_SELF_TEST_DESC_SIGN_ECDSA     "ECDSA"
+# define OSSL_SELF_TEST_DESC_SIGN_EDDSA     "EDDSA"
 # define OSSL_SELF_TEST_DESC_DRBG_CTR       "CTR"
 # define OSSL_SELF_TEST_DESC_DRBG_HASH      "HASH"
 # define OSSL_SELF_TEST_DESC_DRBG_HMAC      "HMAC"
index f64082e89539fdbf5e75d51c91950f59a196c706..7204fa2844475311e0ae230336ea86cd126c1a5d 100644 (file)
@@ -597,9 +597,9 @@ static const OSSL_ALGORITHM fips_signature[] = {
     { PROV_NAMES_RSA, FIPS_DEFAULT_PROPERTIES, ossl_rsa_signature_functions },
 #ifndef OPENSSL_NO_EC
 # ifndef OPENSSL_NO_ECX
-    { PROV_NAMES_ED25519, FIPS_UNAPPROVED_PROPERTIES,
+    { PROV_NAMES_ED25519, FIPS_DEFAULT_PROPERTIES,
       ossl_ed25519_signature_functions },
-    { PROV_NAMES_ED448, FIPS_UNAPPROVED_PROPERTIES, ossl_ed448_signature_functions },
+    { PROV_NAMES_ED448, FIPS_DEFAULT_PROPERTIES, ossl_ed448_signature_functions },
 # endif
     { PROV_NAMES_ECDSA, FIPS_DEFAULT_PROPERTIES, ossl_ecdsa_signature_functions },
 #endif
@@ -645,9 +645,9 @@ static const OSSL_ALGORITHM fips_keymgmt[] = {
       PROV_DESCS_X25519 },
     { PROV_NAMES_X448, FIPS_UNAPPROVED_PROPERTIES, ossl_x448_keymgmt_functions,
       PROV_DESCS_X448 },
-    { PROV_NAMES_ED25519, FIPS_UNAPPROVED_PROPERTIES, ossl_ed25519_keymgmt_functions,
+    { PROV_NAMES_ED25519, FIPS_DEFAULT_PROPERTIES, ossl_ed25519_keymgmt_functions,
       PROV_DESCS_ED25519 },
-    { PROV_NAMES_ED448, FIPS_UNAPPROVED_PROPERTIES, ossl_ed448_keymgmt_functions,
+    { PROV_NAMES_ED448, FIPS_DEFAULT_PROPERTIES, ossl_ed448_keymgmt_functions,
       PROV_DESCS_ED448 },
 # endif
 #endif
index 4abb628c86e28c1f78ee10e5f45e919cc6746252..79335070d271be941f49d4d2b9d919664bfda59c 100644 (file)
@@ -117,6 +117,8 @@ typedef struct st_kat_sign_st {
     size_t persstr_len;
     const unsigned char *sig_expected; /* Set to NULL if this value changes */
     size_t sig_expected_len;
+    int oneshot;
+    const ST_KAT_PARAM *init;
 } ST_KAT_SIGN;
 
 typedef struct st_kat_asym_cipher_st {
@@ -176,7 +178,6 @@ static const ST_KAT_DIGEST st_kat_digest_tests[] =
     },
 };
 
-
 /*- CIPHER TEST DATA */
 
 /* DES3 test data */
@@ -1506,6 +1507,79 @@ static const ST_KAT_PARAM ecdsa_bin_key[] = {
     ST_KAT_PARAM_END()
 };
 # endif /* OPENSSL_NO_EC2M */
+
+# ifndef OPENSSL_NO_ECX
+static const unsigned char ed25519_pub[] = {
+    0xfc, 0x51, 0xcd, 0x8e, 0x62, 0x18, 0xa1, 0xa3,
+    0x8d, 0xa4, 0x7e, 0xd0, 0x02, 0x30, 0xf0, 0x58,
+    0x08, 0x16, 0xed, 0x13, 0xba, 0x33, 0x03, 0xac,
+    0x5d, 0xeb, 0x91, 0x15, 0x48, 0x90, 0x80, 0x25
+};
+static const unsigned char ed25519_priv[] = {
+    0xc5, 0xaa, 0x8d, 0xf4, 0x3f, 0x9f, 0x83, 0x7b,
+    0xed, 0xb7, 0x44, 0x2f, 0x31, 0xdc, 0xb7, 0xb1,
+    0x66, 0xd3, 0x85, 0x35, 0x07, 0x6f, 0x09, 0x4b,
+    0x85, 0xce, 0x3a, 0x2e, 0x0b, 0x44, 0x58, 0xf7
+};
+static const ST_KAT_PARAM ed25519_key[] = {
+    ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ed25519_pub),
+    ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PRIV_KEY, ed25519_priv),
+    ST_KAT_PARAM_END()
+};
+static const unsigned char ed25519_expected_sig[] = {
+    0x1e, 0xf4, 0xc5, 0x61, 0xdc, 0x97, 0x9f, 0xaf,
+    0x55, 0x6b, 0x46, 0xa1, 0xae, 0xb0, 0x64, 0x13,
+    0x1c, 0x98, 0x09, 0x96, 0x88, 0xe0, 0x9d, 0x0e,
+    0x4e, 0x7d, 0xc4, 0xa5, 0xa1, 0x91, 0x09, 0xca,
+    0xd9, 0x5b, 0x4f, 0x1c, 0x80, 0x82, 0x9f, 0x65,
+    0xc1, 0x41, 0xa4, 0xe8, 0x02, 0x05, 0x0c, 0xa6,
+    0x7e, 0xa0, 0xfa, 0x01, 0xee, 0xeb, 0xaa, 0x91,
+    0x62, 0xfd, 0x0f, 0x25, 0xa0, 0x2d, 0x37, 0x09
+};
+
+static const unsigned char ed448_pub[] = {
+    0x3b, 0xa1, 0x6d, 0xa0, 0xc6, 0xf2, 0xcc, 0x1f,
+    0x30, 0x18, 0x77, 0x40, 0x75, 0x6f, 0x5e, 0x79,
+    0x8d, 0x6b, 0xc5, 0xfc, 0x01, 0x5d, 0x7c, 0x63,
+    0xcc, 0x95, 0x10, 0xee, 0x3f, 0xd4, 0x4a, 0xdc,
+    0x24, 0xd8, 0xe9, 0x68, 0xb6, 0xe4, 0x6e, 0x6f,
+    0x94, 0xd1, 0x9b, 0x94, 0x53, 0x61, 0x72, 0x6b,
+    0xd7, 0x5e, 0x14, 0x9e, 0xf0, 0x98, 0x17, 0xf5,
+    0x80
+};
+static const unsigned char ed448_priv[] = {
+   0x25, 0x8c, 0xdd, 0x4a, 0xda, 0x32, 0xed, 0x9c,
+   0x9f, 0xf5, 0x4e, 0x63, 0x75, 0x6a, 0xe5, 0x82,
+   0xfb, 0x8f, 0xab, 0x2a, 0xc7, 0x21, 0xf2, 0xc8,
+   0xe6, 0x76, 0xa7, 0x27, 0x68, 0x51, 0x3d, 0x93,
+   0x9f, 0x63, 0xdd, 0xdb, 0x55, 0x60, 0x91, 0x33,
+   0xf2, 0x9a, 0xdf, 0x86, 0xec, 0x99, 0x29, 0xdc,
+   0xcb, 0x52, 0xc1, 0xc5, 0xfd, 0x2f, 0xf7, 0xe2,
+   0x1b
+};
+static const ST_KAT_PARAM ed448_key[] = {
+    ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PUB_KEY, ed448_pub),
+    ST_KAT_PARAM_OCTET(OSSL_PKEY_PARAM_PRIV_KEY, ed448_priv),
+    ST_KAT_PARAM_END()
+};
+static const unsigned char ed448_expected_sig[] = {
+   0x7e, 0xee, 0xab, 0x7c, 0x4e, 0x50, 0xfb, 0x79,
+   0x9b, 0x41, 0x8e, 0xe5, 0xe3, 0x19, 0x7f, 0xf6,
+   0xbf, 0x15, 0xd4, 0x3a, 0x14, 0xc3, 0x43, 0x89,
+   0xb5, 0x9d, 0xd1, 0xa7, 0xb1, 0xb8, 0x5b, 0x4a,
+   0xe9, 0x04, 0x38, 0xac, 0xa6, 0x34, 0xbe, 0xa4,
+   0x5e, 0x3a, 0x26, 0x95, 0xf1, 0x27, 0x0f, 0x07,
+   0xfd, 0xcd, 0xf7, 0xc6, 0x2b, 0x8e, 0xfe, 0xaf,
+   0x00, 0xb4, 0x5c, 0x2c, 0x96, 0xba, 0x45, 0x7e,
+   0xb1, 0xa8, 0xbf, 0x07, 0x5a, 0x3d, 0xb2, 0x8e,
+   0x5c, 0x24, 0xf6, 0xb9, 0x23, 0xed, 0x4a, 0xd7,
+   0x47, 0xc3, 0xc9, 0xe0, 0x3c, 0x70, 0x79, 0xef,
+   0xb8, 0x7c, 0xb1, 0x10, 0xd3, 0xa9, 0x98, 0x61,
+   0xe7, 0x20, 0x03, 0xcb, 0xae, 0x6d, 0x6b, 0x8b,
+   0x82, 0x7e, 0x4e, 0x6c, 0x14, 0x30, 0x64, 0xff,
+   0x3c, 0x00
+};
+# endif /* OPENSSL_NO_ECX */
 #endif /* OPENSSL_NO_EC */
 
 #ifndef OPENSSL_NO_DSA
@@ -1697,6 +1771,26 @@ static const ST_KAT_SIGN st_kat_sign_tests[] = {
         ITM(ecdsa_bin_expected_sig)
     },
 # endif
+# ifndef OPENSSL_NO_ECX
+    {
+        OSSL_SELF_TEST_DESC_SIGN_EDDSA,
+        "ED448",
+        NULL,
+        ed448_key,
+        NULL, 0, NULL, 0, NULL, 0,
+        ITM(ed448_expected_sig),
+        1
+    },
+    {
+        OSSL_SELF_TEST_DESC_SIGN_EDDSA,
+        "ED25519",
+        NULL,
+        ed25519_key,
+        NULL, 0, NULL, 0, NULL, 0,
+        ITM(ed25519_expected_sig),
+        1
+    },
+# endif /* OPENSSL_NO_ECX */
 #endif /* OPENSSL_NO_EC */
 #ifndef OPENSSL_NO_DSA
     {
index 9f2e58ff7c8b997cdd8ab9fcccbc027a2bf7640a..f2e4df086bb8ca4b3b8069df39348f782a7f9ec4 100644 (file)
@@ -466,6 +466,10 @@ static int self_test_sign(const ST_KAT_SIGN *t,
 
     OSSL_SELF_TEST_onbegin(st, typ, t->desc);
 
+    if (!set_kat_drbg(libctx, t->entropy, t->entropy_len,
+                      t->nonce, t->nonce_len, t->persstr, t->persstr_len))
+        goto err;
+
     bnctx = BN_CTX_new_ex(libctx);
     if (bnctx == NULL)
         goto err;
@@ -531,9 +535,94 @@ err:
     OSSL_PARAM_free(params);
     OSSL_PARAM_free(params_sig);
     OSSL_PARAM_BLD_free(bld);
+    if (!reset_main_drbg(libctx))
+        ret = 0;
+    OSSL_SELF_TEST_onend(st, ret);
+    return ret;
+}
+
+#ifndef OPENSSL_NO_ECX
+static int self_test_digest_sign(const ST_KAT_SIGN *t,
+                                 OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
+{
+    int ret = 0;
+    OSSL_PARAM *paramskey = NULL, *paramsinit = NULL;
+    OSSL_PARAM_BLD *bldkey = NULL, *bldinit = NULL;
+    EVP_MD_CTX *mctx = NULL;
+    EVP_PKEY_CTX *fromctx = NULL;
+    EVP_PKEY *pkey = NULL;
+    unsigned char sig[256];
+    BN_CTX *bnctx = NULL;
+    size_t siglen = sizeof(sig);
+    static const unsigned char in[] = {
+        0x64, 0xa6, 0x5f, 0x3c, 0xde, 0xdc, 0xdd, 0x66,
+        0x81, 0x1e, 0x29, 0x15
+    };
+    const char *typ = OSSL_SELF_TEST_TYPE_KAT_SIGNATURE;
+
+    if (t->sig_expected == NULL)
+        typ = OSSL_SELF_TEST_TYPE_PCT_SIGNATURE;
+
+    OSSL_SELF_TEST_onbegin(st, typ, t->desc);
+
+    bnctx = BN_CTX_new_ex(libctx);
+    if (bnctx == NULL)
+        goto err;
+
+    bldkey = OSSL_PARAM_BLD_new();
+    bldinit = OSSL_PARAM_BLD_new();
+    if (bldkey == NULL || bldinit == NULL)
+        goto err;
+
+    if (!add_params(bldkey, t->key, bnctx))
+        goto err;
+    if (!add_params(bldinit, t->init, bnctx))
+        goto err;
+    paramskey = OSSL_PARAM_BLD_to_param(bldkey);
+    paramsinit = OSSL_PARAM_BLD_to_param(bldinit);
+
+    fromctx = EVP_PKEY_CTX_new_from_name(libctx, t->algorithm, "");
+    if (fromctx == NULL
+        || paramskey == NULL
+        || paramsinit == NULL)
+        goto err;
+    if (EVP_PKEY_fromdata_init(fromctx) <= 0
+        || EVP_PKEY_fromdata(fromctx, &pkey, EVP_PKEY_KEYPAIR, paramskey) <= 0)
+        goto err;
+
+    mctx = EVP_MD_CTX_new();
+    if (mctx == NULL
+        || EVP_DigestSignInit_ex(mctx, NULL, NULL, libctx, NULL,
+                                 pkey, paramsinit) <= 0)
+        goto err;
+
+    if (EVP_DigestSign(mctx, sig, &siglen, in, sizeof(in)) <= 0)
+        goto err;
+    if (t->sig_expected != NULL
+        && (siglen != t->sig_expected_len
+            || memcmp(sig, t->sig_expected, t->sig_expected_len) != 0))
+        goto err;
+
+    if (EVP_DigestVerifyInit_ex(mctx, NULL, NULL, libctx, NULL,
+                                pkey, paramsinit) <= 0)
+        goto err;
+    OSSL_SELF_TEST_oncorrupt_byte(st, sig);
+    if (EVP_DigestVerify(mctx, sig, siglen, in, sizeof(in)) <= 0)
+        goto err;
+    ret = 1;
+err:
+    BN_CTX_free(bnctx);
+    EVP_PKEY_free(pkey);
+    EVP_PKEY_CTX_free(fromctx);
+    EVP_MD_CTX_free(mctx);
+    OSSL_PARAM_free(paramskey);
+    OSSL_PARAM_free(paramsinit);
+    OSSL_PARAM_BLD_free(bldkey);
+    OSSL_PARAM_BLD_free(bldinit);
     OSSL_SELF_TEST_onend(st, ret);
     return ret;
 }
+#endif /* OPENSSL_NO_ECX */
 
 /*
  * Test an encrypt or decrypt KAT..
@@ -704,13 +793,16 @@ static int self_test_signatures(OSSL_SELF_TEST *st, OSSL_LIB_CTX *libctx)
 
     for (i = 0; ret && i < (int)OSSL_NELEM(st_kat_sign_tests); ++i) {
         t = st_kat_sign_tests + i;
-        if (!set_kat_drbg(libctx, t->entropy, t->entropy_len,
-                          t->nonce, t->nonce_len, t->persstr, t->persstr_len))
-            return 0;
-        if (!self_test_sign(t, st, libctx))
-            ret = 0;
-        if (!reset_main_drbg(libctx))
-            ret = 0;
+#ifndef OPENSSL_NO_ECX
+        if (t->oneshot) {
+            if (!self_test_digest_sign(t, st, libctx))
+                ret = 0;
+        } else
+#endif
+        {
+            if (!self_test_sign(t, st, libctx))
+                ret = 0;
+        }
     }
     return ret;
 }