|
|
067bfb |
diff -up openssl-1.1.1c/crypto/fips/fips.c.fork-safety openssl-1.1.1c/crypto/fips/fips.c
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/fips/fips.c.fork-safety 2019-11-20 11:36:22.343506961 +0100
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/fips/fips.c 2019-11-21 17:44:32.920776849 +0100
|
|
|
067bfb |
@@ -472,7 +472,7 @@ int FIPS_module_mode_set(int onoff)
|
|
|
067bfb |
|
|
|
067bfb |
fips_set_mode(onoff);
|
|
|
067bfb |
/* force RNG reseed with entropy from getrandom() on next call */
|
|
|
067bfb |
- rand_fork();
|
|
|
067bfb |
+ rand_force_reseed();
|
|
|
067bfb |
|
|
|
067bfb |
ret = 1;
|
|
|
067bfb |
goto end;
|
|
|
067bfb |
diff -up openssl-1.1.1c/crypto/include/internal/rand_int.h.fork-safety openssl-1.1.1c/crypto/include/internal/rand_int.h
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/include/internal/rand_int.h.fork-safety 2019-11-20 11:36:22.382506277 +0100
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/include/internal/rand_int.h 2019-11-21 17:45:42.102456672 +0100
|
|
|
067bfb |
@@ -24,9 +24,9 @@
|
|
|
067bfb |
typedef struct rand_pool_st RAND_POOL;
|
|
|
067bfb |
|
|
|
067bfb |
void rand_cleanup_int(void);
|
|
|
067bfb |
+void rand_force_reseed(void);
|
|
|
067bfb |
void rand_drbg_cleanup_int(void);
|
|
|
067bfb |
void drbg_delete_thread_state(void);
|
|
|
067bfb |
-void rand_fork(void);
|
|
|
067bfb |
|
|
|
067bfb |
/* Hardware-based seeding functions. */
|
|
|
067bfb |
size_t rand_acquire_entropy_from_tsc(RAND_POOL *pool);
|
|
|
067bfb |
diff -up openssl-1.1.1c/crypto/init.c.fork-safety openssl-1.1.1c/crypto/init.c
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/init.c.fork-safety 2019-05-28 15:12:21.000000000 +0200
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/init.c 2019-11-21 17:34:13.478597398 +0100
|
|
|
067bfb |
@@ -847,6 +847,5 @@ void OPENSSL_fork_parent(void)
|
|
|
067bfb |
|
|
|
067bfb |
void OPENSSL_fork_child(void)
|
|
|
067bfb |
{
|
|
|
067bfb |
- rand_fork();
|
|
|
067bfb |
}
|
|
|
067bfb |
#endif
|
|
|
067bfb |
diff -up openssl-1.1.1c/crypto/rand/drbg_lib.c.fork-safety openssl-1.1.1c/crypto/rand/drbg_lib.c
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/rand/drbg_lib.c.fork-safety 2019-11-20 11:36:22.383506260 +0100
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/rand/drbg_lib.c 2019-11-21 17:46:37.583397431 +0100
|
|
|
067bfb |
@@ -197,7 +197,7 @@ static RAND_DRBG *rand_drbg_new(int secu
|
|
|
067bfb |
}
|
|
|
067bfb |
|
|
|
067bfb |
drbg->secure = secure && CRYPTO_secure_allocated(drbg);
|
|
|
067bfb |
- drbg->fork_count = rand_fork_count;
|
|
|
067bfb |
+ drbg->fork_id = openssl_get_fork_id();
|
|
|
067bfb |
drbg->parent = parent;
|
|
|
067bfb |
|
|
|
067bfb |
if (parent == NULL) {
|
|
|
067bfb |
@@ -583,6 +583,7 @@ int RAND_DRBG_generate(RAND_DRBG *drbg,
|
|
|
067bfb |
int prediction_resistance,
|
|
|
067bfb |
const unsigned char *adin, size_t adinlen)
|
|
|
067bfb |
{
|
|
|
067bfb |
+ int fork_id;
|
|
|
067bfb |
int reseed_required = 0;
|
|
|
067bfb |
|
|
|
067bfb |
if (drbg->state != DRBG_READY) {
|
|
|
067bfb |
@@ -608,8 +609,10 @@ int RAND_DRBG_generate(RAND_DRBG *drbg,
|
|
|
067bfb |
return 0;
|
|
|
067bfb |
}
|
|
|
067bfb |
|
|
|
067bfb |
- if (drbg->fork_count != rand_fork_count) {
|
|
|
067bfb |
- drbg->fork_count = rand_fork_count;
|
|
|
067bfb |
+ fork_id = openssl_get_fork_id();
|
|
|
067bfb |
+
|
|
|
067bfb |
+ if (drbg->fork_id != fork_id) {
|
|
|
067bfb |
+ drbg->fork_id = fork_id;
|
|
|
067bfb |
reseed_required = 1;
|
|
|
067bfb |
}
|
|
|
067bfb |
|
|
|
067bfb |
@@ -1011,6 +1014,20 @@ size_t rand_drbg_seedlen(RAND_DRBG *drbg
|
|
|
067bfb |
return min_entropy > min_entropylen ? min_entropy : min_entropylen;
|
|
|
067bfb |
}
|
|
|
067bfb |
|
|
|
067bfb |
+void rand_force_reseed(void)
|
|
|
067bfb |
+{
|
|
|
067bfb |
+ RAND_DRBG *drbg;
|
|
|
067bfb |
+
|
|
|
067bfb |
+ drbg = RAND_DRBG_get0_master();
|
|
|
067bfb |
+ drbg->fork_id = 0;
|
|
|
067bfb |
+
|
|
|
067bfb |
+ drbg = RAND_DRBG_get0_private();
|
|
|
067bfb |
+ drbg->fork_id = 0;
|
|
|
067bfb |
+
|
|
|
067bfb |
+ drbg = RAND_DRBG_get0_public();
|
|
|
067bfb |
+ drbg->fork_id = 0;
|
|
|
067bfb |
+}
|
|
|
067bfb |
+
|
|
|
067bfb |
/* Implements the default OpenSSL RAND_add() method */
|
|
|
067bfb |
static int drbg_add(const void *buf, int num, double randomness)
|
|
|
067bfb |
{
|
|
|
067bfb |
diff -up openssl-1.1.1c/crypto/rand/rand_lcl.h.fork-safety openssl-1.1.1c/crypto/rand/rand_lcl.h
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/rand/rand_lcl.h.fork-safety 2019-11-20 11:36:22.383506260 +0100
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/rand/rand_lcl.h 2019-11-21 17:34:13.485597265 +0100
|
|
|
067bfb |
@@ -176,12 +176,12 @@ struct rand_drbg_st {
|
|
|
067bfb |
int secure; /* 1: allocated on the secure heap, 0: otherwise */
|
|
|
067bfb |
int type; /* the nid of the underlying algorithm */
|
|
|
067bfb |
/*
|
|
|
067bfb |
- * Stores the value of the rand_fork_count global as of when we last
|
|
|
067bfb |
- * reseeded. The DRBG reseeds automatically whenever drbg->fork_count !=
|
|
|
067bfb |
- * rand_fork_count. Used to provide fork-safety and reseed this DRBG in
|
|
|
067bfb |
- * the child process.
|
|
|
067bfb |
+ * Stores the return value of openssl_get_fork_id() as of when we last
|
|
|
067bfb |
+ * reseeded. The DRBG reseeds automatically whenever drbg->fork_id !=
|
|
|
067bfb |
+ * openssl_get_fork_id(). Used to provide fork-safety and reseed this
|
|
|
067bfb |
+ * DRBG in the child process.
|
|
|
067bfb |
*/
|
|
|
067bfb |
- int fork_count;
|
|
|
067bfb |
+ int fork_id;
|
|
|
067bfb |
unsigned short flags; /* various external flags */
|
|
|
067bfb |
|
|
|
067bfb |
/*
|
|
|
067bfb |
@@ -273,19 +273,6 @@ struct rand_drbg_st {
|
|
|
067bfb |
/* The global RAND method, and the global buffer and DRBG instance. */
|
|
|
067bfb |
extern RAND_METHOD rand_meth;
|
|
|
067bfb |
|
|
|
067bfb |
-/*
|
|
|
067bfb |
- * A "generation count" of forks. Incremented in the child process after a
|
|
|
067bfb |
- * fork. Since rand_fork_count is increment-only, and only ever written to in
|
|
|
067bfb |
- * the child process of the fork, which is guaranteed to be single-threaded, no
|
|
|
067bfb |
- * locking is needed for normal (read) accesses; the rest of pthread fork
|
|
|
067bfb |
- * processing is assumed to introduce the necessary memory barriers. Sibling
|
|
|
067bfb |
- * children of a given parent will produce duplicate values, but this is not
|
|
|
067bfb |
- * problematic because the reseeding process pulls input from the system CSPRNG
|
|
|
067bfb |
- * and/or other global sources, so the siblings will end up generating
|
|
|
067bfb |
- * different output streams.
|
|
|
067bfb |
- */
|
|
|
067bfb |
-extern int rand_fork_count;
|
|
|
067bfb |
-
|
|
|
067bfb |
/* DRBG helpers */
|
|
|
067bfb |
int rand_drbg_restart(RAND_DRBG *drbg,
|
|
|
067bfb |
const unsigned char *buffer, size_t len, size_t entropy);
|
|
|
067bfb |
diff -up openssl-1.1.1c/crypto/rand/rand_lib.c.fork-safety openssl-1.1.1c/crypto/rand/rand_lib.c
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/rand/rand_lib.c.fork-safety 2019-11-20 11:36:22.374506418 +0100
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/rand/rand_lib.c 2019-11-21 17:34:13.487597227 +0100
|
|
|
067bfb |
@@ -30,8 +30,6 @@ static CRYPTO_RWLOCK *rand_meth_lock;
|
|
|
067bfb |
static const RAND_METHOD *default_RAND_meth;
|
|
|
067bfb |
static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT;
|
|
|
067bfb |
|
|
|
067bfb |
-int rand_fork_count;
|
|
|
067bfb |
-
|
|
|
067bfb |
static CRYPTO_RWLOCK *rand_nonce_lock;
|
|
|
067bfb |
static int rand_nonce_count;
|
|
|
067bfb |
|
|
|
067bfb |
@@ -303,11 +301,6 @@ void rand_drbg_cleanup_additional_data(R
|
|
|
067bfb |
rand_pool_reattach(pool, out);
|
|
|
067bfb |
}
|
|
|
067bfb |
|
|
|
067bfb |
-void rand_fork(void)
|
|
|
067bfb |
-{
|
|
|
067bfb |
- rand_fork_count++;
|
|
|
067bfb |
-}
|
|
|
067bfb |
-
|
|
|
067bfb |
DEFINE_RUN_ONCE_STATIC(do_rand_init)
|
|
|
067bfb |
{
|
|
|
067bfb |
#ifndef OPENSSL_NO_ENGINE
|
|
|
067bfb |
diff -up openssl-1.1.1c/crypto/threads_none.c.fork-safety openssl-1.1.1c/crypto/threads_none.c
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/threads_none.c.fork-safety 2019-05-28 15:12:21.000000000 +0200
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/threads_none.c 2019-11-21 17:34:13.489597189 +0100
|
|
|
067bfb |
@@ -12,6 +12,11 @@
|
|
|
067bfb |
|
|
|
067bfb |
#if !defined(OPENSSL_THREADS) || defined(CRYPTO_TDEBUG)
|
|
|
067bfb |
|
|
|
067bfb |
+# if defined(OPENSSL_SYS_UNIX)
|
|
|
067bfb |
+# include <sys/types.h>
|
|
|
067bfb |
+# include <unistd.h>
|
|
|
067bfb |
+# endif
|
|
|
067bfb |
+
|
|
|
067bfb |
CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void)
|
|
|
067bfb |
{
|
|
|
067bfb |
CRYPTO_RWLOCK *lock;
|
|
|
067bfb |
@@ -133,4 +138,12 @@ int openssl_init_fork_handlers(void)
|
|
|
067bfb |
return 0;
|
|
|
067bfb |
}
|
|
|
067bfb |
|
|
|
067bfb |
+int openssl_get_fork_id(void)
|
|
|
067bfb |
+{
|
|
|
067bfb |
+# if defined(OPENSSL_SYS_UNIX)
|
|
|
067bfb |
+ return getpid();
|
|
|
067bfb |
+# else
|
|
|
067bfb |
+ return 0;
|
|
|
067bfb |
+# endif
|
|
|
067bfb |
+}
|
|
|
067bfb |
#endif
|
|
|
067bfb |
diff -up openssl-1.1.1c/crypto/threads_pthread.c.fork-safety openssl-1.1.1c/crypto/threads_pthread.c
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/threads_pthread.c.fork-safety 2019-05-28 15:12:21.000000000 +0200
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/threads_pthread.c 2019-11-21 17:34:13.492597131 +0100
|
|
|
067bfb |
@@ -12,6 +12,11 @@
|
|
|
067bfb |
|
|
|
067bfb |
#if defined(OPENSSL_THREADS) && !defined(CRYPTO_TDEBUG) && !defined(OPENSSL_SYS_WINDOWS)
|
|
|
067bfb |
|
|
|
067bfb |
+# if defined(OPENSSL_SYS_UNIX)
|
|
|
067bfb |
+# include <sys/types.h>
|
|
|
067bfb |
+# include <unistd.h>
|
|
|
067bfb |
+#endif
|
|
|
067bfb |
+
|
|
|
067bfb |
# ifdef PTHREAD_RWLOCK_INITIALIZER
|
|
|
067bfb |
# define USE_RWLOCK
|
|
|
067bfb |
# endif
|
|
|
067bfb |
@@ -193,4 +198,9 @@ int openssl_init_fork_handlers(void)
|
|
|
067bfb |
# endif
|
|
|
067bfb |
return 0;
|
|
|
067bfb |
}
|
|
|
067bfb |
+
|
|
|
067bfb |
+int openssl_get_fork_id(void)
|
|
|
067bfb |
+{
|
|
|
067bfb |
+ return getpid();
|
|
|
067bfb |
+}
|
|
|
067bfb |
#endif
|
|
|
067bfb |
diff -up openssl-1.1.1c/crypto/threads_win.c.fork-safety openssl-1.1.1c/crypto/threads_win.c
|
|
|
067bfb |
--- openssl-1.1.1c/crypto/threads_win.c.fork-safety 2019-05-28 15:12:21.000000000 +0200
|
|
|
067bfb |
+++ openssl-1.1.1c/crypto/threads_win.c 2019-11-21 17:34:13.495597074 +0100
|
|
|
067bfb |
@@ -164,4 +164,8 @@ int openssl_init_fork_handlers(void)
|
|
|
067bfb |
return 0;
|
|
|
067bfb |
}
|
|
|
067bfb |
|
|
|
067bfb |
+int openssl_get_fork_id(void)
|
|
|
067bfb |
+{
|
|
|
067bfb |
+ return 0;
|
|
|
067bfb |
+}
|
|
|
067bfb |
#endif
|
|
|
067bfb |
diff -up openssl-1.1.1c/include/internal/cryptlib.h.fork-safety openssl-1.1.1c/include/internal/cryptlib.h
|
|
|
067bfb |
--- openssl-1.1.1c/include/internal/cryptlib.h.fork-safety 2019-05-28 15:12:21.000000000 +0200
|
|
|
067bfb |
+++ openssl-1.1.1c/include/internal/cryptlib.h 2019-11-21 17:34:13.497597036 +0100
|
|
|
067bfb |
@@ -80,6 +80,7 @@ extern unsigned int OPENSSL_ia32cap_P[];
|
|
|
067bfb |
void OPENSSL_showfatal(const char *fmta, ...);
|
|
|
067bfb |
void crypto_cleanup_all_ex_data_int(void);
|
|
|
067bfb |
int openssl_init_fork_handlers(void);
|
|
|
067bfb |
+int openssl_get_fork_id(void);
|
|
|
067bfb |
|
|
|
067bfb |
char *ossl_safe_getenv(const char *name);
|
|
|
067bfb |
|
|
|
067bfb |
diff -up openssl-1.1.1c/test/drbgtest.c.fork-safety openssl-1.1.1c/test/drbgtest.c
|
|
|
067bfb |
--- openssl-1.1.1c/test/drbgtest.c.fork-safety 2019-11-20 11:36:22.384506242 +0100
|
|
|
067bfb |
+++ openssl-1.1.1c/test/drbgtest.c 2019-11-21 17:34:13.499596998 +0100
|
|
|
067bfb |
@@ -22,6 +22,13 @@
|
|
|
067bfb |
# include <windows.h>
|
|
|
067bfb |
#endif
|
|
|
067bfb |
|
|
|
067bfb |
+
|
|
|
067bfb |
+#if defined(OPENSSL_SYS_UNIX)
|
|
|
067bfb |
+# include <sys/types.h>
|
|
|
067bfb |
+# include <sys/wait.h>
|
|
|
067bfb |
+# include <unistd.h>
|
|
|
067bfb |
+#endif
|
|
|
067bfb |
+
|
|
|
067bfb |
#include "testutil.h"
|
|
|
067bfb |
#include "drbgtest.h"
|
|
|
067bfb |
|
|
|
067bfb |
@@ -696,6 +703,40 @@ static int test_drbg_reseed(int expect_s
|
|
|
067bfb |
return 1;
|
|
|
067bfb |
}
|
|
|
067bfb |
|
|
|
067bfb |
+
|
|
|
067bfb |
+#if defined(OPENSSL_SYS_UNIX)
|
|
|
067bfb |
+/*
|
|
|
067bfb |
+ * Test whether master, public and private DRBG are reseeded after
|
|
|
067bfb |
+ * forking the process.
|
|
|
067bfb |
+ */
|
|
|
067bfb |
+static int test_drbg_reseed_after_fork(RAND_DRBG *master,
|
|
|
067bfb |
+ RAND_DRBG *public,
|
|
|
067bfb |
+ RAND_DRBG *private)
|
|
|
067bfb |
+{
|
|
|
067bfb |
+ pid_t pid;
|
|
|
067bfb |
+ int status=0;
|
|
|
067bfb |
+
|
|
|
067bfb |
+ pid = fork();
|
|
|
067bfb |
+ if (!TEST_int_ge(pid, 0))
|
|
|
067bfb |
+ return 0;
|
|
|
067bfb |
+
|
|
|
067bfb |
+ if (pid > 0) {
|
|
|
067bfb |
+ /* I'm the parent; wait for the child and check its exit code */
|
|
|
067bfb |
+ return TEST_int_eq(waitpid(pid, &status, 0), pid) && TEST_int_eq(status, 0);
|
|
|
067bfb |
+ }
|
|
|
067bfb |
+
|
|
|
067bfb |
+ /* I'm the child; check whether all three DRBGs reseed. */
|
|
|
067bfb |
+ if (!TEST_true(test_drbg_reseed(1, master, public, private, 1, 1, 1, 0)))
|
|
|
067bfb |
+ status = 1;
|
|
|
067bfb |
+
|
|
|
067bfb |
+ /* Remove hooks */
|
|
|
067bfb |
+ unhook_drbg(master);
|
|
|
067bfb |
+ unhook_drbg(public);
|
|
|
067bfb |
+ unhook_drbg(private);
|
|
|
067bfb |
+ exit(status);
|
|
|
067bfb |
+}
|
|
|
067bfb |
+#endif
|
|
|
067bfb |
+
|
|
|
067bfb |
/*
|
|
|
067bfb |
* Test whether the default rand_method (RAND_OpenSSL()) is
|
|
|
067bfb |
* setup correctly, in particular whether reseeding works
|
|
|
067bfb |
@@ -786,6 +827,10 @@ static int test_rand_drbg_reseed(void)
|
|
|
067bfb |
goto error;
|
|
|
067bfb |
reset_drbg_hook_ctx();
|
|
|
067bfb |
|
|
|
067bfb |
+#if defined(OPENSSL_SYS_UNIX)
|
|
|
067bfb |
+ if (!TEST_true(test_drbg_reseed_after_fork(master, public, private)))
|
|
|
067bfb |
+ goto error;
|
|
|
067bfb |
+#endif
|
|
|
067bfb |
|
|
|
067bfb |
/* fill 'randomness' buffer with some arbitrary data */
|
|
|
067bfb |
memset(rand_add_buf, 'r', sizeof(rand_add_buf));
|