[openssl] master update

shane.lontis at oracle.com shane.lontis at oracle.com
Tue Mar 3 04:04:18 UTC 2020


The branch master has been updated
       via  47c239c6b8d6e5d66a6ceef3a2c543b6ea338759 (commit)
      from  97ace6c2dae451ce8e3b099cf242968ecff128af (commit)


- Log -----------------------------------------------------------------
commit 47c239c6b8d6e5d66a6ceef3a2c543b6ea338759
Author: Shane Lontis <shane.lontis at oracle.com>
Date:   Tue Mar 3 14:02:36 2020 +1000

    Add pairwise consistency self tests to asym keygenerators
    
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/10952)

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

Summary of changes:
 crypto/build.info                        |   4 +-
 crypto/dh/dh_gen.c                       |   7 +-
 crypto/dsa/dsa_key.c                     |  67 +++++++++++-
 crypto/ec/ec_key.c                       |  68 +++++++++++-
 crypto/ec/ecp_s390x_nistp.c              |   5 +-
 crypto/rsa/rsa_gen.c                     |  98 ++++++++++++++++--
 crypto/self_test_core.c                  | 108 ++++++++++++++++++-
 doc/man3/OSSL_SELF_TEST_new.pod          | 172 +++++++++++++++++++++++++++++++
 doc/man3/OSSL_SELF_TEST_set_callback.pod |   1 +
 doc/man7/OSSL_PROVIDER-FIPS.pod          |  58 ++---------
 include/crypto/ec.h                      |   1 +
 include/openssl/self_test.h              |   8 ++
 include/openssl/types.h                  |   2 +
 providers/fips/build.info                |   2 +-
 providers/fips/fipsprov.c                |   8 +-
 providers/fips/self_test.c               |  21 ++--
 providers/fips/self_test.h               |  26 +----
 providers/fips/self_test_event.c         |  93 -----------------
 providers/fips/self_test_kats.c          |  58 +++++------
 util/libcrypto.num                       |   5 +
 20 files changed, 577 insertions(+), 235 deletions(-)
 create mode 100644 doc/man3/OSSL_SELF_TEST_new.pod
 delete mode 100644 providers/fips/self_test_event.c

diff --git a/crypto/build.info b/crypto/build.info
index b21cf3f45a..a688248acf 100644
--- a/crypto/build.info
+++ b/crypto/build.info
@@ -61,9 +61,9 @@ ENDIF
 
 # The Core
 $CORE_COMMON=provider_core.c provider_predefined.c \
-        core_fetch.c core_algorithm.c core_namemap.c
+        core_fetch.c core_algorithm.c core_namemap.c self_test_core.c
 
-SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c self_test_core.c
+SOURCE[../libcrypto]=$CORE_COMMON provider_conf.c
 SOURCE[../providers/libfips.a]=$CORE_COMMON
 
 # Central utilities
diff --git a/crypto/dh/dh_gen.c b/crypto/dh/dh_gen.c
index 8e2b773703..f8cda1b7e9 100644
--- a/crypto/dh/dh_gen.c
+++ b/crypto/dh/dh_gen.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -15,6 +15,11 @@
 /*
  * DH low level APIs are deprecated for public use, but still ok for
  * internal use.
+ *
+ * NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
+ * states that no additional pairwise tests are required (apart from the tests
+ * specified in SP800-56A) when generating keys. Hence DH pairwise tests are
+ * omitted here.
  */
 #include "internal/deprecated.h"
 
diff --git a/crypto/dsa/dsa_key.c b/crypto/dsa/dsa_key.c
index c93ea15b76..2dec35f28f 100644
--- a/crypto/dsa/dsa_key.c
+++ b/crypto/dsa/dsa_key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-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
@@ -17,10 +17,12 @@
 #include <time.h>
 #include "internal/cryptlib.h"
 #include <openssl/bn.h>
+#include <openssl/self_test.h>
 #include "crypto/dsa.h"
 #include "dsa_local.h"
 
-static int dsa_builtin_keygen(DSA *dsa);
+static int dsa_keygen(DSA *dsa, int pairwise_test);
+static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg);
 
 int DSA_generate_key(DSA *dsa)
 {
@@ -28,7 +30,7 @@ int DSA_generate_key(DSA *dsa)
     if (dsa->meth->dsa_keygen != NULL)
         return dsa->meth->dsa_keygen(dsa);
 #endif
-    return dsa_builtin_keygen(dsa);
+    return dsa_keygen(dsa, 0);
 }
 
 int dsa_generate_public_key(BN_CTX *ctx, const DSA *dsa, const BIGNUM *priv_key,
@@ -50,7 +52,7 @@ err:
     return ret;
 }
 
-static int dsa_builtin_keygen(DSA *dsa)
+static int dsa_keygen(DSA *dsa, int pairwise_test)
 {
     int ok = 0;
     BN_CTX *ctx = NULL;
@@ -82,8 +84,26 @@ static int dsa_builtin_keygen(DSA *dsa)
 
     dsa->priv_key = priv_key;
     dsa->pub_key = pub_key;
-    dsa->dirty_cnt++;
+
+#ifdef FIPS_MODE
+    pairwise_test = 1;
+#endif /* FIPS_MODE */
+
     ok = 1;
+    if (pairwise_test) {
+        OSSL_CALLBACK *cb = NULL;
+        void *cbarg = NULL;
+
+        OSSL_SELF_TEST_get_callback(dsa->libctx, &cb, &cbarg);
+        ok = dsa_keygen_pairwise_test(dsa, cb, cbarg);
+        if (!ok) {
+            BN_free(dsa->pub_key);
+            BN_clear_free(dsa->priv_key);
+            BN_CTX_free(ctx);
+            return ok;
+        }
+    }
+    dsa->dirty_cnt++;
 
  err:
     if (pub_key != dsa->pub_key)
@@ -91,5 +111,42 @@ static int dsa_builtin_keygen(DSA *dsa)
     if (priv_key != dsa->priv_key)
         BN_free(priv_key);
     BN_CTX_free(ctx);
+
     return ok;
 }
+
+/*
+ * FIPS 140-2 IG 9.9 AS09.33
+ * Perform a sign/verify operation.
+ */
+static int dsa_keygen_pairwise_test(DSA *dsa, OSSL_CALLBACK *cb, void *cbarg)
+{
+    int ret = 0;
+    unsigned char dgst[16] = {0};
+    unsigned int dgst_len = (unsigned int)sizeof(dgst);
+    DSA_SIG *sig = NULL;
+    OSSL_SELF_TEST *st = NULL;
+
+    st = OSSL_SELF_TEST_new(cb, cbarg);
+    if (st == NULL)
+        goto err;
+
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
+                           OSSL_SELF_TEST_DESC_PCT_DSA);
+
+    sig = DSA_do_sign(dgst, (int)dgst_len, dsa);
+    if (sig == NULL)
+        goto err;
+
+    OSSL_SELF_TEST_oncorrupt_byte(st, dgst);
+
+    if (DSA_do_verify(dgst, dgst_len, sig, dsa) != 1)
+        goto err;
+
+    ret = 1;
+err:
+    OSSL_SELF_TEST_onend(st, ret);
+    OSSL_SELF_TEST_free(st);
+    DSA_SIG_free(sig);
+    return ret;
+}
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 4c56777dfe..18b544b9d3 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2002-2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2002-2020 The OpenSSL Project Authors. All Rights Reserved.
  * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved
  *
  * Licensed under the Apache License 2.0 (the "License").  You may not use
@@ -20,8 +20,12 @@
 #include "internal/refcount.h"
 #include <openssl/err.h>
 #include <openssl/engine.h>
+#include <openssl/self_test.h>
 #include "crypto/bn.h"
 
+static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
+                                      void *cbarg);
+
 #ifndef FIPS_MODE
 EC_KEY *EC_KEY_new(void)
 {
@@ -241,11 +245,14 @@ int ossl_ec_key_gen(EC_KEY *eckey)
  * See SP800-56AR3 5.6.1.2.2 "Key Pair Generation by Testing Candidates"
  *
  * Params:
+ *     libctx A context containing an optional self test callback.
  *     eckey An EC key object that contains domain params. The generated keypair
  *           is stored in this object.
+ *     pairwise_test Set to non zero to perform a pairwise test. If the test
+ *                   fails then the keypair is not generated,
  * Returns 1 if the keypair was generated or 0 otherwise.
  */
-int ec_key_simple_generate_key(EC_KEY *eckey)
+int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test)
 {
     int ok = 0;
     BIGNUM *priv_key = NULL;
@@ -305,8 +312,18 @@ int ec_key_simple_generate_key(EC_KEY *eckey)
 
     eckey->dirty_cnt++;
 
+#ifdef FIPS_MODE
+    pairwise_test = 1;
+#endif /* FIPS_MODE */
+
     ok = 1;
+    if (pairwise_test) {
+        OSSL_CALLBACK *cb = NULL;
+        void *cbarg = NULL;
 
+        OSSL_SELF_TEST_get_callback(libctx, &cb, &cbarg);
+        ok = ecdsa_keygen_pairwise_test(eckey, cb, cbarg);
+    }
 err:
     /* Step (9): If there is an error return an invalid keypair. */
     if (!ok) {
@@ -321,6 +338,11 @@ err:
     return ok;
 }
 
+int ec_key_simple_generate_key(EC_KEY *eckey)
+{
+    return ec_generate_key(NULL, eckey, 0);
+}
+
 int ec_key_simple_generate_public_key(EC_KEY *eckey)
 {
     int ret;
@@ -849,3 +871,45 @@ int EC_KEY_can_sign(const EC_KEY *eckey)
         return 0;
     return 1;
 }
+
+/*
+ * FIPS 140-2 IG 9.9 AS09.33
+ * Perform a sign/verify operation.
+ *
+ * NOTE: When generating keys for key-agreement schemes - FIPS 140-2 IG 9.9
+ * states that no additional pairwise tests are required (apart from the tests
+ * specified in SP800-56A) when generating keys. Hence pairwise ECDH tests are
+ * omitted here.
+ */
+static int ecdsa_keygen_pairwise_test(EC_KEY *eckey, OSSL_CALLBACK *cb,
+                                      void *cbarg)
+{
+    int ret = 0;
+    unsigned char dgst[16] = {0};
+    int dgst_len = (int)sizeof(dgst);
+    ECDSA_SIG *sig = NULL;
+    OSSL_SELF_TEST *st = NULL;
+
+    st = OSSL_SELF_TEST_new(cb, cbarg);
+    if (st == NULL)
+        return 0;
+
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
+                           OSSL_SELF_TEST_DESC_PCT_ECDSA);
+
+    sig = ECDSA_do_sign(dgst, dgst_len, eckey);
+    if (sig == NULL)
+        goto err;
+
+    OSSL_SELF_TEST_oncorrupt_byte(st, dgst);
+
+    if (ECDSA_do_verify(dgst, dgst_len, sig, eckey) != 1)
+        goto err;
+
+    ret = 1;
+err:
+    OSSL_SELF_TEST_onend(st, ret);
+    OSSL_SELF_TEST_free(st);
+    ECDSA_SIG_free(sig);
+    return ret;
+}
diff --git a/crypto/ec/ecp_s390x_nistp.c b/crypto/ec/ecp_s390x_nistp.c
index a7cb5d3186..92b199d96a 100644
--- a/crypto/ec/ecp_s390x_nistp.c
+++ b/crypto/ec/ecp_s390x_nistp.c
@@ -169,12 +169,13 @@ static ECDSA_SIG *ecdsa_s390x_nistp_sign_sig(const unsigned char *dgst,
 
     if (r == NULL || kinv == NULL) {
         /*
-         * Generate random k and copy to param param block. RAND_priv_bytes
+         * Generate random k and copy to param param block. RAND_priv_bytes_ex
          * is used instead of BN_priv_rand_range or BN_generate_dsa_nonce
          * because kdsa instruction constructs an in-range, invertible nonce
          * internally implementing counter-measures for RNG weakness.
          */
-         if (RAND_priv_bytes(param + S390X_OFF_RN(len), len) != 1) {
+         if (RAND_priv_bytes_ex(eckey->libctx, param + S390X_OFF_RN(len),
+                                len) != 1) {
              ECerr(EC_F_ECDSA_S390X_NISTP_SIGN_SIG,
                    EC_R_RANDOM_NUMBER_GENERATION_FAILED);
              goto ret;
diff --git a/crypto/rsa/rsa_gen.c b/crypto/rsa/rsa_gen.c
index 5778bdada5..5d82ae6f34 100644
--- a/crypto/rsa/rsa_gen.c
+++ b/crypto/rsa/rsa_gen.c
@@ -23,10 +23,12 @@
 #include <time.h>
 #include "internal/cryptlib.h"
 #include <openssl/bn.h>
+#include <openssl/self_test.h>
 #include "rsa_local.h"
 
-static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
-                              BN_GENCB *cb);
+static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg);
+static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes,
+                      BIGNUM *e_value, BN_GENCB *cb, int pairwise_test);
 
 /*
  * NB: this wrapper would normally be placed in rsa_lib.c and the static
@@ -65,19 +67,21 @@ int RSA_generate_multi_prime_key(RSA *rsa, int bits, int primes,
             return 0;
     }
 #endif /* FIPS_MODE */
-    return rsa_builtin_keygen(rsa, bits, primes, e_value, cb);
+    return rsa_keygen(NULL, rsa, bits, primes, e_value, cb, 0);
 }
 
-static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
-                              BN_GENCB *cb)
+static int rsa_keygen(OPENSSL_CTX *libctx, RSA *rsa, int bits, int primes,
+                      BIGNUM *e_value, BN_GENCB *cb, int pairwise_test)
 {
+    int ok = -1;
 #ifdef FIPS_MODE
     if (primes != 2)
         return 0;
-    return rsa_sp800_56b_generate_key(rsa, bits, e_value, cb);
+    ok = rsa_sp800_56b_generate_key(rsa, bits, e_value, cb);
+    pairwise_test = 1; /* FIPS MODE needs to always run the pairwise test */
 #else
     BIGNUM *r0 = NULL, *r1 = NULL, *r2 = NULL, *tmp, *prime;
-    int ok = -1, n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0;
+    int n = 0, bitsr[RSA_MAX_PRIME_NUM], bitse = 0;
     int i = 0, quo = 0, rmd = 0, adj = 0, retries = 0;
     RSA_PRIME_INFO *pinfo = NULL;
     STACK_OF(RSA_PRIME_INFO) *prime_infos = NULL;
@@ -87,13 +91,13 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
 
     if (bits < RSA_MIN_MODULUS_BITS) {
         ok = 0;             /* we set our own err */
-        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
+        RSAerr(0, RSA_R_KEY_SIZE_TOO_SMALL);
         goto err;
     }
 
     if (primes < RSA_DEFAULT_PRIME_NUM || primes > rsa_multip_cap(bits)) {
         ok = 0;             /* we set our own err */
-        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_PRIME_NUM_INVALID);
+        RSAerr(0, RSA_R_KEY_PRIME_NUM_INVALID);
         goto err;
     }
 
@@ -398,11 +402,83 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, int primes, BIGNUM *e_value,
     ok = 1;
  err:
     if (ok == -1) {
-        RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, ERR_LIB_BN);
+        RSAerr(0, ERR_LIB_BN);
         ok = 0;
     }
     BN_CTX_end(ctx);
     BN_CTX_free(ctx);
-    return ok;
 #endif /* FIPS_MODE */
+
+    if (pairwise_test && ok > 0) {
+        OSSL_CALLBACK *stcb = NULL;
+        void *stcbarg = NULL;
+
+        OSSL_SELF_TEST_get_callback(libctx, &stcb, &stcbarg);
+        ok = rsa_keygen_pairwise_test(rsa, stcb, stcbarg);
+        if (!ok) {
+            /* Clear intermediate results */
+            BN_clear_free(rsa->d);
+            BN_clear_free(rsa->p);
+            BN_clear_free(rsa->q);
+            BN_clear_free(rsa->dmp1);
+            BN_clear_free(rsa->dmq1);
+            BN_clear_free(rsa->iqmp);
+        }
+    }
+    return ok;
+}
+
+/*
+ * For RSA key generation it is not known whether the key pair will be used
+ * for key transport or signatures. FIPS 140-2 IG 9.9 states that in this case
+ * either a signature verification OR an encryption operation may be used to
+ * perform the pairwise consistency check. The simpler encrypt/decrypt operation
+ * has been chosen for this case.
+ */
+static int rsa_keygen_pairwise_test(RSA *rsa, OSSL_CALLBACK *cb, void *cbarg)
+{
+    int ret = 0;
+    unsigned int ciphertxt_len;
+    unsigned char *ciphertxt = NULL;
+    const unsigned char plaintxt[16] = {0};
+    unsigned char decoded[256];
+    unsigned int decoded_len;
+    unsigned int plaintxt_len = (unsigned int)sizeof(plaintxt_len);
+    int padding = RSA_PKCS1_PADDING;
+    OSSL_SELF_TEST *st = NULL;
+
+    st = OSSL_SELF_TEST_new(cb, cbarg);
+    if (st == NULL)
+        goto err;
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_PCT,
+                           OSSL_SELF_TEST_DESC_PCT_RSA_PKCS1);
+
+    ciphertxt_len = RSA_size(rsa);
+    ciphertxt = OPENSSL_zalloc(ciphertxt_len);
+    if (ciphertxt == NULL)
+        goto err;
+
+    ciphertxt_len = RSA_public_encrypt(plaintxt_len, plaintxt, ciphertxt, rsa,
+                                       padding);
+    if (ciphertxt_len <= 0)
+        goto err;
+    if (ciphertxt_len == plaintxt_len
+        && memcmp(decoded, plaintxt, plaintxt_len) == 0)
+        goto err;
+
+    OSSL_SELF_TEST_oncorrupt_byte(st, ciphertxt);
+
+    decoded_len = RSA_private_decrypt(ciphertxt_len, ciphertxt, decoded, rsa,
+                                      padding);
+    if (decoded_len != plaintxt_len
+        || memcmp(decoded, plaintxt,  decoded_len) != 0)
+        goto err;
+
+    ret = 1;
+err:
+    OSSL_SELF_TEST_onend(st, ret);
+    OSSL_SELF_TEST_free(st);
+    OPENSSL_free(ciphertxt);
+
+    return ret;
 }
diff --git a/crypto/self_test_core.c b/crypto/self_test_core.c
index 77864a230b..bee3161ed5 100644
--- a/crypto/self_test_core.c
+++ b/crypto/self_test_core.c
@@ -1,5 +1,5 @@
 /*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019-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
@@ -8,6 +8,8 @@
  */
 
 #include <openssl/self_test.h>
+#include <openssl/core_names.h>
+#include <openssl/params.h>
 #include "internal/cryptlib.h"
 
 typedef struct self_test_cb_st
@@ -16,6 +18,19 @@ typedef struct self_test_cb_st
     void *cbarg;
 } SELF_TEST_CB;
 
+struct ossl_self_test_st
+{
+    /* local state variables */
+    const char *phase;
+    const char *type;
+    const char *desc;
+    OSSL_CALLBACK *cb;
+
+    /* callback related variables used to pass the state back to the user */
+    OSSL_PARAM params[4];
+    void *cb_arg;
+};
+
 static void *self_test_set_callback_new(OPENSSL_CTX *ctx)
 {
     SELF_TEST_CB *stcb;
@@ -40,6 +55,7 @@ static SELF_TEST_CB *get_self_test_callback(OPENSSL_CTX *libctx)
                                 &self_test_set_callback_method);
 }
 
+#ifndef FIPS_MODE
 void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb,
                                  void *cbarg)
 {
@@ -50,6 +66,8 @@ void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb,
         stcb->cbarg = cbarg;
     }
 }
+#endif /* FIPS_MODE */
+
 void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb,
                                  void **cbarg)
 {
@@ -60,3 +78,91 @@ void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb,
     if (cbarg != NULL)
         *cbarg = (stcb != NULL ? stcb->cbarg : NULL);
 }
+
+static void self_test_setparams(OSSL_SELF_TEST *st)
+{
+    size_t n = 0;
+
+    if (st->cb != NULL) {
+        st->params[n++] =
+            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE,
+                                             (char *)st->phase, 0);
+        st->params[n++] =
+            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE,
+                                             (char *)st->type, 0);
+        st->params[n++] =
+            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC,
+                                             (char *)st->desc, 0);
+    }
+    st->params[n++] = OSSL_PARAM_construct_end();
+}
+
+OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg)
+{
+    OSSL_SELF_TEST *ret = OPENSSL_zalloc(sizeof(*ret));
+
+    if (ret == NULL)
+        return NULL;
+
+    ret->cb = cb;
+    ret->cb_arg = cbarg;
+    ret->phase = "";
+    ret->type = "";
+    ret->desc = "";
+    self_test_setparams(ret);
+    return ret;
+}
+
+void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st)
+{
+    OPENSSL_free(st);
+}
+
+/* Can be used during application testing to log that a test has started. */
+void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
+                            const char *desc)
+{
+    if (st != NULL && st->cb != NULL) {
+        st->phase = OSSL_SELF_TEST_PHASE_START;
+        st->type = type;
+        st->desc = desc;
+        self_test_setparams(st);
+        (void)st->cb(st->params, st->cb_arg);
+    }
+}
+
+/*
+ * Can be used during application testing to log that a test has either
+ * passed or failed.
+ */
+void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret)
+{
+    if (st != NULL && st->cb != NULL) {
+        st->phase =
+            (ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL);
+        self_test_setparams(st);
+        (void)st->cb(st->params, st->cb_arg);
+
+        st->phase = OSSL_SELF_TEST_PHASE_NONE;
+        st->type = OSSL_SELF_TEST_TYPE_NONE;
+        st->desc = OSSL_SELF_TEST_DESC_NONE;
+    }
+}
+
+/*
+ * Used for failure testing.
+ *
+ * Call the applications SELF_TEST_cb() if it exists.
+ * If the application callback decides to return 0 then the first byte of 'bytes'
+ * is modified (corrupted). This is used to modify output signatures or
+ * ciphertext before they are verified or decrypted.
+ */
+void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes)
+{
+    if (st != NULL && st->cb != NULL) {
+        st->phase = OSSL_SELF_TEST_PHASE_CORRUPT;
+        self_test_setparams(st);
+        if (!st->cb(st->params, st->cb_arg))
+            bytes[0] ^= 1;
+    }
+}
diff --git a/doc/man3/OSSL_SELF_TEST_new.pod b/doc/man3/OSSL_SELF_TEST_new.pod
new file mode 100644
index 0000000000..32155e1cd0
--- /dev/null
+++ b/doc/man3/OSSL_SELF_TEST_new.pod
@@ -0,0 +1,172 @@
+=pod
+
+=head1 NAME
+
+OSSL_SELF_TEST_new,
+OSSL_SELF_TEST_free,
+OSSL_SELF_TEST_onbegin,
+OSSL_SELF_TEST_oncorrupt_byte,
+OSSL_SELF_TEST_onend - functionality to trigger a callback during a self test
+
+=head1 SYNOPSIS
+
+ #include <openssl/self_test.h>
+
+ OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg);
+ void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st);
+
+ void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
+                             const char *desc);
+ void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes);
+ void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret);
+
+=head1 DESCRIPTION
+
+These methods are intended for use by provider implementors, to display
+diagnostic information during self testing.
+
+OSSL_SELF_TEST_new() allocates an opaque B<OSSL_SELF_TEST> object that has a
+callback and callback argument associated with it.
+
+The callback I<cb> may be triggered multiple times by a self test to indicate
+different phases.
+
+OSSL_SELF_TEST_free() frees the space allocated by OSSL_SELF_TEST_new().
+
+OSSL_SELF_TEST_onbegin() may be inserted at the start of a block of self test
+code. It can be used for diagnostic purposes.
+If this method is called the callback I<cb> will receive the following
+B<OSSL_PARAM> object.
+
+=over 4
+
+=item "st-phase" (B<OSSL_PROV_PARAM_SELF_TEST_PHASE>) <UTF8 string>
+
+The value is the string "Start"
+
+=back
+
+OSSL_SELF_TEST_oncorrupt_byte() may be inserted just after the known answer is
+calculated, but before the self test compares the result. The first byte in the
+passed in array of I<bytes> will be corrupted if the callback returns 0,
+otherwise it leaves the array unaltered. It can be used for failure testing.
+The I<type> and I<desc> can be used to identify an individual self test to
+target for failure testing.
+If this method is called the callback I<cb> will receive the following
+B<OSSL_PARAM> object.
+
+=over 4
+
+=item "st-phase" (B<OSSL_PROV_PARAM_SELF_TEST_PHASE>) <UTF8 string>
+
+The value is the string "Corrupt"
+
+=back
+
+OSSL_SELF_TEST_onend() may be inserted at the end of a block of self test code
+just before cleanup to indicate if the test passed or failed. It can be used for
+diagnostic purposes.
+If this method is called the callback I<cb> will receive the following
+B<OSSL_PARAM> object.
+
+=over 4
+
+=item "st-phase" (B<OSSL_PROV_PARAM_SELF_TEST_PHASE>) <UTF8 string>
+
+The value of the string is "Pass" if I<ret> is non zero, otherwise it has the
+value "Fail".
+
+=back
+
+After the callback I<cb> has been called the values that were set by
+OSSL_SELF_TEST_onbegin() for I<type> and I<desc> are set to the value "None".
+
+If OSSL_SELF_TEST_onbegin(), OSSL_SELF_TEST_oncorrupt_byte() or
+OSSL_SELF_TEST_onend() is called the following additional B<OSSL_PARAM> are
+passed to the callback.
+
+=over 4
+
+=item "st-type" (B<OSSL_PROV_PARAM_SELF_TEST_TYPE>) <UTF8 string>
+
+The value is setup by the I<type> passed to OSSL_SELF_TEST_onbegin().
+This allows the callback to identify the type of test being run.
+
+=item "st-desc" (B<OSSL_PROV_PARAM_SELF_TEST_DESC>) <UTF8 string>
+
+The value is setup by the I<type> passed to OSSL_SELF_TEST_onbegin().
+This allows the callback to identify the sub category of the test being run.
+
+=back
+
+=head1 RETURN VALUES
+
+OSSL_SELF_TEST_new() returns the allocated B<OSSL_SELF_TEST> object, or NULL if
+it fails.
+
+=head1 EXAMPLES
+
+A single self test could be set up in the following way:
+
+    OSSL_SELF_TEST *st = NULL;
+    OSSL_CALLBACK *cb;
+    void *cbarg;
+    int ok = 0;
+    unsigned char out[EVP_MAX_MD_SIZE];
+    unsigned int out_len = 0;
+    EVP_MD_CTX *ctx = EVP_MD_CTX_new();
+    EVP_MD *md = EVP_MD_fetch(libctx, t->algorithm, NULL);
+
+    /*
+     * Retrieve the callback - will be NULL if not set by the application via
+     * OSSL_SELF_TEST_set_callback().
+     */
+    OSSL_SELF_TEST_get_callback(libctx, &cb, &cbarg);
+
+    st = OSSL_SELF_TEST_new(cb, cb_arg);
+
+    /* Trigger the optional callback */
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_DIGEST,
+                           OSSL_SELF_TEST_DESC_MD_SHA2);
+
+    if (!EVP_DigestInit_ex(ctx, md, NULL)
+        || !EVP_DigestUpdate(ctx, pt, pt_len)
+        || !EVP_DigestFinal(ctx, out, &out_len))
+        goto err;
+    
+    /* Optional corruption - If the application callback returns 0 */
+    OSSL_SELF_TEST_oncorrupt_byte(st, out);
+
+    if (out_len != t->expected_len
+        || memcmp(out, t->expected, out_len) != 0)
+        goto err;
+    ok = 1;
+  err:
+    OSSL_SELF_TEST_onend(st, ok);
+    EVP_MD_free(md);
+    EVP_MD_CTX_free(ctx);
+
+Multiple self test's can be set up in a similar way by repeating the pattern of
+OSSL_SELF_TEST_onbegin(), OSSL_SELF_TEST_oncorrupt_byte(), OSSL_SELF_TEST_onend()
+for each test.
+
+=head1 SEE ALSO
+
+L<OSSL_SELF_TEST_set_callback(3)>,
+L<openssl-core.h(7)>,
+L<OSSL_PROVIDER-FIPS(7)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
+
+=head1 COPYRIGHT
+
+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
+L<https://www.openssl.org/source/license.html>.
+
+=cut
diff --git a/doc/man3/OSSL_SELF_TEST_set_callback.pod b/doc/man3/OSSL_SELF_TEST_set_callback.pod
index b2d38fbf7f..be65eca0fe 100644
--- a/doc/man3/OSSL_SELF_TEST_set_callback.pod
+++ b/doc/man3/OSSL_SELF_TEST_set_callback.pod
@@ -32,6 +32,7 @@ not been called.
 
 L<openssl-core.h(7)>,
 L<OSSL_PROVIDER-FIPS(7)>
+L<OSSL_SELF_TEST_new(3)>
 L<OPENSSL_CTX(3)>
 
 =head1 HISTORY
diff --git a/doc/man7/OSSL_PROVIDER-FIPS.pod b/doc/man7/OSSL_PROVIDER-FIPS.pod
index c3768da7bc..1cb75e7c87 100644
--- a/doc/man7/OSSL_PROVIDER-FIPS.pod
+++ b/doc/man7/OSSL_PROVIDER-FIPS.pod
@@ -17,59 +17,16 @@ One of the requirements for the FIPS module is self testing. An optional callbac
 mechanism is available to return information to the user using
 L<OSSL_SELF_TEST_set_callback(3)>.
 
+The parameters passed to the callback are described in L<OSSL_SELF_TEST_new(3)>
+
 The OPENSSL FIPS module uses the following mechanism to provide information
 about the self tests as they run.
 This is useful for debugging if a self test is failing.
 The callback also allows forcing any self test to fail, in order to check that
 it operates correctly on failure.
-
-The 'args' parameter of B<OSSL_CALLBACK> contains the B<OPENSSL_CTX> associated
-with the provider that is triggering the self test. This may be useful if
-multiple fips providers are present.
-
-The OSSL_PARAM names used are:
-
-=over 4
-
-=item "st-phase" (B<OSSL_PROV_PARAM_SELF_TEST_PHASE>) <UTF8 string>
-
-Each self test calls the callback 3 times with the following string values
-for the phase.
-
-=over 4
-
-=item "Start" (B<OSSL_SELF_TEST_PHASE_START>)
-
-This is the initial phase before the self test has run.
-This is used for informational purposes only.
-The value returned by the callback is ignored.
-
-=item "Corrupt" (B<OSSL_SELF_TEST_PHASE_CORRUPT>)
-
-The corrupt phase is run after the self test has calculated its known value.
-The callback may be used to force the self test to fail by returning a value
-of 0 from the callback during this phase.
-Returning any other value from the callback causes the self test to run normally.
-
-=item "Pass" (B<OSSL_SELF_TEST_PHASE_PASS>)
-
-=item "Fail" (B<OSSL_SELF_TEST_PHASE_FAIL>)
-
-The final phase runs after the self test is complete and indicates if a self
-test passed or failed. This is used for informational purposes only.
-The value returned by the callback is ignored.
-"Fail" should normally only be returned if any self test was forced to fail
-during the "Corrupt" phase (or if there was an error such as the integrity
-check of the module failed).
-
 Note that all self tests run even if a self test failure occurs.
 
-=back
-
-=item "st-type" (B<OSSL_PROV_PARAM_SELF_TEST_TYPE>) <UTF8 string>
-
-Used as a category to identify the type of self test being run.
-It includes the following string values:
+The FIPS module passes the following type(s) to OSSL_SELF_TEST_onbegin().
 
 =over 4
 
@@ -126,10 +83,8 @@ All other self test categories are run once at installation time, except for the
 There is only one instance of the "Module_Integrity" and "Install_Integrity"
 self tests. All other self tests may have multiple instances.
 
-=item "st-desc" (B<OSSL_PROV_PARAM_SELF_TEST_DESC>) <UTF8 string>
 
-Used as a sub category to identify an individual self test.
-The following description strings are used.
+The FIPS module passes the following descriptions(s) to OSSL_SELF_TEST_onbegin().
 
 =over 4
 
@@ -187,8 +142,6 @@ DRBG tests used with the "DRBG" type.
 
 =back
 
-=back
-
 =head1 EXAMPLES
 
 A simple self test callback is shown below for illustrative purposes.
@@ -241,6 +194,7 @@ A simple self test callback is shown below for illustrative purposes.
 L<openssl-fipsinstall(1)>,
 L<fips_config(5)>,
 L<OSSL_SELF_TEST_set_callback(3)>,
+L<OSSL_SELF_TEST_new(3)>,
 L<OSSL_PARAM(3)>,
 L<openssl-core.h(7)>
 
@@ -250,7 +204,7 @@ The type and functions described here were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT
 
-Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2019-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
diff --git a/include/crypto/ec.h b/include/crypto/ec.h
index 4a0a967629..c4f7d2e778 100644
--- a/include/crypto/ec.h
+++ b/include/crypto/ec.h
@@ -49,5 +49,6 @@ int ecdh_KDF_X9_63(unsigned char *out, size_t outlen,
                    const unsigned char *sinfo, size_t sinfolen,
                    const EVP_MD *md);
 
+int ec_generate_key(OPENSSL_CTX *libctx, EC_KEY *eckey, int pairwise_test);
 # endif /* OPENSSL_NO_EC */
 #endif
diff --git a/include/openssl/self_test.h b/include/openssl/self_test.h
index 31dd6bd6c5..478d4b3cd5 100644
--- a/include/openssl/self_test.h
+++ b/include/openssl/self_test.h
@@ -65,4 +65,12 @@ void OSSL_SELF_TEST_set_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK *cb,
 void OSSL_SELF_TEST_get_callback(OPENSSL_CTX *libctx, OSSL_CALLBACK **cb,
                                  void **cbarg);
 
+OSSL_SELF_TEST *OSSL_SELF_TEST_new(OSSL_CALLBACK *cb, void *cbarg);
+void OSSL_SELF_TEST_free(OSSL_SELF_TEST *st);
+
+void OSSL_SELF_TEST_onbegin(OSSL_SELF_TEST *st, const char *type,
+                            const char *desc);
+void OSSL_SELF_TEST_oncorrupt_byte(OSSL_SELF_TEST *st, unsigned char *bytes);
+void OSSL_SELF_TEST_onend(OSSL_SELF_TEST *st, int ret);
+
 #endif /* OPENSSL_SELF_TEST_H */
diff --git a/include/openssl/types.h b/include/openssl/types.h
index 5761afc097..e7078df6d0 100644
--- a/include/openssl/types.h
+++ b/include/openssl/types.h
@@ -209,6 +209,8 @@ typedef int pem_password_cb (char *buf, int size, int rwflag, void *userdata);
 typedef struct ossl_serializer_st OSSL_SERIALIZER;
 typedef struct ossl_serializer_ctx_st OSSL_SERIALIZER_CTX;
 
+typedef struct ossl_self_test_st OSSL_SELF_TEST;
+
 #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L && \
     defined(INTMAX_MAX) && defined(UINTMAX_MAX)
 typedef intmax_t ossl_intmax_t;
diff --git a/providers/fips/build.info b/providers/fips/build.info
index d12849ebb0..8d3c5e2049 100644
--- a/providers/fips/build.info
+++ b/providers/fips/build.info
@@ -1,2 +1,2 @@
-SOURCE[../fips]=fipsprov.c self_test.c self_test_kats.c self_test_event.c
+SOURCE[../fips]=fipsprov.c self_test.c self_test_kats.c
 INCLUDE[../fips]=../implementations/include ../common/include ../..
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 0ff0408a26..7063bf5c3f 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -966,12 +966,12 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
     }
 
     if (stcbfn != NULL && c_get_libctx != NULL) {
-        stcbfn(c_get_libctx(provider), &selftest_params.event_cb,
-               &selftest_params.event_cb_arg);
+        stcbfn(c_get_libctx(provider), &selftest_params.cb,
+               &selftest_params.cb_arg);
     }
     else {
-        selftest_params.event_cb = NULL;
-        selftest_params.event_cb_arg = NULL;
+        selftest_params.cb = NULL;
+        selftest_params.cb_arg = NULL;
     }
 
     if (!c_get_params(provider, core_params))
diff --git a/providers/fips/self_test.c b/providers/fips/self_test.c
index e486dd0db0..5bc921c050 100644
--- a/providers/fips/self_test.c
+++ b/providers/fips/self_test.c
@@ -132,7 +132,7 @@ DEP_FINI_ATTRIBUTE void cleanup(void)
  */
 static int verify_integrity(BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb,
                             unsigned char *expected, size_t expected_len,
-                            OPENSSL_CTX *libctx, OSSL_ST_EVENT *ev,
+                            OPENSSL_CTX *libctx, OSSL_SELF_TEST *ev,
                             const char *event_type)
 {
     int ret = 0, status;
@@ -143,7 +143,7 @@ static int verify_integrity(BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb,
     EVP_MAC_CTX *ctx = NULL;
     OSSL_PARAM params[3], *p = params;
 
-    SELF_TEST_EVENT_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
+    OSSL_SELF_TEST_onbegin(ev, event_type, OSSL_SELF_TEST_DESC_INTEGRITY_HMAC);
 
     mac = EVP_MAC_fetch(libctx, MAC_NAME, NULL);
     ctx = EVP_MAC_CTX_new(mac);
@@ -170,13 +170,13 @@ static int verify_integrity(BIO *bio, OSSL_BIO_read_ex_fn read_ex_cb,
     if (!EVP_MAC_final(ctx, out, &out_len, sizeof(out)))
         goto err;
 
-    SELF_TEST_EVENT_oncorrupt_byte(ev, out);
+    OSSL_SELF_TEST_oncorrupt_byte(ev, out);
     if (expected_len != out_len
             || memcmp(expected, out, out_len) != 0)
         goto err;
     ret = 1;
 err:
-    SELF_TEST_EVENT_onend(ev, ret);
+    OSSL_SELF_TEST_onend(ev, ret);
     EVP_MAC_CTX_free(ctx);
     EVP_MAC_free(mac);
     return ret;
@@ -192,7 +192,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
     unsigned char *module_checksum = NULL;
     unsigned char *indicator_checksum = NULL;
     int loclstate;
-    OSSL_ST_EVENT ev;
+    OSSL_SELF_TEST *ev = NULL;
 
     if (!RUN_ONCE(&fips_self_test_init, do_fips_self_test_init))
         return 0;
@@ -223,7 +223,9 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
             || st->module_checksum_data == NULL)
         goto end;
 
-    SELF_TEST_EVENT_init(&ev, st->event_cb, st->event_cb_arg);
+    ev = OSSL_SELF_TEST_new(st->cb, st->cb_arg);
+    if (ev == NULL)
+        goto end;
 
     module_checksum = OPENSSL_hexstr2buf(st->module_checksum_data,
                                          &checksum_len);
@@ -235,7 +237,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
     if (bio_module == NULL
             || !verify_integrity(bio_module, st->bio_read_ex_cb,
                                  module_checksum, checksum_len, st->libctx,
-                                 &ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY))
+                                 ev, OSSL_SELF_TEST_TYPE_MODULE_INTEGRITY))
         goto end;
 
     /* This will be NULL during installation - so the self test KATS will run */
@@ -257,7 +259,7 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
         if (bio_indicator == NULL
                 || !verify_integrity(bio_indicator, st->bio_read_ex_cb,
                                      indicator_checksum, checksum_len,
-                                     st->libctx, &ev,
+                                     st->libctx, ev,
                                      OSSL_SELF_TEST_TYPE_INSTALL_INTEGRITY))
             goto end;
         else
@@ -266,11 +268,12 @@ int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test)
 
     /* Only runs the KAT's during installation OR on_demand() */
     if (on_demand_test || kats_already_passed == 0) {
-        if (!SELF_TEST_kats(&ev, st->libctx))
+        if (!SELF_TEST_kats(ev, st->libctx))
             goto end;
     }
     ok = 1;
 end:
+    OSSL_SELF_TEST_free(ev);
     OPENSSL_free(module_checksum);
     OPENSSL_free(indicator_checksum);
 
diff --git a/providers/fips/self_test.h b/providers/fips/self_test.h
index 5d995adac3..1950261a29 100644
--- a/providers/fips/self_test.h
+++ b/providers/fips/self_test.h
@@ -26,31 +26,11 @@ typedef struct self_test_post_params_st {
     OSSL_BIO_new_membuf_fn *bio_new_buffer_cb;
     OSSL_BIO_read_ex_fn *bio_read_ex_cb;
     OSSL_BIO_free_fn *bio_free_cb;
-    OSSL_CALLBACK *event_cb;
-    void *event_cb_arg;
-    OPENSSL_CTX *libctx;
-
-} SELF_TEST_POST_PARAMS;
-
-typedef struct st_event_st
-{
-    /* local state variables */
-    const char *phase;
-    const char *type;
-    const char *desc;
     OSSL_CALLBACK *cb;
-
-    /* callback related variables used to pass the state back to the user */
-    OSSL_PARAM params[4];
     void *cb_arg;
+    OPENSSL_CTX *libctx;
 
-} OSSL_ST_EVENT;
+} SELF_TEST_POST_PARAMS;
 
 int SELF_TEST_post(SELF_TEST_POST_PARAMS *st, int on_demand_test);
-int SELF_TEST_kats(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx);
-
-void SELF_TEST_EVENT_init(OSSL_ST_EVENT *ev, OSSL_CALLBACK *cb, void *cbarg);
-void SELF_TEST_EVENT_onbegin(OSSL_ST_EVENT *ev, const char *type,
-                             const char *desc);
-void SELF_TEST_EVENT_onend(OSSL_ST_EVENT *ev, int ret);
-void SELF_TEST_EVENT_oncorrupt_byte(OSSL_ST_EVENT *ev, unsigned char *bytes);
+int SELF_TEST_kats(OSSL_SELF_TEST *event, OPENSSL_CTX *libctx);
diff --git a/providers/fips/self_test_event.c b/providers/fips/self_test_event.c
deleted file mode 100644
index 887b9dd17d..0000000000
--- a/providers/fips/self_test_event.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
- *
- * Licensed under the OpenSSL license (the "License").  You may not use
- * this file except in compliance with the License.  You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
-
-#include <openssl/core_names.h>
-#include <openssl/params.h>
-#include "self_test.h"
-
-static void self_test_event_setparams(OSSL_ST_EVENT *ev)
-{
-    size_t n = 0;
-
-    if (ev->cb != NULL) {
-        ev->params[n++] =
-            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_PHASE,
-                                             (char *)ev->phase, 0);
-        ev->params[n++] =
-            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_TYPE,
-                                             (char *)ev->type, 0);
-        ev->params[n++] =
-            OSSL_PARAM_construct_utf8_string(OSSL_PROV_PARAM_SELF_TEST_DESC,
-                                             (char *)ev->desc, 0);
-    }
-    ev->params[n++] = OSSL_PARAM_construct_end();
-}
-
-void SELF_TEST_EVENT_init(OSSL_ST_EVENT *ev, OSSL_CALLBACK *cb, void *cbarg)
-{
-    if (ev == NULL)
-        return;
-
-    ev->cb = cb;
-    ev->cb_arg = cbarg;
-    ev->phase = "";
-    ev->type = "";
-    ev->desc = "";
-    self_test_event_setparams(ev);
-}
-
-/* Can be used during application testing to log that a test has started. */
-void SELF_TEST_EVENT_onbegin(OSSL_ST_EVENT *ev, const char *type,
-                             const char *desc)
-{
-    if (ev != NULL && ev->cb != NULL) {
-        ev->phase = OSSL_SELF_TEST_PHASE_START;
-        ev->type = type;
-        ev->desc = desc;
-        self_test_event_setparams(ev);
-        (void)ev->cb(ev->params, ev->cb_arg);
-    }
-}
-
-/*
- * Can be used during application testing to log that a test has either
- * passed or failed.
- */
-void SELF_TEST_EVENT_onend(OSSL_ST_EVENT *ev, int ret)
-{
-    if (ev != NULL && ev->cb != NULL) {
-        ev->phase =
-            (ret == 1 ? OSSL_SELF_TEST_PHASE_PASS : OSSL_SELF_TEST_PHASE_FAIL);
-        self_test_event_setparams(ev);
-        (void)ev->cb(ev->params, ev->cb_arg);
-
-        ev->phase = OSSL_SELF_TEST_PHASE_NONE;
-        ev->type = OSSL_SELF_TEST_TYPE_NONE;
-        ev->desc = OSSL_SELF_TEST_DESC_NONE;
-    }
-}
-
-/*
- * Used for failure testing.
- *
- * Call the applications SELF_TEST_cb() if it exists.
- * If the application callback decides to return 0 then the first byte of 'bytes'
- * is modified (corrupted). This is used to modify output signatures or
- * ciphertext before they are verified or decrypted.
- */
-void SELF_TEST_EVENT_oncorrupt_byte(OSSL_ST_EVENT *ev, unsigned char *bytes)
-{
-    if (ev != NULL && ev->cb != NULL) {
-        ev->phase = OSSL_SELF_TEST_PHASE_CORRUPT;
-        self_test_event_setparams(ev);
-        if (!ev->cb(ev->params, ev->cb_arg))
-            bytes[0] ^= 1;
-    }
-}
-
diff --git a/providers/fips/self_test_kats.c b/providers/fips/self_test_kats.c
index 06f12a1ead..50e59611c5 100644
--- a/providers/fips/self_test_kats.c
+++ b/providers/fips/self_test_kats.c
@@ -20,7 +20,7 @@
 #define DRBG_PARAM_ENTROPY "DRBG-ENTROPY"
 #define DRBG_PARAM_NONCE   "DRBG-NONCE"
 
-static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_ST_EVENT *event,
+static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_SELF_TEST *st,
                             OPENSSL_CTX *libctx)
 {
     int ok = 0;
@@ -29,7 +29,7 @@ static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_ST_EVENT *event,
     EVP_MD_CTX *ctx = EVP_MD_CTX_new();
     EVP_MD *md = EVP_MD_fetch(libctx, t->algorithm, NULL);
 
-    SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_KAT_DIGEST, t->desc);
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_DIGEST, t->desc);
 
     if (ctx == NULL
             || md == NULL
@@ -39,14 +39,14 @@ static int self_test_digest(const ST_KAT_DIGEST *t, OSSL_ST_EVENT *event,
         goto err;
 
     /* Optional corruption */
-    SELF_TEST_EVENT_oncorrupt_byte(event, out);
+    OSSL_SELF_TEST_oncorrupt_byte(st, out);
 
     if (out_len != t->expected_len
             || memcmp(out, t->expected, out_len) != 0)
         goto err;
     ok = 1;
 err:
-    SELF_TEST_EVENT_onend(event, ok);
+    OSSL_SELF_TEST_onend(st, ok);
     EVP_MD_free(md);
     EVP_MD_CTX_free(ctx);
 
@@ -86,7 +86,7 @@ static int cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher,
 }
 
 /* Test a single KAT for encrypt/decrypt */
-static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
+static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_SELF_TEST *st,
                             OPENSSL_CTX *libctx)
 {
     int ret = 0, encrypt = 1, len, ct_len = 0, pt_len = 0;
@@ -95,7 +95,7 @@ static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
     unsigned char ct_buf[256] = { 0 };
     unsigned char pt_buf[256] = { 0 };
 
-    SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_KAT_CIPHER, t->base.desc);
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_CIPHER, t->base.desc);
 
     ctx = EVP_CIPHER_CTX_new();
     if (ctx == NULL)
@@ -110,7 +110,7 @@ static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
             || !EVP_CipherFinal_ex(ctx, ct_buf + len, &ct_len))
         goto err;
 
-    SELF_TEST_EVENT_oncorrupt_byte(event, ct_buf);
+    OSSL_SELF_TEST_oncorrupt_byte(st, ct_buf);
     ct_len += len;
     if (ct_len != (int)t->base.expected_len
         || memcmp(t->base.expected, ct_buf, ct_len) != 0)
@@ -138,11 +138,11 @@ static int self_test_cipher(const ST_KAT_CIPHER *t, OSSL_ST_EVENT *event,
 err:
     EVP_CIPHER_free(cipher);
     EVP_CIPHER_CTX_free(ctx);
-    SELF_TEST_EVENT_onend(event, ret);
+    OSSL_SELF_TEST_onend(st, ret);
     return ret;
 }
 
-static int self_test_kdf(const ST_KAT_KDF *t, OSSL_ST_EVENT *event,
+static int self_test_kdf(const ST_KAT_KDF *t, OSSL_SELF_TEST *st,
                          OPENSSL_CTX *libctx)
 {
     int ret = 0;
@@ -154,7 +154,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_ST_EVENT *event,
     const OSSL_PARAM *settables = NULL;
 
     numparams = OSSL_NELEM(params);
-    SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc);
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_KAT_KDF, t->desc);
 
     /* Zeroize the params array to avoid mem leaks on error */
     for (i = 0; i < numparams; ++i)
@@ -183,7 +183,7 @@ static int self_test_kdf(const ST_KAT_KDF *t, OSSL_ST_EVENT *event,
     if (EVP_KDF_derive(ctx, out, t->expected_len) <= 0)
         goto err;
 
-    SELF_TEST_EVENT_oncorrupt_byte(event, out);
+    OSSL_SELF_TEST_oncorrupt_byte(st, out);
 
     if (memcmp(out, t->expected,  t->expected_len) != 0)
         goto err;
@@ -194,7 +194,7 @@ err:
         OPENSSL_free(params[i].data);
     EVP_KDF_free(kdf);
     EVP_KDF_CTX_free(ctx);
-    SELF_TEST_EVENT_onend(event, ret);
+    OSSL_SELF_TEST_onend(st, ret);
     return ret;
 }
 
@@ -223,7 +223,7 @@ static size_t drbg_kat_nonce_cb(RAND_DRBG *drbg, unsigned char **pout,
     return p->data_size;
 }
 
-static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_ST_EVENT *event,
+static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_SELF_TEST *st,
                           OPENSSL_CTX *libctx)
 {
     int ret = 0;
@@ -236,7 +236,7 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_ST_EVENT *event,
     };
     static const unsigned char zero[sizeof(drbg->data)] = { 0 };
 
-    SELF_TEST_EVENT_onbegin(event, OSSL_SELF_TEST_TYPE_DRBG, t->desc);
+    OSSL_SELF_TEST_onbegin(st, OSSL_SELF_TEST_TYPE_DRBG, t->desc);
 
     if (strcmp(t->desc, OSSL_SELF_TEST_DESC_DRBG_HMAC) == 0)
         flags |= RAND_DRBG_FLAG_HMAC;
@@ -280,7 +280,7 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_ST_EVENT *event,
                             t->entropyaddin2, t->entropyaddin2len))
         goto err;
 
-    SELF_TEST_EVENT_oncorrupt_byte(event, out);
+    OSSL_SELF_TEST_oncorrupt_byte(st, out);
 
     if (memcmp(out, t->expected, t->expectedlen) != 0)
         goto err;
@@ -296,7 +296,7 @@ static int self_test_drbg(const ST_KAT_DRBG *t, OSSL_ST_EVENT *event,
     ret = 1;
 err:
     RAND_DRBG_free(drbg);
-    SELF_TEST_EVENT_onend(event, ret);
+    OSSL_SELF_TEST_onend(st, ret);
     return ret;
 }
 
@@ -305,45 +305,45 @@ err:
  * All tests are run regardless of if they fail or not.
  * Return 0 if any test fails.
  */
-static int self_test_digests(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
+static int self_test_digests(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx)
 {
     int i, ret = 1;
 
     for (i = 0; i < (int)OSSL_NELEM(st_kat_digest_tests); ++i) {
-        if (!self_test_digest(&st_kat_digest_tests[i], event, libctx))
+        if (!self_test_digest(&st_kat_digest_tests[i], st, libctx))
             ret = 0;
     }
     return ret;
 }
 
-static int self_test_ciphers(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
+static int self_test_ciphers(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx)
 {
     int i, ret = 1;
 
     for (i = 0; i < (int)OSSL_NELEM(st_kat_cipher_tests); ++i) {
-        if (!self_test_cipher(&st_kat_cipher_tests[i], event, libctx))
+        if (!self_test_cipher(&st_kat_cipher_tests[i], st, libctx))
             ret = 0;
     }
     return ret;
 }
 
-static int self_test_kdfs(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
+static int self_test_kdfs(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx)
 {
     int i, ret = 1;
 
     for (i = 0; i < (int)OSSL_NELEM(st_kat_kdf_tests); ++i) {
-        if (!self_test_kdf(&st_kat_kdf_tests[i], event, libctx))
+        if (!self_test_kdf(&st_kat_kdf_tests[i], st, libctx))
             ret = 0;
     }
     return ret;
 }
 
-static int self_test_drbgs(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
+static int self_test_drbgs(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx)
 {
     int i, ret = 1;
 
     for (i = 0; i < (int)OSSL_NELEM(st_kat_drbg_tests); ++i) {
-        if (!self_test_drbg(&st_kat_drbg_tests[i], event, libctx))
+        if (!self_test_drbg(&st_kat_drbg_tests[i], st, libctx))
             ret = 0;
     }
     return ret;
@@ -356,17 +356,17 @@ static int self_test_drbgs(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
  *
  * TODO(3.0) Add self tests for KA, Sign/Verify when they become available
  */
-int SELF_TEST_kats(OSSL_ST_EVENT *event, OPENSSL_CTX *libctx)
+int SELF_TEST_kats(OSSL_SELF_TEST *st, OPENSSL_CTX *libctx)
 {
     int ret = 1;
 
-    if (!self_test_digests(event, libctx))
+    if (!self_test_digests(st, libctx))
         ret = 0;
-    if (!self_test_ciphers(event, libctx))
+    if (!self_test_ciphers(st, libctx))
         ret = 0;
-    if (!self_test_kdfs(event, libctx))
+    if (!self_test_kdfs(st, libctx))
         ret = 0;
-    if (!self_test_drbgs(event, libctx))
+    if (!self_test_drbgs(st, libctx))
         ret = 0;
 
     return ret;
diff --git a/util/libcrypto.num b/util/libcrypto.num
index aefe1b4100..fa220d873f 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4947,3 +4947,8 @@ EVP_PKEY_CTX_set0_ecdh_kdf_ukm          ?	3_0_0	EXIST::FUNCTION:EC
 EVP_PKEY_CTX_get0_ecdh_kdf_ukm          ?	3_0_0	EXIST::FUNCTION:EC
 EVP_PKEY_CTX_set_rsa_pss_saltlen        ?	3_0_0	EXIST::FUNCTION:RSA
 EVP_PKEY_CTX_get_rsa_pss_saltlen        ?	3_0_0	EXIST::FUNCTION:RSA
+OSSL_SELF_TEST_new                      ?	3_0_0	EXIST::FUNCTION:
+OSSL_SELF_TEST_free                     ?	3_0_0	EXIST::FUNCTION:
+OSSL_SELF_TEST_onbegin                  ?	3_0_0	EXIST::FUNCTION:
+OSSL_SELF_TEST_oncorrupt_byte           ?	3_0_0	EXIST::FUNCTION:
+OSSL_SELF_TEST_onend                    ?	3_0_0	EXIST::FUNCTION:


More information about the openssl-commits mailing list