diff options
author | markus <> | 2001-08-01 15:31:16 +0000 |
---|---|---|
committer | markus <> | 2001-08-01 15:31:16 +0000 |
commit | edbfd6c7e91e15e92ef0df548474ac76b6dddca0 (patch) | |
tree | e4d1853e68dcd79943183de0fa5ff0ead4d4b0ca /src/lib/libcrypto | |
parent | c1afda90dd79b98367107633d387abc265dfca60 (diff) | |
download | openbsd-edbfd6c7e91e15e92ef0df548474ac76b6dddca0.tar.gz openbsd-edbfd6c7e91e15e92ef0df548474ac76b6dddca0.tar.bz2 openbsd-edbfd6c7e91e15e92ef0df548474ac76b6dddca0.zip |
http://www.openssl.org/news/secadv_prng.txt; ok beck@
Diffstat (limited to 'src/lib/libcrypto')
-rw-r--r-- | src/lib/libcrypto/rand/md_rand.c | 25 |
1 files changed, 17 insertions, 8 deletions
diff --git a/src/lib/libcrypto/rand/md_rand.c b/src/lib/libcrypto/rand/md_rand.c index 567838f6c3..ae57570608 100644 --- a/src/lib/libcrypto/rand/md_rand.c +++ b/src/lib/libcrypto/rand/md_rand.c | |||
@@ -308,6 +308,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) | |||
308 | { | 308 | { |
309 | static volatile int stirred_pool = 0; | 309 | static volatile int stirred_pool = 0; |
310 | int i,j,k,st_num,st_idx; | 310 | int i,j,k,st_num,st_idx; |
311 | int num_ceil; | ||
311 | int ok; | 312 | int ok; |
312 | long md_c[2]; | 313 | long md_c[2]; |
313 | unsigned char local_md[MD_DIGEST_LENGTH]; | 314 | unsigned char local_md[MD_DIGEST_LENGTH]; |
@@ -328,6 +329,12 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) | |||
328 | } | 329 | } |
329 | #endif | 330 | #endif |
330 | 331 | ||
332 | if (num <= 0) | ||
333 | return 1; | ||
334 | |||
335 | /* round upwards to multiple of MD_DIGEST_LENGTH/2 */ | ||
336 | num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2); | ||
337 | |||
331 | /* | 338 | /* |
332 | * (Based on the rand(3) manpage:) | 339 | * (Based on the rand(3) manpage:) |
333 | * | 340 | * |
@@ -409,11 +416,11 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) | |||
409 | md_c[1] = md_count[1]; | 416 | md_c[1] = md_count[1]; |
410 | memcpy(local_md, md, sizeof md); | 417 | memcpy(local_md, md, sizeof md); |
411 | 418 | ||
412 | state_index+=num; | 419 | state_index+=num_ceil; |
413 | if (state_index > state_num) | 420 | if (state_index > state_num) |
414 | state_index %= state_num; | 421 | state_index %= state_num; |
415 | 422 | ||
416 | /* state[st_idx], ..., state[(st_idx + num - 1) % st_num] | 423 | /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] |
417 | * are now ours (but other threads may use them too) */ | 424 | * are now ours (but other threads may use them too) */ |
418 | 425 | ||
419 | md_count[0] += 1; | 426 | md_count[0] += 1; |
@@ -424,6 +431,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) | |||
424 | 431 | ||
425 | while (num > 0) | 432 | while (num > 0) |
426 | { | 433 | { |
434 | /* num_ceil -= MD_DIGEST_LENGTH/2 */ | ||
427 | j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num; | 435 | j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num; |
428 | num-=j; | 436 | num-=j; |
429 | MD_Init(&m); | 437 | MD_Init(&m); |
@@ -434,27 +442,28 @@ static int ssleay_rand_bytes(unsigned char *buf, int num) | |||
434 | curr_pid = 0; | 442 | curr_pid = 0; |
435 | } | 443 | } |
436 | #endif | 444 | #endif |
437 | MD_Update(&m,&(local_md[MD_DIGEST_LENGTH/2]),MD_DIGEST_LENGTH/2); | 445 | MD_Update(&m,local_md,MD_DIGEST_LENGTH); |
438 | MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); | 446 | MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)); |
439 | #ifndef PURIFY | 447 | #ifndef PURIFY |
440 | MD_Update(&m,buf,j); /* purify complains */ | 448 | MD_Update(&m,buf,j); /* purify complains */ |
441 | #endif | 449 | #endif |
442 | k=(st_idx+j)-st_num; | 450 | k=(st_idx+MD_DIGEST_LENGTH/2)-st_num; |
443 | if (k > 0) | 451 | if (k > 0) |
444 | { | 452 | { |
445 | MD_Update(&m,&(state[st_idx]),j-k); | 453 | MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k); |
446 | MD_Update(&m,&(state[0]),k); | 454 | MD_Update(&m,&(state[0]),k); |
447 | } | 455 | } |
448 | else | 456 | else |
449 | MD_Update(&m,&(state[st_idx]),j); | 457 | MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2); |
450 | MD_Final(local_md,&m); | 458 | MD_Final(local_md,&m); |
451 | 459 | ||
452 | for (i=0; i<j; i++) | 460 | for (i=0; i<MD_DIGEST_LENGTH/2; i++) |
453 | { | 461 | { |
454 | state[st_idx++]^=local_md[i]; /* may compete with other threads */ | 462 | state[st_idx++]^=local_md[i]; /* may compete with other threads */ |
455 | *(buf++)=local_md[i+MD_DIGEST_LENGTH/2]; | ||
456 | if (st_idx >= st_num) | 463 | if (st_idx >= st_num) |
457 | st_idx=0; | 464 | st_idx=0; |
465 | if (i < j) | ||
466 | *(buf++)=local_md[i+MD_DIGEST_LENGTH/2]; | ||
458 | } | 467 | } |
459 | } | 468 | } |
460 | 469 | ||