提交 8eed7e87 编写于 作者: M Matt Caswell

Convert rand code to new threading API

Replace the CRYPTO_LOCK_RAND and CRYPTO_LOCK_RAND2 locks with new thread
API style locks.
Reviewed-by: NRich Salz <rsalz@openssl.org>
上级 29eed3dd
...@@ -125,6 +125,7 @@ ...@@ -125,6 +125,7 @@
#include <openssl/rand.h> #include <openssl/rand.h>
#include <openssl/async.h> #include <openssl/async.h>
#include "rand_lcl.h" #include "rand_lcl.h"
#include "internal/threads.h"
#include <openssl/err.h> #include <openssl/err.h>
...@@ -147,12 +148,15 @@ static long md_count[2] = { 0, 0 }; ...@@ -147,12 +148,15 @@ static long md_count[2] = { 0, 0 };
static double entropy = 0; static double entropy = 0;
static int initialized = 0; static int initialized = 0;
static unsigned int crypto_lock_rand = 0; /* may be set only when a thread static CRYPTO_RWLOCK *rand_lock = NULL;
* holds CRYPTO_LOCK_RAND (to static CRYPTO_RWLOCK *rand_tmp_lock = NULL;
* prevent double locking) */ static CRYPTO_ONCE rand_lock_init = CRYPTO_ONCE_STATIC_INIT;
/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
/* May be set only when a thread holds rand_lock (to prevent double locking) */
static unsigned int crypto_lock_rand = 0;
/* access to locking_threadid is synchronized by rand_tmp_lock */
/* valid iff crypto_lock_rand is set */ /* valid iff crypto_lock_rand is set */
static CRYPTO_THREADID locking_threadid; static CRYPTO_THREAD_ID locking_threadid;
#ifdef PREDICT #ifdef PREDICT
int rand_predictable = 0; int rand_predictable = 0;
...@@ -183,6 +187,12 @@ static RAND_METHOD rand_meth = { ...@@ -183,6 +187,12 @@ static RAND_METHOD rand_meth = {
rand_status rand_status
}; };
static void do_rand_lock_init(void)
{
rand_lock = CRYPTO_THREAD_lock_new();
rand_tmp_lock = CRYPTO_THREAD_lock_new();
}
RAND_METHOD *RAND_OpenSSL(void) RAND_METHOD *RAND_OpenSSL(void)
{ {
return (&rand_meth); return (&rand_meth);
...@@ -198,6 +208,8 @@ static void rand_cleanup(void) ...@@ -198,6 +208,8 @@ static void rand_cleanup(void)
md_count[1] = 0; md_count[1] = 0;
entropy = 0; entropy = 0;
initialized = 0; initialized = 0;
CRYPTO_THREAD_lock_free(rand_lock);
CRYPTO_THREAD_lock_free(rand_tmp_lock);
} }
static int rand_add(const void *buf, int num, double add) static int rand_add(const void *buf, int num, double add)
...@@ -231,18 +243,19 @@ static int rand_add(const void *buf, int num, double add) ...@@ -231,18 +243,19 @@ static int rand_add(const void *buf, int num, double add)
if (m == NULL) if (m == NULL)
goto err; goto err;
CRYPTO_THREAD_run_once(&rand_lock_init, do_rand_lock_init);
/* check if we already have the lock */ /* check if we already have the lock */
if (crypto_lock_rand) { if (crypto_lock_rand) {
CRYPTO_THREADID cur; CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
CRYPTO_THREADID_current(&cur); CRYPTO_THREAD_read_lock(rand_tmp_lock);
CRYPTO_r_lock(CRYPTO_LOCK_RAND2); do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); CRYPTO_THREAD_unlock(rand_tmp_lock);
CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
} else } else
do_not_lock = 0; do_not_lock = 0;
if (!do_not_lock) if (!do_not_lock)
CRYPTO_w_lock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_write_lock(rand_lock);
st_idx = state_index; st_idx = state_index;
/* /*
...@@ -274,7 +287,7 @@ static int rand_add(const void *buf, int num, double add) ...@@ -274,7 +287,7 @@ static int rand_add(const void *buf, int num, double add)
md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0); md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
if (!do_not_lock) if (!do_not_lock)
CRYPTO_w_unlock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_unlock(rand_lock);
for (i = 0; i < num; i += MD_DIGEST_LENGTH) { for (i = 0; i < num; i += MD_DIGEST_LENGTH) {
j = (num - i); j = (num - i);
...@@ -328,7 +341,7 @@ static int rand_add(const void *buf, int num, double add) ...@@ -328,7 +341,7 @@ static int rand_add(const void *buf, int num, double add)
} }
if (!do_not_lock) if (!do_not_lock)
CRYPTO_w_lock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_write_lock(rand_lock);
/* /*
* Don't just copy back local_md into md -- this could mean that other * Don't just copy back local_md into md -- this could mean that other
* thread's seeding remains without effect (except for the incremented * thread's seeding remains without effect (except for the incremented
...@@ -341,7 +354,7 @@ static int rand_add(const void *buf, int num, double add) ...@@ -341,7 +354,7 @@ static int rand_add(const void *buf, int num, double add)
if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */ if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
entropy += add; entropy += add;
if (!do_not_lock) if (!do_not_lock)
CRYPTO_w_unlock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_unlock(rand_lock);
rv = 1; rv = 1;
err: err:
...@@ -428,7 +441,8 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo) ...@@ -428,7 +441,8 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
* global 'md'. * global 'md'.
*/ */
CRYPTO_w_lock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_run_once(&rand_lock_init, do_rand_lock_init);
CRYPTO_THREAD_write_lock(rand_lock);
/* /*
* We could end up in an async engine while holding this lock so ensure * We could end up in an async engine while holding this lock so ensure
* we don't pause and cause a deadlock * we don't pause and cause a deadlock
...@@ -436,9 +450,9 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo) ...@@ -436,9 +450,9 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
ASYNC_block_pause(); ASYNC_block_pause();
/* prevent rand_bytes() from trying to obtain the lock again */ /* prevent rand_bytes() from trying to obtain the lock again */
CRYPTO_w_lock(CRYPTO_LOCK_RAND2); CRYPTO_THREAD_write_lock(rand_tmp_lock);
CRYPTO_THREADID_current(&locking_threadid); locking_threadid = CRYPTO_THREAD_get_current_id();
CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); CRYPTO_THREAD_unlock(rand_tmp_lock);
crypto_lock_rand = 1; crypto_lock_rand = 1;
if (!initialized) { if (!initialized) {
...@@ -513,7 +527,7 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo) ...@@ -513,7 +527,7 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
/* before unlocking, we must clear 'crypto_lock_rand' */ /* before unlocking, we must clear 'crypto_lock_rand' */
crypto_lock_rand = 0; crypto_lock_rand = 0;
ASYNC_unblock_pause(); ASYNC_unblock_pause();
CRYPTO_w_unlock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_unlock(rand_lock);
while (num > 0) { while (num > 0) {
/* num_ceil -= MD_DIGEST_LENGTH/2 */ /* num_ceil -= MD_DIGEST_LENGTH/2 */
...@@ -566,17 +580,17 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo) ...@@ -566,17 +580,17 @@ static int rand_bytes(unsigned char *buf, int num, int pseudo)
|| !MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)) || !MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c))
|| !MD_Update(m, local_md, MD_DIGEST_LENGTH)) || !MD_Update(m, local_md, MD_DIGEST_LENGTH))
goto err; goto err;
CRYPTO_w_lock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_write_lock(rand_lock);
/* /*
* Prevent deadlocks if we end up in an async engine * Prevent deadlocks if we end up in an async engine
*/ */
ASYNC_block_pause(); ASYNC_block_pause();
if (!MD_Update(m, md, MD_DIGEST_LENGTH) || !MD_Final(m, md)) { if (!MD_Update(m, md, MD_DIGEST_LENGTH) || !MD_Final(m, md)) {
CRYPTO_w_unlock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_unlock(rand_lock);
goto err; goto err;
} }
ASYNC_unblock_pause(); ASYNC_unblock_pause();
CRYPTO_w_unlock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_unlock(rand_lock);
EVP_MD_CTX_free(m); EVP_MD_CTX_free(m);
if (ok) if (ok)
...@@ -617,24 +631,25 @@ static int rand_pseudo_bytes(unsigned char *buf, int num) ...@@ -617,24 +631,25 @@ static int rand_pseudo_bytes(unsigned char *buf, int num)
static int rand_status(void) static int rand_status(void)
{ {
CRYPTO_THREADID cur; CRYPTO_THREAD_ID cur;
int ret; int ret;
int do_not_lock; int do_not_lock;
CRYPTO_THREADID_current(&cur); CRYPTO_THREAD_run_once(&rand_lock_init, do_rand_lock_init);
cur = CRYPTO_THREAD_get_current_id();
/* /*
* check if we already have the lock (could happen if a RAND_poll() * check if we already have the lock (could happen if a RAND_poll()
* implementation calls RAND_status()) * implementation calls RAND_status())
*/ */
if (crypto_lock_rand) { if (crypto_lock_rand) {
CRYPTO_r_lock(CRYPTO_LOCK_RAND2); CRYPTO_THREAD_read_lock(rand_tmp_lock);
do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); CRYPTO_THREAD_unlock(rand_tmp_lock);
} else } else
do_not_lock = 0; do_not_lock = 0;
if (!do_not_lock) { if (!do_not_lock) {
CRYPTO_w_lock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_write_lock(rand_lock);
/* /*
* Prevent deadlocks in case we end up in an async engine * Prevent deadlocks in case we end up in an async engine
*/ */
...@@ -643,9 +658,9 @@ static int rand_status(void) ...@@ -643,9 +658,9 @@ static int rand_status(void)
/* /*
* prevent rand_bytes() from trying to obtain the lock again * prevent rand_bytes() from trying to obtain the lock again
*/ */
CRYPTO_w_lock(CRYPTO_LOCK_RAND2); CRYPTO_THREAD_write_lock(rand_tmp_lock);
CRYPTO_THREADID_cpy(&locking_threadid, &cur); locking_threadid = cur;
CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); CRYPTO_THREAD_unlock(rand_tmp_lock);
crypto_lock_rand = 1; crypto_lock_rand = 1;
} }
...@@ -661,7 +676,7 @@ static int rand_status(void) ...@@ -661,7 +676,7 @@ static int rand_status(void)
crypto_lock_rand = 0; crypto_lock_rand = 0;
ASYNC_unblock_pause(); ASYNC_unblock_pause();
CRYPTO_w_unlock(CRYPTO_LOCK_RAND); CRYPTO_THREAD_unlock(rand_lock);
} }
return ret; return ret;
......
...@@ -166,8 +166,6 @@ extern "C" { ...@@ -166,8 +166,6 @@ extern "C" {
*/ */
# define CRYPTO_LOCK_X509_STORE 11 # define CRYPTO_LOCK_X509_STORE 11
# define CRYPTO_LOCK_RAND 18
# define CRYPTO_LOCK_RAND2 19
# define CRYPTO_LOCK_DYNLOCK 29 # define CRYPTO_LOCK_DYNLOCK 29
# define CRYPTO_LOCK_ENGINE 30 # define CRYPTO_LOCK_ENGINE 30
# define CRYPTO_LOCK_ECDSA 32 # define CRYPTO_LOCK_ECDSA 32
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册