source: EcnlProtoTool/trunk/openssl-1.1.0e/crypto/rand/md_rand.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc
File size: 18.5 KB
Line 
1/*
2 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
8 */
9
10#include <stdio.h>
11#include <string.h>
12
13#include "e_os.h"
14
15#if !(defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_DSPBIOS))
16# include <sys/time.h>
17#endif
18#if defined(OPENSSL_SYS_VXWORKS)
19# include <time.h>
20#endif
21
22#include <openssl/opensslconf.h>
23#include <openssl/crypto.h>
24#include <openssl/rand.h>
25#include <openssl/async.h>
26#include "rand_lcl.h"
27
28#include <openssl/err.h>
29
30#include <internal/thread_once.h>
31
32#ifdef OPENSSL_FIPS
33# include <openssl/fips.h>
34#endif
35
36#ifdef BN_DEBUG
37# define PREDICT
38#endif
39
40/* #define PREDICT 1 */
41
42#define STATE_SIZE 1023
43static size_t state_num = 0, state_index = 0;
44static unsigned char state[STATE_SIZE + MD_DIGEST_LENGTH];
45static unsigned char md[MD_DIGEST_LENGTH];
46static long md_count[2] = { 0, 0 };
47
48static double entropy = 0;
49static int initialized = 0;
50
51static CRYPTO_RWLOCK *rand_lock = NULL;
52static CRYPTO_RWLOCK *rand_tmp_lock = NULL;
53static CRYPTO_ONCE rand_lock_init = CRYPTO_ONCE_STATIC_INIT;
54
55/* May be set only when a thread holds rand_lock (to prevent double locking) */
56static unsigned int crypto_lock_rand = 0;
57/* access to locking_threadid is synchronized by rand_tmp_lock */
58/* valid iff crypto_lock_rand is set */
59static CRYPTO_THREAD_ID locking_threadid;
60
61#ifdef PREDICT
62int rand_predictable = 0;
63#endif
64
65static int rand_hw_seed(EVP_MD_CTX *ctx);
66
67static void rand_cleanup(void);
68static int rand_seed(const void *buf, int num);
69static int rand_add(const void *buf, int num, double add_entropy);
70static int rand_bytes(unsigned char *buf, int num, int pseudo);
71static int rand_nopseudo_bytes(unsigned char *buf, int num);
72#if OPENSSL_API_COMPAT < 0x10100000L
73static int rand_pseudo_bytes(unsigned char *buf, int num);
74#endif
75static int rand_status(void);
76
77static RAND_METHOD rand_meth = {
78 rand_seed,
79 rand_nopseudo_bytes,
80 rand_cleanup,
81 rand_add,
82#if OPENSSL_API_COMPAT < 0x10100000L
83 rand_pseudo_bytes,
84#else
85 NULL,
86#endif
87 rand_status
88};
89
90DEFINE_RUN_ONCE_STATIC(do_rand_lock_init)
91{
92 OPENSSL_init_crypto(0, NULL);
93 rand_lock = CRYPTO_THREAD_lock_new();
94 rand_tmp_lock = CRYPTO_THREAD_lock_new();
95 return rand_lock != NULL && rand_tmp_lock != NULL;
96}
97
98RAND_METHOD *RAND_OpenSSL(void)
99{
100 return (&rand_meth);
101}
102
103static void rand_cleanup(void)
104{
105 OPENSSL_cleanse(state, sizeof(state));
106 state_num = 0;
107 state_index = 0;
108 OPENSSL_cleanse(md, MD_DIGEST_LENGTH);
109 md_count[0] = 0;
110 md_count[1] = 0;
111 entropy = 0;
112 initialized = 0;
113 CRYPTO_THREAD_lock_free(rand_lock);
114 CRYPTO_THREAD_lock_free(rand_tmp_lock);
115}
116
117static int rand_add(const void *buf, int num, double add)
118{
119 int i, j, k, st_idx;
120 long md_c[2];
121 unsigned char local_md[MD_DIGEST_LENGTH];
122 EVP_MD_CTX *m;
123 int do_not_lock;
124 int rv = 0;
125
126 if (!num)
127 return 1;
128
129 /*
130 * (Based on the rand(3) manpage)
131 *
132 * The input is chopped up into units of 20 bytes (or less for
133 * the last block). Each of these blocks is run through the hash
134 * function as follows: The data passed to the hash function
135 * is the current 'md', the same number of bytes from the 'state'
136 * (the location determined by in incremented looping index) as
137 * the current 'block', the new key data 'block', and 'count'
138 * (which is incremented after each use).
139 * The result of this is kept in 'md' and also xored into the
140 * 'state' at the same locations that were used as input into the
141 * hash function.
142 */
143
144 m = EVP_MD_CTX_new();
145 if (m == NULL)
146 goto err;
147
148 if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
149 goto err;
150
151 /* check if we already have the lock */
152 if (crypto_lock_rand) {
153 CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
154 CRYPTO_THREAD_read_lock(rand_tmp_lock);
155 do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
156 CRYPTO_THREAD_unlock(rand_tmp_lock);
157 } else
158 do_not_lock = 0;
159
160 if (!do_not_lock)
161 CRYPTO_THREAD_write_lock(rand_lock);
162 st_idx = state_index;
163
164 /*
165 * use our own copies of the counters so that even if a concurrent thread
166 * seeds with exactly the same data and uses the same subarray there's
167 * _some_ difference
168 */
169 md_c[0] = md_count[0];
170 md_c[1] = md_count[1];
171
172 memcpy(local_md, md, sizeof md);
173
174 /* state_index <= state_num <= STATE_SIZE */
175 state_index += num;
176 if (state_index >= STATE_SIZE) {
177 state_index %= STATE_SIZE;
178 state_num = STATE_SIZE;
179 } else if (state_num < STATE_SIZE) {
180 if (state_index > state_num)
181 state_num = state_index;
182 }
183 /* state_index <= state_num <= STATE_SIZE */
184
185 /*
186 * state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE] are what we
187 * will use now, but other threads may use them as well
188 */
189
190 md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
191
192 if (!do_not_lock)
193 CRYPTO_THREAD_unlock(rand_lock);
194
195 for (i = 0; i < num; i += MD_DIGEST_LENGTH) {
196 j = (num - i);
197 j = (j > MD_DIGEST_LENGTH) ? MD_DIGEST_LENGTH : j;
198
199 if (!MD_Init(m))
200 goto err;
201 if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
202 goto err;
203 k = (st_idx + j) - STATE_SIZE;
204 if (k > 0) {
205 if (!MD_Update(m, &(state[st_idx]), j - k))
206 goto err;
207 if (!MD_Update(m, &(state[0]), k))
208 goto err;
209 } else if (!MD_Update(m, &(state[st_idx]), j))
210 goto err;
211
212 /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
213 if (!MD_Update(m, buf, j))
214 goto err;
215 /*
216 * We know that line may cause programs such as purify and valgrind
217 * to complain about use of uninitialized data. The problem is not,
218 * it's with the caller. Removing that line will make sure you get
219 * really bad randomness and thereby other problems such as very
220 * insecure keys.
221 */
222
223 if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
224 goto err;
225 if (!MD_Final(m, local_md))
226 goto err;
227 md_c[1]++;
228
229 buf = (const char *)buf + j;
230
231 for (k = 0; k < j; k++) {
232 /*
233 * Parallel threads may interfere with this, but always each byte
234 * of the new state is the XOR of some previous value of its and
235 * local_md (intermediate values may be lost). Alway using locking
236 * could hurt performance more than necessary given that
237 * conflicts occur only when the total seeding is longer than the
238 * random state.
239 */
240 state[st_idx++] ^= local_md[k];
241 if (st_idx >= STATE_SIZE)
242 st_idx = 0;
243 }
244 }
245
246 if (!do_not_lock)
247 CRYPTO_THREAD_write_lock(rand_lock);
248 /*
249 * Don't just copy back local_md into md -- this could mean that other
250 * thread's seeding remains without effect (except for the incremented
251 * counter). By XORing it we keep at least as much entropy as fits into
252 * md.
253 */
254 for (k = 0; k < (int)sizeof(md); k++) {
255 md[k] ^= local_md[k];
256 }
257 if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
258 entropy += add;
259 if (!do_not_lock)
260 CRYPTO_THREAD_unlock(rand_lock);
261
262 rv = 1;
263 err:
264 EVP_MD_CTX_free(m);
265 return rv;
266}
267
268static int rand_seed(const void *buf, int num)
269{
270 return rand_add(buf, num, (double)num);
271}
272
273static int rand_bytes(unsigned char *buf, int num, int pseudo)
274{
275 static volatile int stirred_pool = 0;
276 int i, j, k;
277 size_t num_ceil, st_idx, st_num;
278 int ok;
279 long md_c[2];
280 unsigned char local_md[MD_DIGEST_LENGTH];
281 EVP_MD_CTX *m;
282#ifndef GETPID_IS_MEANINGLESS
283 pid_t curr_pid = getpid();
284#endif
285 time_t curr_time = time(NULL);
286 int do_stir_pool = 0;
287/* time value for various platforms */
288#ifdef OPENSSL_SYS_WIN32
289 FILETIME tv;
290# ifdef _WIN32_WCE
291 SYSTEMTIME t;
292 GetSystemTime(&t);
293 SystemTimeToFileTime(&t, &tv);
294# else
295 GetSystemTimeAsFileTime(&tv);
296# endif
297#elif defined(OPENSSL_SYS_VXWORKS)
298 struct timespec tv;
299 clock_gettime(CLOCK_REALTIME, &ts);
300#elif defined(OPENSSL_SYS_DSPBIOS)
301 unsigned long long tv, OPENSSL_rdtsc();
302 tv = OPENSSL_rdtsc();
303#else
304 struct timeval tv;
305 gettimeofday(&tv, NULL);
306#endif
307
308#ifdef PREDICT
309 if (rand_predictable) {
310 static unsigned char val = 0;
311
312 for (i = 0; i < num; i++)
313 buf[i] = val++;
314 return (1);
315 }
316#endif
317
318 if (num <= 0)
319 return 1;
320
321 m = EVP_MD_CTX_new();
322 if (m == NULL)
323 goto err_mem;
324
325 /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
326 num_ceil =
327 (1 + (num - 1) / (MD_DIGEST_LENGTH / 2)) * (MD_DIGEST_LENGTH / 2);
328
329 /*
330 * (Based on the rand(3) manpage:)
331 *
332 * For each group of 10 bytes (or less), we do the following:
333 *
334 * Input into the hash function the local 'md' (which is initialized from
335 * the global 'md' before any bytes are generated), the bytes that are to
336 * be overwritten by the random bytes, and bytes from the 'state'
337 * (incrementing looping index). From this digest output (which is kept
338 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
339 * bottom 10 bytes are xored into the 'state'.
340 *
341 * Finally, after we have finished 'num' random bytes for the
342 * caller, 'count' (which is incremented) and the local and global 'md'
343 * are fed into the hash function and the results are kept in the
344 * global 'md'.
345 */
346
347 if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
348 goto err_mem;
349
350 CRYPTO_THREAD_write_lock(rand_lock);
351 /*
352 * We could end up in an async engine while holding this lock so ensure
353 * we don't pause and cause a deadlock
354 */
355 ASYNC_block_pause();
356
357 /* prevent rand_bytes() from trying to obtain the lock again */
358 CRYPTO_THREAD_write_lock(rand_tmp_lock);
359 locking_threadid = CRYPTO_THREAD_get_current_id();
360 CRYPTO_THREAD_unlock(rand_tmp_lock);
361 crypto_lock_rand = 1;
362
363 if (!initialized) {
364 RAND_poll();
365 initialized = 1;
366 }
367
368 if (!stirred_pool)
369 do_stir_pool = 1;
370
371 ok = (entropy >= ENTROPY_NEEDED);
372 if (!ok) {
373 /*
374 * If the PRNG state is not yet unpredictable, then seeing the PRNG
375 * output may help attackers to determine the new state; thus we have
376 * to decrease the entropy estimate. Once we've had enough initial
377 * seeding we don't bother to adjust the entropy count, though,
378 * because we're not ambitious to provide *information-theoretic*
379 * randomness. NOTE: This approach fails if the program forks before
380 * we have enough entropy. Entropy should be collected in a separate
381 * input pool and be transferred to the output pool only when the
382 * entropy limit has been reached.
383 */
384 entropy -= num;
385 if (entropy < 0)
386 entropy = 0;
387 }
388
389 if (do_stir_pool) {
390 /*
391 * In the output function only half of 'md' remains secret, so we
392 * better make sure that the required entropy gets 'evenly
393 * distributed' through 'state', our randomness pool. The input
394 * function (rand_add) chains all of 'md', which makes it more
395 * suitable for this purpose.
396 */
397
398 int n = STATE_SIZE; /* so that the complete pool gets accessed */
399 while (n > 0) {
400#if MD_DIGEST_LENGTH > 20
401# error "Please adjust DUMMY_SEED."
402#endif
403#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
404 /*
405 * Note that the seed does not matter, it's just that
406 * rand_add expects to have something to hash.
407 */
408 rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
409 n -= MD_DIGEST_LENGTH;
410 }
411 if (ok)
412 stirred_pool = 1;
413 }
414
415 st_idx = state_index;
416 st_num = state_num;
417 md_c[0] = md_count[0];
418 md_c[1] = md_count[1];
419 memcpy(local_md, md, sizeof md);
420
421 state_index += num_ceil;
422 if (state_index > state_num)
423 state_index %= state_num;
424
425 /*
426 * state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num] are now
427 * ours (but other threads may use them too)
428 */
429
430 md_count[0] += 1;
431
432 /* before unlocking, we must clear 'crypto_lock_rand' */
433 crypto_lock_rand = 0;
434 ASYNC_unblock_pause();
435 CRYPTO_THREAD_unlock(rand_lock);
436
437 while (num > 0) {
438 /* num_ceil -= MD_DIGEST_LENGTH/2 */
439 j = (num >= MD_DIGEST_LENGTH / 2) ? MD_DIGEST_LENGTH / 2 : num;
440 num -= j;
441 if (!MD_Init(m))
442 goto err;
443#ifndef GETPID_IS_MEANINGLESS
444 if (curr_pid) { /* just in the first iteration to save time */
445 if (!MD_Update(m, (unsigned char *)&curr_pid, sizeof curr_pid))
446 goto err;
447 curr_pid = 0;
448 }
449#endif
450 if (curr_time) { /* just in the first iteration to save time */
451 if (!MD_Update(m, (unsigned char *)&curr_time, sizeof curr_time))
452 goto err;
453 if (!MD_Update(m, (unsigned char *)&tv, sizeof tv))
454 goto err;
455 curr_time = 0;
456 if (!rand_hw_seed(m))
457 goto err;
458 }
459 if (!MD_Update(m, local_md, MD_DIGEST_LENGTH))
460 goto err;
461 if (!MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c)))
462 goto err;
463
464 k = (st_idx + MD_DIGEST_LENGTH / 2) - st_num;
465 if (k > 0) {
466 if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2 - k))
467 goto err;
468 if (!MD_Update(m, &(state[0]), k))
469 goto err;
470 } else if (!MD_Update(m, &(state[st_idx]), MD_DIGEST_LENGTH / 2))
471 goto err;
472 if (!MD_Final(m, local_md))
473 goto err;
474
475 for (i = 0; i < MD_DIGEST_LENGTH / 2; i++) {
476 /* may compete with other threads */
477 state[st_idx++] ^= local_md[i];
478 if (st_idx >= st_num)
479 st_idx = 0;
480 if (i < j)
481 *(buf++) = local_md[i + MD_DIGEST_LENGTH / 2];
482 }
483 }
484
485 if (!MD_Init(m)
486 || !MD_Update(m, (unsigned char *)&(md_c[0]), sizeof(md_c))
487 || !MD_Update(m, local_md, MD_DIGEST_LENGTH))
488 goto err;
489 CRYPTO_THREAD_write_lock(rand_lock);
490 /*
491 * Prevent deadlocks if we end up in an async engine
492 */
493 ASYNC_block_pause();
494 if (!MD_Update(m, md, MD_DIGEST_LENGTH) || !MD_Final(m, md)) {
495 CRYPTO_THREAD_unlock(rand_lock);
496 goto err;
497 }
498 ASYNC_unblock_pause();
499 CRYPTO_THREAD_unlock(rand_lock);
500
501 EVP_MD_CTX_free(m);
502 if (ok)
503 return (1);
504 else if (pseudo)
505 return 0;
506 else {
507 RANDerr(RAND_F_RAND_BYTES, RAND_R_PRNG_NOT_SEEDED);
508 ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
509 "https://www.openssl.org/docs/faq.html");
510 return (0);
511 }
512 err:
513 RANDerr(RAND_F_RAND_BYTES, ERR_R_EVP_LIB);
514 EVP_MD_CTX_free(m);
515 return 0;
516 err_mem:
517 RANDerr(RAND_F_RAND_BYTES, ERR_R_MALLOC_FAILURE);
518 EVP_MD_CTX_free(m);
519 return 0;
520
521}
522
523static int rand_nopseudo_bytes(unsigned char *buf, int num)
524{
525 return rand_bytes(buf, num, 0);
526}
527
528#if OPENSSL_API_COMPAT < 0x10100000L
529/*
530 * pseudo-random bytes that are guaranteed to be unique but not unpredictable
531 */
532static int rand_pseudo_bytes(unsigned char *buf, int num)
533{
534 return rand_bytes(buf, num, 1);
535}
536#endif
537
538static int rand_status(void)
539{
540 CRYPTO_THREAD_ID cur;
541 int ret;
542 int do_not_lock;
543
544 if (!RUN_ONCE(&rand_lock_init, do_rand_lock_init))
545 return 0;
546
547 cur = CRYPTO_THREAD_get_current_id();
548 /*
549 * check if we already have the lock (could happen if a RAND_poll()
550 * implementation calls RAND_status())
551 */
552 if (crypto_lock_rand) {
553 CRYPTO_THREAD_read_lock(rand_tmp_lock);
554 do_not_lock = CRYPTO_THREAD_compare_id(locking_threadid, cur);
555 CRYPTO_THREAD_unlock(rand_tmp_lock);
556 } else
557 do_not_lock = 0;
558
559 if (!do_not_lock) {
560 CRYPTO_THREAD_write_lock(rand_lock);
561 /*
562 * Prevent deadlocks in case we end up in an async engine
563 */
564 ASYNC_block_pause();
565
566 /*
567 * prevent rand_bytes() from trying to obtain the lock again
568 */
569 CRYPTO_THREAD_write_lock(rand_tmp_lock);
570 locking_threadid = cur;
571 CRYPTO_THREAD_unlock(rand_tmp_lock);
572 crypto_lock_rand = 1;
573 }
574
575 if (!initialized) {
576 RAND_poll();
577 initialized = 1;
578 }
579
580 ret = entropy >= ENTROPY_NEEDED;
581
582 if (!do_not_lock) {
583 /* before unlocking, we must clear 'crypto_lock_rand' */
584 crypto_lock_rand = 0;
585
586 ASYNC_unblock_pause();
587 CRYPTO_THREAD_unlock(rand_lock);
588 }
589
590 return ret;
591}
592
593/*
594 * rand_hw_seed: get seed data from any available hardware RNG. only
595 * currently supports rdrand.
596 */
597
598/* Adapted from eng_rdrand.c */
599
600#if (defined(__i386) || defined(__i386__) || defined(_M_IX86) || \
601 defined(__x86_64) || defined(__x86_64__) || \
602 defined(_M_AMD64) || defined (_M_X64)) && defined(OPENSSL_CPUID_OBJ) \
603 && !defined(OPENSSL_NO_RDRAND)
604
605# define RDRAND_CALLS 4
606
607size_t OPENSSL_ia32_rdrand(void);
608extern unsigned int OPENSSL_ia32cap_P[];
609
610static int rand_hw_seed(EVP_MD_CTX *ctx)
611{
612 int i;
613 if (!(OPENSSL_ia32cap_P[1] & (1 << (62 - 32))))
614 return 1;
615 for (i = 0; i < RDRAND_CALLS; i++) {
616 size_t rnd;
617 rnd = OPENSSL_ia32_rdrand();
618 if (rnd == 0)
619 return 1;
620 if (!MD_Update(ctx, (unsigned char *)&rnd, sizeof(size_t)))
621 return 0;
622 }
623 return 1;
624}
625
626/* XOR an existing buffer with random data */
627
628void rand_hw_xor(unsigned char *buf, size_t num)
629{
630 size_t rnd;
631 if (!(OPENSSL_ia32cap_P[1] & (1 << (62 - 32))))
632 return;
633 while (num >= sizeof(size_t)) {
634 rnd = OPENSSL_ia32_rdrand();
635 if (rnd == 0)
636 return;
637 *((size_t *)buf) ^= rnd;
638 buf += sizeof(size_t);
639 num -= sizeof(size_t);
640 }
641 if (num) {
642 rnd = OPENSSL_ia32_rdrand();
643 if (rnd == 0)
644 return;
645 while (num) {
646 *buf ^= rnd & 0xff;
647 rnd >>= 8;
648 buf++;
649 num--;
650 }
651 }
652}
653
654#else
655
656static int rand_hw_seed(EVP_MD_CTX *ctx)
657{
658 return 1;
659}
660
661void rand_hw_xor(unsigned char *buf, size_t num)
662{
663 return;
664}
665
666#endif
Note: See TracBrowser for help on using the repository browser.