summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rand/rand_unix.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rand/rand_unix.c')
-rw-r--r--src/lib/libcrypto/rand/rand_unix.c118
1 files changed, 36 insertions, 82 deletions
diff --git a/src/lib/libcrypto/rand/rand_unix.c b/src/lib/libcrypto/rand/rand_unix.c
index e3a65571c8..4bb9666e49 100644
--- a/src/lib/libcrypto/rand/rand_unix.c
+++ b/src/lib/libcrypto/rand/rand_unix.c
@@ -133,102 +133,56 @@
133# define FD_SETSIZE (8*sizeof(fd_set)) 133# define FD_SETSIZE (8*sizeof(fd_set))
134#endif 134#endif
135 135
136#if defined(OPENSSL_SYS_VOS) 136#ifdef __VOS__
137
138/* The following algorithm repeatedly samples the real-time clock
139 (RTC) to generate a sequence of unpredictable data. The algorithm
140 relies upon the uneven execution speed of the code (due to factors
141 such as cache misses, interrupts, bus activity, and scheduling) and
142 upon the rather large relative difference between the speed of the
143 clock and the rate at which it can be read.
144
145 If this code is ported to an environment where execution speed is
146 more constant or where the RTC ticks at a much slower rate, or the
147 clock can be read with fewer instructions, it is likely that the
148 results would be far more predictable.
149
150 As a precaution, we generate 4 times the minimum required amount of
151 seed data. */
152
153int RAND_poll(void) 137int RAND_poll(void)
154{ 138{
155 short int code; 139 unsigned char buf[ENTROPY_NEEDED];
156 gid_t curr_gid;
157 pid_t curr_pid; 140 pid_t curr_pid;
158 uid_t curr_uid; 141 uid_t curr_uid;
159 int i, k; 142 static int first=1;
143 int i;
144 long rnd = 0;
160 struct timespec ts; 145 struct timespec ts;
161 unsigned char v; 146 unsigned seed;
162 147
163#ifdef OPENSSL_SYS_VOS_HPPA 148/* The VOS random() function starts from a static seed so its
164 long duration; 149 initial value is predictable. If random() returns the
165 extern void s$sleep (long *_duration, short int *_code); 150 initial value, reseed it with dynamic data. The VOS
166#else 151 real-time clock has a granularity of 1 nsec so it should be
167#ifdef OPENSSL_SYS_VOS_IA32 152 reasonably difficult to predict its exact value. Do not
168 long long duration; 153 gratuitously reseed the PRNG because other code in this
169 extern void s$sleep2 (long long *_duration, short int *_code); 154 process or thread may be using it. */
170#else 155
171#error "Unsupported Platform." 156 if (first) {
172#endif /* OPENSSL_SYS_VOS_IA32 */ 157 first = 0;
173#endif /* OPENSSL_SYS_VOS_HPPA */ 158 rnd = random ();
174 159 if (rnd == 1804289383) {
175 /* Seed with the gid, pid, and uid, to ensure *some* 160 clock_gettime (CLOCK_REALTIME, &ts);
176 variation between different processes. */ 161 curr_pid = getpid();
177 162 curr_uid = getuid();
178 curr_gid = getgid(); 163 seed = ts.tv_sec ^ ts.tv_nsec ^ curr_pid ^ curr_uid;
179 RAND_add (&curr_gid, sizeof curr_gid, 1); 164 srandom (seed);
180 curr_gid = 0; 165 }
181 166 }
182 curr_pid = getpid();
183 RAND_add (&curr_pid, sizeof curr_pid, 1);
184 curr_pid = 0;
185
186 curr_uid = getuid();
187 RAND_add (&curr_uid, sizeof curr_uid, 1);
188 curr_uid = 0;
189
190 for (i=0; i<(ENTROPY_NEEDED*4); i++)
191 {
192 /* burn some cpu; hope for interrupts, cache
193 collisions, bus interference, etc. */
194 for (k=0; k<99; k++)
195 ts.tv_nsec = random ();
196
197#ifdef OPENSSL_SYS_VOS_HPPA
198 /* sleep for 1/1024 of a second (976 us). */
199 duration = 1;
200 s$sleep (&duration, &code);
201#else
202#ifdef OPENSSL_SYS_VOS_IA32
203 /* sleep for 1/65536 of a second (15 us). */
204 duration = 1;
205 s$sleep2 (&duration, &code);
206#endif /* OPENSSL_SYS_VOS_IA32 */
207#endif /* OPENSSL_SYS_VOS_HPPA */
208
209 /* get wall clock time. */
210 clock_gettime (CLOCK_REALTIME, &ts);
211 167
212 /* take 8 bits */ 168 for (i = 0; i < sizeof(buf); i++) {
213 v = (unsigned char) (ts.tv_nsec % 256); 169 if (i % 4 == 0)
214 RAND_add (&v, sizeof v, 1); 170 rnd = random();
215 v = 0; 171 buf[i] = rnd;
172 rnd >>= 8;
216 } 173 }
174 RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
175 memset(buf, 0, sizeof(buf));
176
217 return 1; 177 return 1;
218} 178}
219#elif defined __OpenBSD__ 179#elif defined __OpenBSD__
220int RAND_poll(void) 180int RAND_poll(void)
221{ 181{
222 u_int32_t rnd = 0, i;
223 unsigned char buf[ENTROPY_NEEDED]; 182 unsigned char buf[ENTROPY_NEEDED];
224 183
225 for (i = 0; i < sizeof(buf); i++) { 184 arc4random_buf(buf, sizeof(buf));
226 if (i % 4 == 0) 185 RAND_add(buf, sizeof(buf), sizeof(buf));
227 rnd = arc4random();
228 buf[i] = rnd;
229 rnd >>= 8;
230 }
231 RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
232 memset(buf, 0, sizeof(buf)); 186 memset(buf, 0, sizeof(buf));
233 187
234 return 1; 188 return 1;