Rename <openssl/core_numbers.h> -> <openssl/core_dispatch.h>
[oweals/openssl.git] / crypto / initthread.c
index b3f45b9dc49c6f447b42a0ad20b7fe1339f3bf7b..23b34966a564ced1e6bb5b4cd8a74b36d1dbf0be 100644 (file)
@@ -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,12 +8,12 @@
  */
 
 #include <openssl/crypto.h>
-#include <openssl/core_numbers.h>
-#include "internal/cryptlib_int.h"
-#include "internal/providercommon.h"
+#include <openssl/core_dispatch.h>
+#include "crypto/cryptlib.h"
+#include "prov/providercommon.h"
 #include "internal/thread_once.h"
 
-#ifdef FIPS_MODE
+#ifdef FIPS_MODULE
 /*
  * Thread aware code may want to be told about thread stop events. We register
  * to hear about those thread stop events when we see a new thread has started.
@@ -37,7 +37,7 @@ struct thread_event_handler_st {
     THREAD_EVENT_HANDLER *next;
 };
 
-#ifndef FIPS_MODE
+#ifndef FIPS_MODULE
 DEFINE_SPECIAL_STACK_OF(THREAD_EVENT_HANDLER_PTR, THREAD_EVENT_HANDLER *)
 
 typedef struct global_tevent_register_st GLOBAL_TEVENT_REGISTER;
@@ -77,6 +77,12 @@ static GLOBAL_TEVENT_REGISTER *get_global_tevent_register(void)
 }
 #endif
 
+#ifndef FIPS_MODULE
+static int  init_thread_push_handlers(THREAD_EVENT_HANDLER **hands);
+static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin);
+static void init_thread_destructor(void *hands);
+static int  init_thread_deregister(void *arg, int all);
+#endif
 static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands);
 
 static THREAD_EVENT_HANDLER **
@@ -86,40 +92,22 @@ init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep)
 
     if (alloc) {
         if (hands == NULL) {
-#ifndef FIPS_MODE
-            GLOBAL_TEVENT_REGISTER *gtr;
-#endif
 
-            if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL) {
-                OPENSSL_free(hands);
+            if ((hands = OPENSSL_zalloc(sizeof(*hands))) == NULL)
                 return NULL;
-            }
 
-#ifndef FIPS_MODE
-            /*
-             * The thread event handler is thread specific and is a linked
-             * list of all handler functions that should be called for the
-             * current thread. We also keep a global reference to that linked
-             * list, so that we can deregister handlers if necessary before all
-             * the threads are stopped.
-             */
-            gtr = get_global_tevent_register();
-            if (gtr == NULL) {
+            if (!CRYPTO_THREAD_set_local(local, hands)) {
                 OPENSSL_free(hands);
                 return NULL;
             }
-            CRYPTO_THREAD_write_lock(gtr->lock);
-            if (!sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands)) {
+
+#ifndef FIPS_MODULE
+            if (!init_thread_push_handlers(hands)) {
+                CRYPTO_THREAD_set_local(local, NULL);
                 OPENSSL_free(hands);
-                CRYPTO_THREAD_unlock(gtr->lock);
                 return NULL;
             }
-            CRYPTO_THREAD_unlock(gtr->lock);
 #endif
-            if (!CRYPTO_THREAD_set_local(local, hands)) {
-                OPENSSL_free(hands);
-                return NULL;
-            }
         }
     } else if (!keep) {
         CRYPTO_THREAD_set_local(local, NULL);
@@ -128,7 +116,7 @@ init_get_thread_local(CRYPTO_THREAD_LOCAL *local, int alloc, int keep)
     return hands;
 }
 
-#ifndef FIPS_MODE
+#ifndef FIPS_MODULE
 /*
  * Since per-thread-specific-data destructors are not universally
  * available, i.e. not on Windows, only below CRYPTO_THREAD_LOCAL key
@@ -148,6 +136,32 @@ static union {
     CRYPTO_THREAD_LOCAL value;
 } destructor_key = { -1 };
 
+/*
+ * The thread event handler list is a thread specific linked list
+ * of callback functions which are invoked in list order by the
+ * current thread in case of certain events. (Currently, there is
+ * only one type of event, the 'thread stop' event.)
+ *
+ * We also keep a global reference to that linked list, so that we
+ * can deregister handlers if necessary before all the threads are
+ * stopped.
+ */
+static int init_thread_push_handlers(THREAD_EVENT_HANDLER **hands)
+{
+    int ret;
+    GLOBAL_TEVENT_REGISTER *gtr;
+
+    gtr = get_global_tevent_register();
+    if (gtr == NULL)
+        return 0;
+
+    CRYPTO_THREAD_write_lock(gtr->lock);
+    ret = (sk_THREAD_EVENT_HANDLER_PTR_push(gtr->skhands, hands) != 0);
+    CRYPTO_THREAD_unlock(gtr->lock);
+
+    return ret;
+}
+
 static void init_thread_remove_handlers(THREAD_EVENT_HANDLER **handsin)
 {
     GLOBAL_TEVENT_REGISTER *gtr;
@@ -187,8 +201,6 @@ int ossl_init_thread(void)
     return 1;
 }
 
-static int init_thread_deregister(void *arg, int all);
-
 void ossl_cleanup_thread(void)
 {
     init_thread_deregister(NULL, 1);
@@ -280,12 +292,12 @@ void ossl_ctx_thread_stop(void *arg)
     init_thread_stop(arg, hands);
     OPENSSL_free(hands);
 }
-#endif /* FIPS_MODE */
+#endif /* FIPS_MODULE */
 
 
 static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands)
 {
-    THREAD_EVENT_HANDLER *curr, *prev = NULL;
+    THREAD_EVENT_HANDLER *curr, *prev = NULL, *tmp;
 
     /* Can't do much about this */
     if (hands == NULL)
@@ -294,15 +306,20 @@ static void init_thread_stop(void *arg, THREAD_EVENT_HANDLER **hands)
     curr = *hands;
     while (curr != NULL) {
         if (arg != NULL && curr->arg != arg) {
+            prev = curr;
             curr = curr->next;
             continue;
         }
         curr->handfn(curr->arg);
-        prev = curr;
+        if (prev == NULL)
+            *hands = curr->next;
+        else
+            prev->next = curr->next;
+
+        tmp = curr;
         curr = curr->next;
-        if (prev == *hands)
-            *hands = curr;
-        OPENSSL_free(prev);
+
+        OPENSSL_free(tmp);
     }
 }
 
@@ -311,7 +328,7 @@ int ossl_init_thread_start(const void *index, void *arg,
 {
     THREAD_EVENT_HANDLER **hands;
     THREAD_EVENT_HANDLER *hand;
-#ifdef FIPS_MODE
+#ifdef FIPS_MODULE
     OPENSSL_CTX *ctx = arg;
 
     /*
@@ -336,14 +353,14 @@ int ossl_init_thread_start(const void *index, void *arg,
     if (hands == NULL)
         return 0;
 
-#ifdef FIPS_MODE
+#ifdef FIPS_MODULE
     if (*hands == NULL) {
         /*
          * We've not yet registered any handlers for this thread. We need to get
          * libcrypto to tell us about later thread stop events. c_thread_start
          * is a callback to libcrypto defined in fipsprov.c
          */
-        if (!c_thread_start(FIPS_get_provider(ctx), ossl_ctx_thread_stop))
+        if (!c_thread_start(FIPS_get_core_handle(ctx), ossl_ctx_thread_stop))
             return 0;
     }
 #endif
@@ -361,13 +378,15 @@ int ossl_init_thread_start(const void *index, void *arg,
     return 1;
 }
 
-#ifndef FIPS_MODE
+#ifndef FIPS_MODULE
 static int init_thread_deregister(void *index, int all)
 {
     GLOBAL_TEVENT_REGISTER *gtr;
     int i;
 
     gtr = get_global_tevent_register();
+    if (gtr == NULL)
+        return 0;
     if (!all)
         CRYPTO_THREAD_write_lock(gtr->lock);
     for (i = 0; i < sk_THREAD_EVENT_HANDLER_PTR_num(gtr->skhands); i++) {