summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rand/md_rand.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rand/md_rand.c')
-rw-r--r--src/lib/libcrypto/rand/md_rand.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/src/lib/libcrypto/rand/md_rand.c b/src/lib/libcrypto/rand/md_rand.c
index 04b9d695b0..a00ed70718 100644
--- a/src/lib/libcrypto/rand/md_rand.c
+++ b/src/lib/libcrypto/rand/md_rand.c
@@ -56,7 +56,7 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58/* ==================================================================== 58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
60 * 60 *
61 * Redistribution and use in source and binary forms, with or without 61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions 62 * modification, are permitted provided that the following conditions
@@ -119,7 +119,7 @@
119#include <stdio.h> 119#include <stdio.h>
120#include <string.h> 120#include <string.h>
121 121
122#include "openssl/e_os.h" 122#include "e_os.h"
123 123
124#include <openssl/rand.h> 124#include <openssl/rand.h>
125#include "rand_lcl.h" 125#include "rand_lcl.h"
@@ -144,6 +144,7 @@ static int initialized=0;
144static unsigned int crypto_lock_rand = 0; /* may be set only when a thread 144static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
145 * holds CRYPTO_LOCK_RAND 145 * holds CRYPTO_LOCK_RAND
146 * (to prevent double locking) */ 146 * (to prevent double locking) */
147/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
147static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */ 148static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */
148 149
149 150
@@ -191,7 +192,7 @@ static void ssleay_rand_add(const void *buf, int num, double add)
191 int i,j,k,st_idx; 192 int i,j,k,st_idx;
192 long md_c[2]; 193 long md_c[2];
193 unsigned char local_md[MD_DIGEST_LENGTH]; 194 unsigned char local_md[MD_DIGEST_LENGTH];
194 MD_CTX m; 195 EVP_MD_CTX m;
195 int do_not_lock; 196 int do_not_lock;
196 197
197 /* 198 /*
@@ -210,7 +211,14 @@ static void ssleay_rand_add(const void *buf, int num, double add)
210 */ 211 */
211 212
212 /* check if we already have the lock */ 213 /* check if we already have the lock */
213 do_not_lock = crypto_lock_rand && (locking_thread == CRYPTO_thread_id()); 214 if (crypto_lock_rand)
215 {
216 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
217 do_not_lock = (locking_thread == CRYPTO_thread_id());
218 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
219 }
220 else
221 do_not_lock = 0;
214 222
215 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); 223 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
216 st_idx=state_index; 224 st_idx=state_index;
@@ -246,6 +254,7 @@ static void ssleay_rand_add(const void *buf, int num, double add)
246 254
247 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 255 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
248 256
257 EVP_MD_CTX_init(&m);
249 for (i=0; i<num; i+=MD_DIGEST_LENGTH) 258 for (i=0; i<num; i+=MD_DIGEST_LENGTH)
250 { 259 {
251 j=(num-i); 260 j=(num-i);
@@ -264,7 +273,7 @@ static void ssleay_rand_add(const void *buf, int num, double add)
264 273
265 MD_Update(&m,buf,j); 274 MD_Update(&m,buf,j);
266 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); 275 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
267 MD_Final(local_md,&m); 276 MD_Final(&m,local_md);
268 md_c[1]++; 277 md_c[1]++;
269 278
270 buf=(const char *)buf + j; 279 buf=(const char *)buf + j;
@@ -284,7 +293,7 @@ static void ssleay_rand_add(const void *buf, int num, double add)
284 st_idx=0; 293 st_idx=0;
285 } 294 }
286 } 295 }
287 memset((char *)&m,0,sizeof(m)); 296 EVP_MD_CTX_cleanup(&m);
288 297
289 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); 298 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
290 /* Don't just copy back local_md into md -- this could mean that 299 /* 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)
299 entropy += add; 308 entropy += add;
300 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 309 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
301 310
302#if !defined(THREADS) && !defined(WIN32) 311#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
303 assert(md_c[1] == md_count[1]); 312 assert(md_c[1] == md_count[1]);
304#endif 313#endif
305 } 314 }
@@ -317,7 +326,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
317 int ok; 326 int ok;
318 long md_c[2]; 327 long md_c[2];
319 unsigned char local_md[MD_DIGEST_LENGTH]; 328 unsigned char local_md[MD_DIGEST_LENGTH];
320 MD_CTX m; 329 EVP_MD_CTX m;
321#ifndef GETPID_IS_MEANINGLESS 330#ifndef GETPID_IS_MEANINGLESS
322 pid_t curr_pid = getpid(); 331 pid_t curr_pid = getpid();
323#endif 332#endif
@@ -336,7 +345,8 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
336 345
337 if (num <= 0) 346 if (num <= 0)
338 return 1; 347 return 1;
339 348
349 EVP_MD_CTX_init(&m);
340 /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ 350 /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
341 num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2); 351 num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
342 352
@@ -361,8 +371,10 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
361 CRYPTO_w_lock(CRYPTO_LOCK_RAND); 371 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
362 372
363 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ 373 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
364 crypto_lock_rand = 1; 374 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
365 locking_thread = CRYPTO_thread_id(); 375 locking_thread = CRYPTO_thread_id();
376 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
377 crypto_lock_rand = 1;
366 378
367 if (!initialized) 379 if (!initialized)
368 { 380 {
@@ -435,7 +447,6 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
435 447
436 /* before unlocking, we must clear 'crypto_lock_rand' */ 448 /* before unlocking, we must clear 'crypto_lock_rand' */
437 crypto_lock_rand = 0; 449 crypto_lock_rand = 0;
438 locking_thread = 0;
439 CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 450 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
440 451
441 while (num > 0) 452 while (num > 0)
@@ -464,7 +475,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
464 } 475 }
465 else 476 else
466 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); 477 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
467 MD_Final(local_md,&m); 478 MD_Final(&m,local_md);
468 479
469 for (i=0; i<MD_DIGEST_LENGTH/2; i++) 480 for (i=0; i<MD_DIGEST_LENGTH/2; i++)
470 { 481 {
@@ -481,10 +492,10 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
481 MD_Update(&m,local_md,MD_DIGEST_LENGTH); 492 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
482 CRYPTO_w_lock(CRYPTO_LOCK_RAND); 493 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
483 MD_Update(&m,md,MD_DIGEST_LENGTH); 494 MD_Update(&m,md,MD_DIGEST_LENGTH);
484 MD_Final(md,&m); 495 MD_Final(&m,md);
485 CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 496 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
486 497
487 memset(&m,0,sizeof(m)); 498 EVP_MD_CTX_cleanup(&m);
488 if (ok) 499 if (ok)
489 return(1); 500 return(1);
490 else 501 else
@@ -521,15 +532,24 @@ static int ssleay_rand_status(void)
521 532
522 /* check if we already have the lock 533 /* check if we already have the lock
523 * (could happen if a RAND_poll() implementation calls RAND_status()) */ 534 * (could happen if a RAND_poll() implementation calls RAND_status()) */
524 do_not_lock = crypto_lock_rand && (locking_thread == CRYPTO_thread_id()); 535 if (crypto_lock_rand)
536 {
537 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
538 do_not_lock = (locking_thread == CRYPTO_thread_id());
539 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
540 }
541 else
542 do_not_lock = 0;
525 543
526 if (!do_not_lock) 544 if (!do_not_lock)
527 { 545 {
528 CRYPTO_w_lock(CRYPTO_LOCK_RAND); 546 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
529 547
530 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ 548 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
531 crypto_lock_rand = 1; 549 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
532 locking_thread = CRYPTO_thread_id(); 550 locking_thread = CRYPTO_thread_id();
551 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
552 crypto_lock_rand = 1;
533 } 553 }
534 554
535 if (!initialized) 555 if (!initialized)
@@ -544,7 +564,6 @@ static int ssleay_rand_status(void)
544 { 564 {
545 /* before unlocking, we must clear 'crypto_lock_rand' */ 565 /* before unlocking, we must clear 'crypto_lock_rand' */
546 crypto_lock_rand = 0; 566 crypto_lock_rand = 0;
547 locking_thread = 0;
548 567
549 CRYPTO_w_unlock(CRYPTO_LOCK_RAND); 568 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
550 } 569 }