| OLD | NEW |
| 1 /* crypto/rand/md_rand.c */ | 1 /* crypto/rand/md_rand.c */ |
| 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * This package is an SSL implementation written | 5 * This package is an SSL implementation written |
| 6 * by Eric Young (eay@cryptsoft.com). | 6 * by Eric Young (eay@cryptsoft.com). |
| 7 * The implementation was written so as to conform with Netscapes SSL. | 7 * The implementation was written so as to conform with Netscapes SSL. |
| 8 * | 8 * |
| 9 * This library is free for commercial and non-commercial use as long as | 9 * This library is free for commercial and non-commercial use as long as |
| 10 * the following conditions are aheared to. The following conditions | 10 * the following conditions are aheared to. The following conditions |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 #include <stdio.h> | 119 #include <stdio.h> |
| 120 #include <string.h> | 120 #include <string.h> |
| 121 | 121 |
| 122 #include "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" |
| 126 | 126 |
| 127 #include <openssl/crypto.h> | 127 #include <openssl/crypto.h> |
| 128 #include <openssl/err.h> | 128 #include <openssl/err.h> |
| 129 #ifdef OPENSSL_FIPS | |
| 130 #include <openssl/fips.h> | |
| 131 #endif | |
| 132 | |
| 133 | 129 |
| 134 #ifdef BN_DEBUG | 130 #ifdef BN_DEBUG |
| 135 # define PREDICT | 131 # define PREDICT |
| 136 #endif | 132 #endif |
| 137 | 133 |
| 138 /* #define PREDICT 1 */ | 134 /* #define PREDICT 1 */ |
| 139 | 135 |
| 140 #define STATE_SIZE 1023 | 136 #define STATE_SIZE 1023 |
| 141 static int state_num=0,state_index=0; | 137 static int state_num=0,state_index=0; |
| 142 static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH]; | 138 static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH]; |
| 143 static unsigned char md[MD_DIGEST_LENGTH]; | 139 static unsigned char md[MD_DIGEST_LENGTH]; |
| 144 static long md_count[2]={0,0}; | 140 static long md_count[2]={0,0}; |
| 145 static double entropy=0; | 141 static double entropy=0; |
| 146 static int initialized=0; | 142 static int initialized=0; |
| 147 | 143 |
| 148 static unsigned int crypto_lock_rand = 0; /* may be set only when a thread | 144 static unsigned int crypto_lock_rand = 0; /* may be set only when a thread |
| 149 * holds CRYPTO_LOCK_RAND | 145 * holds CRYPTO_LOCK_RAND |
| 150 * (to prevent double locking) */ | 146 * (to prevent double locking) */ |
| 151 /* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ | 147 /* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ |
| 152 static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */ | 148 static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */ |
| 153 | 149 |
| 154 | 150 |
| 155 #ifdef PREDICT | 151 #ifdef PREDICT |
| 156 int rand_predictable=0; | 152 int rand_predictable=0; |
| 157 #endif | 153 #endif |
| 158 | 154 |
| 159 const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT; | 155 const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT; |
| 160 | 156 |
| 161 static void ssleay_rand_cleanup(void); | 157 static void ssleay_rand_cleanup(void); |
| 162 static void ssleay_rand_seed(const void *buf, int num); | 158 static void ssleay_rand_seed(const void *buf, int num); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 210 * the current 'block', the new key data 'block', and 'count' | 206 * the current 'block', the new key data 'block', and 'count' |
| 211 * (which is incremented after each use). | 207 * (which is incremented after each use). |
| 212 * The result of this is kept in 'md' and also xored into the | 208 * The result of this is kept in 'md' and also xored into the |
| 213 * 'state' at the same locations that were used as input into the | 209 * 'state' at the same locations that were used as input into the |
| 214 * hash function. | 210 * hash function. |
| 215 */ | 211 */ |
| 216 | 212 |
| 217 /* check if we already have the lock */ | 213 /* check if we already have the lock */ |
| 218 if (crypto_lock_rand) | 214 if (crypto_lock_rand) |
| 219 { | 215 { |
| 216 CRYPTO_THREADID cur; |
| 217 CRYPTO_THREADID_current(&cur); |
| 220 CRYPTO_r_lock(CRYPTO_LOCK_RAND2); | 218 CRYPTO_r_lock(CRYPTO_LOCK_RAND2); |
| 221 » » do_not_lock = (locking_thread == CRYPTO_thread_id()); | 219 » » do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); |
| 222 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); | 220 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); |
| 223 } | 221 } |
| 224 else | 222 else |
| 225 do_not_lock = 0; | 223 do_not_lock = 0; |
| 226 | 224 |
| 227 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); | 225 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND); |
| 228 st_idx=state_index; | 226 st_idx=state_index; |
| 229 | 227 |
| 230 /* use our own copies of the counters so that even | 228 /* use our own copies of the counters so that even |
| 231 * if a concurrent thread seeds with exactly the | 229 * if a concurrent thread seeds with exactly the |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 267 MD_Init(&m); | 265 MD_Init(&m); |
| 268 MD_Update(&m,local_md,MD_DIGEST_LENGTH); | 266 MD_Update(&m,local_md,MD_DIGEST_LENGTH); |
| 269 k=(st_idx+j)-STATE_SIZE; | 267 k=(st_idx+j)-STATE_SIZE; |
| 270 if (k > 0) | 268 if (k > 0) |
| 271 { | 269 { |
| 272 MD_Update(&m,&(state[st_idx]),j-k); | 270 MD_Update(&m,&(state[st_idx]),j-k); |
| 273 MD_Update(&m,&(state[0]),k); | 271 MD_Update(&m,&(state[0]),k); |
| 274 } | 272 } |
| 275 else | 273 else |
| 276 MD_Update(&m,&(state[st_idx]),j); | 274 MD_Update(&m,&(state[st_idx]),j); |
| 277 » » » | 275 |
| 276 » » /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */ |
| 278 MD_Update(&m,buf,j); | 277 MD_Update(&m,buf,j); |
| 278 /* We know that line may cause programs such as |
| 279 purify and valgrind to complain about use of |
| 280 uninitialized data. The problem is not, it's |
| 281 with the caller. Removing that line will make |
| 282 sure you get really bad randomness and thereby |
| 283 other problems such as very insecure keys. */ |
| 284 |
| 279 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); | 285 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); |
| 280 MD_Final(&m,local_md); | 286 MD_Final(&m,local_md); |
| 281 md_c[1]++; | 287 md_c[1]++; |
| 282 | 288 |
| 283 buf=(const char *)buf + j; | 289 buf=(const char *)buf + j; |
| 284 | 290 |
| 285 for (k=0; k<j; k++) | 291 for (k=0; k<j; k++) |
| 286 { | 292 { |
| 287 /* Parallel threads may interfere with this, | 293 /* Parallel threads may interfere with this, |
| 288 * but always each byte of the new state is | 294 * but always each byte of the new state is |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 329 int num_ceil; | 335 int num_ceil; |
| 330 int ok; | 336 int ok; |
| 331 long md_c[2]; | 337 long md_c[2]; |
| 332 unsigned char local_md[MD_DIGEST_LENGTH]; | 338 unsigned char local_md[MD_DIGEST_LENGTH]; |
| 333 EVP_MD_CTX m; | 339 EVP_MD_CTX m; |
| 334 #ifndef GETPID_IS_MEANINGLESS | 340 #ifndef GETPID_IS_MEANINGLESS |
| 335 pid_t curr_pid = getpid(); | 341 pid_t curr_pid = getpid(); |
| 336 #endif | 342 #endif |
| 337 int do_stir_pool = 0; | 343 int do_stir_pool = 0; |
| 338 | 344 |
| 339 #ifdef OPENSSL_FIPS | |
| 340 if(FIPS_mode()) | |
| 341 { | |
| 342 FIPSerr(FIPS_F_SSLEAY_RAND_BYTES,FIPS_R_NON_FIPS_METHOD); | |
| 343 return 0; | |
| 344 } | |
| 345 #endif | |
| 346 | |
| 347 #ifdef PREDICT | 345 #ifdef PREDICT |
| 348 if (rand_predictable) | 346 if (rand_predictable) |
| 349 { | 347 { |
| 350 static unsigned char val=0; | 348 static unsigned char val=0; |
| 351 | 349 |
| 352 for (i=0; i<num; i++) | 350 for (i=0; i<num; i++) |
| 353 buf[i]=val++; | 351 buf[i]=val++; |
| 354 return(1); | 352 return(1); |
| 355 } | 353 } |
| 356 #endif | 354 #endif |
| (...skipping 20 matching lines...) Expand all Loading... |
| 377 * Finally, after we have finished 'num' random bytes for the | 375 * Finally, after we have finished 'num' random bytes for the |
| 378 * caller, 'count' (which is incremented) and the local and global 'md' | 376 * caller, 'count' (which is incremented) and the local and global 'md' |
| 379 * are fed into the hash function and the results are kept in the | 377 * are fed into the hash function and the results are kept in the |
| 380 * global 'md'. | 378 * global 'md'. |
| 381 */ | 379 */ |
| 382 | 380 |
| 383 CRYPTO_w_lock(CRYPTO_LOCK_RAND); | 381 CRYPTO_w_lock(CRYPTO_LOCK_RAND); |
| 384 | 382 |
| 385 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ | 383 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ |
| 386 CRYPTO_w_lock(CRYPTO_LOCK_RAND2); | 384 CRYPTO_w_lock(CRYPTO_LOCK_RAND2); |
| 387 » locking_thread = CRYPTO_thread_id(); | 385 » CRYPTO_THREADID_current(&locking_threadid); |
| 388 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); | 386 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); |
| 389 crypto_lock_rand = 1; | 387 crypto_lock_rand = 1; |
| 390 | 388 |
| 391 if (!initialized) | 389 if (!initialized) |
| 392 { | 390 { |
| 393 RAND_poll(); | 391 RAND_poll(); |
| 394 initialized = 1; | 392 initialized = 1; |
| 395 } | 393 } |
| 396 | 394 |
| 397 if (!stirred_pool) | 395 if (!stirred_pool) |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 MD_Init(&m); | 467 MD_Init(&m); |
| 470 #ifndef GETPID_IS_MEANINGLESS | 468 #ifndef GETPID_IS_MEANINGLESS |
| 471 if (curr_pid) /* just in the first iteration to save time */ | 469 if (curr_pid) /* just in the first iteration to save time */ |
| 472 { | 470 { |
| 473 MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid); | 471 MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid); |
| 474 curr_pid = 0; | 472 curr_pid = 0; |
| 475 } | 473 } |
| 476 #endif | 474 #endif |
| 477 MD_Update(&m,local_md,MD_DIGEST_LENGTH); | 475 MD_Update(&m,local_md,MD_DIGEST_LENGTH); |
| 478 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); | 476 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); |
| 479 #ifndef PURIFY | 477 |
| 480 » » MD_Update(&m,buf,j); /* purify complains */ | 478 #ifndef PURIFY /* purify complains */ |
| 479 » » /* The following line uses the supplied buffer as a small |
| 480 » » * source of entropy: since this buffer is often uninitialised |
| 481 » » * it may cause programs such as purify or valgrind to |
| 482 » » * complain. So for those builds it is not used: the removal |
| 483 » » * of such a small source of entropy has negligible impact on |
| 484 » » * security. |
| 485 » » */ |
| 486 » » MD_Update(&m,buf,j); |
| 481 #endif | 487 #endif |
| 488 |
| 482 k=(st_idx+MD_DIGEST_LENGTH/2)-st_num; | 489 k=(st_idx+MD_DIGEST_LENGTH/2)-st_num; |
| 483 if (k > 0) | 490 if (k > 0) |
| 484 { | 491 { |
| 485 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k); | 492 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k); |
| 486 MD_Update(&m,&(state[0]),k); | 493 MD_Update(&m,&(state[0]),k); |
| 487 } | 494 } |
| 488 else | 495 else |
| 489 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); | 496 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); |
| 490 MD_Final(&m,local_md); | 497 MD_Final(&m,local_md); |
| 491 | 498 |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 err = ERR_peek_error(); | 539 err = ERR_peek_error(); |
| 533 if (ERR_GET_LIB(err) == ERR_LIB_RAND && | 540 if (ERR_GET_LIB(err) == ERR_LIB_RAND && |
| 534 ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED) | 541 ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED) |
| 535 ERR_clear_error(); | 542 ERR_clear_error(); |
| 536 } | 543 } |
| 537 return (ret); | 544 return (ret); |
| 538 } | 545 } |
| 539 | 546 |
| 540 static int ssleay_rand_status(void) | 547 static int ssleay_rand_status(void) |
| 541 { | 548 { |
| 549 CRYPTO_THREADID cur; |
| 542 int ret; | 550 int ret; |
| 543 int do_not_lock; | 551 int do_not_lock; |
| 544 | 552 |
| 553 CRYPTO_THREADID_current(&cur); |
| 545 /* check if we already have the lock | 554 /* check if we already have the lock |
| 546 * (could happen if a RAND_poll() implementation calls RAND_status()) */ | 555 * (could happen if a RAND_poll() implementation calls RAND_status()) */ |
| 547 if (crypto_lock_rand) | 556 if (crypto_lock_rand) |
| 548 { | 557 { |
| 549 CRYPTO_r_lock(CRYPTO_LOCK_RAND2); | 558 CRYPTO_r_lock(CRYPTO_LOCK_RAND2); |
| 550 » » do_not_lock = (locking_thread == CRYPTO_thread_id()); | 559 » » do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur); |
| 551 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); | 560 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); |
| 552 } | 561 } |
| 553 else | 562 else |
| 554 do_not_lock = 0; | 563 do_not_lock = 0; |
| 555 | 564 |
| 556 if (!do_not_lock) | 565 if (!do_not_lock) |
| 557 { | 566 { |
| 558 CRYPTO_w_lock(CRYPTO_LOCK_RAND); | 567 CRYPTO_w_lock(CRYPTO_LOCK_RAND); |
| 559 | 568 |
| 560 /* prevent ssleay_rand_bytes() from trying to obtain the lock ag
ain */ | 569 /* prevent ssleay_rand_bytes() from trying to obtain the lock ag
ain */ |
| 561 CRYPTO_w_lock(CRYPTO_LOCK_RAND2); | 570 CRYPTO_w_lock(CRYPTO_LOCK_RAND2); |
| 562 » » locking_thread = CRYPTO_thread_id(); | 571 » » CRYPTO_THREADID_cpy(&locking_threadid, &cur); |
| 563 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); | 572 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); |
| 564 crypto_lock_rand = 1; | 573 crypto_lock_rand = 1; |
| 565 } | 574 } |
| 566 | 575 |
| 567 if (!initialized) | 576 if (!initialized) |
| 568 { | 577 { |
| 569 RAND_poll(); | 578 RAND_poll(); |
| 570 initialized = 1; | 579 initialized = 1; |
| 571 } | 580 } |
| 572 | 581 |
| 573 ret = entropy >= ENTROPY_NEEDED; | 582 ret = entropy >= ENTROPY_NEEDED; |
| 574 | 583 |
| 575 if (!do_not_lock) | 584 if (!do_not_lock) |
| 576 { | 585 { |
| 577 /* before unlocking, we must clear 'crypto_lock_rand' */ | 586 /* before unlocking, we must clear 'crypto_lock_rand' */ |
| 578 crypto_lock_rand = 0; | 587 crypto_lock_rand = 0; |
| 579 | 588 |
| 580 CRYPTO_w_unlock(CRYPTO_LOCK_RAND); | 589 CRYPTO_w_unlock(CRYPTO_LOCK_RAND); |
| 581 } | 590 } |
| 582 | 591 |
| 583 return ret; | 592 return ret; |
| 584 } | 593 } |
| OLD | NEW |