summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorČestmír Kalina <ckalina@redhat.com>2021-09-27 22:42:11 +0200
committerMatt Caswell <matt@openssl.org>2022-10-17 09:45:39 +0100
commit4574a7fd8dda070b129d76defca07703cab53842 (patch)
treea6e03446b0f784e550010a2c51efe5b7861e9473 /include
parentb1372197496650c3cb318cade911a3bd6af14adc (diff)
crypto: add preemptive threading support
Some primitives are designed to be used in a multi-threaded environment, if supported, e.g., Argon2. This patch adds support for preemptive threading and basic synchronization primitives for platforms compliant with POSIX threads or Windows CRT. Native functions are wrapped to provide a common (internal) API. Threading support can be disabled at compile time. If enabled, threading is disabled by default and needs to be explicitly enabled by the user. Thread enablement requires an explicit limit on the number of threads that OpenSSL may spawn (non-negative integer/infinity). The limit may be changed. Signed-off-by: Čestmír Kalina <ckalina@redhat.com> Reviewed-by: Hugo Landau <hlandau@openssl.org> Reviewed-by: Matt Caswell <matt@openssl.org> (Merged from https://github.com/openssl/openssl/pull/12255)
Diffstat (limited to 'include')
-rw-r--r--include/crypto/context.h6
-rw-r--r--include/internal/cryptlib.h3
-rw-r--r--include/internal/thread.h39
-rw-r--r--include/internal/thread_arch.h119
-rw-r--r--include/openssl/thread.h23
5 files changed, 189 insertions, 1 deletions
diff --git a/include/crypto/context.h b/include/crypto/context.h
index 143f6d6b6d..950d6f11e4 100644
--- a/include/crypto/context.h
+++ b/include/crypto/context.h
@@ -23,6 +23,9 @@ void *ossl_self_test_set_callback_new(OSSL_LIB_CTX *);
void *ossl_rand_crng_ctx_new(OSSL_LIB_CTX *);
void *ossl_thread_event_ctx_new(OSSL_LIB_CTX *);
void *ossl_fips_prov_ossl_ctx_new(OSSL_LIB_CTX *);
+#if defined(OPENSSL_THREADS)
+void *ossl_threads_ctx_new(OSSL_LIB_CTX *);
+#endif
void ossl_provider_store_free(void *);
void ossl_property_string_data_free(void *);
@@ -38,3 +41,6 @@ void ossl_self_test_set_callback_free(void *);
void ossl_rand_crng_ctx_free(void *);
void ossl_thread_event_ctx_free(void *);
void ossl_fips_prov_ossl_ctx_free(void *);
+#if defined(OPENSSL_THREADS)
+void ossl_threads_ctx_free(void *);
+#endif
diff --git a/include/internal/cryptlib.h b/include/internal/cryptlib.h
index 71b6b125f3..700f387531 100644
--- a/include/internal/cryptlib.h
+++ b/include/internal/cryptlib.h
@@ -116,7 +116,8 @@ typedef struct ossl_ex_data_global_st {
# define OSSL_LIB_CTX_PROVIDER_CONF_INDEX 16
# define OSSL_LIB_CTX_BIO_CORE_INDEX 17
# define OSSL_LIB_CTX_CHILD_PROVIDER_INDEX 18
-# define OSSL_LIB_CTX_MAX_INDEXES 19
+# define OSSL_LIB_CTX_THREAD_INDEX 19
+# define OSSL_LIB_CTX_MAX_INDEXES 20
OSSL_LIB_CTX *ossl_lib_ctx_get_concrete(OSSL_LIB_CTX *ctx);
int ossl_lib_ctx_is_default(OSSL_LIB_CTX *ctx);
diff --git a/include/internal/thread.h b/include/internal/thread.h
new file mode 100644
index 0000000000..8c5bad7763
--- /dev/null
+++ b/include/internal/thread.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2019-2021 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
+ */
+
+#ifndef OPENSSL_INTERNAL_THREAD_H
+# define OPENSSL_INTERNAL_THREAD_H
+# include <openssl/configuration.h>
+# include <internal/thread_arch.h>
+# include <openssl/e_os2.h>
+# include <openssl/types.h>
+# include <internal/cryptlib.h>
+# include "crypto/context.h"
+
+void *ossl_crypto_thread_start(OSSL_LIB_CTX *ctx, CRYPTO_THREAD_ROUTINE start,
+ void *data);
+int ossl_crypto_thread_join(void *task, CRYPTO_THREAD_RETVAL *retval);
+int ossl_crypto_thread_clean(void *vhandle);
+uint64_t ossl_get_avail_threads(OSSL_LIB_CTX *ctx);
+
+# if defined(OPENSSL_THREADS)
+
+# define OSSL_LIB_CTX_GET_THREADS(CTX) \
+ ossl_lib_ctx_get_data(CTX, OSSL_LIB_CTX_THREAD_INDEX);
+
+typedef struct openssl_threads_st {
+ uint64_t max_threads;
+ uint64_t active_threads;
+ CRYPTO_MUTEX *lock;
+ CRYPTO_CONDVAR *cond_finished;
+} OSSL_LIB_CTX_THREADS;
+
+# endif /* defined(OPENSSL_THREADS) */
+
+#endif /* OPENSSL_INTERNAL_THREAD_H */
diff --git a/include/internal/thread_arch.h b/include/internal/thread_arch.h
new file mode 100644
index 0000000000..fcf312ff14
--- /dev/null
+++ b/include/internal/thread_arch.h
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2019-2021 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
+ */
+
+#ifndef OSSL_INTERNAL_THREAD_ARCH_H
+# define OSSL_INTERNAL_THREAD_ARCH_H
+# include <openssl/configuration.h>
+# include <openssl/e_os2.h>
+
+# if defined(_WIN32)
+# include <windows.h>
+# endif
+
+# if defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_UNIX)
+# define OPENSSL_THREADS_POSIX
+# elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_WINDOWS) && \
+ defined(_WIN32_WINNT)
+# if _WIN32_WINNT >= 0x0600
+# define OPENSSL_THREADS_WINNT
+# else
+# define OPENSSL_THREADS_NONE
+# endif
+# else
+# define OPENSSL_THREADS_NONE
+# endif
+
+# include <openssl/crypto.h>
+
+typedef void CRYPTO_MUTEX;
+typedef void CRYPTO_CONDVAR;
+
+CRYPTO_MUTEX *ossl_crypto_mutex_new(void);
+void ossl_crypto_mutex_lock(CRYPTO_MUTEX *mutex);
+int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX *mutex);
+void ossl_crypto_mutex_unlock(CRYPTO_MUTEX *mutex);
+void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex);
+
+CRYPTO_CONDVAR *ossl_crypto_condvar_new(void);
+void ossl_crypto_condvar_wait(CRYPTO_CONDVAR *cv, CRYPTO_MUTEX *mutex);
+void ossl_crypto_condvar_broadcast(CRYPTO_CONDVAR *cv);
+void ossl_crypto_condvar_free(CRYPTO_CONDVAR **cv);
+
+typedef uint32_t CRYPTO_THREAD_RETVAL;
+typedef CRYPTO_THREAD_RETVAL (*CRYPTO_THREAD_ROUTINE)(void *);
+typedef CRYPTO_THREAD_RETVAL (*CRYPTO_THREAD_ROUTINE_CB)(void *,
+ void (**)(void *),
+ void **);
+
+# define CRYPTO_THREAD_NO_STATE 0UL
+# define CRYPTO_THREAD_FINISHED (1UL << 1)
+# define CRYPTO_THREAD_JOINED (1UL << 2)
+# define CRYPTO_THREAD_TERMINATED (1UL << 3)
+
+# define CRYPTO_THREAD_GET_STATE(THREAD, FLAG) ((THREAD)->state & (FLAG))
+# define CRYPTO_THREAD_GET_ERROR(THREAD, FLAG) (((THREAD)->state >> 16) & (FLAG))
+
+typedef struct crypto_thread_st {
+ uint32_t state;
+ void *data;
+ CRYPTO_THREAD_ROUTINE routine;
+ CRYPTO_THREAD_RETVAL retval;
+ void *handle;
+ CRYPTO_MUTEX *lock;
+ CRYPTO_MUTEX *statelock;
+ CRYPTO_CONDVAR *condvar;
+ unsigned long thread_id;
+ int joinable;
+ OSSL_LIB_CTX *ctx;
+} CRYPTO_THREAD;
+
+# if defined(OPENSSL_THREADS)
+
+# define CRYPTO_THREAD_UNSET_STATE(THREAD, FLAG) \
+ do { \
+ (THREAD)->state &= ~(FLAG); \
+ } while ((void)0, 0)
+
+# define CRYPTO_THREAD_SET_STATE(THREAD, FLAG) \
+ do { \
+ (THREAD)->state |= (FLAG); \
+ } while ((void)0, 0)
+
+# define CRYPTO_THREAD_SET_ERROR(THREAD, FLAG) \
+ do { \
+ (THREAD)->state |= ((FLAG) << 16); \
+ } while ((void)0, 0)
+
+# define CRYPTO_THREAD_UNSET_ERROR(THREAD, FLAG) \
+ do { \
+ (THREAD)->state &= ~((FLAG) << 16); \
+ } while ((void)0, 0)
+
+# else
+
+# define CRYPTO_THREAD_UNSET_STATE(THREAD, FLAG)
+# define CRYPTO_THREAD_SET_STATE(THREAD, FLAG)
+# define CRYPTO_THREAD_SET_ERROR(THREAD, FLAG)
+# define CRYPTO_THREAD_UNSET_ERROR(THREAD, FLAG)
+
+# endif /* defined(OPENSSL_THREADS) */
+
+CRYPTO_THREAD * ossl_crypto_thread_native_start(CRYPTO_THREAD_ROUTINE routine,
+ void *data, int joinable);
+int ossl_crypto_thread_native_spawn(CRYPTO_THREAD *thread);
+int ossl_crypto_thread_native_join(CRYPTO_THREAD *thread,
+ CRYPTO_THREAD_RETVAL *retval);
+int ossl_crypto_thread_native_terminate(CRYPTO_THREAD *thread);
+int ossl_crypto_thread_native_exit(void);
+int ossl_crypto_thread_native_is_self(CRYPTO_THREAD *thread);
+int ossl_crypto_thread_native_clean(CRYPTO_THREAD *thread);
+
+void ossl_crypto_mem_barrier(void);
+
+#endif /* OSSL_INTERNAL_THREAD_ARCH_H */
diff --git a/include/openssl/thread.h b/include/openssl/thread.h
new file mode 100644
index 0000000000..68ecf9c4c4
--- /dev/null
+++ b/include/openssl/thread.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright 1995-2022 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
+ * 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
+ */
+
+#ifndef OPENSSL_THREAD_H
+# define OPENSSL_THREAD_H
+
+# define OSSL_THREAD_SUPPORT_FLAG_THREAD_POOL (1U<<0)
+# define OSSL_THREAD_SUPPORT_FLAG_DEFAULT_SPAWN (1U<<1)
+
+# include <openssl/types.h>
+
+uint32_t OSSL_get_thread_support_flags(void);
+int OSSL_set_max_threads(OSSL_LIB_CTX *ctx, uint64_t max_threads);
+uint64_t OSSL_get_max_threads(OSSL_LIB_CTX *ctx);
+
+#endif /* OPENSSL_THREAD_H */