diff options
Diffstat (limited to 'lib/libcrypto/rand/md_rand.c')
-rw-r--r-- | lib/libcrypto/rand/md_rand.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/lib/libcrypto/rand/md_rand.c b/lib/libcrypto/rand/md_rand.c index 04b9d695b0d..a00ed707185 100644 --- a/lib/libcrypto/rand/md_rand.c +++ b/lib/libcrypto/rand/md_rand.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -119,7 +119,7 @@ #include <stdio.h> #include <string.h> -#include "openssl/e_os.h" +#include "e_os.h" #include <openssl/rand.h> #include "rand_lcl.h" @@ -144,6 +144,7 @@ static int initialized=0; static unsigned int crypto_lock_rand = 0; /* may be set only when a thread * holds CRYPTO_LOCK_RAND * (to prevent double locking) */ +/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */ @@ -191,7 +192,7 @@ static void ssleay_rand_add(const void *buf, int num, double add) int i,j,k,st_idx; long md_c[2]; unsigned char local_md[MD_DIGEST_LENGTH]; - MD_CTX m; + EVP_MD_CTX m; int do_not_lock; /* @@ -210,7 +211,14 @@ static void ssleay_rand_add(const void *buf, int num, double add) */ /* check if we already have the lock */ - do_not_lock = crypto_lock_rand && (locking_thread == CRYPTO_thread_id()); + if (crypto_lock_rand) + { + CRYPTO_r_lock(CRYPTO_LOCK_RAND2); + do_not_lock = (locking_thread == CRYPTO_thread_id()); + CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); + } + else + do_not_lock = 0; if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); st_idx=state_index; @@ -246,6 +254,7 @@ static void ssleay_rand_add(const void *buf, int num, double add) if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); + EVP_MD_CTX_init(&m); for (i=0; i<num; i+=MD_DIGEST_LENGTH) { j=(num-i); @@ -264,7 +273,7 @@ static void ssleay_rand_add(const void *buf, int num, double add) MD_Update(&m,buf,j); MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); - MD_Final(local_md,&m); + MD_Final(&m,local_md); md_c[1]++; buf=(const char *)buf + j; @@ -284,7 +293,7 @@ static void ssleay_rand_add(const void *buf, int num, double add) st_idx=0; } } - memset((char *)&m,0,sizeof(m)); + EVP_MD_CTX_cleanup(&m); if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); /* Don't just copy back local_md into md -- this could mean that @@ -299,7 +308,7 @@ static void ssleay_rand_add(const void *buf, int num, double add) entropy += add; if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); -#if !defined(THREADS) && !defined(WIN32) +#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) assert(md_c[1] == md_count[1]); #endif } @@ -317,7 +326,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) int ok; long md_c[2]; unsigned char local_md[MD_DIGEST_LENGTH]; - MD_CTX m; + EVP_MD_CTX m; #ifndef GETPID_IS_MEANINGLESS pid_t curr_pid = getpid(); #endif @@ -336,7 +345,8 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) if (num <= 0) return 1; - + + EVP_MD_CTX_init(&m); /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2); @@ -361,8 +371,10 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) CRYPTO_w_lock(CRYPTO_LOCK_RAND); /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ - crypto_lock_rand = 1; + CRYPTO_w_lock(CRYPTO_LOCK_RAND2); locking_thread = CRYPTO_thread_id(); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); + crypto_lock_rand = 1; if (!initialized) { @@ -435,7 +447,6 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) /* before unlocking, we must clear 'crypto_lock_rand' */ crypto_lock_rand = 0; - locking_thread = 0; CRYPTO_w_unlock(CRYPTO_LOCK_RAND); while (num > 0) @@ -464,7 +475,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) } else MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); - MD_Final(local_md,&m); + MD_Final(&m,local_md); for (i=0; i<MD_DIGEST_LENGTH/2; i++) { @@ -481,10 +492,10 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) MD_Update(&m,local_md,MD_DIGEST_LENGTH); CRYPTO_w_lock(CRYPTO_LOCK_RAND); MD_Update(&m,md,MD_DIGEST_LENGTH); - MD_Final(md,&m); + MD_Final(&m,md); CRYPTO_w_unlock(CRYPTO_LOCK_RAND); - memset(&m,0,sizeof(m)); + EVP_MD_CTX_cleanup(&m); if (ok) return(1); else @@ -521,15 +532,24 @@ static int ssleay_rand_status(void) /* check if we already have the lock * (could happen if a RAND_poll() implementation calls RAND_status()) */ - do_not_lock = crypto_lock_rand && (locking_thread == CRYPTO_thread_id()); + if (crypto_lock_rand) + { + CRYPTO_r_lock(CRYPTO_LOCK_RAND2); + do_not_lock = (locking_thread == CRYPTO_thread_id()); + CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); + } + else + do_not_lock = 0; if (!do_not_lock) { CRYPTO_w_lock(CRYPTO_LOCK_RAND); /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ - crypto_lock_rand = 1; + CRYPTO_w_lock(CRYPTO_LOCK_RAND2); locking_thread = CRYPTO_thread_id(); + CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); + crypto_lock_rand = 1; } if (!initialized) @@ -544,7 +564,6 @@ static int ssleay_rand_status(void) { /* before unlocking, we must clear 'crypto_lock_rand' */ crypto_lock_rand = 0; - locking_thread = 0; CRYPTO_w_unlock(CRYPTO_LOCK_RAND); } |