diff options
Diffstat (limited to 'crypto/rand/md_rand.c')
-rw-r--r-- | crypto/rand/md_rand.c | 88 |
1 files changed, 59 insertions, 29 deletions
diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c index 88088ce73c..4e581f3917 100644 --- a/crypto/rand/md_rand.c +++ b/crypto/rand/md_rand.c @@ -155,8 +155,8 @@ int rand_predictable=0; const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT; static void ssleay_rand_cleanup(void); -static void ssleay_rand_seed(const void *buf, int num); -static void ssleay_rand_add(const void *buf, int num, double add_entropy); +static int ssleay_rand_seed(const void *buf, int num); +static int ssleay_rand_add(const void *buf, int num, double add_entropy); static int ssleay_rand_bytes(unsigned char *buf, int num); static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num); static int ssleay_rand_status(void); @@ -187,13 +187,14 @@ static void ssleay_rand_cleanup(void) initialized=0; } -static void ssleay_rand_add(const void *buf, int num, double add) +static int 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]; EVP_MD_CTX m; int do_not_lock; + int rv = 0; /* * (Based on the rand(3) manpage) @@ -210,6 +211,7 @@ static void ssleay_rand_add(const void *buf, int num, double add) * hash function. */ + EVP_MD_CTX_init(&m); /* check if we already have the lock */ if (crypto_lock_rand) { @@ -256,25 +258,30 @@ 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); j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j; - MD_Init(&m); - MD_Update(&m,local_md,MD_DIGEST_LENGTH); + if (!MD_Init(&m)) + goto err; + if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH)) + goto err; k=(st_idx+j)-STATE_SIZE; if (k > 0) { - MD_Update(&m,&(state[st_idx]),j-k); - MD_Update(&m,&(state[0]),k); + if (!MD_Update(&m,&(state[st_idx]),j-k)) + goto err; + if (!MD_Update(&m,&(state[0]),k)) + goto err; } else - MD_Update(&m,&(state[st_idx]),j); + if (!MD_Update(&m,&(state[st_idx]),j)) + goto err; /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ - MD_Update(&m,buf,j); + if (!MD_Update(&m,buf,j)) + goto err; /* We know that line may cause programs such as purify and valgrind to complain about use of uninitialized data. The problem is not, it's @@ -282,8 +289,10 @@ static void ssleay_rand_add(const void *buf, int num, double add) sure you get really bad randomness and thereby other problems such as very insecure keys. */ - MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); - MD_Final(&m,local_md); + if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c))) + goto err; + if (!MD_Final(&m,local_md)) + goto err; md_c[1]++; buf=(const char *)buf + j; @@ -303,7 +312,6 @@ static void ssleay_rand_add(const void *buf, int num, double add) st_idx=0; } } - 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 @@ -321,11 +329,15 @@ static void ssleay_rand_add(const void *buf, int num, double add) #if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32) assert(md_c[1] == md_count[1]); #endif + rv = 1; + err: + EVP_MD_CTX_cleanup(&m); + return rv; } -static void ssleay_rand_seed(const void *buf, int num) +static int ssleay_rand_seed(const void *buf, int num) { - ssleay_rand_add(buf, num, (double)num); + return ssleay_rand_add(buf, num, (double)num); } static int ssleay_rand_bytes(unsigned char *buf, int num) @@ -464,20 +476,25 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) /* num_ceil -= MD_DIGEST_LENGTH/2 */ j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num; num-=j; - MD_Init(&m); + if (!MD_Init(&m)) + goto err; #ifndef GETPID_IS_MEANINGLESS if (curr_pid) /* just in the first iteration to save time */ { - MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid); + if (!MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid)) + goto err; curr_pid = 0; } #endif - MD_Update(&m,local_md,MD_DIGEST_LENGTH); - MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); + if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH)) + goto err; + if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c))) + goto err; #ifndef PURIFY /* purify complains */ /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ - MD_Update(&m,buf,j); + if (!MD_Update(&m,buf,j)) + goto err; /* We know that line may cause programs such as purify and valgrind to complain about use of uninitialized data. */ @@ -486,12 +503,16 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) k=(st_idx+MD_DIGEST_LENGTH/2)-st_num; if (k > 0) { - MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k); - MD_Update(&m,&(state[0]),k); + if (!MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k)) + goto err; + if (!MD_Update(&m,&(state[0]),k)) + goto err; } else - MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); - MD_Final(&m,local_md); + if (!MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2)) + goto err; + if (!MD_Final(&m,local_md)) + goto err; for (i=0; i<MD_DIGEST_LENGTH/2; i++) { @@ -503,12 +524,16 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) } } - MD_Init(&m); - MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); - MD_Update(&m,local_md,MD_DIGEST_LENGTH); + if (!MD_Init(&m) + || !MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)) + || !MD_Update(&m,local_md,MD_DIGEST_LENGTH)) + goto err; CRYPTO_w_lock(CRYPTO_LOCK_RAND); - 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); + goto err; + } CRYPTO_w_unlock(CRYPTO_LOCK_RAND); EVP_MD_CTX_cleanup(&m); @@ -521,6 +546,11 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) "http://www.openssl.org/support/faq.html"); return(0); } + err: + EVP_MD_CTX_cleanup(&m); + RANDerr(RAND_F_SSLEAY_RAND_BYTES,ERR_R_EVP_LIB); + return 0; + } /* pseudo-random bytes that are guaranteed to be unique but not |