summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rand
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/rand')
-rw-r--r--src/lib/libcrypto/rand/Makefile164
-rw-r--r--src/lib/libcrypto/rand/md_rand.c593
-rw-r--r--src/lib/libcrypto/rand/rand.h9
-rw-r--r--src/lib/libcrypto/rand/rand_egd.c303
-rw-r--r--src/lib/libcrypto/rand/rand_err.c6
-rw-r--r--src/lib/libcrypto/rand/rand_lcl.h158
-rw-r--r--src/lib/libcrypto/rand/rand_lib.c119
-rw-r--r--src/lib/libcrypto/rand/rand_nw.c183
-rw-r--r--src/lib/libcrypto/rand/rand_os2.c153
-rw-r--r--src/lib/libcrypto/rand/rand_unix.c425
-rw-r--r--src/lib/libcrypto/rand/rand_vms.c148
-rw-r--r--src/lib/libcrypto/rand/rand_win.c807
-rw-r--r--src/lib/libcrypto/rand/randfile.c2
-rw-r--r--src/lib/libcrypto/rand/randtest.c219
14 files changed, 3155 insertions, 134 deletions
diff --git a/src/lib/libcrypto/rand/Makefile b/src/lib/libcrypto/rand/Makefile
new file mode 100644
index 0000000000..27694aa664
--- /dev/null
+++ b/src/lib/libcrypto/rand/Makefile
@@ -0,0 +1,164 @@
1#
2# OpenSSL/crypto/rand/Makefile
3#
4
5DIR= rand
6TOP= ../..
7CC= cc
8INCLUDES=
9CFLAG=-g
10MAKEFILE= Makefile
11AR= ar r
12
13CFLAGS= $(INCLUDES) $(CFLAG)
14
15GENERAL=Makefile
16TEST= randtest.c
17APPS=
18
19LIB=$(TOP)/libcrypto.a
20LIBSRC=md_rand.c randfile.c rand_lib.c rand_err.c rand_egd.c \
21 rand_win.c rand_unix.c rand_os2.c rand_nw.c
22LIBOBJ=md_rand.o randfile.o rand_lib.o rand_err.o rand_egd.o \
23 rand_win.o rand_unix.o rand_os2.o rand_nw.o
24
25SRC= $(LIBSRC)
26
27EXHEADER= rand.h
28HEADER= $(EXHEADER)
29
30ALL= $(GENERAL) $(SRC) $(HEADER)
31
32top:
33 (cd ../..; $(MAKE) DIRS=crypto SDIRS=$(DIR) sub_all)
34
35all: lib
36
37lib: $(LIBOBJ)
38 $(AR) $(LIB) $(LIBOBJ)
39 $(RANLIB) $(LIB) || echo Never mind.
40 @touch lib
41
42files:
43 $(PERL) $(TOP)/util/files.pl Makefile >> $(TOP)/MINFO
44
45links:
46 @$(PERL) $(TOP)/util/mklink.pl ../../include/openssl $(EXHEADER)
47 @$(PERL) $(TOP)/util/mklink.pl ../../test $(TEST)
48 @$(PERL) $(TOP)/util/mklink.pl ../../apps $(APPS)
49
50install:
51 @[ -n "$(INSTALLTOP)" ] # should be set by top Makefile...
52 @headerlist="$(EXHEADER)"; for i in $$headerlist ; \
53 do \
54 (cp $$i $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i; \
55 chmod 644 $(INSTALL_PREFIX)$(INSTALLTOP)/include/openssl/$$i ); \
56 done;
57
58tags:
59 ctags $(SRC)
60
61tests:
62
63lint:
64 lint -DLINT $(INCLUDES) $(SRC)>fluff
65
66depend:
67 @[ -n "$(MAKEDEPEND)" ] # should be set by upper Makefile...
68 $(MAKEDEPEND) -- $(CFLAG) $(INCLUDES) $(DEPFLAG) -- $(PROGS) $(LIBSRC)
69
70dclean:
71 $(PERL) -pe 'if (/^# DO NOT DELETE THIS LINE/) {print; exit(0);}' $(MAKEFILE) >Makefile.new
72 mv -f Makefile.new $(MAKEFILE)
73
74clean:
75 rm -f *.o *.obj lib tags core .pure .nfs* *.old *.bak fluff
76
77# DO NOT DELETE THIS LINE -- make depend depends on it.
78
79md_rand.o: ../../e_os.h ../../include/openssl/asn1.h
80md_rand.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
81md_rand.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
82md_rand.o: ../../include/openssl/evp.h ../../include/openssl/lhash.h
83md_rand.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
84md_rand.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
85md_rand.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
86md_rand.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
87md_rand.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
88md_rand.o: md_rand.c rand_lcl.h
89rand_egd.o: ../../include/openssl/buffer.h ../../include/openssl/e_os2.h
90rand_egd.o: ../../include/openssl/opensslconf.h
91rand_egd.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
92rand_egd.o: rand_egd.c
93rand_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
94rand_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
95rand_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
96rand_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
97rand_err.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
98rand_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
99rand_err.o: rand_err.c
100rand_lib.o: ../../e_os.h ../../include/openssl/asn1.h
101rand_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
102rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
103rand_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
104rand_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
105rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
106rand_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
107rand_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
108rand_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
109rand_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
110rand_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
111rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
112rand_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
113rand_lib.o: ../cryptlib.h rand_lib.c
114rand_nw.o: ../../e_os.h ../../include/openssl/asn1.h
115rand_nw.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
116rand_nw.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
117rand_nw.o: ../../include/openssl/err.h ../../include/openssl/evp.h
118rand_nw.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
119rand_nw.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
120rand_nw.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
121rand_nw.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
122rand_nw.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
123rand_nw.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h rand_nw.c
124rand_os2.o: ../../e_os.h ../../include/openssl/asn1.h
125rand_os2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
126rand_os2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
127rand_os2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
128rand_os2.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
129rand_os2.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
130rand_os2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
131rand_os2.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
132rand_os2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
133rand_os2.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
134rand_os2.o: rand_os2.c
135rand_unix.o: ../../e_os.h ../../include/openssl/asn1.h
136rand_unix.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
137rand_unix.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
138rand_unix.o: ../../include/openssl/err.h ../../include/openssl/evp.h
139rand_unix.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
140rand_unix.o: ../../include/openssl/objects.h
141rand_unix.o: ../../include/openssl/opensslconf.h
142rand_unix.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
143rand_unix.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
144rand_unix.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
145rand_unix.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
146rand_unix.o: rand_unix.c
147rand_win.o: ../../e_os.h ../../include/openssl/asn1.h
148rand_win.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
149rand_win.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
150rand_win.o: ../../include/openssl/err.h ../../include/openssl/evp.h
151rand_win.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
152rand_win.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
153rand_win.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
154rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
155rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
156rand_win.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
157rand_win.o: rand_win.c
158randfile.o: ../../e_os.h ../../include/openssl/buffer.h
159randfile.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
160randfile.o: ../../include/openssl/opensslconf.h
161randfile.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
162randfile.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
163randfile.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
164randfile.o: randfile.c
diff --git a/src/lib/libcrypto/rand/md_rand.c b/src/lib/libcrypto/rand/md_rand.c
new file mode 100644
index 0000000000..b2f04ff13e
--- /dev/null
+++ b/src/lib/libcrypto/rand/md_rand.c
@@ -0,0 +1,593 @@
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#ifdef MD_RAND_DEBUG
113# ifndef NDEBUG
114# define NDEBUG
115# endif
116#endif
117
118#include <assert.h>
119#include <stdio.h>
120#include <string.h>
121
122#include "e_os.h"
123
124#include <openssl/rand.h>
125#include "rand_lcl.h"
126
127#include <openssl/crypto.h>
128#include <openssl/err.h>
129
130#ifdef BN_DEBUG
131# define PREDICT
132#endif
133
134/* #define PREDICT 1 */
135
136#define STATE_SIZE 1023
137static int state_num=0,state_index=0;
138static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
139static unsigned char md[MD_DIGEST_LENGTH];
140static long md_count[2]={0,0};
141static double entropy=0;
142static int initialized=0;
143
144static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
145 * holds CRYPTO_LOCK_RAND
146 * (to prevent double locking) */
147/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
148static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
149
150
151#ifdef PREDICT
152int rand_predictable=0;
153#endif
154
155const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
156
157static void ssleay_rand_cleanup(void);
158static void ssleay_rand_seed(const void *buf, int num);
159static void ssleay_rand_add(const void *buf, int num, double add_entropy);
160static int ssleay_rand_bytes(unsigned char *buf, int num);
161static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
162static int ssleay_rand_status(void);
163
164RAND_METHOD rand_ssleay_meth={
165 ssleay_rand_seed,
166 ssleay_rand_bytes,
167 ssleay_rand_cleanup,
168 ssleay_rand_add,
169 ssleay_rand_pseudo_bytes,
170 ssleay_rand_status
171 };
172
173RAND_METHOD *RAND_SSLeay(void)
174 {
175 return(&rand_ssleay_meth);
176 }
177
178static void ssleay_rand_cleanup(void)
179 {
180 OPENSSL_cleanse(state,sizeof(state));
181 state_num=0;
182 state_index=0;
183 OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
184 md_count[0]=0;
185 md_count[1]=0;
186 entropy=0;
187 initialized=0;
188 }
189
190static void ssleay_rand_add(const void *buf, int num, double add)
191 {
192 int i,j,k,st_idx;
193 long md_c[2];
194 unsigned char local_md[MD_DIGEST_LENGTH];
195 EVP_MD_CTX m;
196 int do_not_lock;
197
198 /*
199 * (Based on the rand(3) manpage)
200 *
201 * The input is chopped up into units of 20 bytes (or less for
202 * the last block). Each of these blocks is run through the hash
203 * function as follows: The data passed to the hash function
204 * is the current 'md', the same number of bytes from the 'state'
205 * (the location determined by in incremented looping index) as
206 * the current 'block', the new key data 'block', and 'count'
207 * (which is incremented after each use).
208 * The result of this is kept in 'md' and also xored into the
209 * 'state' at the same locations that were used as input into the
210 * hash function.
211 */
212
213 /* check if we already have the lock */
214 if (crypto_lock_rand)
215 {
216 CRYPTO_THREADID cur;
217 CRYPTO_THREADID_current(&cur);
218 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
219 do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
220 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
221 }
222 else
223 do_not_lock = 0;
224
225 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
226 st_idx=state_index;
227
228 /* use our own copies of the counters so that even
229 * if a concurrent thread seeds with exactly the
230 * same data and uses the same subarray there's _some_
231 * difference */
232 md_c[0] = md_count[0];
233 md_c[1] = md_count[1];
234
235 memcpy(local_md, md, sizeof md);
236
237 /* state_index <= state_num <= STATE_SIZE */
238 state_index += num;
239 if (state_index >= STATE_SIZE)
240 {
241 state_index%=STATE_SIZE;
242 state_num=STATE_SIZE;
243 }
244 else if (state_num < STATE_SIZE)
245 {
246 if (state_index > state_num)
247 state_num=state_index;
248 }
249 /* state_index <= state_num <= STATE_SIZE */
250
251 /* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
252 * are what we will use now, but other threads may use them
253 * as well */
254
255 md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
256
257 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
258
259 EVP_MD_CTX_init(&m);
260 for (i=0; i<num; i+=MD_DIGEST_LENGTH)
261 {
262 j=(num-i);
263 j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
264
265 MD_Init(&m);
266 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
267 k=(st_idx+j)-STATE_SIZE;
268 if (k > 0)
269 {
270 MD_Update(&m,&(state[st_idx]),j-k);
271 MD_Update(&m,&(state[0]),k);
272 }
273 else
274 MD_Update(&m,&(state[st_idx]),j);
275
276 /* DO NOT REMOVE THE FOLLOWING CALL TO MD_Update()! */
277 MD_Update(&m,buf,j);
278 /* We know that line may cause programs such as
279 purify and valgrind to complain about use of
280 uninitialized data. The problem is not, it's
281 with the caller. Removing that line will make
282 sure you get really bad randomness and thereby
283 other problems such as very insecure keys. */
284
285 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
286 MD_Final(&m,local_md);
287 md_c[1]++;
288
289 buf=(const char *)buf + j;
290
291 for (k=0; k<j; k++)
292 {
293 /* Parallel threads may interfere with this,
294 * but always each byte of the new state is
295 * the XOR of some previous value of its
296 * and local_md (itermediate values may be lost).
297 * Alway using locking could hurt performance more
298 * than necessary given that conflicts occur only
299 * when the total seeding is longer than the random
300 * state. */
301 state[st_idx++]^=local_md[k];
302 if (st_idx >= STATE_SIZE)
303 st_idx=0;
304 }
305 }
306 EVP_MD_CTX_cleanup(&m);
307
308 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
309 /* Don't just copy back local_md into md -- this could mean that
310 * other thread's seeding remains without effect (except for
311 * the incremented counter). By XORing it we keep at least as
312 * much entropy as fits into md. */
313 for (k = 0; k < (int)sizeof(md); k++)
314 {
315 md[k] ^= local_md[k];
316 }
317 if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
318 entropy += add;
319 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
320
321#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
322 assert(md_c[1] == md_count[1]);
323#endif
324 }
325
326static void ssleay_rand_seed(const void *buf, int num)
327 {
328 ssleay_rand_add(buf, num, (double)num);
329 }
330
331static int ssleay_rand_bytes(unsigned char *buf, int num)
332 {
333 static volatile int stirred_pool = 0;
334 int i,j,k,st_num,st_idx;
335 int num_ceil;
336 int ok;
337 long md_c[2];
338 unsigned char local_md[MD_DIGEST_LENGTH];
339 EVP_MD_CTX m;
340#ifndef GETPID_IS_MEANINGLESS
341 pid_t curr_pid = getpid();
342#endif
343 int do_stir_pool = 0;
344
345#ifdef PREDICT
346 if (rand_predictable)
347 {
348 static unsigned char val=0;
349
350 for (i=0; i<num; i++)
351 buf[i]=val++;
352 return(1);
353 }
354#endif
355
356 if (num <= 0)
357 return 1;
358
359 EVP_MD_CTX_init(&m);
360 /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
361 num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
362
363 /*
364 * (Based on the rand(3) manpage:)
365 *
366 * For each group of 10 bytes (or less), we do the following:
367 *
368 * Input into the hash function the local 'md' (which is initialized from
369 * the global 'md' before any bytes are generated), the bytes that are to
370 * be overwritten by the random bytes, and bytes from the 'state'
371 * (incrementing looping index). From this digest output (which is kept
372 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
373 * bottom 10 bytes are xored into the 'state'.
374 *
375 * Finally, after we have finished 'num' random bytes for the
376 * caller, 'count' (which is incremented) and the local and global 'md'
377 * are fed into the hash function and the results are kept in the
378 * global 'md'.
379 */
380
381 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
382
383 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
384 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
385 CRYPTO_THREADID_current(&locking_threadid);
386 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
387 crypto_lock_rand = 1;
388
389 if (!initialized)
390 {
391 RAND_poll();
392 initialized = 1;
393 }
394
395 if (!stirred_pool)
396 do_stir_pool = 1;
397
398 ok = (entropy >= ENTROPY_NEEDED);
399 if (!ok)
400 {
401 /* If the PRNG state is not yet unpredictable, then seeing
402 * the PRNG output may help attackers to determine the new
403 * state; thus we have to decrease the entropy estimate.
404 * Once we've had enough initial seeding we don't bother to
405 * adjust the entropy count, though, because we're not ambitious
406 * to provide *information-theoretic* randomness.
407 *
408 * NOTE: This approach fails if the program forks before
409 * we have enough entropy. Entropy should be collected
410 * in a separate input pool and be transferred to the
411 * output pool only when the entropy limit has been reached.
412 */
413 entropy -= num;
414 if (entropy < 0)
415 entropy = 0;
416 }
417
418 if (do_stir_pool)
419 {
420 /* In the output function only half of 'md' remains secret,
421 * so we better make sure that the required entropy gets
422 * 'evenly distributed' through 'state', our randomness pool.
423 * The input function (ssleay_rand_add) chains all of 'md',
424 * which makes it more suitable for this purpose.
425 */
426
427 int n = STATE_SIZE; /* so that the complete pool gets accessed */
428 while (n > 0)
429 {
430#if MD_DIGEST_LENGTH > 20
431# error "Please adjust DUMMY_SEED."
432#endif
433#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
434 /* Note that the seed does not matter, it's just that
435 * ssleay_rand_add expects to have something to hash. */
436 ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
437 n -= MD_DIGEST_LENGTH;
438 }
439 if (ok)
440 stirred_pool = 1;
441 }
442
443 st_idx=state_index;
444 st_num=state_num;
445 md_c[0] = md_count[0];
446 md_c[1] = md_count[1];
447 memcpy(local_md, md, sizeof md);
448
449 state_index+=num_ceil;
450 if (state_index > state_num)
451 state_index %= state_num;
452
453 /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
454 * are now ours (but other threads may use them too) */
455
456 md_count[0] += 1;
457
458 /* before unlocking, we must clear 'crypto_lock_rand' */
459 crypto_lock_rand = 0;
460 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
461
462 while (num > 0)
463 {
464 /* num_ceil -= MD_DIGEST_LENGTH/2 */
465 j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
466 num-=j;
467 MD_Init(&m);
468#ifndef GETPID_IS_MEANINGLESS
469 if (curr_pid) /* just in the first iteration to save time */
470 {
471 MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
472 curr_pid = 0;
473 }
474#endif
475 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
476 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
477
478#ifndef PURIFY /* purify complains */
479 /* The following line uses the supplied buffer as a small
480 * source of entropy: since this buffer is often uninitialised
481 * it may cause programs such as purify or valgrind to
482 * complain. So for those builds it is not used: the removal
483 * of such a small source of entropy has negligible impact on
484 * security.
485 */
486 MD_Update(&m,buf,j);
487#endif
488
489 k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
490 if (k > 0)
491 {
492 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
493 MD_Update(&m,&(state[0]),k);
494 }
495 else
496 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
497 MD_Final(&m,local_md);
498
499 for (i=0; i<MD_DIGEST_LENGTH/2; i++)
500 {
501 state[st_idx++]^=local_md[i]; /* may compete with other threads */
502 if (st_idx >= st_num)
503 st_idx=0;
504 if (i < j)
505 *(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
506 }
507 }
508
509 MD_Init(&m);
510 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
511 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
512 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
513 MD_Update(&m,md,MD_DIGEST_LENGTH);
514 MD_Final(&m,md);
515 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
516
517 EVP_MD_CTX_cleanup(&m);
518 if (ok)
519 return(1);
520 else
521 {
522 RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
523 ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
524 "http://www.openssl.org/support/faq.html");
525 return(0);
526 }
527 }
528
529/* pseudo-random bytes that are guaranteed to be unique but not
530 unpredictable */
531static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
532 {
533 int ret;
534 unsigned long err;
535
536 ret = RAND_bytes(buf, num);
537 if (ret == 0)
538 {
539 err = ERR_peek_error();
540 if (ERR_GET_LIB(err) == ERR_LIB_RAND &&
541 ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED)
542 ERR_clear_error();
543 }
544 return (ret);
545 }
546
547static int ssleay_rand_status(void)
548 {
549 CRYPTO_THREADID cur;
550 int ret;
551 int do_not_lock;
552
553 CRYPTO_THREADID_current(&cur);
554 /* check if we already have the lock
555 * (could happen if a RAND_poll() implementation calls RAND_status()) */
556 if (crypto_lock_rand)
557 {
558 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
559 do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
560 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
561 }
562 else
563 do_not_lock = 0;
564
565 if (!do_not_lock)
566 {
567 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
568
569 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
570 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
571 CRYPTO_THREADID_cpy(&locking_threadid, &cur);
572 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
573 crypto_lock_rand = 1;
574 }
575
576 if (!initialized)
577 {
578 RAND_poll();
579 initialized = 1;
580 }
581
582 ret = entropy >= ENTROPY_NEEDED;
583
584 if (!do_not_lock)
585 {
586 /* before unlocking, we must clear 'crypto_lock_rand' */
587 crypto_lock_rand = 0;
588
589 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
590 }
591
592 return ret;
593 }
diff --git a/src/lib/libcrypto/rand/rand.h b/src/lib/libcrypto/rand/rand.h
index dc8fcf94c5..ac6c021763 100644
--- a/src/lib/libcrypto/rand/rand.h
+++ b/src/lib/libcrypto/rand/rand.h
@@ -119,11 +119,6 @@ int RAND_event(UINT, WPARAM, LPARAM);
119 119
120#endif 120#endif
121 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 */ 122/* BEGIN ERROR CODES */
128/* The following lines are auto generated by the script mkerr.pl. Any changes 123/* 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. 124 * made after this point may be overwritten when the script is next run.
@@ -134,13 +129,9 @@ void ERR_load_RAND_strings(void);
134 129
135/* Function codes. */ 130/* Function codes. */
136#define RAND_F_RAND_GET_RAND_METHOD 101 131#define RAND_F_RAND_GET_RAND_METHOD 101
137#define RAND_F_RAND_INIT_FIPS 102
138#define RAND_F_SSLEAY_RAND_BYTES 100 132#define RAND_F_SSLEAY_RAND_BYTES 100
139 133
140/* Reason codes. */ 134/* Reason codes. */
141#define RAND_R_ERROR_INITIALISING_DRBG 102
142#define RAND_R_ERROR_INSTANTIATING_DRBG 103
143#define RAND_R_NO_FIPS_RANDOM_METHOD_SET 101
144#define RAND_R_PRNG_NOT_SEEDED 100 135#define RAND_R_PRNG_NOT_SEEDED 100
145 136
146#ifdef __cplusplus 137#ifdef __cplusplus
diff --git a/src/lib/libcrypto/rand/rand_egd.c b/src/lib/libcrypto/rand/rand_egd.c
new file mode 100644
index 0000000000..d53b916ebe
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_egd.c
@@ -0,0 +1,303 @@
1/* crypto/rand/rand_egd.c */
2/* Written by Ulf Moeller and Lutz Jaenicke for the OpenSSL project. */
3/* ====================================================================
4 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
16 * distribution.
17 *
18 * 3. All advertising materials mentioning features or use of this
19 * software must display the following acknowledgment:
20 * "This product includes software developed by the OpenSSL Project
21 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22 *
23 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24 * endorse or promote products derived from this software without
25 * prior written permission. For written permission, please contact
26 * openssl-core@openssl.org.
27 *
28 * 5. Products derived from this software may not be called "OpenSSL"
29 * nor may "OpenSSL" appear in their names without prior written
30 * permission of the OpenSSL Project.
31 *
32 * 6. Redistributions of any form whatsoever must retain the following
33 * acknowledgment:
34 * "This product includes software developed by the OpenSSL Project
35 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36 *
37 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
41 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48 * OF THE POSSIBILITY OF SUCH DAMAGE.
49 * ====================================================================
50 *
51 * This product includes cryptographic software written by Eric Young
52 * (eay@cryptsoft.com). This product includes software written by Tim
53 * Hudson (tjh@cryptsoft.com).
54 *
55 */
56
57#include <openssl/e_os2.h>
58#include <openssl/rand.h>
59#include <openssl/buffer.h>
60
61/*
62 * Query the EGD <URL: http://www.lothar.com/tech/crypto/>.
63 *
64 * This module supplies three routines:
65 *
66 * RAND_query_egd_bytes(path, buf, bytes)
67 * will actually query "bytes" bytes of entropy form the egd-socket located
68 * at path and will write them to buf (if supplied) or will directly feed
69 * it to RAND_seed() if buf==NULL.
70 * The number of bytes is not limited by the maximum chunk size of EGD,
71 * which is 255 bytes. If more than 255 bytes are wanted, several chunks
72 * of entropy bytes are requested. The connection is left open until the
73 * query is competed.
74 * RAND_query_egd_bytes() returns with
75 * -1 if an error occured during connection or communication.
76 * num the number of bytes read from the EGD socket. This number is either
77 * the number of bytes requested or smaller, if the EGD pool is
78 * drained and the daemon signals that the pool is empty.
79 * This routine does not touch any RAND_status(). This is necessary, since
80 * PRNG functions may call it during initialization.
81 *
82 * RAND_egd_bytes(path, bytes) will query "bytes" bytes and have them
83 * used to seed the PRNG.
84 * RAND_egd_bytes() is a wrapper for RAND_query_egd_bytes() with buf=NULL.
85 * Unlike RAND_query_egd_bytes(), RAND_status() is used to test the
86 * seed status so that the return value can reflect the seed state:
87 * -1 if an error occured during connection or communication _or_
88 * if the PRNG has still not received the required seeding.
89 * num the number of bytes read from the EGD socket. This number is either
90 * the number of bytes requested or smaller, if the EGD pool is
91 * drained and the daemon signals that the pool is empty.
92 *
93 * RAND_egd(path) will query 255 bytes and use the bytes retreived to seed
94 * the PRNG.
95 * RAND_egd() is a wrapper for RAND_egd_bytes() with numbytes=255.
96 */
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)
100 {
101 return(-1);
102 }
103int RAND_egd(const char *path)
104 {
105 return(-1);
106 }
107
108int RAND_egd_bytes(const char *path,int bytes)
109 {
110 return(-1);
111 }
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_err.c b/src/lib/libcrypto/rand/rand_err.c
index b8586c8f4a..03cda4dd92 100644
--- a/src/lib/libcrypto/rand/rand_err.c
+++ b/src/lib/libcrypto/rand/rand_err.c
@@ -1,6 +1,6 @@
1/* crypto/rand/rand_err.c */ 1/* crypto/rand/rand_err.c */
2/* ==================================================================== 2/* ====================================================================
3 * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved. 3 * Copyright (c) 1999-2006 The OpenSSL Project. All rights reserved.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions 6 * modification, are permitted provided that the following conditions
@@ -71,16 +71,12 @@
71static ERR_STRING_DATA RAND_str_functs[]= 71static ERR_STRING_DATA RAND_str_functs[]=
72 { 72 {
73{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"}, 73{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"},
74{ERR_FUNC(RAND_F_RAND_INIT_FIPS), "RAND_init_fips"},
75{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"}, 74{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"},
76{0,NULL} 75{0,NULL}
77 }; 76 };
78 77
79static ERR_STRING_DATA RAND_str_reasons[]= 78static ERR_STRING_DATA RAND_str_reasons[]=
80 { 79 {
81{ERR_REASON(RAND_R_ERROR_INITIALISING_DRBG),"error initialising drbg"},
82{ERR_REASON(RAND_R_ERROR_INSTANTIATING_DRBG),"error instantiating drbg"},
83{ERR_REASON(RAND_R_NO_FIPS_RANDOM_METHOD_SET),"no fips random method set"},
84{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"}, 80{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"},
85{0,NULL} 81{0,NULL}
86 }; 82 };
diff --git a/src/lib/libcrypto/rand/rand_lcl.h b/src/lib/libcrypto/rand/rand_lcl.h
new file mode 100644
index 0000000000..618a8ec899
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_lcl.h
@@ -0,0 +1,158 @@
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 daf1dab973..513e338985 100644
--- a/src/lib/libcrypto/rand/rand_lib.c
+++ b/src/lib/libcrypto/rand/rand_lib.c
@@ -60,16 +60,10 @@
60#include <time.h> 60#include <time.h>
61#include "cryptlib.h" 61#include "cryptlib.h"
62#include <openssl/rand.h> 62#include <openssl/rand.h>
63
64#ifndef OPENSSL_NO_ENGINE 63#ifndef OPENSSL_NO_ENGINE
65#include <openssl/engine.h> 64#include <openssl/engine.h>
66#endif 65#endif
67 66
68#ifdef OPENSSL_FIPS
69#include <openssl/fips.h>
70#include <openssl/fips_rand.h>
71#endif
72
73#ifndef OPENSSL_NO_ENGINE 67#ifndef OPENSSL_NO_ENGINE
74/* non-NULL if default_RAND_meth is ENGINE-provided */ 68/* non-NULL if default_RAND_meth is ENGINE-provided */
75static ENGINE *funct_ref =NULL; 69static ENGINE *funct_ref =NULL;
@@ -180,116 +174,3 @@ int RAND_status(void)
180 return meth->status(); 174 return meth->status();
181 return 0; 175 return 0;
182 } 176 }
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 OPENSSL_cleanse(out, olen);
214 OPENSSL_free(out);
215 }
216
217/* Set "additional input" when generating random data. This uses the
218 * current PID, a time value and a counter.
219 */
220
221static size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
222 {
223 /* Use of static variables is OK as this happens under a lock */
224 static unsigned char buf[16];
225 static unsigned long counter;
226 FIPS_get_timevec(buf, &counter);
227 *pout = buf;
228 return sizeof(buf);
229 }
230
231/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
232 * correctly seeded by RAND_poll().
233 */
234
235static int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
236 double entropy)
237 {
238 RAND_SSLeay()->add(in, inlen, entropy);
239 return 1;
240 }
241
242static int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
243 {
244 RAND_SSLeay()->seed(in, inlen);
245 return 1;
246 }
247
248#ifndef OPENSSL_DRBG_DEFAULT_TYPE
249#define OPENSSL_DRBG_DEFAULT_TYPE NID_aes_256_ctr
250#endif
251#ifndef OPENSSL_DRBG_DEFAULT_FLAGS
252#define OPENSSL_DRBG_DEFAULT_FLAGS DRBG_FLAG_CTR_USE_DF
253#endif
254
255static int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
256static int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
257
258void RAND_set_fips_drbg_type(int type, int flags)
259 {
260 fips_drbg_type = type;
261 fips_drbg_flags = flags;
262 }
263
264int RAND_init_fips(void)
265 {
266 DRBG_CTX *dctx;
267 size_t plen;
268 unsigned char pers[32], *p;
269 dctx = FIPS_get_default_drbg();
270 if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
271 {
272 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
273 return 0;
274 }
275
276 FIPS_drbg_set_callbacks(dctx,
277 drbg_get_entropy, drbg_free_entropy, 20,
278 drbg_get_entropy, drbg_free_entropy);
279 FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
280 drbg_rand_seed, drbg_rand_add);
281 /* Personalisation string: a string followed by date time vector */
282 strcpy((char *)pers, "OpenSSL DRBG2.0");
283 plen = drbg_get_adin(dctx, &p);
284 memcpy(pers + 16, p, plen);
285
286 if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0)
287 {
288 RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
289 return 0;
290 }
291 FIPS_rand_set_method(FIPS_drbg_method());
292 return 1;
293 }
294
295#endif
diff --git a/src/lib/libcrypto/rand/rand_nw.c b/src/lib/libcrypto/rand/rand_nw.c
new file mode 100644
index 0000000000..8d5b8d2e32
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_nw.c
@@ -0,0 +1,183 @@
1/* crypto/rand/rand_nw.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-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#include "cryptlib.h"
113#include <openssl/rand.h>
114#include "rand_lcl.h"
115
116#if defined (OPENSSL_SYS_NETWARE)
117
118#if defined(NETWARE_LIBC)
119#include <nks/thread.h>
120#else
121#include <nwthread.h>
122#endif
123
124extern int GetProcessSwitchCount(void);
125#if !defined(NETWARE_LIBC) || (CURRENT_NDK_THRESHOLD < 509220000)
126extern void *RunningProcess; /* declare here same as found in newer NDKs */
127extern unsigned long GetSuperHighResolutionTimer(void);
128#endif
129
130 /* the FAQ indicates we need to provide at least 20 bytes (160 bits) of seed
131 */
132int RAND_poll(void)
133{
134 unsigned long l;
135 unsigned long tsc;
136 int i;
137
138 /* There are several options to gather miscellaneous data
139 * but for now we will loop checking the time stamp counter (rdtsc) and
140 * the SuperHighResolutionTimer. Each iteration will collect 8 bytes
141 * of data but it is treated as only 1 byte of entropy. The call to
142 * ThreadSwitchWithDelay() will introduce additional variability into
143 * the data returned by rdtsc.
144 *
145 * Applications can agument the seed material by adding additional
146 * stuff with RAND_add() and should probably do so.
147 */
148 l = GetProcessSwitchCount();
149 RAND_add(&l,sizeof(l),1);
150
151 /* need to cast the void* to unsigned long here */
152 l = (unsigned long)RunningProcess;
153 RAND_add(&l,sizeof(l),1);
154
155 for( i=2; i<ENTROPY_NEEDED; i++)
156 {
157#ifdef __MWERKS__
158 asm
159 {
160 rdtsc
161 mov tsc, eax
162 }
163#elif defined(__GNUC__) && __GNUC__>=2 && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_NO_INLINE_ASM)
164 asm volatile("rdtsc":"=a"(tsc)::"edx");
165#endif
166
167 RAND_add(&tsc, sizeof(tsc), 1);
168
169 l = GetSuperHighResolutionTimer();
170 RAND_add(&l, sizeof(l), 0);
171
172# if defined(NETWARE_LIBC)
173 NXThreadYield();
174# else /* NETWARE_CLIB */
175 ThreadSwitchWithDelay();
176# endif
177 }
178
179 return 1;
180}
181
182#endif
183
diff --git a/src/lib/libcrypto/rand/rand_os2.c b/src/lib/libcrypto/rand/rand_os2.c
new file mode 100644
index 0000000000..fc1e78b179
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_os2.c
@@ -0,0 +1,153 @@
1/* crypto/rand/rand_os2.c */
2/* ====================================================================
3 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * 3. All advertising materials mentioning features or use of this
18 * software must display the following acknowledgment:
19 * "This product includes software developed by the OpenSSL Project
20 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
21 *
22 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
23 * endorse or promote products derived from this software without
24 * prior written permission. For written permission, please contact
25 * openssl-core@openssl.org.
26 *
27 * 5. Products derived from this software may not be called "OpenSSL"
28 * nor may "OpenSSL" appear in their names without prior written
29 * permission of the OpenSSL Project.
30 *
31 * 6. Redistributions of any form whatsoever must retain the following
32 * acknowledgment:
33 * "This product includes software developed by the OpenSSL Project
34 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
35 *
36 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
37 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
38 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
39 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
40 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
42 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
43 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
44 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
45 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
46 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
47 * OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * This product includes cryptographic software written by Eric Young
51 * (eay@cryptsoft.com). This product includes software written by Tim
52 * Hudson (tjh@cryptsoft.com).
53 *
54 */
55
56#include "cryptlib.h"
57#include <openssl/rand.h>
58#include "rand_lcl.h"
59
60#ifdef OPENSSL_SYS_OS2
61
62#define INCL_DOSPROCESS
63#define INCL_DOSPROFILE
64#define INCL_DOSMISC
65#define INCL_DOSMODULEMGR
66#include <os2.h>
67
68#define CMD_KI_RDCNT (0x63)
69
70typedef struct _CPUUTIL {
71 ULONG ulTimeLow; /* Low 32 bits of time stamp */
72 ULONG ulTimeHigh; /* High 32 bits of time stamp */
73 ULONG ulIdleLow; /* Low 32 bits of idle time */
74 ULONG ulIdleHigh; /* High 32 bits of idle time */
75 ULONG ulBusyLow; /* Low 32 bits of busy time */
76 ULONG ulBusyHigh; /* High 32 bits of busy time */
77 ULONG ulIntrLow; /* Low 32 bits of interrupt time */
78 ULONG ulIntrHigh; /* High 32 bits of interrupt time */
79} CPUUTIL;
80
81#ifndef __KLIBC__
82APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, ULONG ulParm2, ULONG ulParm3) = NULL;
83APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz) = NULL;
84#endif
85HMODULE hDoscalls = 0;
86
87int RAND_poll(void)
88{
89 char failed_module[20];
90 QWORD qwTime;
91 ULONG SysVars[QSV_FOREGROUND_PROCESS];
92
93 if (hDoscalls == 0) {
94 ULONG rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", &hDoscalls);
95
96#ifndef __KLIBC__
97 if (rc == 0) {
98 rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
99
100 if (rc)
101 DosPerfSysCall = NULL;
102
103 rc = DosQueryProcAddr(hDoscalls, 368, NULL, (PFN *)&DosQuerySysState);
104
105 if (rc)
106 DosQuerySysState = NULL;
107 }
108#endif
109 }
110
111 /* Sample the hi-res timer, runs at around 1.1 MHz */
112 DosTmrQueryTime(&qwTime);
113 RAND_add(&qwTime, sizeof(qwTime), 2);
114
115 /* Sample a bunch of system variables, includes various process & memory statistics */
116 DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars));
117 RAND_add(SysVars, sizeof(SysVars), 4);
118
119 /* If available, sample CPU registers that count at CPU MHz
120 * Only fairly new CPUs (PPro & K6 onwards) & OS/2 versions support this
121 */
122 if (DosPerfSysCall) {
123 CPUUTIL util;
124
125 if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) {
126 RAND_add(&util, sizeof(util), 10);
127 }
128 else {
129#ifndef __KLIBC__
130 DosPerfSysCall = NULL;
131#endif
132 }
133 }
134
135 /* DosQuerySysState() gives us a huge quantity of process, thread, memory & handle stats */
136 if (DosQuerySysState) {
137 char *buffer = OPENSSL_malloc(256 * 1024);
138
139 if (DosQuerySysState(0x1F, 0, 0, 0, buffer, 256 * 1024) == 0) {
140 /* First 4 bytes in buffer is a pointer to the thread count
141 * there should be at least 1 byte of entropy per thread
142 */
143 RAND_add(buffer, 256 * 1024, **(ULONG **)buffer);
144 }
145
146 OPENSSL_free(buffer);
147 return 1;
148 }
149
150 return 0;
151}
152
153#endif /* OPENSSL_SYS_OS2 */
diff --git a/src/lib/libcrypto/rand/rand_unix.c b/src/lib/libcrypto/rand/rand_unix.c
new file mode 100644
index 0000000000..3316388443
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_unix.c
@@ -0,0 +1,425 @@
1/* crypto/rand/rand_unix.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-2006 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#include <stdio.h>
112
113#define USE_SOCKETS
114#include "e_os.h"
115#include "cryptlib.h"
116#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
178 curr_gid = getgid();
179 RAND_add (&curr_gid, sizeof curr_gid, 1);
180 curr_gid = 0;
181
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)
221{
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;
229}
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/rand_vms.c b/src/lib/libcrypto/rand/rand_vms.c
new file mode 100644
index 0000000000..0bfd8ff7e4
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_vms.c
@@ -0,0 +1,148 @@
1/* crypto/rand/rand_vms.c -*- mode:C; c-file-style: "eay" -*- */
2/* Written by Richard Levitte <richard@levitte.org> for the OpenSSL
3 * project 2000.
4 */
5/* ====================================================================
6 * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
24 *
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * openssl-core@openssl.org.
29 *
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
33 *
34 * 6. Redistributions of any form whatsoever must retain the following
35 * acknowledgment:
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
38 *
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
52 *
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
56 *
57 */
58
59#include <openssl/rand.h>
60#include "rand_lcl.h"
61
62#if defined(OPENSSL_SYS_VMS)
63
64#include <descrip.h>
65#include <jpidef.h>
66#include <ssdef.h>
67#include <starlet.h>
68#ifdef __DECC
69# pragma message disable DOLLARID
70#endif
71
72/* Use 32-bit pointers almost everywhere. Define the type to which to
73 * cast a pointer passed to an external function.
74 */
75#if __INITIAL_POINTER_SIZE == 64
76# define PTR_T __void_ptr64
77# pragma pointer_size save
78# pragma pointer_size 32
79#else /* __INITIAL_POINTER_SIZE == 64 */
80# define PTR_T void *
81#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
82
83static struct items_data_st
84 {
85 short length, code; /* length is amount of bytes */
86 } items_data[] =
87 { { 4, JPI$_BUFIO },
88 { 4, JPI$_CPUTIM },
89 { 4, JPI$_DIRIO },
90 { 8, JPI$_LOGINTIM },
91 { 4, JPI$_PAGEFLTS },
92 { 4, JPI$_PID },
93 { 4, JPI$_WSSIZE },
94 { 0, 0 }
95 };
96
97int RAND_poll(void)
98 {
99 long pid, iosb[2];
100 int status = 0;
101 struct
102 {
103 short length, code;
104 long *buffer;
105 int *retlen;
106 } item[32], *pitem;
107 unsigned char data_buffer[256];
108 short total_length = 0;
109 struct items_data_st *pitems_data;
110
111 pitems_data = items_data;
112 pitem = item;
113
114 /* Setup */
115 while (pitems_data->length
116 && (total_length + pitems_data->length <= 256))
117 {
118 pitem->length = pitems_data->length;
119 pitem->code = pitems_data->code;
120 pitem->buffer = (long *)&data_buffer[total_length];
121 pitem->retlen = 0;
122 total_length += pitems_data->length;
123 pitems_data++;
124 pitem++;
125 }
126 pitem->length = pitem->code = 0;
127
128 /*
129 * Scan through all the processes in the system and add entropy with
130 * results from the processes that were possible to look at.
131 * However, view the information as only half trustable.
132 */
133 pid = -1; /* search context */
134 while ((status = sys$getjpiw(0, &pid, 0, item, iosb, 0, 0))
135 != SS$_NOMOREPROC)
136 {
137 if (status == SS$_NORMAL)
138 {
139 RAND_add( (PTR_T)data_buffer, total_length,
140 total_length/2);
141 }
142 }
143 sys$gettim(iosb);
144 RAND_add( (PTR_T)iosb, sizeof(iosb), sizeof(iosb)/2);
145 return 1;
146}
147
148#endif
diff --git a/src/lib/libcrypto/rand/rand_win.c b/src/lib/libcrypto/rand/rand_win.c
new file mode 100644
index 0000000000..5d134e186b
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_win.c
@@ -0,0 +1,807 @@
1/* crypto/rand/rand_win.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-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#include "cryptlib.h"
113#include <openssl/rand.h>
114#include "rand_lcl.h"
115
116#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
117#include <windows.h>
118#ifndef _WIN32_WINNT
119# define _WIN32_WINNT 0x0400
120#endif
121#include <wincrypt.h>
122#include <tlhelp32.h>
123
124/* Limit the time spent walking through the heap, processes, threads and modules to
125 a maximum of 1000 miliseconds each, unless CryptoGenRandom failed */
126#define MAXDELAY 1000
127
128/* Intel hardware RNG CSP -- available from
129 * http://developer.intel.com/design/security/rng/redist_license.htm
130 */
131#define PROV_INTEL_SEC 22
132#define INTEL_DEF_PROV L"Intel Hardware Cryptographic Service Provider"
133
134static void readtimer(void);
135static void readscreen(void);
136
137/* It appears like CURSORINFO, PCURSORINFO and LPCURSORINFO are only defined
138 when WINVER is 0x0500 and up, which currently only happens on Win2000.
139 Unfortunately, those are typedefs, so they're a little bit difficult to
140 detect properly. On the other hand, the macro CURSOR_SHOWING is defined
141 within the same conditional, so it can be use to detect the absence of said
142 typedefs. */
143
144#ifndef CURSOR_SHOWING
145/*
146 * Information about the global cursor.
147 */
148typedef struct tagCURSORINFO
149{
150 DWORD cbSize;
151 DWORD flags;
152 HCURSOR hCursor;
153 POINT ptScreenPos;
154} CURSORINFO, *PCURSORINFO, *LPCURSORINFO;
155
156#define CURSOR_SHOWING 0x00000001
157#endif /* CURSOR_SHOWING */
158
159#if !defined(OPENSSL_SYS_WINCE)
160typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTW)(HCRYPTPROV *, LPCWSTR, LPCWSTR,
161 DWORD, DWORD);
162typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV, DWORD, BYTE *);
163typedef BOOL (WINAPI *CRYPTRELEASECONTEXT)(HCRYPTPROV, DWORD);
164
165typedef HWND (WINAPI *GETFOREGROUNDWINDOW)(VOID);
166typedef BOOL (WINAPI *GETCURSORINFO)(PCURSORINFO);
167typedef DWORD (WINAPI *GETQUEUESTATUS)(UINT);
168
169typedef HANDLE (WINAPI *CREATETOOLHELP32SNAPSHOT)(DWORD, DWORD);
170typedef BOOL (WINAPI *CLOSETOOLHELP32SNAPSHOT)(HANDLE);
171typedef BOOL (WINAPI *HEAP32FIRST)(LPHEAPENTRY32, DWORD, size_t);
172typedef BOOL (WINAPI *HEAP32NEXT)(LPHEAPENTRY32);
173typedef BOOL (WINAPI *HEAP32LIST)(HANDLE, LPHEAPLIST32);
174typedef BOOL (WINAPI *PROCESS32)(HANDLE, LPPROCESSENTRY32);
175typedef BOOL (WINAPI *THREAD32)(HANDLE, LPTHREADENTRY32);
176typedef BOOL (WINAPI *MODULE32)(HANDLE, LPMODULEENTRY32);
177
178#include <lmcons.h>
179#include <lmstats.h>
180#if 1 /* The NET API is Unicode only. It requires the use of the UNICODE
181 * macro. When UNICODE is defined LPTSTR becomes LPWSTR. LMSTR was
182 * was added to the Platform SDK to allow the NET API to be used in
183 * non-Unicode applications provided that Unicode strings were still
184 * used for input. LMSTR is defined as LPWSTR.
185 */
186typedef NET_API_STATUS (NET_API_FUNCTION * NETSTATGET)
187 (LPWSTR, LPWSTR, DWORD, DWORD, LPBYTE*);
188typedef NET_API_STATUS (NET_API_FUNCTION * NETFREE)(LPBYTE);
189#endif /* 1 */
190#endif /* !OPENSSL_SYS_WINCE */
191
192int RAND_poll(void)
193{
194 MEMORYSTATUS m;
195 HCRYPTPROV hProvider = 0;
196 DWORD w;
197 int good = 0;
198
199 /* Determine the OS version we are on so we can turn off things
200 * that do not work properly.
201 */
202 OSVERSIONINFO osverinfo ;
203 osverinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFO) ;
204 GetVersionEx( &osverinfo ) ;
205
206#if defined(OPENSSL_SYS_WINCE)
207# if defined(_WIN32_WCE) && _WIN32_WCE>=300
208/* Even though MSDN says _WIN32_WCE>=210, it doesn't seem to be available
209 * in commonly available implementations prior 300... */
210 {
211 BYTE buf[64];
212 /* poll the CryptoAPI PRNG */
213 /* The CryptoAPI returns sizeof(buf) bytes of randomness */
214 if (CryptAcquireContextW(&hProvider, NULL, NULL, PROV_RSA_FULL,
215 CRYPT_VERIFYCONTEXT))
216 {
217 if (CryptGenRandom(hProvider, sizeof(buf), buf))
218 RAND_add(buf, sizeof(buf), sizeof(buf));
219 CryptReleaseContext(hProvider, 0);
220 }
221 }
222# endif
223#else /* OPENSSL_SYS_WINCE */
224 /*
225 * None of below libraries are present on Windows CE, which is
226 * why we #ifndef the whole section. This also excuses us from
227 * handling the GetProcAddress issue. The trouble is that in
228 * real Win32 API GetProcAddress is available in ANSI flavor
229 * only. In WinCE on the other hand GetProcAddress is a macro
230 * most commonly defined as GetProcAddressW, which accepts
231 * Unicode argument. If we were to call GetProcAddress under
232 * WinCE, I'd recommend to either redefine GetProcAddress as
233 * GetProcAddressA (there seem to be one in common CE spec) or
234 * implement own shim routine, which would accept ANSI argument
235 * and expand it to Unicode.
236 */
237 {
238 /* load functions dynamically - not available on all systems */
239 HMODULE advapi = LoadLibrary(TEXT("ADVAPI32.DLL"));
240 HMODULE kernel = LoadLibrary(TEXT("KERNEL32.DLL"));
241 HMODULE user = NULL;
242 HMODULE netapi = LoadLibrary(TEXT("NETAPI32.DLL"));
243 CRYPTACQUIRECONTEXTW acquire = NULL;
244 CRYPTGENRANDOM gen = NULL;
245 CRYPTRELEASECONTEXT release = NULL;
246 NETSTATGET netstatget = NULL;
247 NETFREE netfree = NULL;
248 BYTE buf[64];
249
250 if (netapi)
251 {
252 netstatget = (NETSTATGET) GetProcAddress(netapi,"NetStatisticsGet");
253 netfree = (NETFREE) GetProcAddress(netapi,"NetApiBufferFree");
254 }
255
256 if (netstatget && netfree)
257 {
258 LPBYTE outbuf;
259 /* NetStatisticsGet() is a Unicode only function
260 * STAT_WORKSTATION_0 contains 45 fields and STAT_SERVER_0
261 * contains 17 fields. We treat each field as a source of
262 * one byte of entropy.
263 */
264
265 if (netstatget(NULL, L"LanmanWorkstation", 0, 0, &outbuf) == 0)
266 {
267 RAND_add(outbuf, sizeof(STAT_WORKSTATION_0), 45);
268 netfree(outbuf);
269 }
270 if (netstatget(NULL, L"LanmanServer", 0, 0, &outbuf) == 0)
271 {
272 RAND_add(outbuf, sizeof(STAT_SERVER_0), 17);
273 netfree(outbuf);
274 }
275 }
276
277 if (netapi)
278 FreeLibrary(netapi);
279
280 /* It appears like this can cause an exception deep within ADVAPI32.DLL
281 * at random times on Windows 2000. Reported by Jeffrey Altman.
282 * Only use it on NT.
283 */
284 /* Wolfgang Marczy <WMarczy@topcall.co.at> reports that
285 * the RegQueryValueEx call below can hang on NT4.0 (SP6).
286 * So we don't use this at all for now. */
287#if 0
288 if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
289 osverinfo.dwMajorVersion < 5)
290 {
291 /* Read Performance Statistics from NT/2000 registry
292 * The size of the performance data can vary from call
293 * to call so we must guess the size of the buffer to use
294 * and increase its size if we get an ERROR_MORE_DATA
295 * return instead of ERROR_SUCCESS.
296 */
297 LONG rc=ERROR_MORE_DATA;
298 char * buf=NULL;
299 DWORD bufsz=0;
300 DWORD length;
301
302 while (rc == ERROR_MORE_DATA)
303 {
304 buf = realloc(buf,bufsz+8192);
305 if (!buf)
306 break;
307 bufsz += 8192;
308
309 length = bufsz;
310 rc = RegQueryValueEx(HKEY_PERFORMANCE_DATA, TEXT("Global"),
311 NULL, NULL, buf, &length);
312 }
313 if (rc == ERROR_SUCCESS)
314 {
315 /* For entropy count assume only least significant
316 * byte of each DWORD is random.
317 */
318 RAND_add(&length, sizeof(length), 0);
319 RAND_add(buf, length, length / 4.0);
320
321 /* Close the Registry Key to allow Windows to cleanup/close
322 * the open handle
323 * Note: The 'HKEY_PERFORMANCE_DATA' key is implicitly opened
324 * when the RegQueryValueEx above is done. However, if
325 * it is not explicitly closed, it can cause disk
326 * partition manipulation problems.
327 */
328 RegCloseKey(HKEY_PERFORMANCE_DATA);
329 }
330 if (buf)
331 free(buf);
332 }
333#endif
334
335 if (advapi)
336 {
337 /*
338 * If it's available, then it's available in both ANSI
339 * and UNICODE flavors even in Win9x, documentation says.
340 * We favor Unicode...
341 */
342 acquire = (CRYPTACQUIRECONTEXTW) GetProcAddress(advapi,
343 "CryptAcquireContextW");
344 gen = (CRYPTGENRANDOM) GetProcAddress(advapi,
345 "CryptGenRandom");
346 release = (CRYPTRELEASECONTEXT) GetProcAddress(advapi,
347 "CryptReleaseContext");
348 }
349
350 if (acquire && gen && release)
351 {
352 /* poll the CryptoAPI PRNG */
353 /* The CryptoAPI returns sizeof(buf) bytes of randomness */
354 if (acquire(&hProvider, NULL, NULL, PROV_RSA_FULL,
355 CRYPT_VERIFYCONTEXT))
356 {
357 if (gen(hProvider, sizeof(buf), buf) != 0)
358 {
359 RAND_add(buf, sizeof(buf), 0);
360 good = 1;
361#if 0
362 printf("randomness from PROV_RSA_FULL\n");
363#endif
364 }
365 release(hProvider, 0);
366 }
367
368 /* poll the Pentium PRG with CryptoAPI */
369 if (acquire(&hProvider, 0, INTEL_DEF_PROV, PROV_INTEL_SEC, 0))
370 {
371 if (gen(hProvider, sizeof(buf), buf) != 0)
372 {
373 RAND_add(buf, sizeof(buf), sizeof(buf));
374 good = 1;
375#if 0
376 printf("randomness from PROV_INTEL_SEC\n");
377#endif
378 }
379 release(hProvider, 0);
380 }
381 }
382
383 if (advapi)
384 FreeLibrary(advapi);
385
386 if ((osverinfo.dwPlatformId != VER_PLATFORM_WIN32_NT ||
387 !OPENSSL_isservice()) &&
388 (user = LoadLibrary(TEXT("USER32.DLL"))))
389 {
390 GETCURSORINFO cursor;
391 GETFOREGROUNDWINDOW win;
392 GETQUEUESTATUS queue;
393
394 win = (GETFOREGROUNDWINDOW) GetProcAddress(user, "GetForegroundWindow");
395 cursor = (GETCURSORINFO) GetProcAddress(user, "GetCursorInfo");
396 queue = (GETQUEUESTATUS) GetProcAddress(user, "GetQueueStatus");
397
398 if (win)
399 {
400 /* window handle */
401 HWND h = win();
402 RAND_add(&h, sizeof(h), 0);
403 }
404 if (cursor)
405 {
406 /* unfortunately, its not safe to call GetCursorInfo()
407 * on NT4 even though it exists in SP3 (or SP6) and
408 * higher.
409 */
410 if ( osverinfo.dwPlatformId == VER_PLATFORM_WIN32_NT &&
411 osverinfo.dwMajorVersion < 5)
412 cursor = 0;
413 }
414 if (cursor)
415 {
416 /* cursor position */
417 /* assume 2 bytes of entropy */
418 CURSORINFO ci;
419 ci.cbSize = sizeof(CURSORINFO);
420 if (cursor(&ci))
421 RAND_add(&ci, ci.cbSize, 2);
422 }
423
424 if (queue)
425 {
426 /* message queue status */
427 /* assume 1 byte of entropy */
428 w = queue(QS_ALLEVENTS);
429 RAND_add(&w, sizeof(w), 1);
430 }
431
432 FreeLibrary(user);
433 }
434
435 /* Toolhelp32 snapshot: enumerate processes, threads, modules and heap
436 * http://msdn.microsoft.com/library/psdk/winbase/toolhelp_5pfd.htm
437 * (Win 9x and 2000 only, not available on NT)
438 *
439 * This seeding method was proposed in Peter Gutmann, Software
440 * Generation of Practically Strong Random Numbers,
441 * http://www.usenix.org/publications/library/proceedings/sec98/gutmann.html
442 * revised version at http://www.cryptoengines.com/~peter/06_random.pdf
443 * (The assignment of entropy estimates below is arbitrary, but based
444 * on Peter's analysis the full poll appears to be safe. Additional
445 * interactive seeding is encouraged.)
446 */
447
448 if (kernel)
449 {
450 CREATETOOLHELP32SNAPSHOT snap;
451 CLOSETOOLHELP32SNAPSHOT close_snap;
452 HANDLE handle;
453
454 HEAP32FIRST heap_first;
455 HEAP32NEXT heap_next;
456 HEAP32LIST heaplist_first, heaplist_next;
457 PROCESS32 process_first, process_next;
458 THREAD32 thread_first, thread_next;
459 MODULE32 module_first, module_next;
460
461 HEAPLIST32 hlist;
462 HEAPENTRY32 hentry;
463 PROCESSENTRY32 p;
464 THREADENTRY32 t;
465 MODULEENTRY32 m;
466 DWORD starttime = 0;
467
468 snap = (CREATETOOLHELP32SNAPSHOT)
469 GetProcAddress(kernel, "CreateToolhelp32Snapshot");
470 close_snap = (CLOSETOOLHELP32SNAPSHOT)
471 GetProcAddress(kernel, "CloseToolhelp32Snapshot");
472 heap_first = (HEAP32FIRST) GetProcAddress(kernel, "Heap32First");
473 heap_next = (HEAP32NEXT) GetProcAddress(kernel, "Heap32Next");
474 heaplist_first = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListFirst");
475 heaplist_next = (HEAP32LIST) GetProcAddress(kernel, "Heap32ListNext");
476 process_first = (PROCESS32) GetProcAddress(kernel, "Process32First");
477 process_next = (PROCESS32) GetProcAddress(kernel, "Process32Next");
478 thread_first = (THREAD32) GetProcAddress(kernel, "Thread32First");
479 thread_next = (THREAD32) GetProcAddress(kernel, "Thread32Next");
480 module_first = (MODULE32) GetProcAddress(kernel, "Module32First");
481 module_next = (MODULE32) GetProcAddress(kernel, "Module32Next");
482
483 if (snap && heap_first && heap_next && heaplist_first &&
484 heaplist_next && process_first && process_next &&
485 thread_first && thread_next && module_first &&
486 module_next && (handle = snap(TH32CS_SNAPALL,0))
487 != INVALID_HANDLE_VALUE)
488 {
489 /* heap list and heap walking */
490 /* HEAPLIST32 contains 3 fields that will change with
491 * each entry. Consider each field a source of 1 byte
492 * of entropy.
493 * HEAPENTRY32 contains 5 fields that will change with
494 * each entry. Consider each field a source of 1 byte
495 * of entropy.
496 */
497 ZeroMemory(&hlist, sizeof(HEAPLIST32));
498 hlist.dwSize = sizeof(HEAPLIST32);
499 if (good) starttime = GetTickCount();
500#ifdef _MSC_VER
501 if (heaplist_first(handle, &hlist))
502 {
503 /*
504 following discussion on dev ML, exception on WinCE (or other Win
505 platform) is theoretically of unknown origin; prevent infinite
506 loop here when this theoretical case occurs; otherwise cope with
507 the expected (MSDN documented) exception-throwing behaviour of
508 Heap32Next() on WinCE.
509
510 based on patch in original message by Tanguy Fautré (2009/03/02)
511 Subject: RAND_poll() and CreateToolhelp32Snapshot() stability
512 */
513 int ex_cnt_limit = 42;
514 do
515 {
516 RAND_add(&hlist, hlist.dwSize, 3);
517 __try
518 {
519 ZeroMemory(&hentry, sizeof(HEAPENTRY32));
520 hentry.dwSize = sizeof(HEAPENTRY32);
521 if (heap_first(&hentry,
522 hlist.th32ProcessID,
523 hlist.th32HeapID))
524 {
525 int entrycnt = 80;
526 do
527 RAND_add(&hentry,
528 hentry.dwSize, 5);
529 while (heap_next(&hentry)
530 && (!good || (GetTickCount()-starttime)<MAXDELAY)
531 && --entrycnt > 0);
532 }
533 }
534 __except (EXCEPTION_EXECUTE_HANDLER)
535 {
536 /* ignore access violations when walking the heap list */
537 ex_cnt_limit--;
538 }
539 } while (heaplist_next(handle, &hlist)
540 && (!good || (GetTickCount()-starttime)<MAXDELAY)
541 && ex_cnt_limit > 0);
542 }
543
544#else
545 if (heaplist_first(handle, &hlist))
546 {
547 do
548 {
549 RAND_add(&hlist, hlist.dwSize, 3);
550 hentry.dwSize = sizeof(HEAPENTRY32);
551 if (heap_first(&hentry,
552 hlist.th32ProcessID,
553 hlist.th32HeapID))
554 {
555 int entrycnt = 80;
556 do
557 RAND_add(&hentry,
558 hentry.dwSize, 5);
559 while (heap_next(&hentry)
560 && --entrycnt > 0);
561 }
562 } while (heaplist_next(handle, &hlist)
563 && (!good || (GetTickCount()-starttime)<MAXDELAY));
564 }
565#endif
566
567 /* process walking */
568 /* PROCESSENTRY32 contains 9 fields that will change
569 * with each entry. Consider each field a source of
570 * 1 byte of entropy.
571 */
572 p.dwSize = sizeof(PROCESSENTRY32);
573
574 if (good) starttime = GetTickCount();
575 if (process_first(handle, &p))
576 do
577 RAND_add(&p, p.dwSize, 9);
578 while (process_next(handle, &p) && (!good || (GetTickCount()-starttime)<MAXDELAY));
579
580 /* thread walking */
581 /* THREADENTRY32 contains 6 fields that will change
582 * with each entry. Consider each field a source of
583 * 1 byte of entropy.
584 */
585 t.dwSize = sizeof(THREADENTRY32);
586 if (good) starttime = GetTickCount();
587 if (thread_first(handle, &t))
588 do
589 RAND_add(&t, t.dwSize, 6);
590 while (thread_next(handle, &t) && (!good || (GetTickCount()-starttime)<MAXDELAY));
591
592 /* module walking */
593 /* MODULEENTRY32 contains 9 fields that will change
594 * with each entry. Consider each field a source of
595 * 1 byte of entropy.
596 */
597 m.dwSize = sizeof(MODULEENTRY32);
598 if (good) starttime = GetTickCount();
599 if (module_first(handle, &m))
600 do
601 RAND_add(&m, m.dwSize, 9);
602 while (module_next(handle, &m)
603 && (!good || (GetTickCount()-starttime)<MAXDELAY));
604 if (close_snap)
605 close_snap(handle);
606 else
607 CloseHandle(handle);
608
609 }
610
611 FreeLibrary(kernel);
612 }
613 }
614#endif /* !OPENSSL_SYS_WINCE */
615
616 /* timer data */
617 readtimer();
618
619 /* memory usage statistics */
620 GlobalMemoryStatus(&m);
621 RAND_add(&m, sizeof(m), 1);
622
623 /* process ID */
624 w = GetCurrentProcessId();
625 RAND_add(&w, sizeof(w), 1);
626
627#if 0
628 printf("Exiting RAND_poll\n");
629#endif
630
631 return(1);
632}
633
634int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
635 {
636 double add_entropy=0;
637
638 switch (iMsg)
639 {
640 case WM_KEYDOWN:
641 {
642 static WPARAM key;
643 if (key != wParam)
644 add_entropy = 0.05;
645 key = wParam;
646 }
647 break;
648 case WM_MOUSEMOVE:
649 {
650 static int lastx,lasty,lastdx,lastdy;
651 int x,y,dx,dy;
652
653 x=LOWORD(lParam);
654 y=HIWORD(lParam);
655 dx=lastx-x;
656 dy=lasty-y;
657 if (dx != 0 && dy != 0 && dx-lastdx != 0 && dy-lastdy != 0)
658 add_entropy=.2;
659 lastx=x, lasty=y;
660 lastdx=dx, lastdy=dy;
661 }
662 break;
663 }
664
665 readtimer();
666 RAND_add(&iMsg, sizeof(iMsg), add_entropy);
667 RAND_add(&wParam, sizeof(wParam), 0);
668 RAND_add(&lParam, sizeof(lParam), 0);
669
670 return (RAND_status());
671 }
672
673
674void RAND_screen(void) /* function available for backward compatibility */
675{
676 RAND_poll();
677 readscreen();
678}
679
680
681/* feed timing information to the PRNG */
682static void readtimer(void)
683{
684 DWORD w;
685 LARGE_INTEGER l;
686 static int have_perfc = 1;
687#if defined(_MSC_VER) && defined(_M_X86)
688 static int have_tsc = 1;
689 DWORD cyclecount;
690
691 if (have_tsc) {
692 __try {
693 __asm {
694 _emit 0x0f
695 _emit 0x31
696 mov cyclecount, eax
697 }
698 RAND_add(&cyclecount, sizeof(cyclecount), 1);
699 } __except(EXCEPTION_EXECUTE_HANDLER) {
700 have_tsc = 0;
701 }
702 }
703#else
704# define have_tsc 0
705#endif
706
707 if (have_perfc) {
708 if (QueryPerformanceCounter(&l) == 0)
709 have_perfc = 0;
710 else
711 RAND_add(&l, sizeof(l), 0);
712 }
713
714 if (!have_tsc && !have_perfc) {
715 w = GetTickCount();
716 RAND_add(&w, sizeof(w), 0);
717 }
718}
719
720/* feed screen contents to PRNG */
721/*****************************************************************************
722 *
723 * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
724 *
725 * Code adapted from
726 * <URL:http://support.microsoft.com/default.aspx?scid=kb;[LN];97193>;
727 * the original copyright message is:
728 *
729 * (C) Copyright Microsoft Corp. 1993. All rights reserved.
730 *
731 * You have a royalty-free right to use, modify, reproduce and
732 * distribute the Sample Files (and/or any modified version) in
733 * any way you find useful, provided that you agree that
734 * Microsoft has no warranty obligations or liability for any
735 * Sample Application Files which are modified.
736 */
737
738static void readscreen(void)
739{
740#if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN)
741 HDC hScrDC; /* screen DC */
742 HDC hMemDC; /* memory DC */
743 HBITMAP hBitmap; /* handle for our bitmap */
744 HBITMAP hOldBitmap; /* handle for previous bitmap */
745 BITMAP bm; /* bitmap properties */
746 unsigned int size; /* size of bitmap */
747 char *bmbits; /* contents of bitmap */
748 int w; /* screen width */
749 int h; /* screen height */
750 int y; /* y-coordinate of screen lines to grab */
751 int n = 16; /* number of screen lines to grab at a time */
752
753 if (GetVersion() < 0x80000000 && OPENSSL_isservice()>0)
754 return;
755
756 /* Create a screen DC and a memory DC compatible to screen DC */
757 hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
758 hMemDC = CreateCompatibleDC(hScrDC);
759
760 /* Get screen resolution */
761 w = GetDeviceCaps(hScrDC, HORZRES);
762 h = GetDeviceCaps(hScrDC, VERTRES);
763
764 /* Create a bitmap compatible with the screen DC */
765 hBitmap = CreateCompatibleBitmap(hScrDC, w, n);
766
767 /* Select new bitmap into memory DC */
768 hOldBitmap = SelectObject(hMemDC, hBitmap);
769
770 /* Get bitmap properties */
771 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
772 size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes;
773
774 bmbits = OPENSSL_malloc(size);
775 if (bmbits) {
776 /* Now go through the whole screen, repeatedly grabbing n lines */
777 for (y = 0; y < h-n; y += n)
778 {
779 unsigned char md[MD_DIGEST_LENGTH];
780
781 /* Bitblt screen DC to memory DC */
782 BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY);
783
784 /* Copy bitmap bits from memory DC to bmbits */
785 GetBitmapBits(hBitmap, size, bmbits);
786
787 /* Get the hash of the bitmap */
788 MD(bmbits,size,md);
789
790 /* Seed the random generator with the hash value */
791 RAND_add(md, MD_DIGEST_LENGTH, 0);
792 }
793
794 OPENSSL_free(bmbits);
795 }
796
797 /* Select old bitmap back into memory DC */
798 hBitmap = SelectObject(hMemDC, hOldBitmap);
799
800 /* Clean up */
801 DeleteObject(hBitmap);
802 DeleteDC(hMemDC);
803 DeleteDC(hScrDC);
804#endif /* !OPENSSL_SYS_WINCE */
805}
806
807#endif
diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c
index 030e07f418..bc7d9c5804 100644
--- a/src/lib/libcrypto/rand/randfile.c
+++ b/src/lib/libcrypto/rand/randfile.c
@@ -137,7 +137,7 @@ int RAND_load_file(const char *file, long bytes)
137 in=fopen(file,"rb"); 137 in=fopen(file,"rb");
138#endif 138#endif
139 if (in == NULL) goto err; 139 if (in == NULL) goto err;
140#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO) 140#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPNESSL_NO_POSIX_IO)
141 if (sb.st_mode & (S_IFBLK | S_IFCHR)) { 141 if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
142 /* this file is a device. we don't want read an infinite number 142 /* this file is a device. we don't want read an infinite number
143 * of bytes from a random device, nor do we want to use buffered 143 * of bytes from a random device, nor do we want to use buffered
diff --git a/src/lib/libcrypto/rand/randtest.c b/src/lib/libcrypto/rand/randtest.c
new file mode 100644
index 0000000000..9e92a70b03
--- /dev/null
+++ b/src/lib/libcrypto/rand/randtest.c
@@ -0,0 +1,219 @@
1/* crypto/rand/randtest.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#include <stdio.h>
60#include <stdlib.h>
61#include <openssl/rand.h>
62
63#include "../e_os.h"
64
65/* some FIPS 140-1 random number test */
66/* some simple tests */
67
68int main(int argc,char **argv)
69 {
70 unsigned char buf[2500];
71 int i,j,k,s,sign,nsign,err=0;
72 unsigned long n1;
73 unsigned long n2[16];
74 unsigned long runs[2][34];
75 /*double d; */
76 long d;
77
78 i = RAND_pseudo_bytes(buf,2500);
79 if (i < 0)
80 {
81 printf ("init failed, the rand method is not properly installed\n");
82 err++;
83 goto err;
84 }
85
86 n1=0;
87 for (i=0; i<16; i++) n2[i]=0;
88 for (i=0; i<34; i++) runs[0][i]=runs[1][i]=0;
89
90 /* test 1 and 2 */
91 sign=0;
92 nsign=0;
93 for (i=0; i<2500; i++)
94 {
95 j=buf[i];
96
97 n2[j&0x0f]++;
98 n2[(j>>4)&0x0f]++;
99
100 for (k=0; k<8; k++)
101 {
102 s=(j&0x01);
103 if (s == sign)
104 nsign++;
105 else
106 {
107 if (nsign > 34) nsign=34;
108 if (nsign != 0)
109 {
110 runs[sign][nsign-1]++;
111 if (nsign > 6)
112 runs[sign][5]++;
113 }
114 sign=s;
115 nsign=1;
116 }
117
118 if (s) n1++;
119 j>>=1;
120 }
121 }
122 if (nsign > 34) nsign=34;
123 if (nsign != 0) runs[sign][nsign-1]++;
124
125 /* test 1 */
126 if (!((9654 < n1) && (n1 < 10346)))
127 {
128 printf("test 1 failed, X=%lu\n",n1);
129 err++;
130 }
131 printf("test 1 done\n");
132
133 /* test 2 */
134#ifdef undef
135 d=0;
136 for (i=0; i<16; i++)
137 d+=n2[i]*n2[i];
138 d=d*16.0/5000.0-5000.0;
139 if (!((1.03 < d) && (d < 57.4)))
140 {
141 printf("test 2 failed, X=%.2f\n",d);
142 err++;
143 }
144#endif
145 d=0;
146 for (i=0; i<16; i++)
147 d+=n2[i]*n2[i];
148 d=(d*8)/25-500000;
149 if (!((103 < d) && (d < 5740)))
150 {
151 printf("test 2 failed, X=%ld.%02ld\n",d/100L,d%100L);
152 err++;
153 }
154 printf("test 2 done\n");
155
156 /* test 3 */
157 for (i=0; i<2; i++)
158 {
159 if (!((2267 < runs[i][0]) && (runs[i][0] < 2733)))
160 {
161 printf("test 3 failed, bit=%d run=%d num=%lu\n",
162 i,1,runs[i][0]);
163 err++;
164 }
165 if (!((1079 < runs[i][1]) && (runs[i][1] < 1421)))
166 {
167 printf("test 3 failed, bit=%d run=%d num=%lu\n",
168 i,2,runs[i][1]);
169 err++;
170 }
171 if (!(( 502 < runs[i][2]) && (runs[i][2] < 748)))
172 {
173 printf("test 3 failed, bit=%d run=%d num=%lu\n",
174 i,3,runs[i][2]);
175 err++;
176 }
177 if (!(( 223 < runs[i][3]) && (runs[i][3] < 402)))
178 {
179 printf("test 3 failed, bit=%d run=%d num=%lu\n",
180 i,4,runs[i][3]);
181 err++;
182 }
183 if (!(( 90 < runs[i][4]) && (runs[i][4] < 223)))
184 {
185 printf("test 3 failed, bit=%d run=%d num=%lu\n",
186 i,5,runs[i][4]);
187 err++;
188 }
189 if (!(( 90 < runs[i][5]) && (runs[i][5] < 223)))
190 {
191 printf("test 3 failed, bit=%d run=%d num=%lu\n",
192 i,6,runs[i][5]);
193 err++;
194 }
195 }
196 printf("test 3 done\n");
197
198 /* test 4 */
199 if (runs[0][33] != 0)
200 {
201 printf("test 4 failed, bit=%d run=%d num=%lu\n",
202 0,34,runs[0][33]);
203 err++;
204 }
205 if (runs[1][33] != 0)
206 {
207 printf("test 4 failed, bit=%d run=%d num=%lu\n",
208 1,34,runs[1][33]);
209 err++;
210 }
211 printf("test 4 done\n");
212 err:
213 err=((err)?1:0);
214#ifdef OPENSSL_SYS_NETWARE
215 if (err) printf("ERROR: %d\n", err);
216#endif
217 EXIT(err);
218 return(err);
219 }