]>
Commit | Line | Data |
---|---|---|
b1322259 RS |
1 | /* |
2 | * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved. | |
dfeab068 | 3 | * |
b1322259 RS |
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 | |
dfeab068 RE |
8 | */ |
9 | ||
10 | #include <stdio.h> | |
dfeab068 | 11 | #include <time.h> |
b39fc560 | 12 | #include "internal/cryptlib.h" |
98186eb4 | 13 | #include <openssl/opensslconf.h> |
f3cd81d6 | 14 | #include "internal/rand.h" |
3c27208f | 15 | #include <openssl/engine.h> |
87975cfa | 16 | #include "internal/thread_once.h" |
da8fc25a | 17 | #include "rand_lcl.h" |
dfeab068 | 18 | |
0b13e9f0 | 19 | #ifndef OPENSSL_NO_ENGINE |
cb78486d | 20 | /* non-NULL if default_RAND_meth is ENGINE-provided */ |
da8fc25a RS |
21 | static ENGINE *funct_ref; |
22 | static CRYPTO_RWLOCK *rand_engine_lock; | |
0b13e9f0 | 23 | #endif |
da8fc25a RS |
24 | static CRYPTO_RWLOCK *rand_meth_lock; |
25 | static const RAND_METHOD *default_RAND_meth; | |
26 | static CRYPTO_ONCE rand_init = CRYPTO_ONCE_STATIC_INIT; | |
87975cfa | 27 | |
da8fc25a RS |
28 | |
29 | DEFINE_RUN_ONCE_STATIC(do_rand_init) | |
87975cfa | 30 | { |
2f881d2d | 31 | int ret = 1; |
87975cfa RL |
32 | #ifndef OPENSSL_NO_ENGINE |
33 | rand_engine_lock = CRYPTO_THREAD_lock_new(); | |
2f881d2d | 34 | ret &= rand_engine_lock != NULL; |
87975cfa RL |
35 | #endif |
36 | rand_meth_lock = CRYPTO_THREAD_lock_new(); | |
2f881d2d RL |
37 | ret &= rand_meth_lock != NULL; |
38 | return ret; | |
87975cfa | 39 | } |
dfeab068 | 40 | |
da8fc25a RS |
41 | void rand_cleanup_int(void) |
42 | { | |
43 | const RAND_METHOD *meth = default_RAND_meth; | |
44 | ||
45 | if (meth != NULL && meth->cleanup != NULL) | |
46 | meth->cleanup(); | |
47 | RAND_set_rand_method(NULL); | |
48 | #ifndef OPENSSL_NO_ENGINE | |
49 | CRYPTO_THREAD_lock_free(rand_engine_lock); | |
50 | #endif | |
51 | CRYPTO_THREAD_lock_free(rand_meth_lock); | |
12fb8c3d | 52 | rand_drbg_cleanup(); |
da8fc25a RS |
53 | } |
54 | ||
cb78486d | 55 | int RAND_set_rand_method(const RAND_METHOD *meth) |
0f113f3e | 56 | { |
da8fc25a | 57 | if (!RUN_ONCE(&rand_init, do_rand_init)) |
87975cfa RL |
58 | return 0; |
59 | ||
60 | CRYPTO_THREAD_write_lock(rand_meth_lock); | |
0b13e9f0 | 61 | #ifndef OPENSSL_NO_ENGINE |
7c96dbcd RS |
62 | ENGINE_finish(funct_ref); |
63 | funct_ref = NULL; | |
0b13e9f0 | 64 | #endif |
0f113f3e | 65 | default_RAND_meth = meth; |
87975cfa | 66 | CRYPTO_THREAD_unlock(rand_meth_lock); |
0f113f3e MC |
67 | return 1; |
68 | } | |
dfeab068 | 69 | |
a4a9d97a | 70 | const RAND_METHOD *RAND_get_rand_method(void) |
0f113f3e | 71 | { |
87975cfa RL |
72 | const RAND_METHOD *tmp_meth = NULL; |
73 | ||
da8fc25a | 74 | if (!RUN_ONCE(&rand_init, do_rand_init)) |
87975cfa RL |
75 | return NULL; |
76 | ||
77 | CRYPTO_THREAD_write_lock(rand_meth_lock); | |
da8fc25a | 78 | if (default_RAND_meth == NULL) { |
0b13e9f0 | 79 | #ifndef OPENSSL_NO_ENGINE |
da8fc25a RS |
80 | ENGINE *e; |
81 | ||
82 | /* If we have an engine that can do RAND, use it. */ | |
83 | if ((e = ENGINE_get_default_RAND()) != NULL | |
84 | && (tmp_meth = ENGINE_get_RAND(e)) != NULL) { | |
0f113f3e | 85 | funct_ref = e; |
da8fc25a RS |
86 | default_RAND_meth = tmp_meth; |
87 | } else { | |
88 | ENGINE_finish(e); | |
89 | default_RAND_meth = &openssl_rand_meth; | |
90 | } | |
91 | #else | |
92 | default_RAND_meth = &openssl_rand_meth; | |
0b13e9f0 | 93 | #endif |
0f113f3e | 94 | } |
87975cfa RL |
95 | tmp_meth = default_RAND_meth; |
96 | CRYPTO_THREAD_unlock(rand_meth_lock); | |
97 | return tmp_meth; | |
0f113f3e | 98 | } |
cb78486d | 99 | |
0b13e9f0 | 100 | #ifndef OPENSSL_NO_ENGINE |
cb78486d | 101 | int RAND_set_rand_engine(ENGINE *engine) |
0f113f3e MC |
102 | { |
103 | const RAND_METHOD *tmp_meth = NULL; | |
87975cfa | 104 | |
da8fc25a | 105 | if (!RUN_ONCE(&rand_init, do_rand_init)) |
87975cfa RL |
106 | return 0; |
107 | ||
da8fc25a | 108 | if (engine != NULL) { |
0f113f3e MC |
109 | if (!ENGINE_init(engine)) |
110 | return 0; | |
111 | tmp_meth = ENGINE_get_RAND(engine); | |
7c96dbcd | 112 | if (tmp_meth == NULL) { |
0f113f3e MC |
113 | ENGINE_finish(engine); |
114 | return 0; | |
115 | } | |
116 | } | |
87975cfa | 117 | CRYPTO_THREAD_write_lock(rand_engine_lock); |
0f113f3e MC |
118 | /* This function releases any prior ENGINE so call it first */ |
119 | RAND_set_rand_method(tmp_meth); | |
120 | funct_ref = engine; | |
87975cfa | 121 | CRYPTO_THREAD_unlock(rand_engine_lock); |
0f113f3e MC |
122 | return 1; |
123 | } | |
0b13e9f0 | 124 | #endif |
dfeab068 | 125 | |
6343829a | 126 | void RAND_seed(const void *buf, int num) |
0f113f3e MC |
127 | { |
128 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a RS |
129 | |
130 | if (meth->seed != NULL) | |
0f113f3e MC |
131 | meth->seed(buf, num); |
132 | } | |
dfeab068 | 133 | |
da8fc25a | 134 | void RAND_add(const void *buf, int num, double randomness) |
0f113f3e MC |
135 | { |
136 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a RS |
137 | |
138 | if (meth->add != NULL) | |
139 | meth->add(buf, num, randomness); | |
0f113f3e | 140 | } |
eb952088 | 141 | |
6343829a | 142 | int RAND_bytes(unsigned char *buf, int num) |
0f113f3e MC |
143 | { |
144 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a RS |
145 | |
146 | if (meth->bytes != NULL) | |
0f113f3e | 147 | return meth->bytes(buf, num); |
0ea155fc | 148 | RANDerr(RAND_F_RAND_BYTES, RAND_R_FUNC_NOT_IMPLEMENTED); |
da8fc25a | 149 | return -1; |
0f113f3e | 150 | } |
dfeab068 | 151 | |
98186eb4 | 152 | #if OPENSSL_API_COMPAT < 0x10100000L |
6343829a | 153 | int RAND_pseudo_bytes(unsigned char *buf, int num) |
0f113f3e MC |
154 | { |
155 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a RS |
156 | |
157 | if (meth->pseudorand != NULL) | |
0f113f3e | 158 | return meth->pseudorand(buf, num); |
da8fc25a | 159 | return -1; |
0f113f3e | 160 | } |
302d38e3 | 161 | #endif |
5eb8ca4d BM |
162 | |
163 | int RAND_status(void) | |
0f113f3e MC |
164 | { |
165 | const RAND_METHOD *meth = RAND_get_rand_method(); | |
da8fc25a RS |
166 | |
167 | if (meth->status != NULL) | |
0f113f3e MC |
168 | return meth->status(); |
169 | return 0; | |
170 | } |