[openssl] master update

Richard Levitte levitte at openssl.org
Wed Jul 31 04:46:34 UTC 2019


The branch master has been updated
       via  c3612970465d0a13f2fc5b47bc28ca18516a699d (commit)
       via  036913b1076da41f257c640a5e6230476c647eff (commit)
       via  49c6434673ca5e9413062851979cf6ed126c9f1c (commit)
       via  add8c8e9647a71cc755dea22490e2075e342624b (commit)
       via  ed57f7f93508776b898e4c23b65d67f3479edaf1 (commit)
       via  7c0e20dc6f11aa506abc99ccc90b3a39c48c3052 (commit)
       via  8a4dc425cc73040c55bc01d89c5541e37dab939a (commit)
       via  e039ca38c8d77f1e2f182123727c884aaf2d683d (commit)
      from  35f6fe7ac4fbde98d4fd6af968dfe320011bbe1e (commit)


- Log -----------------------------------------------------------------
commit c3612970465d0a13f2fc5b47bc28ca18516a699d
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jul 24 16:55:32 2019 +0200

    Avoid using ERR_put_error() directly in OpenSSL code
    
    If compiled with 'no-deprecated', ERR_put_error() is undefined.  We
    had one spot where we were using it directly, because the file and
    line information was passed from elsewhere.
    
    Fortunately, it's possible to use ERR_raise() for that situation, and
    call ERR_set_debug() immediately after and thereby override the
    information that ERR_raise() stored in the error record.
    
    util/mkerr.pl needed a small adjustment to not generate code that
    won't compile in a 'no-deprecated' configuration.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9452)

commit 036913b1076da41f257c640a5e6230476c647eff
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jul 24 14:00:39 2019 +0200

    Adapt the FIPS provider to use the new core error functions
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9452)

commit 49c6434673ca5e9413062851979cf6ed126c9f1c
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jul 24 13:37:42 2019 +0200

    Refactor provider support for reporting errors
    
    The core now supplies its own versions of ERR_new(), ERR_set_debug()
    and ERR_vset_error().  This should suffice for a provider to have any
    OpenSSL compatible functionlity it desires.
    
    The main difference between the ERR functions and the core
    counterparts is that the core counterparts take an OSSL_PROVIDER
    parameter instead of the library number.  That way, providers do not
    need to know what number they have been assigned, that information
    stays in the core.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9452)

commit add8c8e9647a71cc755dea22490e2075e342624b
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jul 24 13:25:56 2019 +0200

    ERR: Remove ERR_put_func_error() and reimplement ERR_put_error() as a macro
    
    Also, deprecate ERR_put_error()
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9452)

commit ed57f7f93508776b898e4c23b65d67f3479edaf1
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jul 24 13:13:52 2019 +0200

    ERR: Implement the macros ERR_raise() and ERR_raise_data() and use them
    
    The ERR_raise() macro uses a trick in C.  The following is permitted:
    
        #include <stdio.h>
    
        void first(void)
        {
            printf("Hello! ");
        }
    
        void foo(const char *bar)
        {
            printf("%s", bar);
        }
    
        int main()
        {
            /* This */
            (first(),foo)("cookie");
        }
    
    ERR_raise_data() can be used to implement FUNCerr() as well, which
    takes away the need for the special function ERR_put_func_error().
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9452)

commit 7c0e20dc6f11aa506abc99ccc90b3a39c48c3052
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jul 24 13:03:32 2019 +0200

    ERR: Add new building blocks for reporting errors
    
    The new building block are ERR_new(), ERR_set_debug(),
    ERR_set_error(), ERR_vset_error(), which allocate a new error record
    and set the diverse data in them.  They are designed in such a way
    that it's reasonably easy to create macros that use all of them but
    then rely completely on the function signature of ERR_set_error() or
    ERR_vset_error().
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9452)

commit 8a4dc425cc73040c55bc01d89c5541e37dab939a
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jul 24 12:56:58 2019 +0200

    ERR: refactor useful inner macros to err_locl.h.  Add function name field
    
    The useful inner macros are now static inline functions.  That will
    make them easier to debug in the future.
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9452)

commit e039ca38c8d77f1e2f182123727c884aaf2d683d
Author: Richard Levitte <levitte at openssl.org>
Date:   Wed Jul 24 12:53:36 2019 +0200

    Move some macros from include/openssl/opensslconf.h.in, add OPENSSL_FUNC
    
    New header file, include/openssl/macros.h, which contains diverse
    useful macros that we use elsewhere.
    
    We also add the new macro OPENSSL_FUNC, which is an alias for
    __FUNC__, __FUNCTION__, __FUNCSIG or __func__, depending on what the
    compiler supports.  In the worst case, it's an alias for the string
    "(unknown function)".
    
    Reviewed-by: Paul Dale <paul.dale at oracle.com>
    (Merged from https://github.com/openssl/openssl/pull/9452)

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

Summary of changes:
 crypto/err/build.info                          |   2 +-
 crypto/err/err.c                               |  83 +-----------------
 crypto/err/err_blocks.c                        | 113 ++++++++++++++++++++++++
 crypto/err/err_locl.h                          |  68 ++++++++++++++
 crypto/property/property_parse.c               |  53 +++++------
 crypto/provider_core.c                         |  72 +++++++++------
 doc/man3/ERR_new.pod                           |  78 +++++++++++++++++
 doc/man3/ERR_put_error.pod                     |  40 ++++++---
 doc/man7/provider-base.pod                     |  58 ++++++++----
 engines/e_afalg_err.c                          |   3 +-
 engines/e_capi_err.c                           |   3 +-
 engines/e_dasync_err.c                         |   3 +-
 engines/e_ossltest_err.c                       |   3 +-
 include/openssl/core_numbers.h                 |  20 +++--
 include/openssl/err.h                          | 114 ++++++++++++++----------
 include/openssl/{opensslconf.h.in => macros.h} |  74 ++++------------
 include/openssl/opensslconf.h.in               | 117 +------------------------
 providers/fips/fipsprov.c                      |  41 +++++----
 ssl/statem/statem.c                            |   3 +-
 test/errtest.c                                 |   8 +-
 util/libcrypto.num                             |   8 +-
 util/mkerr.pl                                  |   3 +-
 util/private.num                               |   3 +
 23 files changed, 543 insertions(+), 427 deletions(-)
 create mode 100644 crypto/err/err_blocks.c
 create mode 100644 crypto/err/err_locl.h
 create mode 100644 doc/man3/ERR_new.pod
 copy include/openssl/{opensslconf.h.in => macros.h} (70%)

diff --git a/crypto/err/build.info b/crypto/err/build.info
index 6163d95b74..c010ea4cb9 100644
--- a/crypto/err/build.info
+++ b/crypto/err/build.info
@@ -1,3 +1,3 @@
 LIBS=../../libcrypto
 SOURCE[../../libcrypto]=\
-        err.c err_all.c err_prn.c
+        err_blocks.c err.c err_all.c err_prn.c
diff --git a/crypto/err/err.c b/crypto/err/err.c
index 7a35512f87..f129c1c7d6 100644
--- a/crypto/err/err.c
+++ b/crypto/err/err.c
@@ -22,6 +22,7 @@
 #include "internal/ctype.h"
 #include "internal/constant_time_locl.h"
 #include "e_os.h"
+#include "err_locl.h"
 
 static int err_load_strings(const ERR_STRING_DATA *str);
 
@@ -235,40 +236,6 @@ static void build_SYS_str_reasons(void)
 }
 #endif
 
-#define err_get_slot(p) \
-    do { \
-        (p)->top = ((p)->top + 1) % ERR_NUM_ERRORS; \
-        if ((p)->top == (p)->bottom) \
-            (p)->bottom = ((p)->bottom + 1) % ERR_NUM_ERRORS; \
-    } while (0)
-
-#define err_clear_data(p, i, deall)                             \
-        do {                                                    \
-            if ((p)->err_data_flags[i] & ERR_TXT_MALLOCED) {    \
-                if (deall) {                                    \
-                    OPENSSL_free((p)->err_data[i]);             \
-                    (p)->err_data[i] = NULL;                    \
-                    (p)->err_data_size[i] = 0;                  \
-                    (p)->err_data_flags[i] = 0;                 \
-                } else if ((p)->err_data[i] != NULL) {          \
-                    (p)->err_data[i][0] = '\0';                 \
-                }                                               \
-            } else {                                            \
-                (p)->err_data[i] = NULL;                        \
-                (p)->err_data_size[i] = 0;                      \
-                (p)->err_data_flags[i] = 0;                     \
-            }                                                   \
-        } while (0)
-
-#define err_clear(p, i, deall) \
-        do { \
-            err_clear_data((p), (i), (deall)); \
-            (p)->err_flags[i] = 0; \
-            (p)->err_buffer[i] = 0; \
-            (p)->err_file[i] = NULL; \
-            (p)->err_line[i] = -1; \
-        } while (0)
-
 static void ERR_STATE_free(ERR_STATE *s)
 {
     int i;
@@ -388,47 +355,6 @@ void err_free_strings_int(void)
 
 /********************************************************/
 
-void ERR_put_func_error(int lib, const char *func, int reason,
-                        const char *file, int line)
-{
-    ERR_put_error(lib, 0, reason, file, line);
-    ERR_add_error_data(2, "calling function ", func);
-}
-
-void ERR_put_error(int lib, int func, int reason, const char *file, int line)
-{
-    ERR_STATE *es;
-
-#ifdef _OSD_POSIX
-    /*
-     * In the BS2000-OSD POSIX subsystem, the compiler generates path names
-     * in the form "*POSIX(/etc/passwd)". This dirty hack strips them to
-     * something sensible. @@@ We shouldn't modify a const string, though.
-     */
-    if (strncmp(file, "*POSIX(", sizeof("*POSIX(") - 1) == 0) {
-        char *end;
-
-        /* Skip the "*POSIX(" prefix */
-        file += sizeof("*POSIX(") - 1;
-        end = &file[strlen(file) - 1];
-        if (*end == ')')
-            *end = '\0';
-        /* Optional: use the basename of the path only. */
-        if ((end = strrchr(file, '/')) != NULL)
-            file = &end[1];
-    }
-#endif
-    es = ERR_get_state();
-    if (es == NULL)
-        return;
-
-    err_get_slot(es);
-    err_clear(es, es->top, 0);
-    es->err_buffer[es->top] = ERR_PACK(lib, func, reason);
-    es->err_file[es->top] = file;
-    es->err_line[es->top] = line;
-}
-
 void ERR_clear_error(void)
 {
     int i;
@@ -789,18 +715,13 @@ static int err_set_error_data_int(char *data, size_t size, int flags,
                                   int deallocate)
 {
     ERR_STATE *es;
-    int i;
 
     es = ERR_get_state();
     if (es == NULL)
         return 0;
 
-    i = es->top;
-
     err_clear_data(es, es->top, deallocate);
-    es->err_data[i] = data;
-    es->err_data_size[i] = size;
-    es->err_data_flags[i] = flags;
+    err_set_data(es, es->top, data, size, flags);
 
     return 1;
 }
diff --git a/crypto/err/err_blocks.c b/crypto/err/err_blocks.c
new file mode 100644
index 0000000000..49086bd0c2
--- /dev/null
+++ b/crypto/err/err_blocks.c
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2019 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>
+#include <openssl/err.h>
+#include "err_locl.h"
+
+void ERR_new(void)
+{
+    ERR_STATE *es;
+
+    es = ERR_get_state();
+    if (es == NULL)
+        return;
+
+    /* Allocate a slot */
+    err_get_slot(es);
+    err_clear(es, es->top, 0);
+}
+
+void ERR_set_debug(const char *file, int line, const char *func)
+{
+    ERR_STATE *es;
+
+    es = ERR_get_state();
+    if (es == NULL)
+        return;
+
+    err_set_debug(es, es->top, file, line, func);
+}
+
+void ERR_set_error(int lib, int reason, const char *fmt, ...)
+{
+    va_list args;
+
+    va_start(args, fmt);
+    ERR_vset_error(lib, reason, fmt, args);
+    va_end(args);
+}
+
+void ERR_vset_error(int lib, int reason, const char *fmt, va_list args)
+{
+    ERR_STATE *es;
+    char *buf = NULL;
+    size_t buf_size = 0;
+    unsigned long flags = 0;
+    size_t i;
+
+    es = ERR_get_state();
+    if (es == NULL)
+        return;
+    i = es->top;
+
+    if (fmt != NULL) {
+        int printed_len = 0;
+        char *rbuf = NULL;
+
+        buf = es->err_data[i];
+        buf_size = es->err_data_size[i];
+
+        /*
+         * To protect the string we just grabbed from tampering by other
+         * functions we may call, or to protect them from freeing a pointer
+         * that may no longer be valid at that point, we clear away the
+         * data pointer and the flags.  We will set them again at the end
+         * of this function.
+         */
+        es->err_data[i] = NULL;
+        es->err_data_flags[i] = 0;
+
+        /*
+         * Try to maximize the space available.  If that fails, we use what
+         * we have.
+         */
+        if (buf_size < ERR_MAX_DATA_SIZE
+            && (rbuf = OPENSSL_realloc(buf, ERR_MAX_DATA_SIZE)) != NULL) {
+            buf = rbuf;
+            buf_size = ERR_MAX_DATA_SIZE;
+        }
+
+        if (buf != NULL) {
+            printed_len = BIO_vsnprintf(buf, ERR_MAX_DATA_SIZE, fmt, args);
+        }
+        if (printed_len < 0)
+            printed_len = 0;
+        buf[printed_len] = '\0';
+
+        /*
+         * Try to reduce the size, but only if we maximized above.  If that
+         * fails, we keep what we have.
+         * (According to documentation, realloc leaves the old buffer untouched
+         * if it fails)
+         */
+        if ((rbuf = OPENSSL_realloc(buf, printed_len + 1)) != NULL) {
+            buf = rbuf;
+            buf_size = printed_len + 1;
+        }
+
+        if (buf != NULL)
+            flags = ERR_TXT_MALLOCED | ERR_TXT_STRING;
+    }
+
+    err_clear_data(es, es->top, 0);
+    err_set_error(es, es->top, lib, reason);
+    if (fmt != NULL)
+        err_set_data(es, es->top, buf, buf_size, flags);
+}
diff --git a/crypto/err/err_locl.h b/crypto/err/err_locl.h
new file mode 100644
index 0000000000..d45a00e746
--- /dev/null
+++ b/crypto/err/err_locl.h
@@ -0,0 +1,68 @@
+/*
+ * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the Apache License 2.0 (the "License").  You may not use
+ * this file except in compliance with the License.  You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
+#include <openssl/err.h>
+#include <openssl/e_os2.h>
+
+static ossl_inline void err_get_slot(ERR_STATE *es)
+{
+    es->top = (es->top + 1) % ERR_NUM_ERRORS;
+    if (es->top == es->bottom)
+        es->bottom = (es->bottom + 1) % ERR_NUM_ERRORS;
+}
+
+static ossl_inline void err_clear_data(ERR_STATE *es, size_t i, int deall)
+{
+    if (es->err_data_flags[i] & ERR_TXT_MALLOCED) {
+        if (deall) {
+            OPENSSL_free(es->err_data[i]);
+            es->err_data[i] = NULL;
+            es->err_data_size[i] = 0;
+            es->err_data_flags[i] = 0;
+        } else if (es->err_data[i] != NULL) {
+            es->err_data[i][0] = '\0';
+        }
+    } else {
+        es->err_data[i] = NULL;
+        es->err_data_size[i] = 0;
+        es->err_data_flags[i] = 0;
+    }
+}
+
+static ossl_inline void err_set_error(ERR_STATE *es, size_t i,
+                                      int lib, int reason)
+{
+    es->err_buffer[i] = ERR_PACK(lib, 0, reason);
+}
+
+static ossl_inline void err_set_debug(ERR_STATE *es, size_t i,
+                                      const char *file, int line,
+                                      const char *fn)
+{
+    es->err_file[i] = file;
+    es->err_line[i] = line;
+    es->err_func[i] = fn;
+}
+
+static ossl_inline void err_set_data(ERR_STATE *es, size_t i,
+                                     void *data, size_t datasz, int flags)
+{
+    es->err_data[i] = data;
+    es->err_data_size[i] = datasz;
+    es->err_data_flags[i] = flags;
+}
+
+static ossl_inline void err_clear(ERR_STATE *es, size_t i, int deall)
+{
+    err_clear_data(es, i, (deall));
+    es->err_flags[i] = 0;
+    es->err_buffer[i] = 0;
+    es->err_file[i] = NULL;
+    es->err_line[i] = -1;
+}
diff --git a/crypto/property/property_parse.c b/crypto/property/property_parse.c
index 0b4dcfc8aa..c17b0ddefc 100644
--- a/crypto/property/property_parse.c
+++ b/crypto/property/property_parse.c
@@ -91,8 +91,8 @@ static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create,
 
     for (;;) {
         if (!ossl_isalpha(*s)) {
-            PROPerr(PROP_F_PARSE_NAME, PROP_R_NOT_AN_IDENTIFIER);
-            ERR_add_error_data(2, "HERE-->", *t);
+            ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_IDENTIFIER,
+                           "HERE-->%s", *t);
             return 0;
         }
         do {
@@ -112,8 +112,7 @@ static int parse_name(OPENSSL_CTX *ctx, const char *t[], int create,
     }
     name[i] = '\0';
     if (err) {
-        PROPerr(PROP_F_PARSE_NAME, PROP_R_NAME_TOO_LONG);
-        ERR_add_error_data(2, "HERE-->", *t);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_NAME_TOO_LONG, "HERE-->%s", *t);
         return 0;
     }
     *t = skip_space(s);
@@ -132,8 +131,8 @@ static int parse_number(const char *t[], PROPERTY_DEFINITION *res)
         v = v * 10 + (*s++ - '0');
     } while (ossl_isdigit(*s));
     if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
-        PROPerr(PROP_F_PARSE_NUMBER, PROP_R_NOT_A_DECIMAL_DIGIT);
-        ERR_add_error_data(2, "HERE-->", *t);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_A_DECIMAL_DIGIT,
+                       "HERE-->%s", *t);
         return 0;
     }
     *t = skip_space(s);
@@ -157,8 +156,8 @@ static int parse_hex(const char *t[], PROPERTY_DEFINITION *res)
             v += ossl_tolower(*s) - 'a';
     } while (ossl_isxdigit(*++s));
     if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
-        PROPerr(PROP_F_PARSE_HEX, PROP_R_NOT_AN_HEXADECIMAL_DIGIT);
-        ERR_add_error_data(2, "HERE-->", *t);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_HEXADECIMAL_DIGIT,
+                       "HERE-->%s", *t);
         return 0;
     }
     *t = skip_space(s);
@@ -178,8 +177,8 @@ static int parse_oct(const char *t[], PROPERTY_DEFINITION *res)
         v = (v << 3) + (*s - '0');
     } while (ossl_isdigit(*++s) && *s != '9' && *s != '8');
     if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
-        PROPerr(PROP_F_PARSE_OCT, PROP_R_NOT_AN_OCTAL_DIGIT);
-        ERR_add_error_data(2, "HERE-->", *t);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_OCTAL_DIGIT,
+                       "HERE-->%s", *t);
         return 0;
     }
     *t = skip_space(s);
@@ -204,18 +203,13 @@ static int parse_string(OPENSSL_CTX *ctx, const char *t[], char delim,
         s++;
     }
     if (*s == '\0') {
-        char buf[2] = { 0, 0 };
-
-        PROPerr(PROP_F_PARSE_STRING,
-                PROP_R_NO_MATCHING_STRING_DELIMETER);
-        buf[0] = delim;
-        ERR_add_error_data(3, "HERE-->", buf, *t);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_MATCHING_STRING_DELIMETER,
+                       "HERE-->%c%s", delim, *t);
         return 0;
     }
     v[i] = '\0';
     if (err) {
-        PROPerr(PROP_F_PARSE_STRING, PROP_R_STRING_TOO_LONG);
-        ERR_add_error_data(2, "HERE-->", *t);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t);
     } else {
         res->v.str_val = ossl_property_value(ctx, v, create);
     }
@@ -242,14 +236,13 @@ static int parse_unquoted(OPENSSL_CTX *ctx, const char *t[],
         s++;
     }
     if (!ossl_isspace(*s) && *s != '\0' && *s != ',') {
-        PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_NOT_AN_ASCII_CHARACTER);
-        ERR_add_error_data(2, "HERE-->", s);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_NOT_AN_ASCII_CHARACTER,
+                       "HERE-->%s", s);
         return 0;
     }
     v[i] = 0;
     if (err) {
-        PROPerr(PROP_F_PARSE_UNQUOTED, PROP_R_STRING_TOO_LONG);
-        ERR_add_error_data(2, "HERE-->", *t);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_STRING_TOO_LONG, "HERE-->%s", *t);
     } else {
         res->v.str_val = ossl_property_value(ctx, v, create);
     }
@@ -358,14 +351,14 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn)
             goto err;
         prop->oper = PROPERTY_OPER_EQ;
         if (prop->name_idx == 0) {
-            PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_PARSE_FAILED);
-            ERR_add_error_data(2, "Unknown name HERE-->", start);
+            ERR_raise_data(ERR_LIB_PROP, PROP_R_PARSE_FAILED,
+                           "Unknown name HERE-->%s", start);
             goto err;
         }
         if (match_ch(&s, '=')) {
             if (!parse_value(ctx, &s, prop, 1)) {
-                PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_NO_VALUE);
-                ERR_add_error_data(2, "HERE-->", start);
+                ERR_raise_data(ERR_LIB_PROP, PROP_R_NO_VALUE,
+                               "HERE-->%s", start);
                 goto err;
             }
         } else {
@@ -380,8 +373,8 @@ OSSL_PROPERTY_LIST *ossl_parse_property(OPENSSL_CTX *ctx, const char *defn)
         done = !match_ch(&s, ',');
     }
     if (*s != '\0') {
-        PROPerr(PROP_F_OSSL_PARSE_PROPERTY, PROP_R_TRAILING_CHARACTERS);
-        ERR_add_error_data(2, "HERE-->", s);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS,
+                       "HERE-->%s", s);
         goto err;
     }
     res = stack_to_property_list(sk);
@@ -442,8 +435,8 @@ skip_value:
         done = !match_ch(&s, ',');
     }
     if (*s != '\0') {
-        PROPerr(PROP_F_OSSL_PARSE_QUERY, PROP_R_TRAILING_CHARACTERS);
-        ERR_add_error_data(2, "HERE-->", s);
+        ERR_raise_data(ERR_LIB_PROP, PROP_R_TRAILING_CHARACTERS,
+                       "HERE-->%s", s);
         goto err;
     }
     res = stack_to_property_list(sk);
diff --git a/crypto/provider_core.c b/crypto/provider_core.c
index 385a632653..803406d7f7 100644
--- a/crypto/provider_core.c
+++ b/crypto/provider_core.c
@@ -225,9 +225,8 @@ OSSL_PROVIDER *ossl_provider_new(OPENSSL_CTX *libctx, const char *name,
 
     if ((prov = ossl_provider_find(libctx, name)) != NULL) { /* refcount +1 */
         ossl_provider_free(prov); /* refcount -1 */
-        CRYPTOerr(CRYPTO_F_OSSL_PROVIDER_NEW,
-                  CRYPTO_R_PROVIDER_ALREADY_EXISTS);
-        ERR_add_error_data(2, "name=", name);
+        ERR_raise_data(ERR_LIB_CRYPTO, CRYPTO_R_PROVIDER_ALREADY_EXISTS, NULL,
+                       "name=%s", name);
         return NULL;
     }
 
@@ -438,8 +437,8 @@ static int provider_activate(OSSL_PROVIDER *prov)
     if (prov->init_function == NULL
         || !prov->init_function(prov, core_dispatch, &provider_dispatch,
                                 &prov->provctx)) {
-        CRYPTOerr(CRYPTO_F_PROVIDER_ACTIVATE, ERR_R_INIT_FAIL);
-        ERR_add_error_data(2, "name=", prov->name);
+        ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_INIT_FAIL, NULL,
+                       "name=%s", prov->name);
 #ifndef FIPS_MODE
         DSO_free(prov->module);
         prov->module = NULL;
@@ -730,6 +729,21 @@ static const OSSL_PARAM param_types[] = {
     OSSL_PARAM_END
 };
 
+/*
+ * Forward declare all the functions that are provided aa dispatch.
+ * This ensures that the compiler will complain if they aren't defined
+ * with the correct signature.
+ */
+static OSSL_core_get_param_types_fn core_get_param_types;
+static OSSL_core_get_params_fn core_get_params;
+static OSSL_core_thread_start_fn core_thread_start;
+static OSSL_core_get_library_context_fn core_get_libctx;
+#ifndef FIPS_MODE
+static OSSL_core_new_error_fn core_new_error;
+static OSSL_core_set_error_debug_fn core_set_error_debug;
+static OSSL_core_vset_error_fn core_vset_error;
+#endif
+
 static const OSSL_PARAM *core_get_param_types(const OSSL_PROVIDER *prov)
 {
     return param_types;
@@ -758,7 +772,6 @@ static int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[])
     return 1;
 }
 
-static OSSL_core_get_library_context_fn core_get_libctx; /* Check */
 static OPENSSL_CTX *core_get_libctx(const OSSL_PROVIDER *prov)
 {
     return prov->libctx;
@@ -776,8 +789,26 @@ static int core_thread_start(const OSSL_PROVIDER *prov,
  * ones.
  */
 #ifndef FIPS_MODE
-static void core_put_error(const OSSL_PROVIDER *prov,
-                           uint32_t reason, const char *file, int line)
+/*
+ * TODO(3.0) These error functions should use |prov| to select the proper
+ * library context to report in the correct error stack, at least if error
+ * stacks become tied to the library context.
+ * We cannot currently do that since there's no support for it in the
+ * ERR subsystem.
+ */
+static void core_new_error(const OSSL_PROVIDER *prov)
+{
+    ERR_new();
+}
+
+static void core_set_error_debug(const OSSL_PROVIDER *prov,
+                                 const char *file, int line, const char *func)
+{
+    ERR_set_debug(file, line, func);
+}
+
+static void core_vset_error(const OSSL_PROVIDER *prov,
+                            uint32_t reason, const char *fmt, va_list args)
 {
     /*
      * If the uppermost 8 bits are non-zero, it's an OpenSSL library
@@ -785,27 +816,11 @@ static void core_put_error(const OSSL_PROVIDER *prov,
      * provider error and will be treated as such.
      */
     if (ERR_GET_LIB(reason) != 0) {
-        ERR_PUT_error(ERR_GET_LIB(reason),
-                      ERR_GET_FUNC(reason),
-                      ERR_GET_REASON(reason),
-                      file, line);
+        ERR_vset_error(ERR_GET_LIB(reason), ERR_GET_REASON(reason), fmt, args);
     } else {
-        ERR_PUT_error(prov->error_lib, 0, (int)reason, file, line);
+        ERR_vset_error(prov->error_lib, (int)reason, fmt, args);
     }
 }
-
-/*
- * TODO(3.0) This, as well as core_put_error above, should use |prov|
- * to select the proper library context to report in the correct error
- * stack, at least if error stacks become tied to the library context.
- * We cannot currently do that since there's no support for it in the
- * ERR subsystem.
- */
-static void core_add_error_vdata(const OSSL_PROVIDER *prov,
-                                 int num, va_list args)
-{
-    ERR_add_error_vdata(num, args);
-}
 #endif
 
 /*
@@ -818,8 +833,9 @@ static const OSSL_DISPATCH core_dispatch_[] = {
     { OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT, (void (*)(void))core_get_libctx },
     { OSSL_FUNC_CORE_THREAD_START, (void (*)(void))core_thread_start },
 #ifndef FIPS_MODE
-    { OSSL_FUNC_CORE_PUT_ERROR, (void (*)(void))core_put_error },
-    { OSSL_FUNC_CORE_ADD_ERROR_VDATA, (void (*)(void))core_add_error_vdata },
+    { OSSL_FUNC_CORE_NEW_ERROR, (void (*)(void))core_new_error },
+    { OSSL_FUNC_CORE_SET_ERROR_DEBUG, (void (*)(void))core_set_error_debug },
+    { OSSL_FUNC_CORE_VSET_ERROR, (void (*)(void))core_vset_error },
 #endif
 
     { OSSL_FUNC_CRYPTO_MALLOC, (void (*)(void))CRYPTO_malloc },
diff --git a/doc/man3/ERR_new.pod b/doc/man3/ERR_new.pod
new file mode 100644
index 0000000000..80419da2c4
--- /dev/null
+++ b/doc/man3/ERR_new.pod
@@ -0,0 +1,78 @@
+=pod
+
+=head1 NAME
+
+ERR_new, ERR_set_debug, ERR_set_error, ERR_vset_error
+- Error recording building blocks
+
+=head1 SYNOPSIS
+
+ #include <openssl/err.h>
+
+ void ERR_new(void);
+ void ERR_set_debug(const char *file, int line, const char *func);
+ void ERR_set_error(int lib, int reason, const char *fmt, ...);
+ void ERR_vset_error(int lib, int reason, const char *fmt, va_list args);
+
+=head1 DESCRIPTION
+
+The functions described here are generally not used directly, but
+rather through macros such as L<ERR_raise(3)>.
+They can still be useful for anyone that wants to make their own
+macros.
+
+ERR_new() allocates a new slot in the thread's error queue.
+
+ERR_set_debug() sets the debug information related to the current
+error in the thread's error queue.
+The values that can be given are the file name I<file>, line in the
+file I<line> and the name of the function I<func> where the error
+occured.
+The names must be constant, this function will only save away the
+pointers, not copy the strings.
+
+ERR_set_error() sets the error information, which are the library
+number I<lib> and the reason code I<reason>, and additional data as a
+format string I<fmt> and an arbitrary number of arguments.
+The additional data is processed with L<BIO_snprintf(3)> to form the
+additional data string, which is allocated and store in the error
+record.
+
+ERR_vset_error() works like ERR_set_error(), but takes a B<va_list>
+argument instead of a variable number of arguments.
+
+=head1 RETURN VALUES
+
+ERR_new, ERR_set_debug, ERR_set_error and ERR_vset_error
+do not return any values.
+
+=head1 NOTES
+
+The library number is unique to each unit that records errors.
+OpenSSL has a number of pre-allocated ones for its own uses, but
+others may allocate their own library number dynamically with
+L<ERR_get_next_error_library(3)>.
+
+Reason codes are unique within each library, and may have an
+associated set of strings as a short description of the reason.
+For dynamically allocated library numbers, reason strings are recorded
+with L<ERR_load_strings(3)>.
+
+Provider authors are supplied with core versions of these functions,
+see L<provider-base(7)>.
+
+=head1 SEE ALSO
+
+L<ERR_raise(3)>, L<ERR_get_next_error_library(3)>,
+L<ERR_load_strings(3)>, L<BIO_snprintf(3)>, L<provider-base(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2000-2019 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/ERR_put_error.pod b/doc/man3/ERR_put_error.pod
index c2913d5af4..729eb574ce 100644
--- a/doc/man3/ERR_put_error.pod
+++ b/doc/man3/ERR_put_error.pod
@@ -2,31 +2,41 @@
 
 =head1 NAME
 
-ERR_put_error, ERR_put_func_error,
-ERR_add_error_data, ERR_add_error_vdata - record an error
+ERR_raise, ERR_raise_data,
+ERR_put_error, ERR_add_error_data, ERR_add_error_vdata
+- record an error
 
 =head1 SYNOPSIS
 
  #include <openssl/err.h>
 
- void ERR_put_error(int lib, int func, int reason, const char *file, int line);
- void ERR_put_func_error(int lib, const char *func, int reason,
-                         const char *file, int line);
+ void ERR_raise(int lib, int reason);
+ void ERR_raise_data(int lib, int reason, const char *fmt, ...);
 
  void ERR_add_error_data(int num, ...);
  void ERR_add_error_vdata(int num, va_list arg);
 
+Deprecated since OpenSSL 3.0:
+
+ void ERR_put_error(int lib, int func, int reason, const char *file, int line);
+
 =head1 DESCRIPTION
 
+ERR_raise() adds a new error to the thread's error queue.  The
+error occured in the library B<lib> for the reason given by the
+B<reason> code.  Furthermore, the name of the file, the line, and name
+of the function where the error occured is saved with the error
+record.
+
+ERR_raise_data() does the same thing as ERR_raise(), but also lets the
+caller specify additional information as a format string B<fmt> and an
+arbitrary number of values, which are processed with L<BIO_snprintf(3)>.  
+
 ERR_put_error() adds an error code to the thread's error queue. It
 signals that the error of reason code B<reason> occurred in function
 B<func> of library B<lib>, in line number B<line> of B<file>.
 This function is usually called by a macro.
 
-ERR_put_func_err() is similar except that the B<func> is a string naming
-a function external to OpenSSL, usually provided by the platform on which
-OpenSSL and the application is running.
-
 ERR_add_error_data() associates the concatenation of its B<num> string
 arguments with the error code added last.
 ERR_add_error_vdata() is similar except the argument is a B<va_list>.
@@ -38,6 +48,8 @@ error messages for the error code.
 
 =head2 Reporting errors
 
+=for comment TODO(3.0) should this be internal documentation?
+
 Each sub-library has a specific macro XXXerr() that is used to report
 errors. Its first argument is a function code B<XXX_F_...>, the second
 argument is a reason code B<XXX_R_...>. Function codes are derived
@@ -64,8 +76,12 @@ the ASN1err() macro.
 
 =head1 RETURN VALUES
 
-ERR_put_error() and ERR_add_error_data() return
-no values.
+ERR_raise(), ERR_put_error(), ERR_add_error_data() and
+ERR_add_error_vdata() return no values.
+
+=head1 NOTES
+
+ERR_raise() and ERR_put_error() are implemented as macros.
 
 =head1 SEE ALSO
 
@@ -73,7 +89,7 @@ L<ERR_load_strings(3)>
 
 =head1 COPYRIGHT
 
-Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved.
+Copyright 2000-2019 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/doc/man7/provider-base.pod b/doc/man7/provider-base.pod
index e8e5d28560..aa1a3d634b 100644
--- a/doc/man7/provider-base.pod
+++ b/doc/man7/provider-base.pod
@@ -20,11 +20,12 @@ provider-base
  int core_get_params(const OSSL_PROVIDER *prov, OSSL_PARAM params[]);
  int core_thread_start(const OSSL_PROVIDER *prov,
                        OSSL_thread_stop_handler_fn handfn);
- void core_put_error(const OSSL_PROVIDER *prov,
-                     uint32_t reason, const char *file, int line);
- void core_add_error_vdata(const OSSL_PROVIDER *prov,
-                           int num, va_list args);
  OPENSSL_CTX *core_get_library_context(const OSSL_PROVIDER *prov);
+ void core_new_error(const OSSL_PROVIDER *prov);
+ void core_set_error_debug(const OSSL_PROVIDER *prov,
+                           const char *file, int line, const char *func);
+ void core_vset_error(const OSSL_PROVIDER *prov,
+                      uint32_t reason, const char *fmt, va_list args);
 
  /*
   * Some OpenSSL functionality is directly offered to providers via
@@ -89,9 +90,10 @@ provider):
  core_get_param_types           OSSL_FUNC_CORE_GET_PARAM_TYPES
  core_get_params                OSSL_FUNC_CORE_GET_PARAMS
  core_thread_start              OSSL_FUNC_CORE_THREAD_START
- core_put_error                 OSSL_FUNC_CORE_PUT_ERROR
- core_add_error_vdata           OSSL_FUNC_CORE_ADD_ERROR_VDATA
  core_get_library_context       OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT
+ core_new_error                 OSSL_FUNC_CORE_NEW_ERROR
+ core_set_error_debug           OSSL_FUNC_CORE_SET_ERROR_DEBUG
+ core_set_error                 OSSL_FUNC_CORE_SET_ERROR
  CRYPTO_malloc                  OSSL_FUNC_CRYPTO_MALLOC
  CRYPTO_zalloc                  OSSL_FUNC_CRYPTO_ZALLOC
  CRYPTO_memdup                  OSSL_FUNC_CRYPTO_MEMDUP
@@ -129,25 +131,47 @@ parameters.
 
 =for comment core_thread_start() TBA
 
-core_put_error() is used to report an error back to the core, with
+core_get_library_context() retrieves the library context in which the
+B<OSSL_PROVIDER> object I<prov> is stored.
+This may sometimes be useful if the provider wishes to store a
+reference to its context in the same library context.
+
+core_new_error(), core_set_error_debug() and core_set_error() are
+building blocks for reporting an error back to the core, with
 reference to the provider object I<prov>.
+
+=over 4
+
+=item core_new_error()
+
+allocates a new thread specific error record.
+
+This corresponds to the OpenSSL function L<ERR_new(3)>.
+
+=item core_set_error_debug()
+
+sets debugging information in the current thread specific error
+record.
+The debugging information includes the name of the file I<file>, the
+line I<line> and the function name I<func> where the error occured.
+
+This corresponds to the OpenSSL function L<ERR_set_debug(3)>.
+
+=item core_set_error()
+
+sets the I<reason> for the error, along with any addition data.
 The I<reason> is a number defined by the provider and used to index
 the reason strings table that's returned by
 provider_get_reason_strings().
+The additional data is given as a format string I<fmt> and a set of
+arguments I<args>, which are treated in the same manner as with
+BIO_vsnprintf().
 I<file> and I<line> may also be passed to indicate exactly where the
 error occured or was reported.
-This corresponds to the OpenSSL function L<ERR_put_error(3)>.
 
-core_add_error_vdata() is used to add additional text data to an
-error already reported with core_put_error().
-It takes I<num> strings in a B<va_list> and concatenates them.
-Provider authors will have to write the corresponding variadic
-argument function.
+This corresponds to the OpenSSL function L<ERR_vset_error(3)>.
 
-core_get_library_context() retrieves the library context in which the
-B<OSSL_PROVIDER> object I<prov> is stored.
-This may sometimes be useful if the provider wishes to store a
-reference to its context in the same library context.
+=back
 
 CRYPTO_malloc(), CRYPTO_zalloc(), CRYPTO_memdup(), CRYPTO_strdup(),
 CRYPTO_strndup(), CRYPTO_free(), CRYPTO_clear_free(),
diff --git a/engines/e_afalg_err.c b/engines/e_afalg_err.c
index c436f10a41..4db6d660c9 100644
--- a/engines/e_afalg_err.c
+++ b/engines/e_afalg_err.c
@@ -66,5 +66,6 @@ static void ERR_AFALG_error(int function, int reason, char *file, int line)
 {
     if (lib_code == 0)
         lib_code = ERR_get_next_error_library();
-    ERR_PUT_error(lib_code, function, reason, file, line);
+    ERR_raise(lib_code, reason);
+    ERR_set_debug(file, line, NULL);
 }
diff --git a/engines/e_capi_err.c b/engines/e_capi_err.c
index acbec41d08..e2b1f7561f 100644
--- a/engines/e_capi_err.c
+++ b/engines/e_capi_err.c
@@ -89,5 +89,6 @@ static void ERR_CAPI_error(int function, int reason, char *file, int line)
 {
     if (lib_code == 0)
         lib_code = ERR_get_next_error_library();
-    ERR_PUT_error(lib_code, function, reason, file, line);
+    ERR_raise(lib_code, reason);
+    ERR_set_debug(file, line, NULL);
 }
diff --git a/engines/e_dasync_err.c b/engines/e_dasync_err.c
index 0920690af6..a2e6c0dc86 100644
--- a/engines/e_dasync_err.c
+++ b/engines/e_dasync_err.c
@@ -51,5 +51,6 @@ static void ERR_DASYNC_error(int function, int reason, char *file, int line)
 {
     if (lib_code == 0)
         lib_code = ERR_get_next_error_library();
-    ERR_PUT_error(lib_code, function, reason, file, line);
+    ERR_raise(lib_code, reason);
+    ERR_set_debug(file, line, NULL);
 }
diff --git a/engines/e_ossltest_err.c b/engines/e_ossltest_err.c
index b81e00b43c..d9ee80cb83 100644
--- a/engines/e_ossltest_err.c
+++ b/engines/e_ossltest_err.c
@@ -51,5 +51,6 @@ static void ERR_OSSLTEST_error(int function, int reason, char *file, int line)
 {
     if (lib_code == 0)
         lib_code = ERR_get_next_error_library();
-    ERR_PUT_error(lib_code, function, reason, file, line);
+    ERR_raise(lib_code, reason);
+    ERR_set_debug(file, line, NULL);
 }
diff --git a/include/openssl/core_numbers.h b/include/openssl/core_numbers.h
index 3428ab59d9..0bbe92709c 100644
--- a/include/openssl/core_numbers.h
+++ b/include/openssl/core_numbers.h
@@ -66,17 +66,19 @@ OSSL_CORE_MAKE_FUNC(int,core_get_params,(const OSSL_PROVIDER *prov,
 # define OSSL_FUNC_CORE_THREAD_START           3
 OSSL_CORE_MAKE_FUNC(int,core_thread_start,(const OSSL_PROVIDER *prov,
                                            OSSL_thread_stop_handler_fn handfn))
-# define OSSL_FUNC_CORE_PUT_ERROR              4
-OSSL_CORE_MAKE_FUNC(void,core_put_error,
-                    (const OSSL_PROVIDER *prov,
-                     uint32_t reason, const char *file, int line))
-# define OSSL_FUNC_CORE_ADD_ERROR_VDATA        5
-OSSL_CORE_MAKE_FUNC(void,core_add_error_vdata,(const OSSL_PROVIDER *prov,
-                                               int num, va_list args))
-# define OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT    6
+# define OSSL_FUNC_CORE_GET_LIBRARY_CONTEXT    4
 OSSL_CORE_MAKE_FUNC(OPENSSL_CTX *,core_get_library_context,
                     (const OSSL_PROVIDER *prov))
-
+# define OSSL_FUNC_CORE_NEW_ERROR              5
+OSSL_CORE_MAKE_FUNC(void,core_new_error,(const OSSL_PROVIDER *prov))
+# define OSSL_FUNC_CORE_SET_ERROR_DEBUG        6
+OSSL_CORE_MAKE_FUNC(void,core_set_error_debug,
+                    (const OSSL_PROVIDER *prov,
+                     const char *file, int line, const char *func))
+# define OSSL_FUNC_CORE_VSET_ERROR             7
+OSSL_CORE_MAKE_FUNC(void,core_vset_error,
+                    (const OSSL_PROVIDER *prov,
+                     uint32_t reason, const char *fmt, va_list args))
 
 /* Memory allocation, freeing, clearing. */
 #define OSSL_FUNC_CRYPTO_MALLOC               10
diff --git a/include/openssl/err.h b/include/openssl/err.h
index e84bc68a4e..142321d2c8 100644
--- a/include/openssl/err.h
+++ b/include/openssl/err.h
@@ -50,6 +50,7 @@ typedef struct err_state_st {
     int err_data_flags[ERR_NUM_ERRORS];
     const char *err_file[ERR_NUM_ERRORS];
     int err_line[ERR_NUM_ERRORS];
+    const char *err_func[ERR_NUM_ERRORS];
     int top, bottom;
 } ERR_STATE;
 
@@ -107,49 +108,49 @@ typedef struct err_state_st {
 # define ERR_LIB_USER            128
 
 # if ! OPENSSL_API_3
-#  define SYSerr(f,r)  ERR_PUT_error(ERR_LIB_SYS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-#endif
-# define FUNCerr(f,r)  ERR_PUT_func_error(ERR_LIB_SYS,(f),(r),OPENSSL_FILE,OPENSSL_LINE)
-# define BNerr(f,r)   ERR_PUT_error(ERR_LIB_BN,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define RSAerr(f,r)  ERR_PUT_error(ERR_LIB_RSA,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define DHerr(f,r)   ERR_PUT_error(ERR_LIB_DH,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define EVPerr(f,r)  ERR_PUT_error(ERR_LIB_EVP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define BUFerr(f,r)  ERR_PUT_error(ERR_LIB_BUF,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define OBJerr(f,r)  ERR_PUT_error(ERR_LIB_OBJ,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PEMerr(f,r)  ERR_PUT_error(ERR_LIB_PEM,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define DSAerr(f,r)  ERR_PUT_error(ERR_LIB_DSA,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define X509err(f,r) ERR_PUT_error(ERR_LIB_X509,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ASN1err(f,r) ERR_PUT_error(ERR_LIB_ASN1,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CONFerr(f,r) ERR_PUT_error(ERR_LIB_CONF,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CRYPTOerr(f,r) ERR_PUT_error(ERR_LIB_CRYPTO,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ECerr(f,r)   ERR_PUT_error(ERR_LIB_EC,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define SSLerr(f,r)  ERR_PUT_error(ERR_LIB_SSL,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define BIOerr(f,r)  ERR_PUT_error(ERR_LIB_BIO,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PKCS7err(f,r) ERR_PUT_error(ERR_LIB_PKCS7,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define X509V3err(f,r) ERR_PUT_error(ERR_LIB_X509V3,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PKCS12err(f,r) ERR_PUT_error(ERR_LIB_PKCS12,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define RANDerr(f,r) ERR_PUT_error(ERR_LIB_RAND,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define DSOerr(f,r) ERR_PUT_error(ERR_LIB_DSO,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ENGINEerr(f,r) ERR_PUT_error(ERR_LIB_ENGINE,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define OCSPerr(f,r) ERR_PUT_error(ERR_LIB_OCSP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define UIerr(f,r) ERR_PUT_error(ERR_LIB_UI,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define COMPerr(f,r) ERR_PUT_error(ERR_LIB_COMP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ECDSAerr(f,r)  ERR_PUT_error(ERR_LIB_ECDSA,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ECDHerr(f,r)  ERR_PUT_error(ERR_LIB_ECDH,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define OSSL_STOREerr(f,r) ERR_PUT_error(ERR_LIB_OSSL_STORE,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define FIPSerr(f,r) ERR_PUT_error(ERR_LIB_FIPS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CMSerr(f,r) ERR_PUT_error(ERR_LIB_CMS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CRMFerr(f,r) ERR_PUT_error(ERR_LIB_CRMF,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CMPerr(f,r) ERR_PUT_error(ERR_LIB_CMP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define TSerr(f,r) ERR_PUT_error(ERR_LIB_TS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define HMACerr(f,r) ERR_PUT_error(ERR_LIB_HMAC,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define CTerr(f,r) ERR_PUT_error(ERR_LIB_CT,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ASYNCerr(f,r) ERR_PUT_error(ERR_LIB_ASYNC,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define KDFerr(f,r) ERR_PUT_error(ERR_LIB_KDF,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define SM2err(f,r) ERR_PUT_error(ERR_LIB_SM2,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define ESSerr(f,r) ERR_PUT_error(ERR_LIB_ESS,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PROPerr(f,r) ERR_PUT_error(ERR_LIB_PROP,0,(r),OPENSSL_FILE,OPENSSL_LINE)
-# define PROVerr(f,r) ERR_PUT_error(ERR_LIB_PROV,0,(r),OPENSSL_FILE,OPENSSL_LINE)
+#  define SYSerr(f,r)  ERR_raise(ERR_LIB_SYS,(r))
+# endif
+# define FUNCerr(f,r)  ERR_raise_data(ERR_LIB_SYS,(r),"calling function %s",(f))
+# define BNerr(f,r)   ERR_raise(ERR_LIB_RSA,(r))
+# define RSAerr(f,r)  ERR_raise(ERR_LIB_RSA,(r))
+# define DHerr(f,r)   ERR_raise(ERR_LIB_DH,(r))
+# define EVPerr(f,r)  ERR_raise(ERR_LIB_EVP,(r))
+# define BUFerr(f,r)  ERR_raise(ERR_LIB_BUF,(r))
+# define OBJerr(f,r)  ERR_raise(ERR_LIB_OBJ,(r))
+# define PEMerr(f,r)  ERR_raise(ERR_LIB_PEM,(r))
+# define DSAerr(f,r)  ERR_raise(ERR_LIB_DSA,(r))
+# define X509err(f,r) ERR_raise(ERR_LIB_X509,(r))
+# define ASN1err(f,r) ERR_raise(ERR_LIB_ASN1,(r))
+# define CONFerr(f,r) ERR_raise(ERR_LIB_CONF,(r))
+# define CRYPTOerr(f,r) ERR_raise(ERR_LIB_CRYPTO,(r))
+# define ECerr(f,r)   ERR_raise(ERR_LIB_EC,(r))
+# define SSLerr(f,r)  ERR_raise(ERR_LIB_SSL,(r))
+# define BIOerr(f,r)  ERR_raise(ERR_LIB_BIO,(r))
+# define PKCS7err(f,r) ERR_raise(ERR_LIB_PKCS7,(r))
+# define X509V3err(f,r) ERR_raise(ERR_LIB_X509V3,(r))
+# define PKCS12err(f,r) ERR_raise(ERR_LIB_PKCS12,(r))
+# define RANDerr(f,r) ERR_raise(ERR_LIB_RAND,(r))
+# define DSOerr(f,r) ERR_raise(ERR_LIB_DSO,(r))
+# define ENGINEerr(f,r) ERR_raise(ERR_LIB_ENGINE,(r))
+# define OCSPerr(f,r) ERR_raise(ERR_LIB_OCSP,(r))
+# define UIerr(f,r) ERR_raise(ERR_LIB_UI,(r))
+# define COMPerr(f,r) ERR_raise(ERR_LIB_COMP,(r))
+# define ECDSAerr(f,r)  ERR_raise(ERR_LIB_ECDSA,(r))
+# define ECDHerr(f,r)  ERR_raise(ERR_LIB_ECDH,(r))
+# define OSSL_STOREerr(f,r) ERR_raise(ERR_LIB_OSSL_STORE,(r))
+# define FIPSerr(f,r) ERR_raise(ERR_LIB_FIPS,(r))
+# define CMSerr(f,r) ERR_raise(ERR_LIB_CMS,(r))
+# define CRMFerr(f,r) ERR_raise(ERR_LIB_CRMF,(r))
+# define CMPerr(f,r) ERR_raise(ERR_LIB_CMP,(r))
+# define TSerr(f,r) ERR_raise(ERR_LIB_TS,(r))
+# define HMACerr(f,r) ERR_raise(ERR_LIB_HMAC,(r))
+# define CTerr(f,r) ERR_raise(ERR_LIB_CT,(r))
+# define ASYNCerr(f,r) ERR_raise(ERR_LIB_ASYNC,(r))
+# define KDFerr(f,r) ERR_raise(ERR_LIB_KDF,(r))
+# define SM2err(f,r) ERR_raise(ERR_LIB_SM2,(r))
+# define ESSerr(f,r) ERR_raise(ERR_LIB_ESS,(r))
+# define PROPerr(f,r) ERR_raise(ERR_LIB_PROP,(r))
+# define PROVerr(f,r) ERR_raise(ERR_LIB_PROV,(r))
 
 # define ERR_PACK(l,f,r) ( \
         (((unsigned int)(l) & 0x0FF) << 24L) | \
@@ -235,9 +236,30 @@ typedef struct ERR_string_data_st {
 
 DEFINE_LHASH_OF(ERR_STRING_DATA);
 
-void ERR_put_error(int lib, int func, int reason, const char *file, int line);
-void ERR_put_func_error(int lib, const char *func, int reason,
-                        const char *file, int line);
+/* 12 lines and some on an 80 column terminal */
+#define ERR_MAX_DATA_SIZE       1024
+
+/* Building blocks */
+void ERR_new(void);
+void ERR_set_debug(const char *file, int line, const char *func);
+void ERR_set_error(int lib, int reason, const char *fmt, ...);
+void ERR_vset_error(int lib, int reason, const char *fmt, va_list args);
+
+/* Main error raising functions */
+#define ERR_raise(lib, reason) ERR_raise_data((lib),(reason),NULL)
+#define ERR_raise_data                                          \
+    (ERR_new(),                                                 \
+     ERR_set_debug(OPENSSL_FILE,OPENSSL_LINE,OPENSSL_FUNC),     \
+     ERR_set_error)
+
+#if !OPENSSL_API_3
+/* Backward compatibility */
+#define ERR_put_error(lib, func, reason, file, line)            \
+    (ERR_new(),                                                 \
+     ERR_set_debug((file), (line), NULL),                       \
+     ERR_set_error((lib), (reason), NULL))
+#endif
+
 void ERR_set_error_data(char *data, int flags);
 
 unsigned long ERR_get_error(void);
diff --git a/include/openssl/opensslconf.h.in b/include/openssl/macros.h
similarity index 70%
copy from include/openssl/opensslconf.h.in
copy to include/openssl/macros.h
index b0d339ac9a..6b735b6b0b 100644
--- a/include/openssl/opensslconf.h.in
+++ b/include/openssl/macros.h
@@ -1,7 +1,5 @@
 /*
- * {- join("\n * ", @autowarntext) -}
- *
- * Copyright 2016-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2019 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
@@ -9,43 +7,8 @@
  * https://www.openssl.org/source/license.html
  */
 
-#include <openssl/opensslv.h>
-
-#ifndef HEADER_OPENSSLCONF_H
-# define HEADER_OPENSSLCONF_H
-
-# ifdef  __cplusplus
-extern "C" {
-# endif
-
-# ifdef OPENSSL_ALGORITHM_DEFINES
-#  error OPENSSL_ALGORITHM_DEFINES no longer supported
-# endif
-
-/*
- * OpenSSL was configured with the following options:
- */
-
-{- if (@{$config{openssl_sys_defines}}) {
-      foreach (@{$config{openssl_sys_defines}}) {
-	$OUT .= "# ifndef $_\n";
-	$OUT .= "#  define $_ 1\n";
-	$OUT .= "# endif\n";
-      }
-    }
-    foreach (@{$config{openssl_api_defines}}) {
-        (my $macro, my $value) = $_ =~ /^(.*?)=(.*?)$/;
-        $OUT .= "# define $macro $value\n";
-    }
-    if (@{$config{openssl_feature_defines}}) {
-      foreach (@{$config{openssl_feature_defines}}) {
-	$OUT .= "# ifndef $_\n";
-	$OUT .= "#  define $_\n";
-	$OUT .= "# endif\n";
-      }
-    }
-    "";
--}
+#ifndef OPENSSL_MACROS_H
+# define OPENSSL_MACROS_H
 
 /*
  * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers
@@ -162,23 +125,18 @@ extern "C" {
 #  endif
 # endif
 
-/* Generate 80386 code? */
-{- $config{processor} eq "386" ? "# define" : "# undef" -} I386_ONLY
-
-/*
- * The following are cipher-specific, but are part of the public API.
- */
-# if !defined(OPENSSL_SYS_UEFI)
-{- $config{bn_ll} ? "#  define" : "#  undef" -} BN_LLONG
-/* Only one for the following should be defined */
-{- $config{b64l} ? "#  define" : "#  undef" -} SIXTY_FOUR_BIT_LONG
-{- $config{b64}  ? "#  define" : "#  undef" -} SIXTY_FOUR_BIT
-{- $config{b32}  ? "#  define" : "#  undef" -} THIRTY_TWO_BIT
+# ifndef OPENSSL_FUNC
+#  if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+#   define OPENSSL_FUNC __func__
+#  elif defined(__STDC__) && defined(PEDANTIC)
+#   define OPENSSL_FUNC "(PEDANTIC disallows function name)"
+#  elif defined(_MSC_VER) || (defined(__GNUC__) && __GNUC__ >= 2)
+#   define OPENSSL_FUNC __FUNCTION__
+#  elif defined(__FUNCSIG__)
+#   define OPENSSL_FUNC __FUNCSIG__
+#  else
+#   define OPENSSL_FUNC "(unknown function)"
+#  endif
 # endif
 
-# define RC4_INT {- $config{rc4_int} -}
-
-# ifdef  __cplusplus
-}
-# endif
-#endif                          /* HEADER_OPENSSLCONF_H */
+#endif  /* OPENSSL_MACROS_H */
diff --git a/include/openssl/opensslconf.h.in b/include/openssl/opensslconf.h.in
index b0d339ac9a..5673b5b963 100644
--- a/include/openssl/opensslconf.h.in
+++ b/include/openssl/opensslconf.h.in
@@ -47,121 +47,6 @@ extern "C" {
     "";
 -}
 
-/*
- * Sometimes OPENSSSL_NO_xxx ends up with an empty file and some compilers
- * don't like that.  This will hopefully silence them.
- */
-# define NON_EMPTY_TRANSLATION_UNIT static void *dummy = &dummy;
-
-/*
- * Applications should use -DOPENSSL_API_COMPAT=<version> to suppress the
- * declarations of functions deprecated in or before <version>.  If this is
- * undefined, the value of the macro OPENSSL_API_MIN above is the default.
- *
- * For any version number up until version 1.1.x, <version> is expected to be
- * the calculated version number 0xMNNFFPPSL.  For version numbers 3.0.0 and
- * on, <version> is expected to be only the major version number (i.e. 3 for
- * version 3.0.0).
- */
-# ifndef DECLARE_DEPRECATED
-#  define DECLARE_DEPRECATED(f)   f;
-#  ifdef __GNUC__
-#   if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 0)
-#    undef DECLARE_DEPRECATED
-#    define DECLARE_DEPRECATED(f)    f __attribute__ ((deprecated));
-#   endif
-#  endif
-# endif
-
-/*
- * We convert the OPENSSL_API_COMPAT value to an API level.  The API level
- * is the major version number for 3.0.0 and on.  For earlier versions, it
- * uses this scheme, which is close enough for our purposes:
- *
- *      0.x.y   0       (0.9.8 was the last release in this series)
- *      1.0.x   1       (1.0.2 was the last release in this series)
- *      1.1.x   2       (1.1.1 was the last release in this series)
- */
-
-/* In case someone defined both */
-# if defined(OPENSSL_API_COMPAT) && defined(OPENSSL_API_LEVEL)
-#  error "Disallowed to define both OPENSSL_API_COMPAT and OPENSSL_API_LEVEL"
-# endif
-
-# ifndef OPENSSL_API_COMPAT
-#  define OPENSSL_API_LEVEL OPENSSL_MIN_API
-# else
-#  if (OPENSSL_API_COMPAT < 0x1000L) /* Major version numbers up to 16777215 */
-#   define OPENSSL_API_LEVEL OPENSSL_API_COMPAT
-#  elif (OPENSSL_API_COMPAT & 0xF0000000L) == 0x00000000L
-#   define OPENSSL_API_LEVEL 0
-#  elif (OPENSSL_API_COMPAT & 0xFFF00000L) == 0x10000000L
-#   define OPENSSL_API_LEVEL 1
-#  elif (OPENSSL_API_COMPAT & 0xFFF00000L) == 0x10100000L
-#   define OPENSSL_API_LEVEL 2
-#  else
-    /* Major number 3 to 15 */
-#   define OPENSSL_API_LEVEL ((OPENSSL_API_COMPAT >> 28) & 0xF)
-#  endif
-# endif
-
-/*
- * Do not deprecate things to be deprecated in version 4.0 before the
- * OpenSSL version number matches.
- */
-# if OPENSSL_VERSION_MAJOR < 4
-#  define DEPRECATEDIN_4(f)       f;
-#  define OPENSSL_API_4 0
-# elif OPENSSL_API_LEVEL < 4
-#  define DEPRECATEDIN_4(f)       DECLARE_DEPRECATED(f)
-#  define OPENSSL_API_4 0
-# else
-#  define DEPRECATEDIN_4(f)
-#  define OPENSSL_API_4 1
-# endif
-
-# if OPENSSL_API_LEVEL < 3
-#  define DEPRECATEDIN_3(f)       DECLARE_DEPRECATED(f)
-#  define OPENSSL_API_3 0
-# else
-#  define DEPRECATEDIN_3(f)
-#  define OPENSSL_API_3 1
-# endif
-
-# if OPENSSL_API_LEVEL < 2
-#  define DEPRECATEDIN_1_1_0(f)   DECLARE_DEPRECATED(f)
-#  define OPENSSL_API_1_1_0 0
-# else
-#  define DEPRECATEDIN_1_1_0(f)
-#  define OPENSSL_API_1_1_0 1
-# endif
-
-# if OPENSSL_API_LEVEL < 1
-#  define DEPRECATEDIN_1_0_0(f)   DECLARE_DEPRECATED(f)
-#  define OPENSSL_API_1_0_0 0
-# else
-#  define DEPRECATEDIN_1_0_0(f)
-#  define OPENSSL_API_1_0_0 1
-# endif
-
-# if OPENSSL_API_LEVEL < 0
-#  define DEPRECATEDIN_0_9_8(f)   DECLARE_DEPRECATED(f)
-#  define OPENSSL_API_0_9_8 0
-# else
-#  define DEPRECATEDIN_0_9_8(f)
-#  define OPENSSL_API_0_9_8 1
-# endif
-
-# ifndef OPENSSL_FILE
-#  ifdef OPENSSL_NO_FILENAMES
-#   define OPENSSL_FILE ""
-#   define OPENSSL_LINE 0
-#  else
-#   define OPENSSL_FILE __FILE__
-#   define OPENSSL_LINE __LINE__
-#  endif
-# endif
-
 /* Generate 80386 code? */
 {- $config{processor} eq "386" ? "# define" : "# undef" -} I386_ONLY
 
@@ -178,6 +63,8 @@ extern "C" {
 
 # define RC4_INT {- $config{rc4_int} -}
 
+#include <openssl/macros.h>
+
 # ifdef  __cplusplus
 }
 # endif
diff --git a/providers/fips/fipsprov.c b/providers/fips/fipsprov.c
index 4c010c895e..b62bfeec39 100644
--- a/providers/fips/fipsprov.c
+++ b/providers/fips/fipsprov.c
@@ -39,8 +39,9 @@ extern OSSL_core_thread_start_fn *c_thread_start;
 static OSSL_core_get_param_types_fn *c_get_param_types;
 static OSSL_core_get_params_fn *c_get_params;
 OSSL_core_thread_start_fn *c_thread_start;
-static OSSL_core_put_error_fn *c_put_error;
-static OSSL_core_add_error_vdata_fn *c_add_error_vdata;
+static OSSL_core_new_error_fn *c_new_error;
+static OSSL_core_set_error_debug_fn *c_set_error_debug;
+static OSSL_core_vset_error_fn *c_vset_error;
 static OSSL_CRYPTO_malloc_fn *c_CRYPTO_malloc;
 static OSSL_CRYPTO_zalloc_fn *c_CRYPTO_zalloc;
 static OSSL_CRYPTO_free_fn *c_CRYPTO_free;
@@ -305,11 +306,14 @@ int OSSL_provider_init(const OSSL_PROVIDER *provider,
         case OSSL_FUNC_CORE_THREAD_START:
             c_thread_start = OSSL_get_core_thread_start(in);
             break;
-        case OSSL_FUNC_CORE_PUT_ERROR:
-            c_put_error = OSSL_get_core_put_error(in);
+        case OSSL_FUNC_CORE_NEW_ERROR:
+            c_new_error = OSSL_get_core_new_error(in);
             break;
-        case OSSL_FUNC_CORE_ADD_ERROR_VDATA:
-            c_add_error_vdata = OSSL_get_core_add_error_vdata(in);
+        case OSSL_FUNC_CORE_SET_ERROR_DEBUG:
+            c_set_error_debug = OSSL_get_core_set_error_debug(in);
+            break;
+        case OSSL_FUNC_CORE_VSET_ERROR:
+            c_vset_error = OSSL_get_core_vset_error(in);
             break;
         case OSSL_FUNC_CRYPTO_MALLOC:
             c_CRYPTO_malloc = OSSL_get_CRYPTO_malloc(in);
@@ -416,29 +420,28 @@ int fips_intern_provider_init(const OSSL_PROVIDER *provider,
     return 1;
 }
 
-void ERR_put_error(int lib, int func, int reason, const char *file, int line)
+void ERR_new(void)
 {
-    /*
-     * TODO(3.0) the first argument is currently NULL but is expected to
-     * be passed something else in the future, either an OSSL_PROVIDER or
-     * a OPENSSL_CTX pointer.
-     */
-    c_put_error(NULL, ERR_PACK(lib, func, reason), file, line);
-    ERR_add_error_data(1, "(in the FIPS module)");
+    c_new_error(NULL);
+}
+
+void ERR_set_debug(const char *file, int line, const char *func)
+{
+    c_set_error_debug(NULL, file, line, func);
 }
 
-void ERR_add_error_data(int num, ...)
+void ERR_set_error(int lib, int reason, const char *fmt, ...)
 {
     va_list args;
 
-    va_start(args, num);
-    ERR_add_error_vdata(num, args);
+    va_start(args, fmt);
+    c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args);
     va_end(args);
 }
 
-void ERR_add_error_vdata(int num, va_list args)
+void ERR_vset_error(int lib, int reason, const char *fmt, va_list args)
 {
-    c_add_error_vdata(NULL, num, args);
+    c_vset_error(NULL, ERR_PACK(lib, 0, reason), fmt, args);
 }
 
 const OSSL_PROVIDER *FIPS_get_provider(OPENSSL_CTX *ctx)
diff --git a/ssl/statem/statem.c b/ssl/statem/statem.c
index a35573c935..bd9277b71e 100644
--- a/ssl/statem/statem.c
+++ b/ssl/statem/statem.c
@@ -118,7 +118,8 @@ void ossl_statem_set_renegotiate(SSL *s)
 void ossl_statem_fatal(SSL *s, int al, int func, int reason, const char *file,
                        int line)
 {
-    ERR_put_error(ERR_LIB_SSL, func, reason, file, line);
+    ERR_raise(ERR_LIB_SSL, reason);
+    ERR_set_debug(file, line, NULL); /* Override what ERR_raise set */
     /* We shouldn't call SSLfatal() twice. Once is enough */
     if (s->statem.in_init && s->statem.state == MSG_FLOW_ERROR)
       return;
diff --git a/test/errtest.c b/test/errtest.c
index 88ff860092..1a18335b6e 100644
--- a/test/errtest.c
+++ b/test/errtest.c
@@ -47,12 +47,14 @@ static int vdata_appends(void)
 /* Test that setting a platform error sets the right values. */
 static int platform_error(void)
 {
-    const char *file = __FILE__, *f, *data;
-    const int line = __LINE__;
+    const char *file, *f, *data;
+    int line;
     int l;
     unsigned long e;
 
-    ERR_put_func_error(ERR_LIB_SYS, "exit", ERR_R_INTERNAL_ERROR, file, line);
+    file = __FILE__;
+    line = __LINE__ + 1; /* The error is generated on the next line */
+    FUNCerr("exit", ERR_R_INTERNAL_ERROR);
     if (!TEST_ulong_ne(e = ERR_get_error_line_data(&f, &l, &data, NULL), 0)
             || !TEST_int_eq(ERR_GET_REASON(e), ERR_R_INTERNAL_ERROR)
             || !TEST_int_eq(l, line)
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 81462480ca..a6c5097e1c 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -998,7 +998,7 @@ OPENSSL_LH_get_down_load                1023	3_0_0	EXIST::FUNCTION:
 EVP_md4                                 1024	3_0_0	EXIST::FUNCTION:MD4
 X509_set_subject_name                   1025	3_0_0	EXIST::FUNCTION:
 i2d_PKCS8PrivateKey_nid_bio             1026	3_0_0	EXIST::FUNCTION:
-ERR_put_error                           1027	3_0_0	EXIST::FUNCTION:
+ERR_put_error                           1027	3_0_0	NOEXIST::FUNCTION:
 ERR_add_error_data                      1028	3_0_0	EXIST::FUNCTION:
 X509_ALGORS_it                          1029	3_0_0	EXIST::FUNCTION:
 MD5_Update                              1030	3_0_0	EXIST::FUNCTION:MD5
@@ -4690,7 +4690,7 @@ EVP_KEYMGMT_up_ref                      4795	3_0_0	EXIST::FUNCTION:
 EVP_KEYMGMT_free                        4796	3_0_0	EXIST::FUNCTION:
 EVP_KEYMGMT_provider                    4797	3_0_0	EXIST::FUNCTION:
 X509_PUBKEY_dup                         4798	3_0_0	EXIST::FUNCTION:
-ERR_put_func_error                      4799	3_0_0	EXIST::FUNCTION:
+ERR_put_func_error                      4799	3_0_0	NOEXIST::FUNCTION:
 EVP_MD_name                             4800	3_0_0	EXIST::FUNCTION:
 EVP_CIPHER_name                         4801	3_0_0	EXIST::FUNCTION:
 EVP_MD_provider                         4802	3_0_0	EXIST::FUNCTION:
@@ -4700,3 +4700,7 @@ EVP_CIPHER_do_all_ex                    4805	3_0_0	EXIST::FUNCTION:
 EVP_MD_do_all_ex                        4806	3_0_0	EXIST::FUNCTION:
 EVP_KEYEXCH_provider                    4807	3_0_0	EXIST::FUNCTION:
 OSSL_PROVIDER_available                 4808	3_0_0	EXIST::FUNCTION:
+ERR_new                                 4809	3_0_0	EXIST::FUNCTION:
+ERR_set_debug                           4810	3_0_0	EXIST::FUNCTION:
+ERR_set_error                           4811	3_0_0	EXIST::FUNCTION:
+ERR_vset_error                          4812	3_0_0	EXIST::FUNCTION:
diff --git a/util/mkerr.pl b/util/mkerr.pl
index 956b66179a..51e034703d 100755
--- a/util/mkerr.pl
+++ b/util/mkerr.pl
@@ -650,7 +650,8 @@ ${st}void ERR_${lib}_error(int function, int reason, char *file, int line)
 {
     if (lib_code == 0)
         lib_code = ERR_get_next_error_library();
-    ERR_PUT_error(lib_code, function, reason, file, line);
+    ERR_raise(lib_code, reason);
+    ERR_set_debug(file, line, NULL);
 }
 EOF
 
diff --git a/util/private.num b/util/private.num
index 1e76dfb43c..82cb72e606 100644
--- a/util/private.num
+++ b/util/private.num
@@ -195,7 +195,10 @@ ERR_GET_LIB                             define
 ERR_GET_REASON                          define
 ERR_PACK                                define
 ERR_free_strings                        define deprecated 1.1.0
+ERR_put_error                           define deprecated 3.0
 ERR_load_crypto_strings                 define deprecated 1.1.0
+ERR_raise                               define
+ERR_raise_data                          define
 EVP_DigestSignUpdate                    define
 EVP_DigestVerifyUpdate                  define
 EVP_KDF_name                            define


More information about the openssl-commits mailing list