]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/rand/md_rand.c
Change OPENSSL_FIPSEVP to OPENSSL_FIPSAPI as it doesn't just refer
[thirdparty/openssl.git] / crypto / rand / md_rand.c
CommitLineData
a6aa71ff 1/* crypto/rand/md_rand.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
3 * All rights reserved.
4 *
5 * This package is an SSL implementation written
6 * by Eric Young (eay@cryptsoft.com).
7 * The implementation was written so as to conform with Netscapes SSL.
8 *
9 * This library is free for commercial and non-commercial use as long as
10 * the following conditions are aheared to. The following conditions
11 * apply to all code found in this distribution, be it the RC4, RSA,
12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 * included with this distribution is covered by the same copyright terms
14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 *
16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 * the code are not to be removed.
18 * If this package is used in a product, Eric Young should be given attribution
19 * as the author of the parts of the library used.
20 * This can be in the form of a textual message at program startup or
21 * in documentation (online or textual) provided with the package.
22 *
23 * Redistribution and use in source and binary forms, with or without
24 * modification, are permitted provided that the following conditions
25 * are met:
26 * 1. Redistributions of source code must retain the copyright
27 * notice, this list of conditions and the following disclaimer.
28 * 2. Redistributions in binary form must reproduce the above copyright
29 * notice, this list of conditions and the following disclaimer in the
30 * documentation and/or other materials provided with the distribution.
31 * 3. All advertising materials mentioning features or use of this software
32 * must display the following acknowledgement:
33 * "This product includes cryptographic software written by
34 * Eric Young (eay@cryptsoft.com)"
35 * The word 'cryptographic' can be left out if the rouines from the library
36 * being used are not cryptographic related :-).
37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 * the apps directory (application code) you must include an acknowledgement:
39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 *
41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 * SUCH DAMAGE.
52 *
53 * The licence and distribution terms for any publically available version or
54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 * copied and put under another distribution licence
56 * [including the GNU Public Licence.]
57 */
863fe2ec 58/* ====================================================================
f9b0f47c 59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
863fe2ec
BM
60 *
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
63 * are met:
64 *
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
67 *
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
71 * distribution.
72 *
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 *
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
82 *
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
86 *
87 * 6. Redistributions of any form whatsoever must retain the following
88 * acknowledgment:
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 *
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
105 *
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
109 *
110 */
d02b48c6 111
7c8ced94 112#define OPENSSL_FIPSAPI
4ead4e52 113
2ace287d 114#ifdef MD_RAND_DEBUG
c1e744b9
BM
115# ifndef NDEBUG
116# define NDEBUG
117# endif
118#endif
119
120#include <assert.h>
d02b48c6 121#include <stdio.h>
a224de3f 122#include <string.h>
17e3dd1c 123
41d2a336 124#include "e_os.h"
17e3dd1c 125
8ad7635e
UM
126#include <openssl/rand.h>
127#include "rand_lcl.h"
128
ec577822 129#include <openssl/crypto.h>
eb952088 130#include <openssl/err.h>
d02b48c6 131
e64dceab
UM
132#ifdef BN_DEBUG
133# define PREDICT
134#endif
135
dfeab068 136/* #define PREDICT 1 */
d02b48c6
RE
137
138#define STATE_SIZE 1023
139static int state_num=0,state_index=0;
58964a49 140static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
d02b48c6 141static unsigned char md[MD_DIGEST_LENGTH];
dfeab068 142static long md_count[2]={0,0};
853f757e 143static double entropy=0;
4ec2d4d2 144static int initialized=0;
d02b48c6 145
6e6d04e2
BM
146static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
147 * holds CRYPTO_LOCK_RAND
148 * (to prevent double locking) */
daba492c 149/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
4c329696 150static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
6e6d04e2 151
a4125514 152
e64dceab
UM
153#ifdef PREDICT
154int rand_predictable=0;
155#endif
156
560b79cb 157const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
d02b48c6 158
dfeab068 159static void ssleay_rand_cleanup(void);
b6dcdbfc
DSH
160static int ssleay_rand_seed(const void *buf, int num);
161static int ssleay_rand_add(const void *buf, int num, double add_entropy);
4ead4e52
DSH
162static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo);
163static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
6343829a 164static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
5eb8ca4d 165static int ssleay_rand_status(void);
dfeab068 166
651d0aff 167RAND_METHOD rand_ssleay_meth={
dfeab068 168 ssleay_rand_seed,
4ead4e52 169 ssleay_rand_nopseudo_bytes,
dfeab068 170 ssleay_rand_cleanup,
eb952088 171 ssleay_rand_add,
373b575f 172 ssleay_rand_pseudo_bytes,
5eb8ca4d 173 ssleay_rand_status
dfeab068
RE
174 };
175
6b691a5c 176RAND_METHOD *RAND_SSLeay(void)
dfeab068 177 {
651d0aff 178 return(&rand_ssleay_meth);
dfeab068
RE
179 }
180
6b691a5c 181static void ssleay_rand_cleanup(void)
d02b48c6 182 {
4579924b 183 OPENSSL_cleanse(state,sizeof(state));
d02b48c6
RE
184 state_num=0;
185 state_index=0;
4579924b 186 OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
dfeab068
RE
187 md_count[0]=0;
188 md_count[1]=0;
eb952088 189 entropy=0;
d3093944 190 initialized=0;
d02b48c6
RE
191 }
192
b6dcdbfc 193static int ssleay_rand_add(const void *buf, int num, double add)
d02b48c6 194 {
6343829a 195 int i,j,k,st_idx;
c1e744b9
BM
196 long md_c[2];
197 unsigned char local_md[MD_DIGEST_LENGTH];
dbad1690 198 EVP_MD_CTX m;
6e6d04e2 199 int do_not_lock;
b6dcdbfc 200 int rv = 0;
d02b48c6 201
c1e744b9 202 /*
60b52453 203 * (Based on the rand(3) manpage)
c1e744b9 204 *
c88a900f 205 * The input is chopped up into units of 20 bytes (or less for
60b52453 206 * the last block). Each of these blocks is run through the hash
0b5cfe32 207 * function as follows: The data passed to the hash function
c1e744b9
BM
208 * is the current 'md', the same number of bytes from the 'state'
209 * (the location determined by in incremented looping index) as
210 * the current 'block', the new key data 'block', and 'count'
211 * (which is incremented after each use).
212 * The result of this is kept in 'md' and also xored into the
60b52453
UM
213 * 'state' at the same locations that were used as input into the
214 * hash function.
c1e744b9
BM
215 */
216
b6dcdbfc 217 EVP_MD_CTX_init(&m);
6e6d04e2 218 /* check if we already have the lock */
daba492c
BM
219 if (crypto_lock_rand)
220 {
4c329696
GT
221 CRYPTO_THREADID cur;
222 CRYPTO_THREADID_current(&cur);
daba492c 223 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
4c329696 224 do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
daba492c
BM
225 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
226 }
227 else
228 do_not_lock = 0;
6e6d04e2
BM
229
230 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
d02b48c6 231 st_idx=state_index;
d02b48c6 232
c1e744b9
BM
233 /* use our own copies of the counters so that even
234 * if a concurrent thread seeds with exactly the
235 * same data and uses the same subarray there's _some_
236 * difference */
237 md_c[0] = md_count[0];
238 md_c[1] = md_count[1];
239
240 memcpy(local_md, md, sizeof md);
241
242 /* state_index <= state_num <= STATE_SIZE */
243 state_index += num;
58964a49 244 if (state_index >= STATE_SIZE)
d02b48c6
RE
245 {
246 state_index%=STATE_SIZE;
247 state_num=STATE_SIZE;
248 }
249 else if (state_num < STATE_SIZE)
250 {
251 if (state_index > state_num)
252 state_num=state_index;
253 }
c1e744b9
BM
254 /* state_index <= state_num <= STATE_SIZE */
255
256 /* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
257 * are what we will use now, but other threads may use them
258 * as well */
259
260 md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
261
6e6d04e2 262 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
d02b48c6
RE
263
264 for (i=0; i<num; i+=MD_DIGEST_LENGTH)
265 {
266 j=(num-i);
267 j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
268
b6dcdbfc
DSH
269 if (!MD_Init(&m))
270 goto err;
271 if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
272 goto err;
d02b48c6
RE
273 k=(st_idx+j)-STATE_SIZE;
274 if (k > 0)
275 {
b6dcdbfc
DSH
276 if (!MD_Update(&m,&(state[st_idx]),j-k))
277 goto err;
278 if (!MD_Update(&m,&(state[0]),k))
279 goto err;
d02b48c6
RE
280 }
281 else
b6dcdbfc
DSH
282 if (!MD_Update(&m,&(state[st_idx]),j))
283 goto err;
792bbc23
RL
284
285 /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
b6dcdbfc
DSH
286 if (!MD_Update(&m,buf,j))
287 goto err;
792bbc23
RL
288 /* We know that line may cause programs such as
289 purify and valgrind to complain about use of
290 uninitialized data. The problem is not, it's
291 with the caller. Removing that line will make
292 sure you get really bad randomness and thereby
293 other problems such as very insecure keys. */
294
b6dcdbfc
DSH
295 if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)))
296 goto err;
297 if (!MD_Final(&m,local_md))
298 goto err;
c1e744b9 299 md_c[1]++;
d02b48c6 300
e778802f 301 buf=(const char *)buf + j;
d02b48c6
RE
302
303 for (k=0; k<j; k++)
304 {
c1e744b9
BM
305 /* Parallel threads may interfere with this,
306 * but always each byte of the new state is
307 * the XOR of some previous value of its
308 * and local_md (itermediate values may be lost).
309 * Alway using locking could hurt performance more
310 * than necessary given that conflicts occur only
311 * when the total seeding is longer than the random
312 * state. */
313 state[st_idx++]^=local_md[k];
d02b48c6 314 if (st_idx >= STATE_SIZE)
d02b48c6 315 st_idx=0;
d02b48c6
RE
316 }
317 }
c1e744b9 318
6e6d04e2 319 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
c1e744b9
BM
320 /* Don't just copy back local_md into md -- this could mean that
321 * other thread's seeding remains without effect (except for
322 * the incremented counter). By XORing it we keep at least as
323 * much entropy as fits into md. */
6343829a 324 for (k = 0; k < (int)sizeof(md); k++)
c1e744b9
BM
325 {
326 md[k] ^= local_md[k];
327 }
c6709c6b
BM
328 if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
329 entropy += add;
6e6d04e2 330 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
c1e744b9 331
bc36ee62 332#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
c1e744b9
BM
333 assert(md_c[1] == md_count[1]);
334#endif
b6dcdbfc
DSH
335 rv = 1;
336 err:
337 EVP_MD_CTX_cleanup(&m);
338 return rv;
eb952088
UM
339 }
340
b6dcdbfc 341static int ssleay_rand_seed(const void *buf, int num)
eb952088 342 {
b6dcdbfc 343 return ssleay_rand_add(buf, num, (double)num);
d02b48c6
RE
344 }
345
4ead4e52 346static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
d02b48c6 347 {
361ee973 348 static volatile int stirred_pool = 0;
6343829a 349 int i,j,k,st_num,st_idx;
e9ad0d2c 350 int num_ceil;
eb952088 351 int ok;
c1e744b9
BM
352 long md_c[2];
353 unsigned char local_md[MD_DIGEST_LENGTH];
dbad1690 354 EVP_MD_CTX m;
9a1e34e5 355#ifndef GETPID_IS_MEANINGLESS
62ac2938 356 pid_t curr_pid = getpid();
c1e744b9 357#endif
361ee973 358 int do_stir_pool = 0;
d02b48c6
RE
359
360#ifdef PREDICT
e64dceab
UM
361 if (rand_predictable)
362 {
363 static unsigned char val=0;
d02b48c6 364
e64dceab
UM
365 for (i=0; i<num; i++)
366 buf[i]=val++;
367 return(1);
368 }
d02b48c6
RE
369#endif
370
e9ad0d2c
BM
371 if (num <= 0)
372 return 1;
dbad1690
BL
373
374 EVP_MD_CTX_init(&m);
e9ad0d2c
BM
375 /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
376 num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
377
c1e744b9 378 /*
2c8aeddc 379 * (Based on the rand(3) manpage:)
c1e744b9 380 *
c88a900f 381 * For each group of 10 bytes (or less), we do the following:
c1e744b9 382 *
e9ad0d2c
BM
383 * Input into the hash function the local 'md' (which is initialized from
384 * the global 'md' before any bytes are generated), the bytes that are to
385 * be overwritten by the random bytes, and bytes from the 'state'
386 * (incrementing looping index). From this digest output (which is kept
387 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
388 * bottom 10 bytes are xored into the 'state'.
389 *
c1e744b9 390 * Finally, after we have finished 'num' random bytes for the
2c8aeddc
BM
391 * caller, 'count' (which is incremented) and the local and global 'md'
392 * are fed into the hash function and the results are kept in the
393 * global 'md'.
c1e744b9
BM
394 */
395
8ad7635e 396 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
d02b48c6 397
6e6d04e2 398 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
daba492c 399 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
4c329696 400 CRYPTO_THREADID_current(&locking_threadid);
daba492c 401 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
badb910f 402 crypto_lock_rand = 1;
6e6d04e2
BM
403
404 if (!initialized)
405 {
406 RAND_poll();
407 initialized = 1;
408 }
409
361ee973
BM
410 if (!stirred_pool)
411 do_stir_pool = 1;
412
eb952088 413 ok = (entropy >= ENTROPY_NEEDED);
c6709c6b
BM
414 if (!ok)
415 {
416 /* If the PRNG state is not yet unpredictable, then seeing
417 * the PRNG output may help attackers to determine the new
418 * state; thus we have to decrease the entropy estimate.
419 * Once we've had enough initial seeding we don't bother to
420 * adjust the entropy count, though, because we're not ambitious
421 * to provide *information-theoretic* randomness.
361ee973
BM
422 *
423 * NOTE: This approach fails if the program forks before
424 * we have enough entropy. Entropy should be collected
425 * in a separate input pool and be transferred to the
426 * output pool only when the entropy limit has been reached.
c6709c6b
BM
427 */
428 entropy -= num;
429 if (entropy < 0)
430 entropy = 0;
431 }
eb952088 432
361ee973
BM
433 if (do_stir_pool)
434 {
e9ad0d2c
BM
435 /* In the output function only half of 'md' remains secret,
436 * so we better make sure that the required entropy gets
437 * 'evenly distributed' through 'state', our randomness pool.
438 * The input function (ssleay_rand_add) chains all of 'md',
439 * which makes it more suitable for this purpose.
361ee973
BM
440 */
441
442 int n = STATE_SIZE; /* so that the complete pool gets accessed */
443 while (n > 0)
444 {
445#if MD_DIGEST_LENGTH > 20
446# error "Please adjust DUMMY_SEED."
447#endif
448#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
449 /* Note that the seed does not matter, it's just that
450 * ssleay_rand_add expects to have something to hash. */
451 ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
452 n -= MD_DIGEST_LENGTH;
453 }
454 if (ok)
455 stirred_pool = 1;
456 }
457
d02b48c6
RE
458 st_idx=state_index;
459 st_num=state_num;
c1e744b9
BM
460 md_c[0] = md_count[0];
461 md_c[1] = md_count[1];
462 memcpy(local_md, md, sizeof md);
463
e9ad0d2c 464 state_index+=num_ceil;
d02b48c6 465 if (state_index > state_num)
c1e744b9
BM
466 state_index %= state_num;
467
e9ad0d2c 468 /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
c1e744b9 469 * are now ours (but other threads may use them too) */
d02b48c6 470
c1e744b9 471 md_count[0] += 1;
a4125514 472
6e6d04e2
BM
473 /* before unlocking, we must clear 'crypto_lock_rand' */
474 crypto_lock_rand = 0;
d02b48c6
RE
475 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
476
477 while (num > 0)
478 {
e9ad0d2c 479 /* num_ceil -= MD_DIGEST_LENGTH/2 */
d02b48c6
RE
480 j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
481 num-=j;
b6dcdbfc
DSH
482 if (!MD_Init(&m))
483 goto err;
9a1e34e5 484#ifndef GETPID_IS_MEANINGLESS
62ac2938
BM
485 if (curr_pid) /* just in the first iteration to save time */
486 {
b6dcdbfc
DSH
487 if (!MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid))
488 goto err;
62ac2938
BM
489 curr_pid = 0;
490 }
491#endif
b6dcdbfc
DSH
492 if (!MD_Update(&m,local_md,MD_DIGEST_LENGTH))
493 goto err;
494 if (!MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c)))
495 goto err;
792bbc23
RL
496
497#ifndef PURIFY /* purify complains */
a7c64928
DSH
498 /* The following line uses the supplied buffer as a small
499 * source of entropy: since this buffer is often uninitialised
500 * it may cause programs such as purify or valgrind to
501 * complain. So for those builds it is not used: the removal
502 * of such a small source of entropy has negligible impact on
503 * security.
504 */
b6dcdbfc
DSH
505 if (!MD_Update(&m,buf,j))
506 goto err;
d02b48c6 507#endif
792bbc23 508
e9ad0d2c 509 k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
d02b48c6
RE
510 if (k > 0)
511 {
b6dcdbfc
DSH
512 if (!MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k))
513 goto err;
514 if (!MD_Update(&m,&(state[0]),k))
515 goto err;
d02b48c6
RE
516 }
517 else
b6dcdbfc
DSH
518 if (!MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2))
519 goto err;
520 if (!MD_Final(&m,local_md))
521 goto err;
d02b48c6 522
e9ad0d2c 523 for (i=0; i<MD_DIGEST_LENGTH/2; i++)
d02b48c6 524 {
c1e744b9 525 state[st_idx++]^=local_md[i]; /* may compete with other threads */
d02b48c6
RE
526 if (st_idx >= st_num)
527 st_idx=0;
e9ad0d2c
BM
528 if (i < j)
529 *(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
d02b48c6
RE
530 }
531 }
532
b6dcdbfc
DSH
533 if (!MD_Init(&m)
534 || !MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c))
535 || !MD_Update(&m,local_md,MD_DIGEST_LENGTH))
536 goto err;
c1e744b9 537 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
b6dcdbfc
DSH
538 if (!MD_Update(&m,md,MD_DIGEST_LENGTH) || !MD_Final(&m,md))
539 {
540 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
541 goto err;
542 }
c1e744b9
BM
543 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
544
dbad1690 545 EVP_MD_CTX_cleanup(&m);
eb952088
UM
546 if (ok)
547 return(1);
4ead4e52
DSH
548 else if (pseudo)
549 return 0;
550 else
eb952088
UM
551 {
552 RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
3b3bc455
RL
553 ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
554 "http://www.openssl.org/support/faq.html");
eb952088
UM
555 return(0);
556 }
b6dcdbfc
DSH
557 err:
558 EVP_MD_CTX_cleanup(&m);
559 RANDerr(RAND_F_SSLEAY_RAND_BYTES,ERR_R_EVP_LIB);
560 return 0;
561
d02b48c6
RE
562 }
563
4ead4e52
DSH
564static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
565 {
566 return ssleay_rand_bytes(buf, num, 0);
567 }
568
373b575f
UM
569/* pseudo-random bytes that are guaranteed to be unique but not
570 unpredictable */
6343829a 571static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
373b575f 572 {
4ead4e52 573 return ssleay_rand_bytes(buf, num, 1);
373b575f
UM
574 }
575
5eb8ca4d 576static int ssleay_rand_status(void)
4ec2d4d2 577 {
4c329696 578 CRYPTO_THREADID cur;
b841e0ac 579 int ret;
6e6d04e2 580 int do_not_lock;
b841e0ac 581
4c329696 582 CRYPTO_THREADID_current(&cur);
6e6d04e2
BM
583 /* check if we already have the lock
584 * (could happen if a RAND_poll() implementation calls RAND_status()) */
daba492c
BM
585 if (crypto_lock_rand)
586 {
587 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
4c329696 588 do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
daba492c
BM
589 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
590 }
591 else
592 do_not_lock = 0;
6e6d04e2
BM
593
594 if (!do_not_lock)
595 {
596 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
597
598 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
daba492c 599 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
4c329696 600 CRYPTO_THREADID_cpy(&locking_threadid, &cur);
daba492c 601 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
badb910f 602 crypto_lock_rand = 1;
6e6d04e2
BM
603 }
604
4ec2d4d2 605 if (!initialized)
6e6d04e2 606 {
8ad7635e 607 RAND_poll();
6e6d04e2
BM
608 initialized = 1;
609 }
7ae634de 610
8ad7635e 611 ret = entropy >= ENTROPY_NEEDED;
7ae634de 612
6e6d04e2
BM
613 if (!do_not_lock)
614 {
615 /* before unlocking, we must clear 'crypto_lock_rand' */
616 crypto_lock_rand = 0;
6e6d04e2
BM
617
618 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
619 }
620
b841e0ac 621 return ret;
4ec2d4d2 622 }