summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormiod <>2014-04-15 16:52:50 +0000
committermiod <>2014-04-15 16:52:50 +0000
commitbe03b064bffafbd378c0d5cc5971594573544d64 (patch)
treecd099da9298b8ab84a5dbbead9a6560737057c97 /src
parentf08ae3b01d60723e8f4334e0aaf4a57f03c478ba (diff)
downloadopenbsd-be03b064bffafbd378c0d5cc5971594573544d64.tar.gz
openbsd-be03b064bffafbd378c0d5cc5971594573544d64.tar.bz2
openbsd-be03b064bffafbd378c0d5cc5971594573544d64.zip
Replace the old OpenSSL PRNG by direct use of arc4random_buf(), keeping the
existing RAND interfaces unchanged. All interfaces allowing external feed or seed of the RNG (either from a file or a local entropy gathering daemon) are kept for ABI compatibility, but are no longer do anything. While the OpenSSL PRNG was required 15+ years ago when many systems lacked proper entropy collection, things have evolved and one can reasonably assume it is better to use the kernel (system global) entropy pool rather than trying to build one's own and having to compensate for thread scheduling... <RANT> Whoever thought that RAND_screen(), feeding the PRNG with the contents of the local workstation's display, under Win32, was a smart idea, ought to be banned from security programming. </RANT> ok beck@ deraadt@ tedu@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libcrypto/crypto/Makefile4
-rw-r--r--src/lib/libcrypto/doc/RAND_add.pod57
-rw-r--r--src/lib/libcrypto/doc/RAND_load_file.pod14
-rw-r--r--src/lib/libcrypto/rand/md_rand.c607
-rw-r--r--src/lib/libcrypto/rand/rand.h26
-rw-r--r--src/lib/libcrypto/rand/rand_egd.c193
-rw-r--r--src/lib/libcrypto/rand/rand_lcl.h158
-rw-r--r--src/lib/libcrypto/rand/rand_lib.c129
-rw-r--r--src/lib/libcrypto/rand/rand_unix.c308
-rw-r--r--src/lib/libcrypto/rand/randfile.c152
-rw-r--r--src/lib/libcrypto/rand/rc4_rand.c44
-rw-r--r--src/lib/libssl/src/crypto/rand/md_rand.c607
-rw-r--r--src/lib/libssl/src/crypto/rand/rand.h26
-rw-r--r--src/lib/libssl/src/crypto/rand/rand_egd.c193
-rw-r--r--src/lib/libssl/src/crypto/rand/rand_lcl.h158
-rw-r--r--src/lib/libssl/src/crypto/rand/rand_lib.c129
-rw-r--r--src/lib/libssl/src/crypto/rand/rand_unix.c308
-rw-r--r--src/lib/libssl/src/crypto/rand/randfile.c152
-rw-r--r--src/lib/libssl/src/crypto/rand/rc4_rand.c44
-rw-r--r--src/lib/libssl/src/doc/crypto/RAND_add.pod57
-rw-r--r--src/lib/libssl/src/doc/crypto/RAND_egd.pod69
-rw-r--r--src/lib/libssl/src/doc/crypto/RAND_load_file.pod14
-rw-r--r--src/lib/libssl/src/doc/crypto/rand.pod105
23 files changed, 137 insertions, 3417 deletions
diff --git a/src/lib/libcrypto/crypto/Makefile b/src/lib/libcrypto/crypto/Makefile
index 116a3d4fd0..26fe163249 100644
--- a/src/lib/libcrypto/crypto/Makefile
+++ b/src/lib/libcrypto/crypto/Makefile
@@ -1,4 +1,4 @@
1# $OpenBSD: Makefile,v 1.5 2014/04/14 04:27:50 miod Exp $ 1# $OpenBSD: Makefile,v 1.6 2014/04/15 16:52:50 miod Exp $
2 2
3LIB= crypto 3LIB= crypto
4 4
@@ -220,7 +220,7 @@ SRCS+= pk7_mime.c bio_pk7.c
220SRCS+= pqueue.c 220SRCS+= pqueue.c
221 221
222# rand/ 222# rand/
223SRCS+= md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c 223SRCS+= rc4_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c
224SRCS+= rand_unix.c 224SRCS+= rand_unix.c
225 225
226# rc2/ 226# rc2/
diff --git a/src/lib/libcrypto/doc/RAND_add.pod b/src/lib/libcrypto/doc/RAND_add.pod
index 67c66f3e0c..d55dc125d3 100644
--- a/src/lib/libcrypto/doc/RAND_add.pod
+++ b/src/lib/libcrypto/doc/RAND_add.pod
@@ -2,8 +2,7 @@
2 2
3=head1 NAME 3=head1 NAME
4 4
5RAND_add, RAND_seed, RAND_status, RAND_event, RAND_screen - add 5RAND_add, RAND_seed, RAND_status - add entropy to the PRNG (DEPRECATED)
6entropy to the PRNG
7 6
8=head1 SYNOPSIS 7=head1 SYNOPSIS
9 8
@@ -15,63 +14,17 @@ entropy to the PRNG
15 14
16 int RAND_status(void); 15 int RAND_status(void);
17 16
18 int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam);
19 void RAND_screen(void);
20
21=head1 DESCRIPTION 17=head1 DESCRIPTION
22 18
23RAND_add() mixes the B<num> bytes at B<buf> into the PRNG state. Thus, 19These functions used to allow for the state of the random number generator
24if the data at B<buf> are unpredictable to an adversary, this 20to be controlled by external sources.
25increases the uncertainty about the state and makes the PRNG output
26less predictable. Suitable input comes from user interaction (random
27key presses, mouse movements) and certain hardware events. The
28B<entropy> argument is (the lower bound of) an estimate of how much
29randomness is contained in B<buf>, measured in bytes. Details about
30sources of randomness and how to estimate their entropy can be found
31in the literature, e.g. RFC 1750.
32
33RAND_add() may be called with sensitive data such as user entered
34passwords. The seed values cannot be recovered from the PRNG output.
35
36OpenSSL makes sure that the PRNG state is unique for each thread. On
37systems that provide C</dev/urandom>, the randomness device is used
38to seed the PRNG transparently. However, on all other systems, the
39application is responsible for seeding the PRNG by calling RAND_add(),
40L<RAND_egd(3)|RAND_egd(3)>
41or L<RAND_load_file(3)|RAND_load_file(3)>.
42
43RAND_seed() is equivalent to RAND_add() when B<num == entropy>.
44
45RAND_event() collects the entropy from Windows events such as mouse
46movements and other user interaction. It should be called with the
47B<iMsg>, B<wParam> and B<lParam> arguments of I<all> messages sent to
48the window procedure. It will estimate the entropy contained in the
49event message (if any), and add it to the PRNG. The program can then
50process the messages as usual.
51 21
52The RAND_screen() function is available for the convenience of Windows 22They are kept for ABI compatibility but are no longer functional, and
53programmers. It adds the current contents of the screen to the PRNG. 23should not used in new programs.
54For applications that can catch Windows events, seeding the PRNG by
55calling RAND_event() is a significantly better source of
56randomness. It should be noted that both methods cannot be used on
57servers that run without user interaction.
58
59=head1 RETURN VALUES
60
61RAND_status() and RAND_event() return 1 if the PRNG has been seeded
62with enough data, 0 otherwise.
63
64The other functions do not return values.
65 24
66=head1 SEE ALSO 25=head1 SEE ALSO
67 26
68L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>, 27L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>,
69L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> 28L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)>
70 29
71=head1 HISTORY
72
73RAND_seed() and RAND_screen() are available in all versions of SSLeay
74and OpenSSL. RAND_add() and RAND_status() have been added in OpenSSL
750.9.5, RAND_event() in OpenSSL 0.9.5a.
76
77=cut 30=cut
diff --git a/src/lib/libcrypto/doc/RAND_load_file.pod b/src/lib/libcrypto/doc/RAND_load_file.pod
index d8c134e621..3f7e944d86 100644
--- a/src/lib/libcrypto/doc/RAND_load_file.pod
+++ b/src/lib/libcrypto/doc/RAND_load_file.pod
@@ -22,18 +22,18 @@ filename. The seed file is $RANDFILE if that environment variable is
22set, $HOME/.rnd otherwise. If $HOME is not set either, or B<num> is 22set, $HOME/.rnd otherwise. If $HOME is not set either, or B<num> is
23too small for the path name, an error occurs. 23too small for the path name, an error occurs.
24 24
25RAND_load_file() reads a number of bytes from file B<filename> and 25RAND_load_file() used to allow for the state of the random number generator
26adds them to the PRNG. If B<max_bytes> is non-negative, 26to be controlled by external sources.
27up to to B<max_bytes> are read; starting with OpenSSL 0.9.5, 27
28if B<max_bytes> is -1, the complete file is read. 28It is kept for ABI compatibility but is no longer functional, and
29should not used in new programs.
29 30
30RAND_write_file() writes a number of random bytes (currently 1024) to 31RAND_write_file() writes a number of random bytes (currently 1024) to
31file B<filename> which can be used to initialize the PRNG by calling 32file B<filename>.
32RAND_load_file() in a later session.
33 33
34=head1 RETURN VALUES 34=head1 RETURN VALUES
35 35
36RAND_load_file() returns the number of bytes read. 36RAND_load_file() always returns 0.
37 37
38RAND_write_file() returns the number of bytes written, and -1 if the 38RAND_write_file() returns the number of bytes written, and -1 if the
39bytes written were generated without appropriate seed. 39bytes written were generated without appropriate seed.
diff --git a/src/lib/libcrypto/rand/md_rand.c b/src/lib/libcrypto/rand/md_rand.c
deleted file mode 100644
index aee1c30b0a..0000000000
--- a/src/lib/libcrypto/rand/md_rand.c
+++ /dev/null
@@ -1,607 +0,0 @@
1/* crypto/rand/md_rand.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
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 */
111
112#define OPENSSL_FIPSEVP
113
114#ifdef MD_RAND_DEBUG
115# ifndef NDEBUG
116# define NDEBUG
117# endif
118#endif
119
120#include <assert.h>
121#include <stdio.h>
122#include <string.h>
123
124#include "e_os.h"
125
126#include <openssl/crypto.h>
127#include <openssl/rand.h>
128#include "rand_lcl.h"
129
130#include <openssl/err.h>
131
132#ifdef BN_DEBUG
133# define PREDICT
134#endif
135
136/* #define PREDICT 1 */
137
138#define STATE_SIZE 1023
139static int state_num=0,state_index=0;
140static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
141static unsigned char md[MD_DIGEST_LENGTH];
142static long md_count[2]={0,0};
143static double entropy=0;
144static int initialized=0;
145
146static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
147 * holds CRYPTO_LOCK_RAND
148 * (to prevent double locking) */
149/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
150static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
151
152
153#ifdef PREDICT
154int rand_predictable=0;
155#endif
156
157const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
158
159static void ssleay_rand_cleanup(void);
160static void ssleay_rand_seed(const void *buf, int num);
161static void ssleay_rand_add(const void *buf, int num, double add_entropy);
162static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo);
163static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
164static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
165static int ssleay_rand_status(void);
166
167RAND_METHOD rand_ssleay_meth={
168 ssleay_rand_seed,
169 ssleay_rand_nopseudo_bytes,
170 ssleay_rand_cleanup,
171 ssleay_rand_add,
172 ssleay_rand_pseudo_bytes,
173 ssleay_rand_status
174 };
175
176RAND_METHOD *RAND_SSLeay(void)
177 {
178 return(&rand_ssleay_meth);
179 }
180
181static void ssleay_rand_cleanup(void)
182 {
183 OPENSSL_cleanse(state,sizeof(state));
184 state_num=0;
185 state_index=0;
186 OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
187 md_count[0]=0;
188 md_count[1]=0;
189 entropy=0;
190 initialized=0;
191 }
192
193static void ssleay_rand_add(const void *buf, int num, double add)
194 {
195 int i,j,k,st_idx;
196 long md_c[2];
197 unsigned char local_md[MD_DIGEST_LENGTH];
198 EVP_MD_CTX m;
199 int do_not_lock;
200
201 if (!num)
202 return;
203
204 /*
205 * (Based on the rand(3) manpage)
206 *
207 * The input is chopped up into units of 20 bytes (or less for
208 * the last block). Each of these blocks is run through the hash
209 * function as follows: The data passed to the hash function
210 * is the current 'md', the same number of bytes from the 'state'
211 * (the location determined by in incremented looping index) as
212 * the current 'block', the new key data 'block', and 'count'
213 * (which is incremented after each use).
214 * The result of this is kept in 'md' and also xored into the
215 * 'state' at the same locations that were used as input into the
216 * hash function.
217 */
218
219 /* check if we already have the lock */
220 if (crypto_lock_rand)
221 {
222 CRYPTO_THREADID cur;
223 CRYPTO_THREADID_current(&cur);
224 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
225 do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
226 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
227 }
228 else
229 do_not_lock = 0;
230
231 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
232 st_idx=state_index;
233
234 /* use our own copies of the counters so that even
235 * if a concurrent thread seeds with exactly the
236 * same data and uses the same subarray there's _some_
237 * difference */
238 md_c[0] = md_count[0];
239 md_c[1] = md_count[1];
240
241 memcpy(local_md, md, sizeof md);
242
243 /* state_index <= state_num <= STATE_SIZE */
244 state_index += num;
245 if (state_index >= STATE_SIZE)
246 {
247 state_index%=STATE_SIZE;
248 state_num=STATE_SIZE;
249 }
250 else if (state_num < STATE_SIZE)
251 {
252 if (state_index > state_num)
253 state_num=state_index;
254 }
255 /* state_index <= state_num <= STATE_SIZE */
256
257 /* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
258 * are what we will use now, but other threads may use them
259 * as well */
260
261 md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
262
263 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
264
265 EVP_MD_CTX_init(&m);
266 for (i=0; i<num; i+=MD_DIGEST_LENGTH)
267 {
268 j=(num-i);
269 j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
270
271 MD_Init(&m);
272 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
273 k=(st_idx+j)-STATE_SIZE;
274 if (k > 0)
275 {
276 MD_Update(&m,&(state[st_idx]),j-k);
277 MD_Update(&m,&(state[0]),k);
278 }
279 else
280 MD_Update(&m,&(state[st_idx]),j);
281
282 /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
283 MD_Update(&m,buf,j);
284 /* We know that line may cause programs such as
285 purify and valgrind to complain about use of
286 uninitialized data. The problem is not, it's
287 with the caller. Removing that line will make
288 sure you get really bad randomness and thereby
289 other problems such as very insecure keys. */
290
291 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
292 MD_Final(&m,local_md);
293 md_c[1]++;
294
295 buf=(const char *)buf + j;
296
297 for (k=0; k<j; k++)
298 {
299 /* Parallel threads may interfere with this,
300 * but always each byte of the new state is
301 * the XOR of some previous value of its
302 * and local_md (itermediate values may be lost).
303 * Alway using locking could hurt performance more
304 * than necessary given that conflicts occur only
305 * when the total seeding is longer than the random
306 * state. */
307 state[st_idx++]^=local_md[k];
308 if (st_idx >= STATE_SIZE)
309 st_idx=0;
310 }
311 }
312 EVP_MD_CTX_cleanup(&m);
313
314 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
315 /* Don't just copy back local_md into md -- this could mean that
316 * other thread's seeding remains without effect (except for
317 * the incremented counter). By XORing it we keep at least as
318 * much entropy as fits into md. */
319 for (k = 0; k < (int)sizeof(md); k++)
320 {
321 md[k] ^= local_md[k];
322 }
323 if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
324 entropy += add;
325 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
326
327#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
328 assert(md_c[1] == md_count[1]);
329#endif
330 }
331
332static void ssleay_rand_seed(const void *buf, int num)
333 {
334 ssleay_rand_add(buf, num, (double)num);
335 }
336
337static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
338 {
339 static volatile int stirred_pool = 0;
340 int i,j,k,st_num,st_idx;
341 int num_ceil;
342 int ok;
343 long md_c[2];
344 unsigned char local_md[MD_DIGEST_LENGTH];
345 EVP_MD_CTX m;
346#ifndef GETPID_IS_MEANINGLESS
347 pid_t curr_pid = getpid();
348#endif
349 int do_stir_pool = 0;
350
351#ifdef PREDICT
352 if (rand_predictable)
353 {
354 static unsigned char val=0;
355
356 for (i=0; i<num; i++)
357 buf[i]=val++;
358 return(1);
359 }
360#endif
361
362 if (num <= 0)
363 return 1;
364
365 EVP_MD_CTX_init(&m);
366 /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
367 num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
368
369 /*
370 * (Based on the rand(3) manpage:)
371 *
372 * For each group of 10 bytes (or less), we do the following:
373 *
374 * Input into the hash function the local 'md' (which is initialized from
375 * the global 'md' before any bytes are generated), the bytes that are to
376 * be overwritten by the random bytes, and bytes from the 'state'
377 * (incrementing looping index). From this digest output (which is kept
378 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
379 * bottom 10 bytes are xored into the 'state'.
380 *
381 * Finally, after we have finished 'num' random bytes for the
382 * caller, 'count' (which is incremented) and the local and global 'md'
383 * are fed into the hash function and the results are kept in the
384 * global 'md'.
385 */
386#ifdef OPENSSL_FIPS
387 /* NB: in FIPS mode we are already under a lock */
388 if (!FIPS_mode())
389#endif
390 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
391
392 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
393 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
394 CRYPTO_THREADID_current(&locking_threadid);
395 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
396 crypto_lock_rand = 1;
397
398 if (!initialized)
399 {
400 RAND_poll();
401 initialized = 1;
402 }
403
404 if (!stirred_pool)
405 do_stir_pool = 1;
406
407 ok = (entropy >= ENTROPY_NEEDED);
408 if (!ok)
409 {
410 /* If the PRNG state is not yet unpredictable, then seeing
411 * the PRNG output may help attackers to determine the new
412 * state; thus we have to decrease the entropy estimate.
413 * Once we've had enough initial seeding we don't bother to
414 * adjust the entropy count, though, because we're not ambitious
415 * to provide *information-theoretic* randomness.
416 *
417 * NOTE: This approach fails if the program forks before
418 * we have enough entropy. Entropy should be collected
419 * in a separate input pool and be transferred to the
420 * output pool only when the entropy limit has been reached.
421 */
422 entropy -= num;
423 if (entropy < 0)
424 entropy = 0;
425 }
426
427 if (do_stir_pool)
428 {
429 /* In the output function only half of 'md' remains secret,
430 * so we better make sure that the required entropy gets
431 * 'evenly distributed' through 'state', our randomness pool.
432 * The input function (ssleay_rand_add) chains all of 'md',
433 * which makes it more suitable for this purpose.
434 */
435
436 int n = STATE_SIZE; /* so that the complete pool gets accessed */
437 while (n > 0)
438 {
439#if MD_DIGEST_LENGTH > 20
440# error "Please adjust DUMMY_SEED."
441#endif
442#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
443 /* Note that the seed does not matter, it's just that
444 * ssleay_rand_add expects to have something to hash. */
445 ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
446 n -= MD_DIGEST_LENGTH;
447 }
448 if (ok)
449 stirred_pool = 1;
450 }
451
452 st_idx=state_index;
453 st_num=state_num;
454 md_c[0] = md_count[0];
455 md_c[1] = md_count[1];
456 memcpy(local_md, md, sizeof md);
457
458 state_index+=num_ceil;
459 if (state_index > state_num)
460 state_index %= state_num;
461
462 /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
463 * are now ours (but other threads may use them too) */
464
465 md_count[0] += 1;
466
467 /* before unlocking, we must clear 'crypto_lock_rand' */
468 crypto_lock_rand = 0;
469#ifdef OPENSSL_FIPS
470 if (!FIPS_mode())
471#endif
472 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
473
474 while (num > 0)
475 {
476 /* num_ceil -= MD_DIGEST_LENGTH/2 */
477 j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
478 num-=j;
479 MD_Init(&m);
480#ifndef GETPID_IS_MEANINGLESS
481 if (curr_pid) /* just in the first iteration to save time */
482 {
483 MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
484 curr_pid = 0;
485 }
486#endif
487 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
488 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
489
490#ifndef PURIFY /* purify complains */
491 /* The following line uses the supplied buffer as a small
492 * source of entropy: since this buffer is often uninitialised
493 * it may cause programs such as purify or valgrind to
494 * complain. So for those builds it is not used: the removal
495 * of such a small source of entropy has negligible impact on
496 * security.
497 */
498 MD_Update(&m,buf,j);
499#endif
500
501 k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
502 if (k > 0)
503 {
504 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
505 MD_Update(&m,&(state[0]),k);
506 }
507 else
508 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
509 MD_Final(&m,local_md);
510
511 for (i=0; i<MD_DIGEST_LENGTH/2; i++)
512 {
513 state[st_idx++]^=local_md[i]; /* may compete with other threads */
514 if (st_idx >= st_num)
515 st_idx=0;
516 if (i < j)
517 *(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
518 }
519 }
520
521 MD_Init(&m);
522 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
523 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
524#ifdef OPENSSL_FIPS
525 if (!FIPS_mode())
526#endif
527 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
528 MD_Update(&m,md,MD_DIGEST_LENGTH);
529 MD_Final(&m,md);
530#ifdef OPENSSL_FIPS
531 if (!FIPS_mode())
532#endif
533 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
534
535 EVP_MD_CTX_cleanup(&m);
536 if (ok)
537 return(1);
538 else if (pseudo)
539 return 0;
540 else
541 {
542 RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
543 ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
544 "http://www.openssl.org/support/faq.html");
545 return(0);
546 }
547 }
548
549static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
550 {
551 return ssleay_rand_bytes(buf, num, 0);
552 }
553
554/* pseudo-random bytes that are guaranteed to be unique but not
555 unpredictable */
556static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
557 {
558 return ssleay_rand_bytes(buf, num, 1);
559 }
560
561static int ssleay_rand_status(void)
562 {
563 CRYPTO_THREADID cur;
564 int ret;
565 int do_not_lock;
566
567 CRYPTO_THREADID_current(&cur);
568 /* check if we already have the lock
569 * (could happen if a RAND_poll() implementation calls RAND_status()) */
570 if (crypto_lock_rand)
571 {
572 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
573 do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
574 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
575 }
576 else
577 do_not_lock = 0;
578
579 if (!do_not_lock)
580 {
581 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
582
583 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
584 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
585 CRYPTO_THREADID_cpy(&locking_threadid, &cur);
586 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
587 crypto_lock_rand = 1;
588 }
589
590 if (!initialized)
591 {
592 RAND_poll();
593 initialized = 1;
594 }
595
596 ret = entropy >= ENTROPY_NEEDED;
597
598 if (!do_not_lock)
599 {
600 /* before unlocking, we must clear 'crypto_lock_rand' */
601 crypto_lock_rand = 0;
602
603 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
604 }
605
606 return ret;
607 }
diff --git a/src/lib/libcrypto/rand/rand.h b/src/lib/libcrypto/rand/rand.h
index bb5520e80a..e65b4b2e35 100644
--- a/src/lib/libcrypto/rand/rand.h
+++ b/src/lib/libcrypto/rand/rand.h
@@ -63,18 +63,10 @@
63#include <openssl/ossl_typ.h> 63#include <openssl/ossl_typ.h>
64#include <openssl/e_os2.h> 64#include <openssl/e_os2.h>
65 65
66#if defined(OPENSSL_SYS_WINDOWS)
67#include <windows.h>
68#endif
69
70#ifdef __cplusplus 66#ifdef __cplusplus
71extern "C" { 67extern "C" {
72#endif 68#endif
73 69
74#if defined(OPENSSL_FIPS)
75#define FIPS_RAND_SIZE_T size_t
76#endif
77
78/* Already defined in ossl_typ.h */ 70/* Already defined in ossl_typ.h */
79/* typedef struct rand_meth_st RAND_METHOD; */ 71/* typedef struct rand_meth_st RAND_METHOD; */
80 72
@@ -88,10 +80,6 @@ struct rand_meth_st
88 int (*status)(void); 80 int (*status)(void);
89 }; 81 };
90 82
91#ifdef BN_DEBUG
92extern int rand_predictable;
93#endif
94
95int RAND_set_rand_method(const RAND_METHOD *meth); 83int RAND_set_rand_method(const RAND_METHOD *meth);
96const RAND_METHOD *RAND_get_rand_method(void); 84const RAND_METHOD *RAND_get_rand_method(void);
97#ifndef OPENSSL_NO_ENGINE 85#ifndef OPENSSL_NO_ENGINE
@@ -112,25 +100,13 @@ int RAND_egd(const char *path);
112int RAND_egd_bytes(const char *path,int bytes); 100int RAND_egd_bytes(const char *path,int bytes);
113int RAND_poll(void); 101int RAND_poll(void);
114 102
115#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
116
117void RAND_screen(void);
118int RAND_event(UINT, WPARAM, LPARAM);
119
120#endif
121
122#ifdef OPENSSL_FIPS
123void RAND_set_fips_drbg_type(int type, int flags);
124int RAND_init_fips(void);
125#endif
126
127/* BEGIN ERROR CODES */ 103/* BEGIN ERROR CODES */
128/* The following lines are auto generated by the script mkerr.pl. Any changes 104/* The following lines are auto generated by the script mkerr.pl. Any changes
129 * made after this point may be overwritten when the script is next run. 105 * made after this point may be overwritten when the script is next run.
130 */ 106 */
131void ERR_load_RAND_strings(void); 107void ERR_load_RAND_strings(void);
132 108
133/* Error codes for the RAND functions. */ 109/* Error codes for the RAND functions. (no longer used) */
134 110
135/* Function codes. */ 111/* Function codes. */
136#define RAND_F_RAND_GET_RAND_METHOD 101 112#define RAND_F_RAND_GET_RAND_METHOD 101
diff --git a/src/lib/libcrypto/rand/rand_egd.c b/src/lib/libcrypto/rand/rand_egd.c
index d53b916ebe..a78aa90c46 100644
--- a/src/lib/libcrypto/rand/rand_egd.c
+++ b/src/lib/libcrypto/rand/rand_egd.c
@@ -95,7 +95,6 @@
95 * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. 95 * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
96 */ 96 */
97 97
98#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
99int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) 98int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
100 { 99 {
101 return(-1); 100 return(-1);
@@ -109,195 +108,3 @@ int RAND_egd_bytes(const char *path,int bytes)
109 { 108 {
110 return(-1); 109 return(-1);
111 } 110 }
112#else
113#include <openssl/opensslconf.h>
114#include OPENSSL_UNISTD
115#include <sys/types.h>
116#include <sys/socket.h>
117#ifndef NO_SYS_UN_H
118# ifdef OPENSSL_SYS_VXWORKS
119# include <streams/un.h>
120# else
121# include <sys/un.h>
122# endif
123#else
124struct sockaddr_un {
125 short sun_family; /* AF_UNIX */
126 char sun_path[108]; /* path name (gag) */
127};
128#endif /* NO_SYS_UN_H */
129#include <string.h>
130#include <errno.h>
131
132#ifndef offsetof
133# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
134#endif
135
136int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
137 {
138 int ret = 0;
139 struct sockaddr_un addr;
140 int len, num, numbytes;
141 int fd = -1;
142 int success;
143 unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
144
145 memset(&addr, 0, sizeof(addr));
146 addr.sun_family = AF_UNIX;
147 if (strlen(path) >= sizeof(addr.sun_path))
148 return (-1);
149 BUF_strlcpy(addr.sun_path,path,sizeof addr.sun_path);
150 len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
151 fd = socket(AF_UNIX, SOCK_STREAM, 0);
152 if (fd == -1) return (-1);
153 success = 0;
154 while (!success)
155 {
156 if (connect(fd, (struct sockaddr *)&addr, len) == 0)
157 success = 1;
158 else
159 {
160 switch (errno)
161 {
162#ifdef EINTR
163 case EINTR:
164#endif
165#ifdef EAGAIN
166 case EAGAIN:
167#endif
168#ifdef EINPROGRESS
169 case EINPROGRESS:
170#endif
171#ifdef EALREADY
172 case EALREADY:
173#endif
174 /* No error, try again */
175 break;
176#ifdef EISCONN
177 case EISCONN:
178 success = 1;
179 break;
180#endif
181 default:
182 goto err; /* failure */
183 }
184 }
185 }
186
187 while(bytes > 0)
188 {
189 egdbuf[0] = 1;
190 egdbuf[1] = bytes < 255 ? bytes : 255;
191 numbytes = 0;
192 while (numbytes != 2)
193 {
194 num = write(fd, egdbuf + numbytes, 2 - numbytes);
195 if (num >= 0)
196 numbytes += num;
197 else
198 {
199 switch (errno)
200 {
201#ifdef EINTR
202 case EINTR:
203#endif
204#ifdef EAGAIN
205 case EAGAIN:
206#endif
207 /* No error, try again */
208 break;
209 default:
210 ret = -1;
211 goto err; /* failure */
212 }
213 }
214 }
215 numbytes = 0;
216 while (numbytes != 1)
217 {
218 num = read(fd, egdbuf, 1);
219 if (num == 0)
220 goto err; /* descriptor closed */
221 else if (num > 0)
222 numbytes += num;
223 else
224 {
225 switch (errno)
226 {
227#ifdef EINTR
228 case EINTR:
229#endif
230#ifdef EAGAIN
231 case EAGAIN:
232#endif
233 /* No error, try again */
234 break;
235 default:
236 ret = -1;
237 goto err; /* failure */
238 }
239 }
240 }
241 if(egdbuf[0] == 0)
242 goto err;
243 if (buf)
244 retrievebuf = buf + ret;
245 else
246 retrievebuf = tempbuf;
247 numbytes = 0;
248 while (numbytes != egdbuf[0])
249 {
250 num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
251 if (num == 0)
252 goto err; /* descriptor closed */
253 else if (num > 0)
254 numbytes += num;
255 else
256 {
257 switch (errno)
258 {
259#ifdef EINTR
260 case EINTR:
261#endif
262#ifdef EAGAIN
263 case EAGAIN:
264#endif
265 /* No error, try again */
266 break;
267 default:
268 ret = -1;
269 goto err; /* failure */
270 }
271 }
272 }
273 ret += egdbuf[0];
274 bytes -= egdbuf[0];
275 if (!buf)
276 RAND_seed(tempbuf, egdbuf[0]);
277 }
278 err:
279 if (fd != -1) close(fd);
280 return(ret);
281 }
282
283
284int RAND_egd_bytes(const char *path, int bytes)
285 {
286 int num, ret = 0;
287
288 num = RAND_query_egd_bytes(path, NULL, bytes);
289 if (num < 1) goto err;
290 if (RAND_status() == 1)
291 ret = num;
292 err:
293 return(ret);
294 }
295
296
297int RAND_egd(const char *path)
298 {
299 return (RAND_egd_bytes(path, 255));
300 }
301
302
303#endif
diff --git a/src/lib/libcrypto/rand/rand_lcl.h b/src/lib/libcrypto/rand/rand_lcl.h
deleted file mode 100644
index 618a8ec899..0000000000
--- a/src/lib/libcrypto/rand/rand_lcl.h
+++ /dev/null
@@ -1,158 +0,0 @@
1/* crypto/rand/rand_lcl.h */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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 */
58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
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 */
111
112#ifndef HEADER_RAND_LCL_H
113#define HEADER_RAND_LCL_H
114
115#define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */
116
117
118#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
119#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
120#define USE_SHA1_RAND
121#elif !defined(OPENSSL_NO_MD5)
122#define USE_MD5_RAND
123#elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
124#define USE_MDC2_RAND
125#elif !defined(OPENSSL_NO_MD2)
126#define USE_MD2_RAND
127#else
128#error No message digest algorithm available
129#endif
130#endif
131
132#include <openssl/evp.h>
133#define MD_Update(a,b,c) EVP_DigestUpdate(a,b,c)
134#define MD_Final(a,b) EVP_DigestFinal_ex(a,b,NULL)
135#if defined(USE_MD5_RAND)
136#include <openssl/md5.h>
137#define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH
138#define MD_Init(a) EVP_DigestInit_ex(a,EVP_md5(), NULL)
139#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md5(), NULL)
140#elif defined(USE_SHA1_RAND)
141#include <openssl/sha.h>
142#define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH
143#define MD_Init(a) EVP_DigestInit_ex(a,EVP_sha1(), NULL)
144#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL)
145#elif defined(USE_MDC2_RAND)
146#include <openssl/mdc2.h>
147#define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH
148#define MD_Init(a) EVP_DigestInit_ex(a,EVP_mdc2(), NULL)
149#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL)
150#elif defined(USE_MD2_RAND)
151#include <openssl/md2.h>
152#define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH
153#define MD_Init(a) EVP_DigestInit_ex(a,EVP_md2(), NULL)
154#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
155#endif
156
157
158#endif
diff --git a/src/lib/libcrypto/rand/rand_lib.c b/src/lib/libcrypto/rand/rand_lib.c
index 5ac0e14caf..243a87ddfb 100644
--- a/src/lib/libcrypto/rand/rand_lib.c
+++ b/src/lib/libcrypto/rand/rand_lib.c
@@ -65,11 +65,6 @@
65#include <openssl/engine.h> 65#include <openssl/engine.h>
66#endif 66#endif
67 67
68#ifdef OPENSSL_FIPS
69#include <openssl/fips.h>
70#include <openssl/fips_rand.h>
71#endif
72
73#ifndef OPENSSL_NO_ENGINE 68#ifndef OPENSSL_NO_ENGINE
74/* non-NULL if default_RAND_meth is ENGINE-provided */ 69/* non-NULL if default_RAND_meth is ENGINE-provided */
75static ENGINE *funct_ref =NULL; 70static ENGINE *funct_ref =NULL;
@@ -180,127 +175,3 @@ int RAND_status(void)
180 return meth->status(); 175 return meth->status();
181 return 0; 176 return 0;
182 } 177 }
183
184#ifdef OPENSSL_FIPS
185
186/* FIPS DRBG initialisation code. This sets up the DRBG for use by the
187 * rest of OpenSSL.
188 */
189
190/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
191 * entropy internally through RAND_poll().
192 */
193
194static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
195 int entropy, size_t min_len, size_t max_len)
196 {
197 /* Round up request to multiple of block size */
198 min_len = ((min_len + 19) / 20) * 20;
199 *pout = OPENSSL_malloc(min_len);
200 if (!*pout)
201 return 0;
202 if (RAND_SSLeay()->bytes(*pout, min_len) <= 0)
203 {
204 OPENSSL_free(*pout);
205 *pout = NULL;
206 return 0;
207 }
208 return min_len;
209 }
210
211static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
212 {
213 if (out)
214 {
215 OPENSSL_cleanse(out, olen);
216 OPENSSL_free(out);
217 }
218 }
219
220/* Set "additional input" when generating random data. This uses the
221 * current PID, a time value and a counter.
222 */
223
224static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
225 {
226 /* Use of static variables is OK as this happens under a lock */
227 static unsigned char buf[16];
228 static unsigned long counter;
229 FIPS_get_timevec(buf, &counter);
230 *pout = buf;
231 return sizeof(buf);
232 }
233
234/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
235 * correctly seeded by RAND_poll().
236 */
237
238static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
239 double entropy)
240 {
241 RAND_SSLeay()->add(in, inlen, entropy);
242 return 1;
243 }
244
245static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
246 {
247 RAND_SSLeay()->seed(in, inlen);
248 return 1;
249 }
250
251#ifndef OPENSSL_DRBG_DEFAULT_TYPE
252#define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr
253#endif
254#ifndef OPENSSL_DRBG_DEFAULT_FLAGS
255#define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF
256#endif
257
258static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
259static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
260
261void RAND_set_fips_drbg_type(int type, int flags)
262 {
263 fips_drbg_type = type;
264 fips_drbg_flags = flags;
265 }
266
267int RAND_init_fips(void)
268 {
269 DRBG_CTX *dctx;
270 size_t plen;
271 unsigned char pers[32], *p;
272#ifndef OPENSSL_ALLOW_DUAL_EC_DRBG
273 if (fips_drbg_type >> 16)
274 {
275 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED);
276 return 0;
277 }
278#endif
279
280 dctx = FIPS_get_default_drbg();
281 if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
282 {
283 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
284 return 0;
285 }
286
287 FIPS_drbg_set_callbacks(dctx,
288 drbg_get_entropy, drbg_free_entropy, 20,
289 drbg_get_entropy, drbg_free_entropy);
290 FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
291 drbg_rand_seed, drbg_rand_add);
292 /* Personalisation string: a string followed by date time vector */
293 strcpy((char *)pers, "OpenSSL DRBG2.0");
294 plen = drbg_get_adin(dctx, &p);
295 memcpy(pers + 16, p, plen);
296
297 if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0)
298 {
299 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
300 return 0;
301 }
302 FIPS_rand_set_method(FIPS_drbg_method());
303 return 1;
304 }
305
306#endif
diff --git a/src/lib/libcrypto/rand/rand_unix.c b/src/lib/libcrypto/rand/rand_unix.c
index 3316388443..a5b9b2a529 100644
--- a/src/lib/libcrypto/rand/rand_unix.c
+++ b/src/lib/libcrypto/rand/rand_unix.c
@@ -108,318 +108,14 @@
108 * Hudson (tjh@cryptsoft.com). 108 * Hudson (tjh@cryptsoft.com).
109 * 109 *
110 */ 110 */
111#include <stdio.h>
112
113#define USE_SOCKETS
114#include "e_os.h" 111#include "e_os.h"
115#include "cryptlib.h" 112#include "cryptlib.h"
116#include <openssl/rand.h> 113#include <openssl/rand.h>
117#include "rand_lcl.h"
118
119#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE))
120
121#include <sys/types.h>
122#include <sys/time.h>
123#include <sys/times.h>
124#include <sys/stat.h>
125#include <fcntl.h>
126#include <unistd.h>
127#include <time.h>
128#if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywhere */
129# include <poll.h>
130#endif
131#include <limits.h>
132#ifndef FD_SETSIZE
133# define FD_SETSIZE (8*sizeof(fd_set))
134#endif
135
136#if defined(OPENSSL_SYS_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)
154{
155 short int code;
156 gid_t curr_gid;
157 pid_t curr_pid;
158 uid_t curr_uid;
159 int i, k;
160 struct timespec ts;
161 unsigned char v;
162
163#ifdef OPENSSL_SYS_VOS_HPPA
164 long duration;
165 extern void s$sleep (long *_duration, short int *_code);
166#else
167#ifdef OPENSSL_SYS_VOS_IA32
168 long long duration;
169 extern void s$sleep2 (long long *_duration, short int *_code);
170#else
171#error "Unsupported Platform."
172#endif /* OPENSSL_SYS_VOS_IA32 */
173#endif /* OPENSSL_SYS_VOS_HPPA */
174
175 /* Seed with the gid, pid, and uid, to ensure *some*
176 variation between different processes. */
177 114
178 curr_gid = getgid(); 115#include <stdlib.h>
179 RAND_add (&curr_gid, sizeof curr_gid, 1); 116#include <string.h>
180 curr_gid = 0;
181 117
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
212 /* take 8 bits */
213 v = (unsigned char) (ts.tv_nsec % 256);
214 RAND_add (&v, sizeof v, 1);
215 v = 0;
216 }
217 return 1;
218}
219#elif defined __OpenBSD__
220int RAND_poll(void) 118int RAND_poll(void)
221{ 119{
222 unsigned char buf[ENTROPY_NEEDED];
223
224 arc4random_buf(buf, sizeof(buf));
225 RAND_add(buf, sizeof(buf), sizeof(buf));
226 memset(buf, 0, sizeof(buf));
227
228 return 1; 120 return 1;
229} 121}
230#else /* !defined(__OpenBSD__) */
231int RAND_poll(void)
232{
233 unsigned long l;
234 pid_t curr_pid = getpid();
235#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
236 unsigned char tmpbuf[ENTROPY_NEEDED];
237 int n = 0;
238#endif
239#ifdef DEVRANDOM
240 static const char *randomfiles[] = { DEVRANDOM };
241 struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
242 int fd;
243 unsigned int i;
244#endif
245#ifdef DEVRANDOM_EGD
246 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
247 const char **egdsocket = NULL;
248#endif
249
250#ifdef DEVRANDOM
251 memset(randomstats,0,sizeof(randomstats));
252 /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
253 * have this. Use /dev/urandom if you can as /dev/random may block
254 * if it runs out of random entries. */
255
256 for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) &&
257 (n < ENTROPY_NEEDED); i++)
258 {
259 if ((fd = open(randomfiles[i], O_RDONLY
260#ifdef O_NONBLOCK
261 |O_NONBLOCK
262#endif
263#ifdef O_BINARY
264 |O_BINARY
265#endif
266#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
267 our controlling tty */
268 |O_NOCTTY
269#endif
270 )) >= 0)
271 {
272 int usec = 10*1000; /* spend 10ms on each file */
273 int r;
274 unsigned int j;
275 struct stat *st=&randomstats[i];
276
277 /* Avoid using same input... Used to be O_NOFOLLOW
278 * above, but it's not universally appropriate... */
279 if (fstat(fd,st) != 0) { close(fd); continue; }
280 for (j=0;j<i;j++)
281 {
282 if (randomstats[j].st_ino==st->st_ino &&
283 randomstats[j].st_dev==st->st_dev)
284 break;
285 }
286 if (j<i) { close(fd); continue; }
287
288 do
289 {
290 int try_read = 0;
291
292#if defined(OPENSSL_SYS_BEOS_R5)
293 /* select() is broken in BeOS R5, so we simply
294 * try to read something and snooze if we couldn't */
295 try_read = 1;
296
297#elif defined(OPENSSL_SYS_LINUX)
298 /* use poll() */
299 struct pollfd pset;
300
301 pset.fd = fd;
302 pset.events = POLLIN;
303 pset.revents = 0;
304
305 if (poll(&pset, 1, usec / 1000) < 0)
306 usec = 0;
307 else
308 try_read = (pset.revents & POLLIN) != 0;
309
310#else
311 /* use select() */
312 fd_set fset;
313 struct timeval t;
314
315 t.tv_sec = 0;
316 t.tv_usec = usec;
317
318 if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE)
319 {
320 /* can't use select, so just try to read once anyway */
321 try_read = 1;
322 }
323 else
324 {
325 FD_ZERO(&fset);
326 FD_SET(fd, &fset);
327
328 if (select(fd+1,&fset,NULL,NULL,&t) >= 0)
329 {
330 usec = t.tv_usec;
331 if (FD_ISSET(fd, &fset))
332 try_read = 1;
333 }
334 else
335 usec = 0;
336 }
337#endif
338
339 if (try_read)
340 {
341 r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
342 if (r > 0)
343 n += r;
344#if defined(OPENSSL_SYS_BEOS_R5)
345 if (r == 0)
346 snooze(t.tv_usec);
347#endif
348 }
349 else
350 r = -1;
351
352 /* Some Unixen will update t in select(), some
353 won't. For those who won't, or if we
354 didn't use select() in the first place,
355 give up here, otherwise, we will do
356 this once again for the remaining
357 time. */
358 if (usec == 10*1000)
359 usec = 0;
360 }
361 while ((r > 0 ||
362 (errno == EINTR || errno == EAGAIN)) && usec != 0 && n < ENTROPY_NEEDED);
363
364 close(fd);
365 }
366 }
367#endif /* defined(DEVRANDOM) */
368
369#ifdef DEVRANDOM_EGD
370 /* Use an EGD socket to read entropy from an EGD or PRNGD entropy
371 * collecting daemon. */
372
373 for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++)
374 {
375 int r;
376
377 r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n,
378 ENTROPY_NEEDED-n);
379 if (r > 0)
380 n += r;
381 }
382#endif /* defined(DEVRANDOM_EGD) */
383
384#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
385 if (n > 0)
386 {
387 RAND_add(tmpbuf,sizeof tmpbuf,(double)n);
388 OPENSSL_cleanse(tmpbuf,n);
389 }
390#endif
391
392 /* put in some default random data, we need more than just this */
393 l=curr_pid;
394 RAND_add(&l,sizeof(l),0.0);
395 l=getuid();
396 RAND_add(&l,sizeof(l),0.0);
397
398 l=time(NULL);
399 RAND_add(&l,sizeof(l),0.0);
400
401#if defined(OPENSSL_SYS_BEOS)
402 {
403 system_info sysInfo;
404 get_system_info(&sysInfo);
405 RAND_add(&sysInfo,sizeof(sysInfo),0);
406 }
407#endif
408
409#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
410 return 1;
411#else
412 return 0;
413#endif
414}
415
416#endif /* defined(__OpenBSD__) */
417#endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) */
418
419
420#if defined(OPENSSL_SYS_VXWORKS)
421int RAND_poll(void)
422 {
423 return 0;
424 }
425#endif
diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c
index 10d511b8e8..2cacebcf07 100644
--- a/src/lib/libcrypto/rand/randfile.c
+++ b/src/lib/libcrypto/rand/randfile.c
@@ -56,11 +56,6 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59/* We need to define this to get macros like S_IFBLK and S_IFCHR */
60#if !defined(OPENSSL_SYS_VXWORKS)
61#define _XOPEN_SOURCE 500
62#endif
63
64#include <errno.h> 59#include <errno.h>
65#include <stdio.h> 60#include <stdio.h>
66#include <stdlib.h> 61#include <stdlib.h>
@@ -71,35 +66,14 @@
71#include <openssl/rand.h> 66#include <openssl/rand.h>
72#include <openssl/buffer.h> 67#include <openssl/buffer.h>
73 68
74#ifdef OPENSSL_SYS_VMS 69#include <sys/types.h>
75#include <unixio.h> 70#include <sys/stat.h>
76#endif 71#include <fcntl.h>
77#ifndef NO_SYS_TYPES_H
78# include <sys/types.h>
79#endif
80#ifndef OPENSSL_NO_POSIX_IO
81# include <sys/stat.h>
82#endif
83
84#ifdef _WIN32
85#define stat _stat
86#define chmod _chmod
87#define open _open
88#define fdopen _fdopen
89#endif
90 72
91#undef BUFSIZE 73#undef BUFSIZE
92#define BUFSIZE 1024 74#define BUFSIZE 1024
93#define RAND_DATA 1024 75#define RAND_DATA 1024
94 76
95#ifdef OPENSSL_SYS_VMS
96/* This declaration is a nasty hack to get around vms' extension to fopen
97 * for passing in sharing options being disabled by our /STANDARD=ANSI89 */
98static FILE *(*const vms_fopen)(const char *, const char *, ...) =
99 (FILE *(*)(const char *, const char *, ...))fopen;
100#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
101#endif
102
103/* #define RFILE ".rnd" - defined in ../../e_os.h */ 77/* #define RFILE ".rnd" - defined in ../../e_os.h */
104 78
105/* Note that these functions are intended for seed files only. 79/* Note that these functions are intended for seed files only.
@@ -107,75 +81,7 @@ static FILE *(*const vms_fopen)(const char *, const char *, ...) =
107 81
108int RAND_load_file(const char *file, long bytes) 82int RAND_load_file(const char *file, long bytes)
109 { 83 {
110 /* If bytes >= 0, read up to 'bytes' bytes. 84 return(0);
111 * if bytes == -1, read complete file. */
112
113 unsigned char buf[BUFSIZE];
114#ifndef OPENSSL_NO_POSIX_IO
115 struct stat sb;
116#endif
117 int i,ret=0,n;
118 FILE *in;
119
120 if (file == NULL) return(0);
121
122#ifndef OPENSSL_NO_POSIX_IO
123#ifdef PURIFY
124 /* struct stat can have padding and unused fields that may not be
125 * initialized in the call to stat(). We need to clear the entire
126 * structure before calling RAND_add() to avoid complaints from
127 * applications such as Valgrind.
128 */
129 memset(&sb, 0, sizeof(sb));
130#endif
131 if (stat(file,&sb) < 0) return(0);
132 RAND_add(&sb,sizeof(sb),0.0);
133#endif
134 if (bytes == 0) return(ret);
135
136#ifdef OPENSSL_SYS_VMS
137 in=vms_fopen(file,"rb",VMS_OPEN_ATTRS);
138#else
139 in=fopen(file,"rb");
140#endif
141 if (in == NULL) goto err;
142#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
143 if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
144 /* this file is a device. we don't want read an infinite number
145 * of bytes from a random device, nor do we want to use buffered
146 * I/O because we will waste system entropy.
147 */
148 bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
149#ifndef OPENSSL_NO_SETVBUF_IONBF
150 setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
151#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
152 }
153#endif
154 for (;;)
155 {
156 if (bytes > 0)
157 n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
158 else
159 n = BUFSIZE;
160 i=fread(buf,1,n,in);
161 if (i <= 0) break;
162#ifdef PURIFY
163 RAND_add(buf,i,(double)i);
164#else
165 /* even if n != i, use the full array */
166 RAND_add(buf,n,(double)i);
167#endif
168 ret+=i;
169 if (bytes > 0)
170 {
171 bytes-=n;
172 if (bytes <= 0) break;
173 }
174 }
175 fclose(in);
176 OPENSSL_cleanse(buf,BUFSIZE);
177err:
178 return(ret);
179 } 85 }
180 86
181int RAND_write_file(const char *file) 87int RAND_write_file(const char *file)
@@ -184,12 +90,10 @@ int RAND_write_file(const char *file)
184 int i,ret=0,rand_err=0; 90 int i,ret=0,rand_err=0;
185 FILE *out = NULL; 91 FILE *out = NULL;
186 int n; 92 int n;
187#ifndef OPENSSL_NO_POSIX_IO
188 struct stat sb; 93 struct stat sb;
189 94
190 i=stat(file,&sb); 95 i=stat(file,&sb);
191 if (i != -1) { 96 if (i != -1) {
192#if defined(S_ISBLK) && defined(S_ISCHR)
193 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { 97 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
194 /* this file is a device. we don't write back to it. 98 /* this file is a device. we don't write back to it.
195 * we "succeed" on the assumption this is some sort 99 * we "succeed" on the assumption this is some sort
@@ -198,55 +102,21 @@ int RAND_write_file(const char *file)
198 */ 102 */
199 return(1); 103 return(1);
200 } 104 }
201#endif
202 } 105 }
203#endif
204 106
205#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
206 { 107 {
207#ifndef O_BINARY
208#define O_BINARY 0
209#endif
210 /* chmod(..., 0600) is too late to protect the file, 108 /* chmod(..., 0600) is too late to protect the file,
211 * permissions should be restrictive from the start */ 109 * permissions should be restrictive from the start */
212 int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600); 110 int fd = open(file, O_WRONLY|O_CREAT, 0600);
213 if (fd != -1) 111 if (fd != -1)
214 out = fdopen(fd, "wb"); 112 out = fdopen(fd, "wb");
215 } 113 }
216#endif
217
218#ifdef OPENSSL_SYS_VMS
219 /* VMS NOTE: Prior versions of this routine created a _new_
220 * version of the rand file for each call into this routine, then
221 * deleted all existing versions named ;-1, and finally renamed
222 * the current version as ';1'. Under concurrent usage, this
223 * resulted in an RMS race condition in rename() which could
224 * orphan files (see vms message help for RMS$_REENT). With the
225 * fopen() calls below, openssl/VMS now shares the top-level
226 * version of the rand file. Note that there may still be
227 * conditions where the top-level rand file is locked. If so, this
228 * code will then create a new version of the rand file. Without
229 * the delete and rename code, this can result in ascending file
230 * versions that stop at version 32767, and this routine will then
231 * return an error. The remedy for this is to recode the calling
232 * application to avoid concurrent use of the rand file, or
233 * synchronize usage at the application level. Also consider
234 * whether or not you NEED a persistent rand file in a concurrent
235 * use situation.
236 */
237 114
238 out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS);
239 if (out == NULL)
240 out = vms_fopen(file,"wb",VMS_OPEN_ATTRS);
241#else
242 if (out == NULL) 115 if (out == NULL)
243 out = fopen(file,"wb"); 116 out = fopen(file,"wb");
244#endif
245 if (out == NULL) goto err; 117 if (out == NULL) goto err;
246 118
247#ifndef NO_CHMOD
248 chmod(file,0600); 119 chmod(file,0600);
249#endif
250 n=RAND_DATA; 120 n=RAND_DATA;
251 for (;;) 121 for (;;)
252 { 122 {
@@ -273,9 +143,7 @@ err:
273const char *RAND_file_name(char *buf, size_t size) 143const char *RAND_file_name(char *buf, size_t size)
274 { 144 {
275 char *s=NULL; 145 char *s=NULL;
276#ifdef __OpenBSD__
277 struct stat sb; 146 struct stat sb;
278#endif
279 147
280 if (OPENSSL_issetugid() == 0) 148 if (OPENSSL_issetugid() == 0)
281 s=getenv("RANDFILE"); 149 s=getenv("RANDFILE");
@@ -288,25 +156,16 @@ const char *RAND_file_name(char *buf, size_t size)
288 { 156 {
289 if (OPENSSL_issetugid() == 0) 157 if (OPENSSL_issetugid() == 0)
290 s=getenv("HOME"); 158 s=getenv("HOME");
291#ifdef DEFAULT_HOME
292 if (s == NULL)
293 {
294 s = DEFAULT_HOME;
295 }
296#endif
297 if (s && *s && strlen(s)+strlen(RFILE)+2 < size) 159 if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
298 { 160 {
299 BUF_strlcpy(buf,s,size); 161 BUF_strlcpy(buf,s,size);
300#ifndef OPENSSL_SYS_VMS
301 BUF_strlcat(buf,"/",size); 162 BUF_strlcat(buf,"/",size);
302#endif
303 BUF_strlcat(buf,RFILE,size); 163 BUF_strlcat(buf,RFILE,size);
304 } 164 }
305 else 165 else
306 buf[0] = '\0'; /* no file name */ 166 buf[0] = '\0'; /* no file name */
307 } 167 }
308 168
309#ifdef __OpenBSD__
310 /* given that all random loads just fail if the file can't be 169 /* given that all random loads just fail if the file can't be
311 * seen on a stat, we stat the file we're returning, if it 170 * seen on a stat, we stat the file we're returning, if it
312 * fails, use /dev/arandom instead. this allows the user to 171 * fails, use /dev/arandom instead. this allows the user to
@@ -323,6 +182,5 @@ const char *RAND_file_name(char *buf, size_t size)
323 return(NULL); 182 return(NULL);
324 } 183 }
325 184
326#endif
327 return(buf); 185 return(buf);
328 } 186 }
diff --git a/src/lib/libcrypto/rand/rc4_rand.c b/src/lib/libcrypto/rand/rc4_rand.c
new file mode 100644
index 0000000000..ebfb241d53
--- /dev/null
+++ b/src/lib/libcrypto/rand/rc4_rand.c
@@ -0,0 +1,44 @@
1/* $OpenBSD: rc4_rand.c,v 1.1 2014/04/15 16:52:50 miod Exp $ */
2
3/*
4 * Copyright (c) 2014 Miodrag Vallat.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <stdlib.h>
20
21#include <openssl/rand.h>
22
23static int
24arc4_rand_bytes(unsigned char *buf, int num)
25{
26 if (num > 0)
27 arc4random_buf(buf, (size_t)num);
28
29 return 1;
30}
31
32static RAND_METHOD rand_arc4_meth = {
33 .seed = NULL, /* no external seed allowed */
34 .bytes = arc4_rand_bytes,
35 .cleanup = NULL, /* no cleanup necessary */
36 .add = NULL, /* no external feed allowed */
37 .pseudorand = arc4_rand_bytes,
38 .status = NULL /* no possible error condition */
39};
40
41RAND_METHOD *RAND_SSLeay(void)
42{
43 return &rand_arc4_meth;
44}
diff --git a/src/lib/libssl/src/crypto/rand/md_rand.c b/src/lib/libssl/src/crypto/rand/md_rand.c
deleted file mode 100644
index aee1c30b0a..0000000000
--- a/src/lib/libssl/src/crypto/rand/md_rand.c
+++ /dev/null
@@ -1,607 +0,0 @@
1/* crypto/rand/md_rand.c */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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 */
58/* ====================================================================
59 * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved.
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 */
111
112#define OPENSSL_FIPSEVP
113
114#ifdef MD_RAND_DEBUG
115# ifndef NDEBUG
116# define NDEBUG
117# endif
118#endif
119
120#include <assert.h>
121#include <stdio.h>
122#include <string.h>
123
124#include "e_os.h"
125
126#include <openssl/crypto.h>
127#include <openssl/rand.h>
128#include "rand_lcl.h"
129
130#include <openssl/err.h>
131
132#ifdef BN_DEBUG
133# define PREDICT
134#endif
135
136/* #define PREDICT 1 */
137
138#define STATE_SIZE 1023
139static int state_num=0,state_index=0;
140static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
141static unsigned char md[MD_DIGEST_LENGTH];
142static long md_count[2]={0,0};
143static double entropy=0;
144static int initialized=0;
145
146static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
147 * holds CRYPTO_LOCK_RAND
148 * (to prevent double locking) */
149/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
150static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
151
152
153#ifdef PREDICT
154int rand_predictable=0;
155#endif
156
157const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
158
159static void ssleay_rand_cleanup(void);
160static void ssleay_rand_seed(const void *buf, int num);
161static void ssleay_rand_add(const void *buf, int num, double add_entropy);
162static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo);
163static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num);
164static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
165static int ssleay_rand_status(void);
166
167RAND_METHOD rand_ssleay_meth={
168 ssleay_rand_seed,
169 ssleay_rand_nopseudo_bytes,
170 ssleay_rand_cleanup,
171 ssleay_rand_add,
172 ssleay_rand_pseudo_bytes,
173 ssleay_rand_status
174 };
175
176RAND_METHOD *RAND_SSLeay(void)
177 {
178 return(&rand_ssleay_meth);
179 }
180
181static void ssleay_rand_cleanup(void)
182 {
183 OPENSSL_cleanse(state,sizeof(state));
184 state_num=0;
185 state_index=0;
186 OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
187 md_count[0]=0;
188 md_count[1]=0;
189 entropy=0;
190 initialized=0;
191 }
192
193static void ssleay_rand_add(const void *buf, int num, double add)
194 {
195 int i,j,k,st_idx;
196 long md_c[2];
197 unsigned char local_md[MD_DIGEST_LENGTH];
198 EVP_MD_CTX m;
199 int do_not_lock;
200
201 if (!num)
202 return;
203
204 /*
205 * (Based on the rand(3) manpage)
206 *
207 * The input is chopped up into units of 20 bytes (or less for
208 * the last block). Each of these blocks is run through the hash
209 * function as follows: The data passed to the hash function
210 * is the current 'md', the same number of bytes from the 'state'
211 * (the location determined by in incremented looping index) as
212 * the current 'block', the new key data 'block', and 'count'
213 * (which is incremented after each use).
214 * The result of this is kept in 'md' and also xored into the
215 * 'state' at the same locations that were used as input into the
216 * hash function.
217 */
218
219 /* check if we already have the lock */
220 if (crypto_lock_rand)
221 {
222 CRYPTO_THREADID cur;
223 CRYPTO_THREADID_current(&cur);
224 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
225 do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
226 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
227 }
228 else
229 do_not_lock = 0;
230
231 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
232 st_idx=state_index;
233
234 /* use our own copies of the counters so that even
235 * if a concurrent thread seeds with exactly the
236 * same data and uses the same subarray there's _some_
237 * difference */
238 md_c[0] = md_count[0];
239 md_c[1] = md_count[1];
240
241 memcpy(local_md, md, sizeof md);
242
243 /* state_index <= state_num <= STATE_SIZE */
244 state_index += num;
245 if (state_index >= STATE_SIZE)
246 {
247 state_index%=STATE_SIZE;
248 state_num=STATE_SIZE;
249 }
250 else if (state_num < STATE_SIZE)
251 {
252 if (state_index > state_num)
253 state_num=state_index;
254 }
255 /* state_index <= state_num <= STATE_SIZE */
256
257 /* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
258 * are what we will use now, but other threads may use them
259 * as well */
260
261 md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
262
263 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
264
265 EVP_MD_CTX_init(&m);
266 for (i=0; i<num; i+=MD_DIGEST_LENGTH)
267 {
268 j=(num-i);
269 j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
270
271 MD_Init(&m);
272 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
273 k=(st_idx+j)-STATE_SIZE;
274 if (k > 0)
275 {
276 MD_Update(&m,&(state[st_idx]),j-k);
277 MD_Update(&m,&(state[0]),k);
278 }
279 else
280 MD_Update(&m,&(state[st_idx]),j);
281
282 /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
283 MD_Update(&m,buf,j);
284 /* We know that line may cause programs such as
285 purify and valgrind to complain about use of
286 uninitialized data. The problem is not, it's
287 with the caller. Removing that line will make
288 sure you get really bad randomness and thereby
289 other problems such as very insecure keys. */
290
291 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
292 MD_Final(&m,local_md);
293 md_c[1]++;
294
295 buf=(const char *)buf + j;
296
297 for (k=0; k<j; k++)
298 {
299 /* Parallel threads may interfere with this,
300 * but always each byte of the new state is
301 * the XOR of some previous value of its
302 * and local_md (itermediate values may be lost).
303 * Alway using locking could hurt performance more
304 * than necessary given that conflicts occur only
305 * when the total seeding is longer than the random
306 * state. */
307 state[st_idx++]^=local_md[k];
308 if (st_idx >= STATE_SIZE)
309 st_idx=0;
310 }
311 }
312 EVP_MD_CTX_cleanup(&m);
313
314 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
315 /* Don't just copy back local_md into md -- this could mean that
316 * other thread's seeding remains without effect (except for
317 * the incremented counter). By XORing it we keep at least as
318 * much entropy as fits into md. */
319 for (k = 0; k < (int)sizeof(md); k++)
320 {
321 md[k] ^= local_md[k];
322 }
323 if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
324 entropy += add;
325 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
326
327#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
328 assert(md_c[1] == md_count[1]);
329#endif
330 }
331
332static void ssleay_rand_seed(const void *buf, int num)
333 {
334 ssleay_rand_add(buf, num, (double)num);
335 }
336
337static int ssleay_rand_bytes(unsigned char *buf, int num, int pseudo)
338 {
339 static volatile int stirred_pool = 0;
340 int i,j,k,st_num,st_idx;
341 int num_ceil;
342 int ok;
343 long md_c[2];
344 unsigned char local_md[MD_DIGEST_LENGTH];
345 EVP_MD_CTX m;
346#ifndef GETPID_IS_MEANINGLESS
347 pid_t curr_pid = getpid();
348#endif
349 int do_stir_pool = 0;
350
351#ifdef PREDICT
352 if (rand_predictable)
353 {
354 static unsigned char val=0;
355
356 for (i=0; i<num; i++)
357 buf[i]=val++;
358 return(1);
359 }
360#endif
361
362 if (num <= 0)
363 return 1;
364
365 EVP_MD_CTX_init(&m);
366 /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
367 num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
368
369 /*
370 * (Based on the rand(3) manpage:)
371 *
372 * For each group of 10 bytes (or less), we do the following:
373 *
374 * Input into the hash function the local 'md' (which is initialized from
375 * the global 'md' before any bytes are generated), the bytes that are to
376 * be overwritten by the random bytes, and bytes from the 'state'
377 * (incrementing looping index). From this digest output (which is kept
378 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
379 * bottom 10 bytes are xored into the 'state'.
380 *
381 * Finally, after we have finished 'num' random bytes for the
382 * caller, 'count' (which is incremented) and the local and global 'md'
383 * are fed into the hash function and the results are kept in the
384 * global 'md'.
385 */
386#ifdef OPENSSL_FIPS
387 /* NB: in FIPS mode we are already under a lock */
388 if (!FIPS_mode())
389#endif
390 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
391
392 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
393 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
394 CRYPTO_THREADID_current(&locking_threadid);
395 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
396 crypto_lock_rand = 1;
397
398 if (!initialized)
399 {
400 RAND_poll();
401 initialized = 1;
402 }
403
404 if (!stirred_pool)
405 do_stir_pool = 1;
406
407 ok = (entropy >= ENTROPY_NEEDED);
408 if (!ok)
409 {
410 /* If the PRNG state is not yet unpredictable, then seeing
411 * the PRNG output may help attackers to determine the new
412 * state; thus we have to decrease the entropy estimate.
413 * Once we've had enough initial seeding we don't bother to
414 * adjust the entropy count, though, because we're not ambitious
415 * to provide *information-theoretic* randomness.
416 *
417 * NOTE: This approach fails if the program forks before
418 * we have enough entropy. Entropy should be collected
419 * in a separate input pool and be transferred to the
420 * output pool only when the entropy limit has been reached.
421 */
422 entropy -= num;
423 if (entropy < 0)
424 entropy = 0;
425 }
426
427 if (do_stir_pool)
428 {
429 /* In the output function only half of 'md' remains secret,
430 * so we better make sure that the required entropy gets
431 * 'evenly distributed' through 'state', our randomness pool.
432 * The input function (ssleay_rand_add) chains all of 'md',
433 * which makes it more suitable for this purpose.
434 */
435
436 int n = STATE_SIZE; /* so that the complete pool gets accessed */
437 while (n > 0)
438 {
439#if MD_DIGEST_LENGTH > 20
440# error "Please adjust DUMMY_SEED."
441#endif
442#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
443 /* Note that the seed does not matter, it's just that
444 * ssleay_rand_add expects to have something to hash. */
445 ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
446 n -= MD_DIGEST_LENGTH;
447 }
448 if (ok)
449 stirred_pool = 1;
450 }
451
452 st_idx=state_index;
453 st_num=state_num;
454 md_c[0] = md_count[0];
455 md_c[1] = md_count[1];
456 memcpy(local_md, md, sizeof md);
457
458 state_index+=num_ceil;
459 if (state_index > state_num)
460 state_index %= state_num;
461
462 /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
463 * are now ours (but other threads may use them too) */
464
465 md_count[0] += 1;
466
467 /* before unlocking, we must clear 'crypto_lock_rand' */
468 crypto_lock_rand = 0;
469#ifdef OPENSSL_FIPS
470 if (!FIPS_mode())
471#endif
472 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
473
474 while (num > 0)
475 {
476 /* num_ceil -= MD_DIGEST_LENGTH/2 */
477 j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
478 num-=j;
479 MD_Init(&m);
480#ifndef GETPID_IS_MEANINGLESS
481 if (curr_pid) /* just in the first iteration to save time */
482 {
483 MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
484 curr_pid = 0;
485 }
486#endif
487 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
488 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
489
490#ifndef PURIFY /* purify complains */
491 /* The following line uses the supplied buffer as a small
492 * source of entropy: since this buffer is often uninitialised
493 * it may cause programs such as purify or valgrind to
494 * complain. So for those builds it is not used: the removal
495 * of such a small source of entropy has negligible impact on
496 * security.
497 */
498 MD_Update(&m,buf,j);
499#endif
500
501 k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
502 if (k > 0)
503 {
504 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
505 MD_Update(&m,&(state[0]),k);
506 }
507 else
508 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
509 MD_Final(&m,local_md);
510
511 for (i=0; i<MD_DIGEST_LENGTH/2; i++)
512 {
513 state[st_idx++]^=local_md[i]; /* may compete with other threads */
514 if (st_idx >= st_num)
515 st_idx=0;
516 if (i < j)
517 *(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
518 }
519 }
520
521 MD_Init(&m);
522 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
523 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
524#ifdef OPENSSL_FIPS
525 if (!FIPS_mode())
526#endif
527 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
528 MD_Update(&m,md,MD_DIGEST_LENGTH);
529 MD_Final(&m,md);
530#ifdef OPENSSL_FIPS
531 if (!FIPS_mode())
532#endif
533 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
534
535 EVP_MD_CTX_cleanup(&m);
536 if (ok)
537 return(1);
538 else if (pseudo)
539 return 0;
540 else
541 {
542 RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
543 ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
544 "http://www.openssl.org/support/faq.html");
545 return(0);
546 }
547 }
548
549static int ssleay_rand_nopseudo_bytes(unsigned char *buf, int num)
550 {
551 return ssleay_rand_bytes(buf, num, 0);
552 }
553
554/* pseudo-random bytes that are guaranteed to be unique but not
555 unpredictable */
556static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
557 {
558 return ssleay_rand_bytes(buf, num, 1);
559 }
560
561static int ssleay_rand_status(void)
562 {
563 CRYPTO_THREADID cur;
564 int ret;
565 int do_not_lock;
566
567 CRYPTO_THREADID_current(&cur);
568 /* check if we already have the lock
569 * (could happen if a RAND_poll() implementation calls RAND_status()) */
570 if (crypto_lock_rand)
571 {
572 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
573 do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
574 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
575 }
576 else
577 do_not_lock = 0;
578
579 if (!do_not_lock)
580 {
581 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
582
583 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
584 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
585 CRYPTO_THREADID_cpy(&locking_threadid, &cur);
586 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
587 crypto_lock_rand = 1;
588 }
589
590 if (!initialized)
591 {
592 RAND_poll();
593 initialized = 1;
594 }
595
596 ret = entropy >= ENTROPY_NEEDED;
597
598 if (!do_not_lock)
599 {
600 /* before unlocking, we must clear 'crypto_lock_rand' */
601 crypto_lock_rand = 0;
602
603 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
604 }
605
606 return ret;
607 }
diff --git a/src/lib/libssl/src/crypto/rand/rand.h b/src/lib/libssl/src/crypto/rand/rand.h
index bb5520e80a..e65b4b2e35 100644
--- a/src/lib/libssl/src/crypto/rand/rand.h
+++ b/src/lib/libssl/src/crypto/rand/rand.h
@@ -63,18 +63,10 @@
63#include <openssl/ossl_typ.h> 63#include <openssl/ossl_typ.h>
64#include <openssl/e_os2.h> 64#include <openssl/e_os2.h>
65 65
66#if defined(OPENSSL_SYS_WINDOWS)
67#include <windows.h>
68#endif
69
70#ifdef __cplusplus 66#ifdef __cplusplus
71extern "C" { 67extern "C" {
72#endif 68#endif
73 69
74#if defined(OPENSSL_FIPS)
75#define FIPS_RAND_SIZE_T size_t
76#endif
77
78/* Already defined in ossl_typ.h */ 70/* Already defined in ossl_typ.h */
79/* typedef struct rand_meth_st RAND_METHOD; */ 71/* typedef struct rand_meth_st RAND_METHOD; */
80 72
@@ -88,10 +80,6 @@ struct rand_meth_st
88 int (*status)(void); 80 int (*status)(void);
89 }; 81 };
90 82
91#ifdef BN_DEBUG
92extern int rand_predictable;
93#endif
94
95int RAND_set_rand_method(const RAND_METHOD *meth); 83int RAND_set_rand_method(const RAND_METHOD *meth);
96const RAND_METHOD *RAND_get_rand_method(void); 84const RAND_METHOD *RAND_get_rand_method(void);
97#ifndef OPENSSL_NO_ENGINE 85#ifndef OPENSSL_NO_ENGINE
@@ -112,25 +100,13 @@ int RAND_egd(const char *path);
112int RAND_egd_bytes(const char *path,int bytes); 100int RAND_egd_bytes(const char *path,int bytes);
113int RAND_poll(void); 101int RAND_poll(void);
114 102
115#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
116
117void RAND_screen(void);
118int RAND_event(UINT, WPARAM, LPARAM);
119
120#endif
121
122#ifdef OPENSSL_FIPS
123void RAND_set_fips_drbg_type(int type, int flags);
124int RAND_init_fips(void);
125#endif
126
127/* BEGIN ERROR CODES */ 103/* BEGIN ERROR CODES */
128/* The following lines are auto generated by the script mkerr.pl. Any changes 104/* The following lines are auto generated by the script mkerr.pl. Any changes
129 * made after this point may be overwritten when the script is next run. 105 * made after this point may be overwritten when the script is next run.
130 */ 106 */
131void ERR_load_RAND_strings(void); 107void ERR_load_RAND_strings(void);
132 108
133/* Error codes for the RAND functions. */ 109/* Error codes for the RAND functions. (no longer used) */
134 110
135/* Function codes. */ 111/* Function codes. */
136#define RAND_F_RAND_GET_RAND_METHOD 101 112#define RAND_F_RAND_GET_RAND_METHOD 101
diff --git a/src/lib/libssl/src/crypto/rand/rand_egd.c b/src/lib/libssl/src/crypto/rand/rand_egd.c
index d53b916ebe..a78aa90c46 100644
--- a/src/lib/libssl/src/crypto/rand/rand_egd.c
+++ b/src/lib/libssl/src/crypto/rand/rand_egd.c
@@ -95,7 +95,6 @@
95 * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255. 95 * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
96 */ 96 */
97 97
98#if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE) || defined(OPENSSL_SYS_VOS) || defined(OPENSSL_SYS_BEOS)
99int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes) 98int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
100 { 99 {
101 return(-1); 100 return(-1);
@@ -109,195 +108,3 @@ int RAND_egd_bytes(const char *path,int bytes)
109 { 108 {
110 return(-1); 109 return(-1);
111 } 110 }
112#else
113#include <openssl/opensslconf.h>
114#include OPENSSL_UNISTD
115#include <sys/types.h>
116#include <sys/socket.h>
117#ifndef NO_SYS_UN_H
118# ifdef OPENSSL_SYS_VXWORKS
119# include <streams/un.h>
120# else
121# include <sys/un.h>
122# endif
123#else
124struct sockaddr_un {
125 short sun_family; /* AF_UNIX */
126 char sun_path[108]; /* path name (gag) */
127};
128#endif /* NO_SYS_UN_H */
129#include <string.h>
130#include <errno.h>
131
132#ifndef offsetof
133# define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
134#endif
135
136int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
137 {
138 int ret = 0;
139 struct sockaddr_un addr;
140 int len, num, numbytes;
141 int fd = -1;
142 int success;
143 unsigned char egdbuf[2], tempbuf[255], *retrievebuf;
144
145 memset(&addr, 0, sizeof(addr));
146 addr.sun_family = AF_UNIX;
147 if (strlen(path) >= sizeof(addr.sun_path))
148 return (-1);
149 BUF_strlcpy(addr.sun_path,path,sizeof addr.sun_path);
150 len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
151 fd = socket(AF_UNIX, SOCK_STREAM, 0);
152 if (fd == -1) return (-1);
153 success = 0;
154 while (!success)
155 {
156 if (connect(fd, (struct sockaddr *)&addr, len) == 0)
157 success = 1;
158 else
159 {
160 switch (errno)
161 {
162#ifdef EINTR
163 case EINTR:
164#endif
165#ifdef EAGAIN
166 case EAGAIN:
167#endif
168#ifdef EINPROGRESS
169 case EINPROGRESS:
170#endif
171#ifdef EALREADY
172 case EALREADY:
173#endif
174 /* No error, try again */
175 break;
176#ifdef EISCONN
177 case EISCONN:
178 success = 1;
179 break;
180#endif
181 default:
182 goto err; /* failure */
183 }
184 }
185 }
186
187 while(bytes > 0)
188 {
189 egdbuf[0] = 1;
190 egdbuf[1] = bytes < 255 ? bytes : 255;
191 numbytes = 0;
192 while (numbytes != 2)
193 {
194 num = write(fd, egdbuf + numbytes, 2 - numbytes);
195 if (num >= 0)
196 numbytes += num;
197 else
198 {
199 switch (errno)
200 {
201#ifdef EINTR
202 case EINTR:
203#endif
204#ifdef EAGAIN
205 case EAGAIN:
206#endif
207 /* No error, try again */
208 break;
209 default:
210 ret = -1;
211 goto err; /* failure */
212 }
213 }
214 }
215 numbytes = 0;
216 while (numbytes != 1)
217 {
218 num = read(fd, egdbuf, 1);
219 if (num == 0)
220 goto err; /* descriptor closed */
221 else if (num > 0)
222 numbytes += num;
223 else
224 {
225 switch (errno)
226 {
227#ifdef EINTR
228 case EINTR:
229#endif
230#ifdef EAGAIN
231 case EAGAIN:
232#endif
233 /* No error, try again */
234 break;
235 default:
236 ret = -1;
237 goto err; /* failure */
238 }
239 }
240 }
241 if(egdbuf[0] == 0)
242 goto err;
243 if (buf)
244 retrievebuf = buf + ret;
245 else
246 retrievebuf = tempbuf;
247 numbytes = 0;
248 while (numbytes != egdbuf[0])
249 {
250 num = read(fd, retrievebuf + numbytes, egdbuf[0] - numbytes);
251 if (num == 0)
252 goto err; /* descriptor closed */
253 else if (num > 0)
254 numbytes += num;
255 else
256 {
257 switch (errno)
258 {
259#ifdef EINTR
260 case EINTR:
261#endif
262#ifdef EAGAIN
263 case EAGAIN:
264#endif
265 /* No error, try again */
266 break;
267 default:
268 ret = -1;
269 goto err; /* failure */
270 }
271 }
272 }
273 ret += egdbuf[0];
274 bytes -= egdbuf[0];
275 if (!buf)
276 RAND_seed(tempbuf, egdbuf[0]);
277 }
278 err:
279 if (fd != -1) close(fd);
280 return(ret);
281 }
282
283
284int RAND_egd_bytes(const char *path, int bytes)
285 {
286 int num, ret = 0;
287
288 num = RAND_query_egd_bytes(path, NULL, bytes);
289 if (num < 1) goto err;
290 if (RAND_status() == 1)
291 ret = num;
292 err:
293 return(ret);
294 }
295
296
297int RAND_egd(const char *path)
298 {
299 return (RAND_egd_bytes(path, 255));
300 }
301
302
303#endif
diff --git a/src/lib/libssl/src/crypto/rand/rand_lcl.h b/src/lib/libssl/src/crypto/rand/rand_lcl.h
deleted file mode 100644
index 618a8ec899..0000000000
--- a/src/lib/libssl/src/crypto/rand/rand_lcl.h
+++ /dev/null
@@ -1,158 +0,0 @@
1/* crypto/rand/rand_lcl.h */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
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 */
58/* ====================================================================
59 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
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 */
111
112#ifndef HEADER_RAND_LCL_H
113#define HEADER_RAND_LCL_H
114
115#define ENTROPY_NEEDED 32 /* require 256 bits = 32 bytes of randomness */
116
117
118#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
119#if !defined(OPENSSL_NO_SHA) && !defined(OPENSSL_NO_SHA1)
120#define USE_SHA1_RAND
121#elif !defined(OPENSSL_NO_MD5)
122#define USE_MD5_RAND
123#elif !defined(OPENSSL_NO_MDC2) && !defined(OPENSSL_NO_DES)
124#define USE_MDC2_RAND
125#elif !defined(OPENSSL_NO_MD2)
126#define USE_MD2_RAND
127#else
128#error No message digest algorithm available
129#endif
130#endif
131
132#include <openssl/evp.h>
133#define MD_Update(a,b,c) EVP_DigestUpdate(a,b,c)
134#define MD_Final(a,b) EVP_DigestFinal_ex(a,b,NULL)
135#if defined(USE_MD5_RAND)
136#include <openssl/md5.h>
137#define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH
138#define MD_Init(a) EVP_DigestInit_ex(a,EVP_md5(), NULL)
139#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md5(), NULL)
140#elif defined(USE_SHA1_RAND)
141#include <openssl/sha.h>
142#define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH
143#define MD_Init(a) EVP_DigestInit_ex(a,EVP_sha1(), NULL)
144#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_sha1(), NULL)
145#elif defined(USE_MDC2_RAND)
146#include <openssl/mdc2.h>
147#define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH
148#define MD_Init(a) EVP_DigestInit_ex(a,EVP_mdc2(), NULL)
149#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_mdc2(), NULL)
150#elif defined(USE_MD2_RAND)
151#include <openssl/md2.h>
152#define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH
153#define MD_Init(a) EVP_DigestInit_ex(a,EVP_md2(), NULL)
154#define MD(a,b,c) EVP_Digest(a,b,c,NULL,EVP_md2(), NULL)
155#endif
156
157
158#endif
diff --git a/src/lib/libssl/src/crypto/rand/rand_lib.c b/src/lib/libssl/src/crypto/rand/rand_lib.c
index 5ac0e14caf..243a87ddfb 100644
--- a/src/lib/libssl/src/crypto/rand/rand_lib.c
+++ b/src/lib/libssl/src/crypto/rand/rand_lib.c
@@ -65,11 +65,6 @@
65#include <openssl/engine.h> 65#include <openssl/engine.h>
66#endif 66#endif
67 67
68#ifdef OPENSSL_FIPS
69#include <openssl/fips.h>
70#include <openssl/fips_rand.h>
71#endif
72
73#ifndef OPENSSL_NO_ENGINE 68#ifndef OPENSSL_NO_ENGINE
74/* non-NULL if default_RAND_meth is ENGINE-provided */ 69/* non-NULL if default_RAND_meth is ENGINE-provided */
75static ENGINE *funct_ref =NULL; 70static ENGINE *funct_ref =NULL;
@@ -180,127 +175,3 @@ int RAND_status(void)
180 return meth->status(); 175 return meth->status();
181 return 0; 176 return 0;
182 } 177 }
183
184#ifdef OPENSSL_FIPS
185
186/* FIPS DRBG initialisation code. This sets up the DRBG for use by the
187 * rest of OpenSSL.
188 */
189
190/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
191 * entropy internally through RAND_poll().
192 */
193
194static size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
195 int entropy, size_t min_len, size_t max_len)
196 {
197 /* Round up request to multiple of block size */
198 min_len = ((min_len + 19) / 20) * 20;
199 *pout = OPENSSL_malloc(min_len);
200 if (!*pout)
201 return 0;
202 if (RAND_SSLeay()->bytes(*pout, min_len) <= 0)
203 {
204 OPENSSL_free(*pout);
205 *pout = NULL;
206 return 0;
207 }
208 return min_len;
209 }
210
211static void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
212 {
213 if (out)
214 {
215 OPENSSL_cleanse(out, olen);
216 OPENSSL_free(out);
217 }
218 }
219
220/* Set "additional input" when generating random data. This uses the
221 * current PID, a time value and a counter.
222 */
223
224static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
225 {
226 /* Use of static variables is OK as this happens under a lock */
227 static unsigned char buf[16];
228 static unsigned long counter;
229 FIPS_get_timevec(buf, &counter);
230 *pout = buf;
231 return sizeof(buf);
232 }
233
234/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
235 * correctly seeded by RAND_poll().
236 */
237
238static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
239 double entropy)
240 {
241 RAND_SSLeay()->add(in, inlen, entropy);
242 return 1;
243 }
244
245static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
246 {
247 RAND_SSLeay()->seed(in, inlen);
248 return 1;
249 }
250
251#ifndef OPENSSL_DRBG_DEFAULT_TYPE
252#define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr
253#endif
254#ifndef OPENSSL_DRBG_DEFAULT_FLAGS
255#define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF
256#endif
257
258static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
259static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
260
261void RAND_set_fips_drbg_type(int type, int flags)
262 {
263 fips_drbg_type = type;
264 fips_drbg_flags = flags;
265 }
266
267int RAND_init_fips(void)
268 {
269 DRBG_CTX *dctx;
270 size_t plen;
271 unsigned char pers[32], *p;
272#ifndef OPENSSL_ALLOW_DUAL_EC_DRBG
273 if (fips_drbg_type >> 16)
274 {
275 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED);
276 return 0;
277 }
278#endif
279
280 dctx = FIPS_get_default_drbg();
281 if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
282 {
283 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
284 return 0;
285 }
286
287 FIPS_drbg_set_callbacks(dctx,
288 drbg_get_entropy, drbg_free_entropy, 20,
289 drbg_get_entropy, drbg_free_entropy);
290 FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
291 drbg_rand_seed, drbg_rand_add);
292 /* Personalisation string: a string followed by date time vector */
293 strcpy((char *)pers, "OpenSSL DRBG2.0");
294 plen = drbg_get_adin(dctx, &p);
295 memcpy(pers + 16, p, plen);
296
297 if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0)
298 {
299 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
300 return 0;
301 }
302 FIPS_rand_set_method(FIPS_drbg_method());
303 return 1;
304 }
305
306#endif
diff --git a/src/lib/libssl/src/crypto/rand/rand_unix.c b/src/lib/libssl/src/crypto/rand/rand_unix.c
index 3316388443..a5b9b2a529 100644
--- a/src/lib/libssl/src/crypto/rand/rand_unix.c
+++ b/src/lib/libssl/src/crypto/rand/rand_unix.c
@@ -108,318 +108,14 @@
108 * Hudson (tjh@cryptsoft.com). 108 * Hudson (tjh@cryptsoft.com).
109 * 109 *
110 */ 110 */
111#include <stdio.h>
112
113#define USE_SOCKETS
114#include "e_os.h" 111#include "e_os.h"
115#include "cryptlib.h" 112#include "cryptlib.h"
116#include <openssl/rand.h> 113#include <openssl/rand.h>
117#include "rand_lcl.h"
118
119#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE))
120
121#include <sys/types.h>
122#include <sys/time.h>
123#include <sys/times.h>
124#include <sys/stat.h>
125#include <fcntl.h>
126#include <unistd.h>
127#include <time.h>
128#if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywhere */
129# include <poll.h>
130#endif
131#include <limits.h>
132#ifndef FD_SETSIZE
133# define FD_SETSIZE (8*sizeof(fd_set))
134#endif
135
136#if defined(OPENSSL_SYS_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)
154{
155 short int code;
156 gid_t curr_gid;
157 pid_t curr_pid;
158 uid_t curr_uid;
159 int i, k;
160 struct timespec ts;
161 unsigned char v;
162
163#ifdef OPENSSL_SYS_VOS_HPPA
164 long duration;
165 extern void s$sleep (long *_duration, short int *_code);
166#else
167#ifdef OPENSSL_SYS_VOS_IA32
168 long long duration;
169 extern void s$sleep2 (long long *_duration, short int *_code);
170#else
171#error "Unsupported Platform."
172#endif /* OPENSSL_SYS_VOS_IA32 */
173#endif /* OPENSSL_SYS_VOS_HPPA */
174
175 /* Seed with the gid, pid, and uid, to ensure *some*
176 variation between different processes. */
177 114
178 curr_gid = getgid(); 115#include <stdlib.h>
179 RAND_add (&curr_gid, sizeof curr_gid, 1); 116#include <string.h>
180 curr_gid = 0;
181 117
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
212 /* take 8 bits */
213 v = (unsigned char) (ts.tv_nsec % 256);
214 RAND_add (&v, sizeof v, 1);
215 v = 0;
216 }
217 return 1;
218}
219#elif defined __OpenBSD__
220int RAND_poll(void) 118int RAND_poll(void)
221{ 119{
222 unsigned char buf[ENTROPY_NEEDED];
223
224 arc4random_buf(buf, sizeof(buf));
225 RAND_add(buf, sizeof(buf), sizeof(buf));
226 memset(buf, 0, sizeof(buf));
227
228 return 1; 120 return 1;
229} 121}
230#else /* !defined(__OpenBSD__) */
231int RAND_poll(void)
232{
233 unsigned long l;
234 pid_t curr_pid = getpid();
235#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
236 unsigned char tmpbuf[ENTROPY_NEEDED];
237 int n = 0;
238#endif
239#ifdef DEVRANDOM
240 static const char *randomfiles[] = { DEVRANDOM };
241 struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
242 int fd;
243 unsigned int i;
244#endif
245#ifdef DEVRANDOM_EGD
246 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
247 const char **egdsocket = NULL;
248#endif
249
250#ifdef DEVRANDOM
251 memset(randomstats,0,sizeof(randomstats));
252 /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
253 * have this. Use /dev/urandom if you can as /dev/random may block
254 * if it runs out of random entries. */
255
256 for (i = 0; (i < sizeof(randomfiles)/sizeof(randomfiles[0])) &&
257 (n < ENTROPY_NEEDED); i++)
258 {
259 if ((fd = open(randomfiles[i], O_RDONLY
260#ifdef O_NONBLOCK
261 |O_NONBLOCK
262#endif
263#ifdef O_BINARY
264 |O_BINARY
265#endif
266#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
267 our controlling tty */
268 |O_NOCTTY
269#endif
270 )) >= 0)
271 {
272 int usec = 10*1000; /* spend 10ms on each file */
273 int r;
274 unsigned int j;
275 struct stat *st=&randomstats[i];
276
277 /* Avoid using same input... Used to be O_NOFOLLOW
278 * above, but it's not universally appropriate... */
279 if (fstat(fd,st) != 0) { close(fd); continue; }
280 for (j=0;j<i;j++)
281 {
282 if (randomstats[j].st_ino==st->st_ino &&
283 randomstats[j].st_dev==st->st_dev)
284 break;
285 }
286 if (j<i) { close(fd); continue; }
287
288 do
289 {
290 int try_read = 0;
291
292#if defined(OPENSSL_SYS_BEOS_R5)
293 /* select() is broken in BeOS R5, so we simply
294 * try to read something and snooze if we couldn't */
295 try_read = 1;
296
297#elif defined(OPENSSL_SYS_LINUX)
298 /* use poll() */
299 struct pollfd pset;
300
301 pset.fd = fd;
302 pset.events = POLLIN;
303 pset.revents = 0;
304
305 if (poll(&pset, 1, usec / 1000) < 0)
306 usec = 0;
307 else
308 try_read = (pset.revents & POLLIN) != 0;
309
310#else
311 /* use select() */
312 fd_set fset;
313 struct timeval t;
314
315 t.tv_sec = 0;
316 t.tv_usec = usec;
317
318 if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE)
319 {
320 /* can't use select, so just try to read once anyway */
321 try_read = 1;
322 }
323 else
324 {
325 FD_ZERO(&fset);
326 FD_SET(fd, &fset);
327
328 if (select(fd+1,&fset,NULL,NULL,&t) >= 0)
329 {
330 usec = t.tv_usec;
331 if (FD_ISSET(fd, &fset))
332 try_read = 1;
333 }
334 else
335 usec = 0;
336 }
337#endif
338
339 if (try_read)
340 {
341 r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
342 if (r > 0)
343 n += r;
344#if defined(OPENSSL_SYS_BEOS_R5)
345 if (r == 0)
346 snooze(t.tv_usec);
347#endif
348 }
349 else
350 r = -1;
351
352 /* Some Unixen will update t in select(), some
353 won't. For those who won't, or if we
354 didn't use select() in the first place,
355 give up here, otherwise, we will do
356 this once again for the remaining
357 time. */
358 if (usec == 10*1000)
359 usec = 0;
360 }
361 while ((r > 0 ||
362 (errno == EINTR || errno == EAGAIN)) && usec != 0 && n < ENTROPY_NEEDED);
363
364 close(fd);
365 }
366 }
367#endif /* defined(DEVRANDOM) */
368
369#ifdef DEVRANDOM_EGD
370 /* Use an EGD socket to read entropy from an EGD or PRNGD entropy
371 * collecting daemon. */
372
373 for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++)
374 {
375 int r;
376
377 r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n,
378 ENTROPY_NEEDED-n);
379 if (r > 0)
380 n += r;
381 }
382#endif /* defined(DEVRANDOM_EGD) */
383
384#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
385 if (n > 0)
386 {
387 RAND_add(tmpbuf,sizeof tmpbuf,(double)n);
388 OPENSSL_cleanse(tmpbuf,n);
389 }
390#endif
391
392 /* put in some default random data, we need more than just this */
393 l=curr_pid;
394 RAND_add(&l,sizeof(l),0.0);
395 l=getuid();
396 RAND_add(&l,sizeof(l),0.0);
397
398 l=time(NULL);
399 RAND_add(&l,sizeof(l),0.0);
400
401#if defined(OPENSSL_SYS_BEOS)
402 {
403 system_info sysInfo;
404 get_system_info(&sysInfo);
405 RAND_add(&sysInfo,sizeof(sysInfo),0);
406 }
407#endif
408
409#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
410 return 1;
411#else
412 return 0;
413#endif
414}
415
416#endif /* defined(__OpenBSD__) */
417#endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) */
418
419
420#if defined(OPENSSL_SYS_VXWORKS)
421int RAND_poll(void)
422 {
423 return 0;
424 }
425#endif
diff --git a/src/lib/libssl/src/crypto/rand/randfile.c b/src/lib/libssl/src/crypto/rand/randfile.c
index 10d511b8e8..2cacebcf07 100644
--- a/src/lib/libssl/src/crypto/rand/randfile.c
+++ b/src/lib/libssl/src/crypto/rand/randfile.c
@@ -56,11 +56,6 @@
56 * [including the GNU Public Licence.] 56 * [including the GNU Public Licence.]
57 */ 57 */
58 58
59/* We need to define this to get macros like S_IFBLK and S_IFCHR */
60#if !defined(OPENSSL_SYS_VXWORKS)
61#define _XOPEN_SOURCE 500
62#endif
63
64#include <errno.h> 59#include <errno.h>
65#include <stdio.h> 60#include <stdio.h>
66#include <stdlib.h> 61#include <stdlib.h>
@@ -71,35 +66,14 @@
71#include <openssl/rand.h> 66#include <openssl/rand.h>
72#include <openssl/buffer.h> 67#include <openssl/buffer.h>
73 68
74#ifdef OPENSSL_SYS_VMS 69#include <sys/types.h>
75#include <unixio.h> 70#include <sys/stat.h>
76#endif 71#include <fcntl.h>
77#ifndef NO_SYS_TYPES_H
78# include <sys/types.h>
79#endif
80#ifndef OPENSSL_NO_POSIX_IO
81# include <sys/stat.h>
82#endif
83
84#ifdef _WIN32
85#define stat _stat
86#define chmod _chmod
87#define open _open
88#define fdopen _fdopen
89#endif
90 72
91#undef BUFSIZE 73#undef BUFSIZE
92#define BUFSIZE 1024 74#define BUFSIZE 1024
93#define RAND_DATA 1024 75#define RAND_DATA 1024
94 76
95#ifdef OPENSSL_SYS_VMS
96/* This declaration is a nasty hack to get around vms' extension to fopen
97 * for passing in sharing options being disabled by our /STANDARD=ANSI89 */
98static FILE *(*const vms_fopen)(const char *, const char *, ...) =
99 (FILE *(*)(const char *, const char *, ...))fopen;
100#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
101#endif
102
103/* #define RFILE ".rnd" - defined in ../../e_os.h */ 77/* #define RFILE ".rnd" - defined in ../../e_os.h */
104 78
105/* Note that these functions are intended for seed files only. 79/* Note that these functions are intended for seed files only.
@@ -107,75 +81,7 @@ static FILE *(*const vms_fopen)(const char *, const char *, ...) =
107 81
108int RAND_load_file(const char *file, long bytes) 82int RAND_load_file(const char *file, long bytes)
109 { 83 {
110 /* If bytes >= 0, read up to 'bytes' bytes. 84 return(0);
111 * if bytes == -1, read complete file. */
112
113 unsigned char buf[BUFSIZE];
114#ifndef OPENSSL_NO_POSIX_IO
115 struct stat sb;
116#endif
117 int i,ret=0,n;
118 FILE *in;
119
120 if (file == NULL) return(0);
121
122#ifndef OPENSSL_NO_POSIX_IO
123#ifdef PURIFY
124 /* struct stat can have padding and unused fields that may not be
125 * initialized in the call to stat(). We need to clear the entire
126 * structure before calling RAND_add() to avoid complaints from
127 * applications such as Valgrind.
128 */
129 memset(&sb, 0, sizeof(sb));
130#endif
131 if (stat(file,&sb) < 0) return(0);
132 RAND_add(&sb,sizeof(sb),0.0);
133#endif
134 if (bytes == 0) return(ret);
135
136#ifdef OPENSSL_SYS_VMS
137 in=vms_fopen(file,"rb",VMS_OPEN_ATTRS);
138#else
139 in=fopen(file,"rb");
140#endif
141 if (in == NULL) goto err;
142#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
143 if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
144 /* this file is a device. we don't want read an infinite number
145 * of bytes from a random device, nor do we want to use buffered
146 * I/O because we will waste system entropy.
147 */
148 bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
149#ifndef OPENSSL_NO_SETVBUF_IONBF
150 setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
151#endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
152 }
153#endif
154 for (;;)
155 {
156 if (bytes > 0)
157 n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
158 else
159 n = BUFSIZE;
160 i=fread(buf,1,n,in);
161 if (i <= 0) break;
162#ifdef PURIFY
163 RAND_add(buf,i,(double)i);
164#else
165 /* even if n != i, use the full array */
166 RAND_add(buf,n,(double)i);
167#endif
168 ret+=i;
169 if (bytes > 0)
170 {
171 bytes-=n;
172 if (bytes <= 0) break;
173 }
174 }
175 fclose(in);
176 OPENSSL_cleanse(buf,BUFSIZE);
177err:
178 return(ret);
179 } 85 }
180 86
181int RAND_write_file(const char *file) 87int RAND_write_file(const char *file)
@@ -184,12 +90,10 @@ int RAND_write_file(const char *file)
184 int i,ret=0,rand_err=0; 90 int i,ret=0,rand_err=0;
185 FILE *out = NULL; 91 FILE *out = NULL;
186 int n; 92 int n;
187#ifndef OPENSSL_NO_POSIX_IO
188 struct stat sb; 93 struct stat sb;
189 94
190 i=stat(file,&sb); 95 i=stat(file,&sb);
191 if (i != -1) { 96 if (i != -1) {
192#if defined(S_ISBLK) && defined(S_ISCHR)
193 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) { 97 if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
194 /* this file is a device. we don't write back to it. 98 /* this file is a device. we don't write back to it.
195 * we "succeed" on the assumption this is some sort 99 * we "succeed" on the assumption this is some sort
@@ -198,55 +102,21 @@ int RAND_write_file(const char *file)
198 */ 102 */
199 return(1); 103 return(1);
200 } 104 }
201#endif
202 } 105 }
203#endif
204 106
205#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
206 { 107 {
207#ifndef O_BINARY
208#define O_BINARY 0
209#endif
210 /* chmod(..., 0600) is too late to protect the file, 108 /* chmod(..., 0600) is too late to protect the file,
211 * permissions should be restrictive from the start */ 109 * permissions should be restrictive from the start */
212 int fd = open(file, O_WRONLY|O_CREAT|O_BINARY, 0600); 110 int fd = open(file, O_WRONLY|O_CREAT, 0600);
213 if (fd != -1) 111 if (fd != -1)
214 out = fdopen(fd, "wb"); 112 out = fdopen(fd, "wb");
215 } 113 }
216#endif
217
218#ifdef OPENSSL_SYS_VMS
219 /* VMS NOTE: Prior versions of this routine created a _new_
220 * version of the rand file for each call into this routine, then
221 * deleted all existing versions named ;-1, and finally renamed
222 * the current version as ';1'. Under concurrent usage, this
223 * resulted in an RMS race condition in rename() which could
224 * orphan files (see vms message help for RMS$_REENT). With the
225 * fopen() calls below, openssl/VMS now shares the top-level
226 * version of the rand file. Note that there may still be
227 * conditions where the top-level rand file is locked. If so, this
228 * code will then create a new version of the rand file. Without
229 * the delete and rename code, this can result in ascending file
230 * versions that stop at version 32767, and this routine will then
231 * return an error. The remedy for this is to recode the calling
232 * application to avoid concurrent use of the rand file, or
233 * synchronize usage at the application level. Also consider
234 * whether or not you NEED a persistent rand file in a concurrent
235 * use situation.
236 */
237 114
238 out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS);
239 if (out == NULL)
240 out = vms_fopen(file,"wb",VMS_OPEN_ATTRS);
241#else
242 if (out == NULL) 115 if (out == NULL)
243 out = fopen(file,"wb"); 116 out = fopen(file,"wb");
244#endif
245 if (out == NULL) goto err; 117 if (out == NULL) goto err;
246 118
247#ifndef NO_CHMOD
248 chmod(file,0600); 119 chmod(file,0600);
249#endif
250 n=RAND_DATA; 120 n=RAND_DATA;
251 for (;;) 121 for (;;)
252 { 122 {
@@ -273,9 +143,7 @@ err:
273const char *RAND_file_name(char *buf, size_t size) 143const char *RAND_file_name(char *buf, size_t size)
274 { 144 {
275 char *s=NULL; 145 char *s=NULL;
276#ifdef __OpenBSD__
277 struct stat sb; 146 struct stat sb;
278#endif
279 147
280 if (OPENSSL_issetugid() == 0) 148 if (OPENSSL_issetugid() == 0)
281 s=getenv("RANDFILE"); 149 s=getenv("RANDFILE");
@@ -288,25 +156,16 @@ const char *RAND_file_name(char *buf, size_t size)
288 { 156 {
289 if (OPENSSL_issetugid() == 0) 157 if (OPENSSL_issetugid() == 0)
290 s=getenv("HOME"); 158 s=getenv("HOME");
291#ifdef DEFAULT_HOME
292 if (s == NULL)
293 {
294 s = DEFAULT_HOME;
295 }
296#endif
297 if (s && *s && strlen(s)+strlen(RFILE)+2 < size) 159 if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
298 { 160 {
299 BUF_strlcpy(buf,s,size); 161 BUF_strlcpy(buf,s,size);
300#ifndef OPENSSL_SYS_VMS
301 BUF_strlcat(buf,"/",size); 162 BUF_strlcat(buf,"/",size);
302#endif
303 BUF_strlcat(buf,RFILE,size); 163 BUF_strlcat(buf,RFILE,size);
304 } 164 }
305 else 165 else
306 buf[0] = '\0'; /* no file name */ 166 buf[0] = '\0'; /* no file name */
307 } 167 }
308 168
309#ifdef __OpenBSD__
310 /* given that all random loads just fail if the file can't be 169 /* given that all random loads just fail if the file can't be
311 * seen on a stat, we stat the file we're returning, if it 170 * seen on a stat, we stat the file we're returning, if it
312 * fails, use /dev/arandom instead. this allows the user to 171 * fails, use /dev/arandom instead. this allows the user to
@@ -323,6 +182,5 @@ const char *RAND_file_name(char *buf, size_t size)
323 return(NULL); 182 return(NULL);
324 } 183 }
325 184
326#endif
327 return(buf); 185 return(buf);
328 } 186 }
diff --git a/src/lib/libssl/src/crypto/rand/rc4_rand.c b/src/lib/libssl/src/crypto/rand/rc4_rand.c
new file mode 100644
index 0000000000..ebfb241d53
--- /dev/null
+++ b/src/lib/libssl/src/crypto/rand/rc4_rand.c
@@ -0,0 +1,44 @@
1/* $OpenBSD: rc4_rand.c,v 1.1 2014/04/15 16:52:50 miod Exp $ */
2
3/*
4 * Copyright (c) 2014 Miodrag Vallat.
5 *
6 * Permission to use, copy, modify, and distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19#include <stdlib.h>
20
21#include <openssl/rand.h>
22
23static int
24arc4_rand_bytes(unsigned char *buf, int num)
25{
26 if (num > 0)
27 arc4random_buf(buf, (size_t)num);
28
29 return 1;
30}
31
32static RAND_METHOD rand_arc4_meth = {
33 .seed = NULL, /* no external seed allowed */
34 .bytes = arc4_rand_bytes,
35 .cleanup = NULL, /* no cleanup necessary */
36 .add = NULL, /* no external feed allowed */
37 .pseudorand = arc4_rand_bytes,
38 .status = NULL /* no possible error condition */
39};
40
41RAND_METHOD *RAND_SSLeay(void)
42{
43 return &rand_arc4_meth;
44}
diff --git a/src/lib/libssl/src/doc/crypto/RAND_add.pod b/src/lib/libssl/src/doc/crypto/RAND_add.pod
index 67c66f3e0c..d55dc125d3 100644
--- a/src/lib/libssl/src/doc/crypto/RAND_add.pod
+++ b/src/lib/libssl/src/doc/crypto/RAND_add.pod
@@ -2,8 +2,7 @@
2 2
3=head1 NAME 3=head1 NAME
4 4
5RAND_add, RAND_seed, RAND_status, RAND_event, RAND_screen - add 5RAND_add, RAND_seed, RAND_status - add entropy to the PRNG (DEPRECATED)
6entropy to the PRNG
7 6
8=head1 SYNOPSIS 7=head1 SYNOPSIS
9 8
@@ -15,63 +14,17 @@ entropy to the PRNG
15 14
16 int RAND_status(void); 15 int RAND_status(void);
17 16
18 int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam);
19 void RAND_screen(void);
20
21=head1 DESCRIPTION 17=head1 DESCRIPTION
22 18
23RAND_add() mixes the B<num> bytes at B<buf> into the PRNG state. Thus, 19These functions used to allow for the state of the random number generator
24if the data at B<buf> are unpredictable to an adversary, this 20to be controlled by external sources.
25increases the uncertainty about the state and makes the PRNG output
26less predictable. Suitable input comes from user interaction (random
27key presses, mouse movements) and certain hardware events. The
28B<entropy> argument is (the lower bound of) an estimate of how much
29randomness is contained in B<buf>, measured in bytes. Details about
30sources of randomness and how to estimate their entropy can be found
31in the literature, e.g. RFC 1750.
32
33RAND_add() may be called with sensitive data such as user entered
34passwords. The seed values cannot be recovered from the PRNG output.
35
36OpenSSL makes sure that the PRNG state is unique for each thread. On
37systems that provide C</dev/urandom>, the randomness device is used
38to seed the PRNG transparently. However, on all other systems, the
39application is responsible for seeding the PRNG by calling RAND_add(),
40L<RAND_egd(3)|RAND_egd(3)>
41or L<RAND_load_file(3)|RAND_load_file(3)>.
42
43RAND_seed() is equivalent to RAND_add() when B<num == entropy>.
44
45RAND_event() collects the entropy from Windows events such as mouse
46movements and other user interaction. It should be called with the
47B<iMsg>, B<wParam> and B<lParam> arguments of I<all> messages sent to
48the window procedure. It will estimate the entropy contained in the
49event message (if any), and add it to the PRNG. The program can then
50process the messages as usual.
51 21
52The RAND_screen() function is available for the convenience of Windows 22They are kept for ABI compatibility but are no longer functional, and
53programmers. It adds the current contents of the screen to the PRNG. 23should not used in new programs.
54For applications that can catch Windows events, seeding the PRNG by
55calling RAND_event() is a significantly better source of
56randomness. It should be noted that both methods cannot be used on
57servers that run without user interaction.
58
59=head1 RETURN VALUES
60
61RAND_status() and RAND_event() return 1 if the PRNG has been seeded
62with enough data, 0 otherwise.
63
64The other functions do not return values.
65 24
66=head1 SEE ALSO 25=head1 SEE ALSO
67 26
68L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>, 27L<rand(3)|rand(3)>, L<RAND_egd(3)|RAND_egd(3)>,
69L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)> 28L<RAND_load_file(3)|RAND_load_file(3)>, L<RAND_cleanup(3)|RAND_cleanup(3)>
70 29
71=head1 HISTORY
72
73RAND_seed() and RAND_screen() are available in all versions of SSLeay
74and OpenSSL. RAND_add() and RAND_status() have been added in OpenSSL
750.9.5, RAND_event() in OpenSSL 0.9.5a.
76
77=cut 30=cut
diff --git a/src/lib/libssl/src/doc/crypto/RAND_egd.pod b/src/lib/libssl/src/doc/crypto/RAND_egd.pod
index 8b8c61d161..771f525df8 100644
--- a/src/lib/libssl/src/doc/crypto/RAND_egd.pod
+++ b/src/lib/libssl/src/doc/crypto/RAND_egd.pod
@@ -2,7 +2,7 @@
2 2
3=head1 NAME 3=head1 NAME
4 4
5RAND_egd - query entropy gathering daemon 5RAND_egd - query entropy gathering daemon (DEPRECATED)
6 6
7=head1 SYNOPSIS 7=head1 SYNOPSIS
8 8
@@ -15,74 +15,15 @@ RAND_egd - query entropy gathering daemon
15 15
16=head1 DESCRIPTION 16=head1 DESCRIPTION
17 17
18RAND_egd() queries the entropy gathering daemon EGD on socket B<path>. 18These functions used to allow for the state of the random number generator
19It queries 255 bytes and uses L<RAND_add(3)|RAND_add(3)> to seed the 19to be controlled by external sources.
20OpenSSL built-in PRNG. RAND_egd(path) is a wrapper for
21RAND_egd_bytes(path, 255);
22 20
23RAND_egd_bytes() queries the entropy gathering daemon EGD on socket B<path>. 21They are kept for ABI compatibility but are no longer functional, and
24It queries B<bytes> bytes and uses L<RAND_add(3)|RAND_add(3)> to seed the 22should not used in new programs.
25OpenSSL built-in PRNG.
26This function is more flexible than RAND_egd().
27When only one secret key must
28be generated, it is not necessary to request the full amount 255 bytes from
29the EGD socket. This can be advantageous, since the amount of entropy
30that can be retrieved from EGD over time is limited.
31
32RAND_query_egd_bytes() performs the actual query of the EGD daemon on socket
33B<path>. If B<buf> is given, B<bytes> bytes are queried and written into
34B<buf>. If B<buf> is NULL, B<bytes> bytes are queried and used to seed the
35OpenSSL built-in PRNG using L<RAND_add(3)|RAND_add(3)>.
36
37=head1 NOTES
38
39On systems without /dev/*random devices providing entropy from the kernel,
40the EGD entropy gathering daemon can be used to collect entropy. It provides
41a socket interface through which entropy can be gathered in chunks up to
42255 bytes. Several chunks can be queried during one connection.
43
44EGD is available from http://www.lothar.com/tech/crypto/ (C<perl
45Makefile.PL; make; make install> to install). It is run as B<egd>
46I<path>, where I<path> is an absolute path designating a socket. When
47RAND_egd() is called with that path as an argument, it tries to read
48random bytes that EGD has collected. RAND_egd() retrieves entropy from the
49daemon using the daemon's "non-blocking read" command which shall
50be answered immediately by the daemon without waiting for additional
51entropy to be collected. The write and read socket operations in the
52communication are blocking.
53
54Alternatively, the EGD-interface compatible daemon PRNGD can be used. It is
55available from
56http://prngd.sourceforge.net/ .
57PRNGD does employ an internal PRNG itself and can therefore never run
58out of entropy.
59
60OpenSSL automatically queries EGD when entropy is requested via RAND_bytes()
61or the status is checked via RAND_status() for the first time, if the socket
62is located at /var/run/egd-pool, /dev/egd-pool or /etc/egd-pool.
63
64=head1 RETURN VALUE
65
66RAND_egd() and RAND_egd_bytes() return the number of bytes read from the
67daemon on success, and -1 if the connection failed or the daemon did not
68return enough data to fully seed the PRNG.
69
70RAND_query_egd_bytes() returns the number of bytes read from the daemon on
71success, and -1 if the connection failed. The PRNG state is not considered.
72 23
73=head1 SEE ALSO 24=head1 SEE ALSO
74 25
75L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>, 26L<rand(3)|rand(3)>, L<RAND_add(3)|RAND_add(3)>,
76L<RAND_cleanup(3)|RAND_cleanup(3)> 27L<RAND_cleanup(3)|RAND_cleanup(3)>
77 28
78=head1 HISTORY
79
80RAND_egd() is available since OpenSSL 0.9.5.
81
82RAND_egd_bytes() is available since OpenSSL 0.9.6.
83
84RAND_query_egd_bytes() is available since OpenSSL 0.9.7.
85
86The automatic query of /var/run/egd-pool et al was added in OpenSSL 0.9.7.
87
88=cut 29=cut
diff --git a/src/lib/libssl/src/doc/crypto/RAND_load_file.pod b/src/lib/libssl/src/doc/crypto/RAND_load_file.pod
index d8c134e621..3f7e944d86 100644
--- a/src/lib/libssl/src/doc/crypto/RAND_load_file.pod
+++ b/src/lib/libssl/src/doc/crypto/RAND_load_file.pod
@@ -22,18 +22,18 @@ filename. The seed file is $RANDFILE if that environment variable is
22set, $HOME/.rnd otherwise. If $HOME is not set either, or B<num> is 22set, $HOME/.rnd otherwise. If $HOME is not set either, or B<num> is
23too small for the path name, an error occurs. 23too small for the path name, an error occurs.
24 24
25RAND_load_file() reads a number of bytes from file B<filename> and 25RAND_load_file() used to allow for the state of the random number generator
26adds them to the PRNG. If B<max_bytes> is non-negative, 26to be controlled by external sources.
27up to to B<max_bytes> are read; starting with OpenSSL 0.9.5, 27
28if B<max_bytes> is -1, the complete file is read. 28It is kept for ABI compatibility but is no longer functional, and
29should not used in new programs.
29 30
30RAND_write_file() writes a number of random bytes (currently 1024) to 31RAND_write_file() writes a number of random bytes (currently 1024) to
31file B<filename> which can be used to initialize the PRNG by calling 32file B<filename>.
32RAND_load_file() in a later session.
33 33
34=head1 RETURN VALUES 34=head1 RETURN VALUES
35 35
36RAND_load_file() returns the number of bytes read. 36RAND_load_file() always returns 0.
37 37
38RAND_write_file() returns the number of bytes written, and -1 if the 38RAND_write_file() returns the number of bytes written, and -1 if the
39bytes written were generated without appropriate seed. 39bytes written were generated without appropriate seed.
diff --git a/src/lib/libssl/src/doc/crypto/rand.pod b/src/lib/libssl/src/doc/crypto/rand.pod
index 1c068c85b3..e987414477 100644
--- a/src/lib/libssl/src/doc/crypto/rand.pod
+++ b/src/lib/libssl/src/doc/crypto/rand.pod
@@ -29,10 +29,6 @@ rand - pseudo-random number generator
29 29
30 void RAND_cleanup(void); 30 void RAND_cleanup(void);
31 31
32 /* For Win32 only */
33 void RAND_screen(void);
34 int RAND_event(UINT, WPARAM, LPARAM);
35
36=head1 DESCRIPTION 32=head1 DESCRIPTION
37 33
38Since the introduction of the ENGINE API, the recommended way of controlling 34Since the introduction of the ENGINE API, the recommended way of controlling
@@ -64,105 +60,8 @@ PRNG.
64 60
65=head1 INTERNALS 61=head1 INTERNALS
66 62
67The RAND_SSLeay() method implements a PRNG based on a cryptographic 63The RAND_SSLeay() method implements a PRNG based on the systems'
68hash function. 64L<arc4random_buf(3)> random number generator.
69
70The following description of its design is based on the SSLeay
71documentation:
72
73First up I will state the things I believe I need for a good RNG.
74
75=over 4
76
77=item 1
78
79A good hashing algorithm to mix things up and to convert the RNG 'state'
80to random numbers.
81
82=item 2
83
84An initial source of random 'state'.
85
86=item 3
87
88The state should be very large. If the RNG is being used to generate
894096 bit RSA keys, 2 2048 bit random strings are required (at a minimum).
90If your RNG state only has 128 bits, you are obviously limiting the
91search space to 128 bits, not 2048. I'm probably getting a little
92carried away on this last point but it does indicate that it may not be
93a bad idea to keep quite a lot of RNG state. It should be easier to
94break a cipher than guess the RNG seed data.
95
96=item 4
97
98Any RNG seed data should influence all subsequent random numbers
99generated. This implies that any random seed data entered will have
100an influence on all subsequent random numbers generated.
101
102=item 5
103
104When using data to seed the RNG state, the data used should not be
105extractable from the RNG state. I believe this should be a
106requirement because one possible source of 'secret' semi random
107data would be a private key or a password. This data must
108not be disclosed by either subsequent random numbers or a
109'core' dump left by a program crash.
110
111=item 6
112
113Given the same initial 'state', 2 systems should deviate in their RNG state
114(and hence the random numbers generated) over time if at all possible.
115
116=item 7
117
118Given the random number output stream, it should not be possible to determine
119the RNG state or the next random number.
120
121=back
122
123The algorithm is as follows.
124
125There is global state made up of a 1023 byte buffer (the 'state'), a
126working hash value ('md'), and a counter ('count').
127
128Whenever seed data is added, it is inserted into the 'state' as
129follows.
130
131The input is chopped up into units of 20 bytes (or less for
132the last block). Each of these blocks is run through the hash
133function as follows: The data passed to the hash function
134is the current 'md', the same number of bytes from the 'state'
135(the location determined by in incremented looping index) as
136the current 'block', the new key data 'block', and 'count'
137(which is incremented after each use).
138The result of this is kept in 'md' and also xored into the
139'state' at the same locations that were used as input into the
140hash function. I
141believe this system addresses points 1 (hash function; currently
142SHA-1), 3 (the 'state'), 4 (via the 'md'), 5 (by the use of a hash
143function and xor).
144
145When bytes are extracted from the RNG, the following process is used.
146For each group of 10 bytes (or less), we do the following:
147
148Input into the hash function the local 'md' (which is initialized from
149the global 'md' before any bytes are generated), the bytes that are to
150be overwritten by the random bytes, and bytes from the 'state'
151(incrementing looping index). From this digest output (which is kept
152in 'md'), the top (up to) 10 bytes are returned to the caller and the
153bottom 10 bytes are xored into the 'state'.
154
155Finally, after we have finished 'num' random bytes for the caller,
156'count' (which is incremented) and the local and global 'md' are fed
157into the hash function and the results are kept in the global 'md'.
158
159I believe the above addressed points 1 (use of SHA-1), 6 (by hashing
160into the 'state' the 'old' data from the caller that is about to be
161overwritten) and 7 (by not using the 10 bytes given to the caller to
162update the 'state', but they are used to update 'md').
163
164So of the points raised, only 2 is not addressed (but see
165L<RAND_add(3)|RAND_add(3)>).
166 65
167=head1 SEE ALSO 66=head1 SEE ALSO
168 67