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/Makefile187
-rw-r--r--src/lib/libcrypto/rand/md_rand.c584
-rw-r--r--src/lib/libcrypto/rand/rand.h167
-rw-r--r--src/lib/libcrypto/rand/rand_egd.c303
-rw-r--r--src/lib/libcrypto/rand/rand_eng.c152
-rw-r--r--src/lib/libcrypto/rand/rand_err.c114
-rw-r--r--src/lib/libcrypto/rand/rand_lcl.h169
-rw-r--r--src/lib/libcrypto/rand/rand_lib.c245
-rw-r--r--src/lib/libcrypto/rand/rand_os2.c147
-rw-r--r--src/lib/libcrypto/rand/rand_unix.c324
-rw-r--r--src/lib/libcrypto/rand/rand_vms.c136
-rw-r--r--src/lib/libcrypto/rand/rand_win.c758
-rw-r--r--src/lib/libcrypto/rand/randfile.c313
-rw-r--r--src/lib/libcrypto/rand/randtest.c219
14 files changed, 3818 insertions, 0 deletions
diff --git a/src/lib/libcrypto/rand/Makefile b/src/lib/libcrypto/rand/Makefile
new file mode 100644
index 0000000000..30794305cb
--- /dev/null
+++ b/src/lib/libcrypto/rand/Makefile
@@ -0,0 +1,187 @@
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_eng.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_eng.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 $(ARX) $(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/fips.h
83md_rand.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
84md_rand.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
85md_rand.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
86md_rand.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
87md_rand.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
88md_rand.o: ../../include/openssl/symhacks.h 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_eng.o: ../../e_os.h ../../include/openssl/asn1.h
94rand_eng.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
95rand_eng.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
96rand_eng.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
97rand_eng.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
98rand_eng.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
99rand_eng.o: ../../include/openssl/err.h ../../include/openssl/evp.h
100rand_eng.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
101rand_eng.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
102rand_eng.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
103rand_eng.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
104rand_eng.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
105rand_eng.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
106rand_eng.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
107rand_eng.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
108rand_eng.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
109rand_eng.o: ../cryptlib.h rand_eng.c rand_lcl.h
110rand_err.o: ../../include/openssl/bio.h ../../include/openssl/crypto.h
111rand_err.o: ../../include/openssl/e_os2.h ../../include/openssl/err.h
112rand_err.o: ../../include/openssl/lhash.h ../../include/openssl/opensslconf.h
113rand_err.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
114rand_err.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
115rand_err.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
116rand_err.o: rand_err.c
117rand_lib.o: ../../e_os.h ../../include/openssl/asn1.h
118rand_lib.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
119rand_lib.o: ../../include/openssl/crypto.h ../../include/openssl/des.h
120rand_lib.o: ../../include/openssl/des_old.h ../../include/openssl/e_os2.h
121rand_lib.o: ../../include/openssl/ec.h ../../include/openssl/ecdh.h
122rand_lib.o: ../../include/openssl/ecdsa.h ../../include/openssl/engine.h
123rand_lib.o: ../../include/openssl/err.h ../../include/openssl/evp.h
124rand_lib.o: ../../include/openssl/fips.h ../../include/openssl/fips_rand.h
125rand_lib.o: ../../include/openssl/lhash.h ../../include/openssl/obj_mac.h
126rand_lib.o: ../../include/openssl/objects.h ../../include/openssl/opensslconf.h
127rand_lib.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
128rand_lib.o: ../../include/openssl/pkcs7.h ../../include/openssl/rand.h
129rand_lib.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
130rand_lib.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
131rand_lib.o: ../../include/openssl/ui.h ../../include/openssl/ui_compat.h
132rand_lib.o: ../../include/openssl/x509.h ../../include/openssl/x509_vfy.h
133rand_lib.o: ../cryptlib.h rand_lcl.h rand_lib.c
134rand_nw.o: ../../e_os.h ../../include/openssl/asn1.h
135rand_nw.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
136rand_nw.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
137rand_nw.o: ../../include/openssl/err.h ../../include/openssl/evp.h
138rand_nw.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
139rand_nw.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
140rand_nw.o: ../../include/openssl/opensslconf.h ../../include/openssl/opensslv.h
141rand_nw.o: ../../include/openssl/ossl_typ.h ../../include/openssl/rand.h
142rand_nw.o: ../../include/openssl/safestack.h ../../include/openssl/sha.h
143rand_nw.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
144rand_nw.o: ../cryptlib.h rand_lcl.h rand_nw.c
145rand_os2.o: ../../e_os.h ../../include/openssl/asn1.h
146rand_os2.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
147rand_os2.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
148rand_os2.o: ../../include/openssl/err.h ../../include/openssl/evp.h
149rand_os2.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
150rand_os2.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
151rand_os2.o: ../../include/openssl/opensslconf.h
152rand_os2.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
153rand_os2.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
154rand_os2.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
155rand_os2.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
156rand_os2.o: rand_os2.c
157rand_unix.o: ../../e_os.h ../../include/openssl/asn1.h
158rand_unix.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
159rand_unix.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
160rand_unix.o: ../../include/openssl/err.h ../../include/openssl/evp.h
161rand_unix.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
162rand_unix.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
163rand_unix.o: ../../include/openssl/opensslconf.h
164rand_unix.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
165rand_unix.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
166rand_unix.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
167rand_unix.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
168rand_unix.o: rand_unix.c
169rand_win.o: ../../e_os.h ../../include/openssl/asn1.h
170rand_win.o: ../../include/openssl/bio.h ../../include/openssl/buffer.h
171rand_win.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
172rand_win.o: ../../include/openssl/err.h ../../include/openssl/evp.h
173rand_win.o: ../../include/openssl/fips.h ../../include/openssl/lhash.h
174rand_win.o: ../../include/openssl/obj_mac.h ../../include/openssl/objects.h
175rand_win.o: ../../include/openssl/opensslconf.h
176rand_win.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
177rand_win.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
178rand_win.o: ../../include/openssl/sha.h ../../include/openssl/stack.h
179rand_win.o: ../../include/openssl/symhacks.h ../cryptlib.h rand_lcl.h
180rand_win.o: rand_win.c
181randfile.o: ../../e_os.h ../../include/openssl/buffer.h
182randfile.o: ../../include/openssl/crypto.h ../../include/openssl/e_os2.h
183randfile.o: ../../include/openssl/opensslconf.h
184randfile.o: ../../include/openssl/opensslv.h ../../include/openssl/ossl_typ.h
185randfile.o: ../../include/openssl/rand.h ../../include/openssl/safestack.h
186randfile.o: ../../include/openssl/stack.h ../../include/openssl/symhacks.h
187randfile.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..0f8dd3e00f
--- /dev/null
+++ b/src/lib/libcrypto/rand/md_rand.c
@@ -0,0 +1,584 @@
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#ifdef OPENSSL_FIPS
130#include <openssl/fips.h>
131#endif
132
133
134#ifdef BN_DEBUG
135# define PREDICT
136#endif
137
138/* #define PREDICT 1 */
139
140#define STATE_SIZE 1023
141static int state_num=0,state_index=0;
142static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
143static unsigned char md[MD_DIGEST_LENGTH];
144static long md_count[2]={0,0};
145static double entropy=0;
146static int initialized=0;
147
148static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
149 * holds CRYPTO_LOCK_RAND
150 * (to prevent double locking) */
151/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
152static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */
153
154
155#ifdef PREDICT
156int rand_predictable=0;
157#endif
158
159const char RAND_version[]="RAND" OPENSSL_VERSION_PTEXT;
160
161static void ssleay_rand_cleanup(void);
162static void ssleay_rand_seed(const void *buf, int num);
163static void ssleay_rand_add(const void *buf, int num, double add_entropy);
164static int ssleay_rand_bytes(unsigned char *buf, int num);
165static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num);
166static int ssleay_rand_status(void);
167
168RAND_METHOD rand_ssleay_meth={
169 ssleay_rand_seed,
170 ssleay_rand_bytes,
171 ssleay_rand_cleanup,
172 ssleay_rand_add,
173 ssleay_rand_pseudo_bytes,
174 ssleay_rand_status
175 };
176
177RAND_METHOD *RAND_SSLeay(void)
178 {
179 return(&rand_ssleay_meth);
180 }
181
182static void ssleay_rand_cleanup(void)
183 {
184 OPENSSL_cleanse(state,sizeof(state));
185 state_num=0;
186 state_index=0;
187 OPENSSL_cleanse(md,MD_DIGEST_LENGTH);
188 md_count[0]=0;
189 md_count[1]=0;
190 entropy=0;
191 initialized=0;
192 }
193
194static void ssleay_rand_add(const void *buf, int num, double add)
195 {
196 int i,j,k,st_idx;
197 long md_c[2];
198 unsigned char local_md[MD_DIGEST_LENGTH];
199 EVP_MD_CTX m;
200 int do_not_lock;
201
202 /*
203 * (Based on the rand(3) manpage)
204 *
205 * The input is chopped up into units of 20 bytes (or less for
206 * the last block). Each of these blocks is run through the hash
207 * function as follows: The data passed to the hash function
208 * is the current 'md', the same number of bytes from the 'state'
209 * (the location determined by in incremented looping index) as
210 * the current 'block', the new key data 'block', and 'count'
211 * (which is incremented after each use).
212 * The result of this is kept in 'md' and also xored into the
213 * 'state' at the same locations that were used as input into the
214 * hash function.
215 */
216
217 /* check if we already have the lock */
218 if (crypto_lock_rand)
219 {
220 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
221 do_not_lock = (locking_thread == CRYPTO_thread_id());
222 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
223 }
224 else
225 do_not_lock = 0;
226
227 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
228 st_idx=state_index;
229
230 /* use our own copies of the counters so that even
231 * if a concurrent thread seeds with exactly the
232 * same data and uses the same subarray there's _some_
233 * difference */
234 md_c[0] = md_count[0];
235 md_c[1] = md_count[1];
236
237 memcpy(local_md, md, sizeof md);
238
239 /* state_index <= state_num <= STATE_SIZE */
240 state_index += num;
241 if (state_index >= STATE_SIZE)
242 {
243 state_index%=STATE_SIZE;
244 state_num=STATE_SIZE;
245 }
246 else if (state_num < STATE_SIZE)
247 {
248 if (state_index > state_num)
249 state_num=state_index;
250 }
251 /* state_index <= state_num <= STATE_SIZE */
252
253 /* state[st_idx], ..., state[(st_idx + num - 1) % STATE_SIZE]
254 * are what we will use now, but other threads may use them
255 * as well */
256
257 md_count[1] += (num / MD_DIGEST_LENGTH) + (num % MD_DIGEST_LENGTH > 0);
258
259 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
260
261 EVP_MD_CTX_init(&m);
262 for (i=0; i<num; i+=MD_DIGEST_LENGTH)
263 {
264 j=(num-i);
265 j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
266
267 MD_Init(&m);
268 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
269 k=(st_idx+j)-STATE_SIZE;
270 if (k > 0)
271 {
272 MD_Update(&m,&(state[st_idx]),j-k);
273 MD_Update(&m,&(state[0]),k);
274 }
275 else
276 MD_Update(&m,&(state[st_idx]),j);
277
278 MD_Update(&m,buf,j);
279 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
280 MD_Final(&m,local_md);
281 md_c[1]++;
282
283 buf=(const char *)buf + j;
284
285 for (k=0; k<j; k++)
286 {
287 /* Parallel threads may interfere with this,
288 * but always each byte of the new state is
289 * the XOR of some previous value of its
290 * and local_md (itermediate values may be lost).
291 * Alway using locking could hurt performance more
292 * than necessary given that conflicts occur only
293 * when the total seeding is longer than the random
294 * state. */
295 state[st_idx++]^=local_md[k];
296 if (st_idx >= STATE_SIZE)
297 st_idx=0;
298 }
299 }
300 EVP_MD_CTX_cleanup(&m);
301
302 if (!do_not_lock) CRYPTO_w_lock(CRYPTO_LOCK_RAND);
303 /* Don't just copy back local_md into md -- this could mean that
304 * other thread's seeding remains without effect (except for
305 * the incremented counter). By XORing it we keep at least as
306 * much entropy as fits into md. */
307 for (k = 0; k < (int)sizeof(md); k++)
308 {
309 md[k] ^= local_md[k];
310 }
311 if (entropy < ENTROPY_NEEDED) /* stop counting when we have enough */
312 entropy += add;
313 if (!do_not_lock) CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
314
315#if !defined(OPENSSL_THREADS) && !defined(OPENSSL_SYS_WIN32)
316 assert(md_c[1] == md_count[1]);
317#endif
318 }
319
320static void ssleay_rand_seed(const void *buf, int num)
321 {
322 ssleay_rand_add(buf, num, (double)num);
323 }
324
325static int ssleay_rand_bytes(unsigned char *buf, int num)
326 {
327 static volatile int stirred_pool = 0;
328 int i,j,k,st_num,st_idx;
329 int num_ceil;
330 int ok;
331 long md_c[2];
332 unsigned char local_md[MD_DIGEST_LENGTH];
333 EVP_MD_CTX m;
334#ifndef GETPID_IS_MEANINGLESS
335 pid_t curr_pid = getpid();
336#endif
337 int do_stir_pool = 0;
338
339#ifdef OPENSSL_FIPS
340 if(FIPS_mode())
341 {
342 FIPSerr(FIPS_F_SSLEAY_RAND_BYTES,FIPS_R_NON_FIPS_METHOD);
343 return 0;
344 }
345#endif
346
347#ifdef PREDICT
348 if (rand_predictable)
349 {
350 static unsigned char val=0;
351
352 for (i=0; i<num; i++)
353 buf[i]=val++;
354 return(1);
355 }
356#endif
357
358 if (num <= 0)
359 return 1;
360
361 EVP_MD_CTX_init(&m);
362 /* round upwards to multiple of MD_DIGEST_LENGTH/2 */
363 num_ceil = (1 + (num-1)/(MD_DIGEST_LENGTH/2)) * (MD_DIGEST_LENGTH/2);
364
365 /*
366 * (Based on the rand(3) manpage:)
367 *
368 * For each group of 10 bytes (or less), we do the following:
369 *
370 * Input into the hash function the local 'md' (which is initialized from
371 * the global 'md' before any bytes are generated), the bytes that are to
372 * be overwritten by the random bytes, and bytes from the 'state'
373 * (incrementing looping index). From this digest output (which is kept
374 * in 'md'), the top (up to) 10 bytes are returned to the caller and the
375 * bottom 10 bytes are xored into the 'state'.
376 *
377 * Finally, after we have finished 'num' random bytes for the
378 * caller, 'count' (which is incremented) and the local and global 'md'
379 * are fed into the hash function and the results are kept in the
380 * global 'md'.
381 */
382
383 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
384
385 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
386 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
387 locking_thread = CRYPTO_thread_id();
388 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
389 crypto_lock_rand = 1;
390
391 if (!initialized)
392 {
393 RAND_poll();
394 initialized = 1;
395 }
396
397 if (!stirred_pool)
398 do_stir_pool = 1;
399
400 ok = (entropy >= ENTROPY_NEEDED);
401 if (!ok)
402 {
403 /* If the PRNG state is not yet unpredictable, then seeing
404 * the PRNG output may help attackers to determine the new
405 * state; thus we have to decrease the entropy estimate.
406 * Once we've had enough initial seeding we don't bother to
407 * adjust the entropy count, though, because we're not ambitious
408 * to provide *information-theoretic* randomness.
409 *
410 * NOTE: This approach fails if the program forks before
411 * we have enough entropy. Entropy should be collected
412 * in a separate input pool and be transferred to the
413 * output pool only when the entropy limit has been reached.
414 */
415 entropy -= num;
416 if (entropy < 0)
417 entropy = 0;
418 }
419
420 if (do_stir_pool)
421 {
422 /* In the output function only half of 'md' remains secret,
423 * so we better make sure that the required entropy gets
424 * 'evenly distributed' through 'state', our randomness pool.
425 * The input function (ssleay_rand_add) chains all of 'md',
426 * which makes it more suitable for this purpose.
427 */
428
429 int n = STATE_SIZE; /* so that the complete pool gets accessed */
430 while (n > 0)
431 {
432#if MD_DIGEST_LENGTH > 20
433# error "Please adjust DUMMY_SEED."
434#endif
435#define DUMMY_SEED "...................." /* at least MD_DIGEST_LENGTH */
436 /* Note that the seed does not matter, it's just that
437 * ssleay_rand_add expects to have something to hash. */
438 ssleay_rand_add(DUMMY_SEED, MD_DIGEST_LENGTH, 0.0);
439 n -= MD_DIGEST_LENGTH;
440 }
441 if (ok)
442 stirred_pool = 1;
443 }
444
445 st_idx=state_index;
446 st_num=state_num;
447 md_c[0] = md_count[0];
448 md_c[1] = md_count[1];
449 memcpy(local_md, md, sizeof md);
450
451 state_index+=num_ceil;
452 if (state_index > state_num)
453 state_index %= state_num;
454
455 /* state[st_idx], ..., state[(st_idx + num_ceil - 1) % st_num]
456 * are now ours (but other threads may use them too) */
457
458 md_count[0] += 1;
459
460 /* before unlocking, we must clear 'crypto_lock_rand' */
461 crypto_lock_rand = 0;
462 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
463
464 while (num > 0)
465 {
466 /* num_ceil -= MD_DIGEST_LENGTH/2 */
467 j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
468 num-=j;
469 MD_Init(&m);
470#ifndef GETPID_IS_MEANINGLESS
471 if (curr_pid) /* just in the first iteration to save time */
472 {
473 MD_Update(&m,(unsigned char*)&curr_pid,sizeof curr_pid);
474 curr_pid = 0;
475 }
476#endif
477 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
478 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
479#ifndef PURIFY
480 MD_Update(&m,buf,j); /* purify complains */
481#endif
482 k=(st_idx+MD_DIGEST_LENGTH/2)-st_num;
483 if (k > 0)
484 {
485 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2-k);
486 MD_Update(&m,&(state[0]),k);
487 }
488 else
489 MD_Update(&m,&(state[st_idx]),MD_DIGEST_LENGTH/2);
490 MD_Final(&m,local_md);
491
492 for (i=0; i<MD_DIGEST_LENGTH/2; i++)
493 {
494 state[st_idx++]^=local_md[i]; /* may compete with other threads */
495 if (st_idx >= st_num)
496 st_idx=0;
497 if (i < j)
498 *(buf++)=local_md[i+MD_DIGEST_LENGTH/2];
499 }
500 }
501
502 MD_Init(&m);
503 MD_Update(&m,(unsigned char *)&(md_c[0]),sizeof(md_c));
504 MD_Update(&m,local_md,MD_DIGEST_LENGTH);
505 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
506 MD_Update(&m,md,MD_DIGEST_LENGTH);
507 MD_Final(&m,md);
508 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
509
510 EVP_MD_CTX_cleanup(&m);
511 if (ok)
512 return(1);
513 else
514 {
515 RANDerr(RAND_F_SSLEAY_RAND_BYTES,RAND_R_PRNG_NOT_SEEDED);
516 ERR_add_error_data(1, "You need to read the OpenSSL FAQ, "
517 "http://www.openssl.org/support/faq.html");
518 return(0);
519 }
520 }
521
522/* pseudo-random bytes that are guaranteed to be unique but not
523 unpredictable */
524static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
525 {
526 int ret;
527 unsigned long err;
528
529 ret = RAND_bytes(buf, num);
530 if (ret == 0)
531 {
532 err = ERR_peek_error();
533 if (ERR_GET_LIB(err) == ERR_LIB_RAND &&
534 ERR_GET_REASON(err) == RAND_R_PRNG_NOT_SEEDED)
535 ERR_clear_error();
536 }
537 return (ret);
538 }
539
540static int ssleay_rand_status(void)
541 {
542 int ret;
543 int do_not_lock;
544
545 /* check if we already have the lock
546 * (could happen if a RAND_poll() implementation calls RAND_status()) */
547 if (crypto_lock_rand)
548 {
549 CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
550 do_not_lock = (locking_thread == CRYPTO_thread_id());
551 CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
552 }
553 else
554 do_not_lock = 0;
555
556 if (!do_not_lock)
557 {
558 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
559
560 /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
561 CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
562 locking_thread = CRYPTO_thread_id();
563 CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
564 crypto_lock_rand = 1;
565 }
566
567 if (!initialized)
568 {
569 RAND_poll();
570 initialized = 1;
571 }
572
573 ret = entropy >= ENTROPY_NEEDED;
574
575 if (!do_not_lock)
576 {
577 /* before unlocking, we must clear 'crypto_lock_rand' */
578 crypto_lock_rand = 0;
579
580 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
581 }
582
583 return ret;
584 }
diff --git a/src/lib/libcrypto/rand/rand.h b/src/lib/libcrypto/rand/rand.h
new file mode 100644
index 0000000000..ea89153cba
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand.h
@@ -0,0 +1,167 @@
1/* crypto/rand/rand.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#ifndef HEADER_RAND_H
60#define HEADER_RAND_H
61
62#include <stdlib.h>
63#include <openssl/ossl_typ.h>
64#include <openssl/e_os2.h>
65
66#if defined(OPENSSL_SYS_WINDOWS)
67#include <windows.h>
68#endif
69
70#ifdef __cplusplus
71extern "C" {
72#endif
73
74#if defined(OPENSSL_FIPS)
75#define FIPS_RAND_SIZE_T int
76#endif
77
78/* Already defined in ossl_typ.h */
79/* typedef struct rand_meth_st RAND_METHOD; */
80
81struct rand_meth_st
82 {
83 void (*seed)(const void *buf, int num);
84 int (*bytes)(unsigned char *buf, int num);
85 void (*cleanup)(void);
86 void (*add)(const void *buf, int num, double entropy);
87 int (*pseudorand)(unsigned char *buf, int num);
88 int (*status)(void);
89 };
90
91#ifdef BN_DEBUG
92extern int rand_predictable;
93#endif
94
95int RAND_set_rand_method(const RAND_METHOD *meth);
96const RAND_METHOD *RAND_get_rand_method(void);
97#ifndef OPENSSL_NO_ENGINE
98int RAND_set_rand_engine(ENGINE *engine);
99#endif
100RAND_METHOD *RAND_SSLeay(void);
101void RAND_cleanup(void );
102int RAND_bytes(unsigned char *buf,int num);
103int RAND_pseudo_bytes(unsigned char *buf,int num);
104void RAND_seed(const void *buf,int num);
105void RAND_add(const void *buf,int num,double entropy);
106int RAND_load_file(const char *file,long max_bytes);
107int RAND_write_file(const char *file);
108const char *RAND_file_name(char *file,size_t num);
109int RAND_status(void);
110int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes);
111int RAND_egd(const char *path);
112int RAND_egd_bytes(const char *path,int bytes);
113int RAND_poll(void);
114#ifndef OPENSSL_NO_ENGINE
115#ifdef OPENSSL_FIPS
116void int_RAND_init_engine_callbacks(void);
117void int_RAND_set_callbacks(
118 int (*set_rand_func)(const RAND_METHOD *meth,
119 const RAND_METHOD **pmeth),
120 const RAND_METHOD *(*get_rand_func)(const RAND_METHOD **pmeth));
121#endif
122#endif
123
124#if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
125
126void RAND_screen(void);
127int RAND_event(UINT, WPARAM, LPARAM);
128
129#endif
130
131/* BEGIN ERROR CODES */
132/* The following lines are auto generated by the script mkerr.pl. Any changes
133 * made after this point may be overwritten when the script is next run.
134 */
135void ERR_load_RAND_strings(void);
136
137/* Error codes for the RAND functions. */
138
139/* Function codes. */
140#define RAND_F_ENG_RAND_GET_RAND_METHOD 108
141#define RAND_F_FIPS_RAND 103
142#define RAND_F_FIPS_RAND_BYTES 102
143#define RAND_F_FIPS_RAND_GET_RAND_METHOD 109
144#define RAND_F_FIPS_RAND_SET_DT 106
145#define RAND_F_FIPS_SET_DT 104
146#define RAND_F_FIPS_SET_PRNG_SEED 107
147#define RAND_F_FIPS_SET_TEST_MODE 105
148#define RAND_F_RAND_GET_RAND_METHOD 101
149#define RAND_F_SSLEAY_RAND_BYTES 100
150
151/* Reason codes. */
152#define RAND_R_NON_FIPS_METHOD 105
153#define RAND_R_NOT_IN_TEST_MODE 106
154#define RAND_R_NO_KEY_SET 107
155#define RAND_R_PRNG_ASKING_FOR_TOO_MUCH 101
156#define RAND_R_PRNG_ERROR 108
157#define RAND_R_PRNG_KEYED 109
158#define RAND_R_PRNG_NOT_REKEYED 102
159#define RAND_R_PRNG_NOT_RESEEDED 103
160#define RAND_R_PRNG_NOT_SEEDED 100
161#define RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY 110
162#define RAND_R_PRNG_STUCK 104
163
164#ifdef __cplusplus
165}
166#endif
167#endif
diff --git a/src/lib/libcrypto/rand/rand_egd.c b/src/lib/libcrypto/rand/rand_egd.c
new file mode 100644
index 0000000000..50bce6caba
--- /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)
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_eng.c b/src/lib/libcrypto/rand/rand_eng.c
new file mode 100644
index 0000000000..1669cef43c
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_eng.c
@@ -0,0 +1,152 @@
1/* crypto/rand/rand_lib.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 <time.h>
61#include "cryptlib.h"
62#include "rand_lcl.h"
63#include <openssl/rand.h>
64#ifdef OPENSSL_FIPS
65#include <openssl/fips.h>
66#include <openssl/fips_rand.h>
67#endif
68
69#ifndef OPENSSL_NO_ENGINE
70#include <openssl/engine.h>
71#endif
72
73#if defined(OPENSSL_FIPS) && !defined(OPENSSL_NO_ENGINE)
74
75/* non-NULL if default_RAND_meth is ENGINE-provided */
76static ENGINE *funct_ref =NULL;
77
78int eng_RAND_set_rand_method(const RAND_METHOD *meth, const RAND_METHOD **pmeth)
79 {
80 if(funct_ref)
81 {
82 ENGINE_finish(funct_ref);
83 funct_ref = NULL;
84 }
85 *pmeth = meth;
86 return 1;
87 }
88
89const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth)
90 {
91 if (!*pmeth)
92 {
93 ENGINE *e = ENGINE_get_default_RAND();
94 if(e)
95 {
96 *pmeth = ENGINE_get_RAND(e);
97 if(!*pmeth)
98 {
99 ENGINE_finish(e);
100 e = NULL;
101 }
102 }
103 if(e)
104 funct_ref = e;
105 else
106 if(FIPS_mode())
107 *pmeth=FIPS_rand_method();
108 else
109 *pmeth = RAND_SSLeay();
110 }
111
112 if(FIPS_mode()
113 && *pmeth != FIPS_rand_check())
114 {
115 RANDerr(RAND_F_ENG_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
116 return 0;
117 }
118
119 return *pmeth;
120 }
121
122int RAND_set_rand_engine(ENGINE *engine)
123 {
124 const RAND_METHOD *tmp_meth = NULL;
125 if(engine)
126 {
127 if(!ENGINE_init(engine))
128 return 0;
129 tmp_meth = ENGINE_get_RAND(engine);
130 if(!tmp_meth)
131 {
132 ENGINE_finish(engine);
133 return 0;
134 }
135 }
136 /* This function releases any prior ENGINE so call it first */
137 RAND_set_rand_method(tmp_meth);
138 funct_ref = engine;
139 return 1;
140 }
141
142void int_RAND_init_engine_callbacks(void)
143 {
144 static int done = 0;
145 if (done)
146 return;
147 int_RAND_set_callbacks(eng_RAND_set_rand_method,
148 eng_RAND_get_rand_method);
149 done = 1;
150 }
151
152#endif
diff --git a/src/lib/libcrypto/rand/rand_err.c b/src/lib/libcrypto/rand/rand_err.c
new file mode 100644
index 0000000000..829fb44d77
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_err.c
@@ -0,0 +1,114 @@
1/* crypto/rand/rand_err.c */
2/* ====================================================================
3 * Copyright (c) 1999-2007 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/* NOTE: this file was auto generated by the mkerr.pl script: any changes
57 * made to it will be overwritten when the script next updates this file,
58 * only reason strings will be preserved.
59 */
60
61#include <stdio.h>
62#include <openssl/err.h>
63#include <openssl/rand.h>
64
65/* BEGIN ERROR CODES */
66#ifndef OPENSSL_NO_ERR
67
68#define ERR_FUNC(func) ERR_PACK(ERR_LIB_RAND,func,0)
69#define ERR_REASON(reason) ERR_PACK(ERR_LIB_RAND,0,reason)
70
71static ERR_STRING_DATA RAND_str_functs[]=
72 {
73{ERR_FUNC(RAND_F_ENG_RAND_GET_RAND_METHOD), "ENG_RAND_GET_RAND_METHOD"},
74{ERR_FUNC(RAND_F_FIPS_RAND), "FIPS_RAND"},
75{ERR_FUNC(RAND_F_FIPS_RAND_BYTES), "FIPS_RAND_BYTES"},
76{ERR_FUNC(RAND_F_FIPS_RAND_GET_RAND_METHOD), "FIPS_RAND_GET_RAND_METHOD"},
77{ERR_FUNC(RAND_F_FIPS_RAND_SET_DT), "FIPS_RAND_SET_DT"},
78{ERR_FUNC(RAND_F_FIPS_SET_DT), "FIPS_SET_DT"},
79{ERR_FUNC(RAND_F_FIPS_SET_PRNG_SEED), "FIPS_SET_PRNG_SEED"},
80{ERR_FUNC(RAND_F_FIPS_SET_TEST_MODE), "FIPS_SET_TEST_MODE"},
81{ERR_FUNC(RAND_F_RAND_GET_RAND_METHOD), "RAND_get_rand_method"},
82{ERR_FUNC(RAND_F_SSLEAY_RAND_BYTES), "SSLEAY_RAND_BYTES"},
83{0,NULL}
84 };
85
86static ERR_STRING_DATA RAND_str_reasons[]=
87 {
88{ERR_REASON(RAND_R_NON_FIPS_METHOD) ,"non fips method"},
89{ERR_REASON(RAND_R_NOT_IN_TEST_MODE) ,"not in test mode"},
90{ERR_REASON(RAND_R_NO_KEY_SET) ,"no key set"},
91{ERR_REASON(RAND_R_PRNG_ASKING_FOR_TOO_MUCH),"prng asking for too much"},
92{ERR_REASON(RAND_R_PRNG_ERROR) ,"prng error"},
93{ERR_REASON(RAND_R_PRNG_KEYED) ,"prng keyed"},
94{ERR_REASON(RAND_R_PRNG_NOT_REKEYED) ,"prng not rekeyed"},
95{ERR_REASON(RAND_R_PRNG_NOT_RESEEDED) ,"prng not reseeded"},
96{ERR_REASON(RAND_R_PRNG_NOT_SEEDED) ,"PRNG not seeded"},
97{ERR_REASON(RAND_R_PRNG_SEED_MUST_NOT_MATCH_KEY),"prng seed must not match key"},
98{ERR_REASON(RAND_R_PRNG_STUCK) ,"prng stuck"},
99{0,NULL}
100 };
101
102#endif
103
104void ERR_load_RAND_strings(void)
105 {
106#ifndef OPENSSL_NO_ERR
107
108 if (ERR_func_error_string(RAND_str_functs[0].error) == NULL)
109 {
110 ERR_load_strings(0,RAND_str_functs);
111 ERR_load_strings(0,RAND_str_reasons);
112 }
113#endif
114 }
diff --git a/src/lib/libcrypto/rand/rand_lcl.h b/src/lib/libcrypto/rand/rand_lcl.h
new file mode 100644
index 0000000000..18cc9b1e4a
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_lcl.h
@@ -0,0 +1,169 @@
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#ifndef OPENSSL_NO_ENGINE
158void int_RAND_set_callbacks(
159 int (*set_rand_func)(const RAND_METHOD *meth,
160 const RAND_METHOD **pmeth),
161 const RAND_METHOD *(*get_rand_func)
162 (const RAND_METHOD **pmeth));
163int eng_RAND_set_rand_method(const RAND_METHOD *meth,
164 const RAND_METHOD **pmeth);
165const RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth);
166#endif
167
168
169#endif
diff --git a/src/lib/libcrypto/rand/rand_lib.c b/src/lib/libcrypto/rand/rand_lib.c
new file mode 100644
index 0000000000..da6b4e0e86
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_lib.c
@@ -0,0 +1,245 @@
1/* crypto/rand/rand_lib.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 <time.h>
61#include "cryptlib.h"
62#include <openssl/rand.h>
63#include "rand_lcl.h"
64#ifdef OPENSSL_FIPS
65#include <openssl/fips.h>
66#include <openssl/fips_rand.h>
67#endif
68
69#ifndef OPENSSL_NO_ENGINE
70#include <openssl/engine.h>
71#endif
72
73static const RAND_METHOD *default_RAND_meth = NULL;
74
75#ifdef OPENSSL_FIPS
76
77static int fips_RAND_set_rand_method(const RAND_METHOD *meth,
78 const RAND_METHOD **pmeth)
79 {
80 *pmeth = meth;
81 return 1;
82 }
83
84static const RAND_METHOD *fips_RAND_get_rand_method(const RAND_METHOD **pmeth)
85 {
86 if (!*pmeth)
87 {
88 if(FIPS_mode())
89 *pmeth=FIPS_rand_method();
90 else
91 *pmeth = RAND_SSLeay();
92 }
93
94 if(FIPS_mode()
95 && *pmeth != FIPS_rand_check())
96 {
97 RANDerr(RAND_F_FIPS_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
98 return 0;
99 }
100
101 return *pmeth;
102 }
103
104static int (*RAND_set_rand_method_func)(const RAND_METHOD *meth,
105 const RAND_METHOD **pmeth)
106 = fips_RAND_set_rand_method;
107static const RAND_METHOD *(*RAND_get_rand_method_func)
108 (const RAND_METHOD **pmeth)
109 = fips_RAND_get_rand_method;
110
111#ifndef OPENSSL_NO_ENGINE
112void int_RAND_set_callbacks(
113 int (*set_rand_func)(const RAND_METHOD *meth,
114 const RAND_METHOD **pmeth),
115 const RAND_METHOD *(*get_rand_func)
116 (const RAND_METHOD **pmeth))
117 {
118 RAND_set_rand_method_func = set_rand_func;
119 RAND_get_rand_method_func = get_rand_func;
120 }
121#endif
122
123int RAND_set_rand_method(const RAND_METHOD *meth)
124 {
125 return RAND_set_rand_method_func(meth, &default_RAND_meth);
126 }
127
128const RAND_METHOD *RAND_get_rand_method(void)
129 {
130 return RAND_get_rand_method_func(&default_RAND_meth);
131 }
132
133#else
134
135#ifndef OPENSSL_NO_ENGINE
136/* non-NULL if default_RAND_meth is ENGINE-provided */
137static ENGINE *funct_ref =NULL;
138#endif
139
140int RAND_set_rand_method(const RAND_METHOD *meth)
141 {
142#ifndef OPENSSL_NO_ENGINE
143 if(funct_ref)
144 {
145 ENGINE_finish(funct_ref);
146 funct_ref = NULL;
147 }
148#endif
149 default_RAND_meth = meth;
150 return 1;
151 }
152
153const RAND_METHOD *RAND_get_rand_method(void)
154 {
155 if (!default_RAND_meth)
156 {
157#ifndef OPENSSL_NO_ENGINE
158 ENGINE *e = ENGINE_get_default_RAND();
159 if(e)
160 {
161 default_RAND_meth = ENGINE_get_RAND(e);
162 if(!default_RAND_meth)
163 {
164 ENGINE_finish(e);
165 e = NULL;
166 }
167 }
168 if(e)
169 funct_ref = e;
170 else
171#endif
172 default_RAND_meth = RAND_SSLeay();
173 }
174 return default_RAND_meth;
175 }
176
177#ifndef OPENSSL_NO_ENGINE
178int RAND_set_rand_engine(ENGINE *engine)
179 {
180 const RAND_METHOD *tmp_meth = NULL;
181 if(engine)
182 {
183 if(!ENGINE_init(engine))
184 return 0;
185 tmp_meth = ENGINE_get_RAND(engine);
186 if(!tmp_meth)
187 {
188 ENGINE_finish(engine);
189 return 0;
190 }
191 }
192 /* This function releases any prior ENGINE so call it first */
193 RAND_set_rand_method(tmp_meth);
194 funct_ref = engine;
195 return 1;
196 }
197#endif
198
199#endif
200
201void RAND_cleanup(void)
202 {
203 const RAND_METHOD *meth = RAND_get_rand_method();
204 if (meth && meth->cleanup)
205 meth->cleanup();
206 RAND_set_rand_method(NULL);
207 }
208
209void RAND_seed(const void *buf, int num)
210 {
211 const RAND_METHOD *meth = RAND_get_rand_method();
212 if (meth && meth->seed)
213 meth->seed(buf,num);
214 }
215
216void RAND_add(const void *buf, int num, double entropy)
217 {
218 const RAND_METHOD *meth = RAND_get_rand_method();
219 if (meth && meth->add)
220 meth->add(buf,num,entropy);
221 }
222
223int RAND_bytes(unsigned char *buf, int num)
224 {
225 const RAND_METHOD *meth = RAND_get_rand_method();
226 if (meth && meth->bytes)
227 return meth->bytes(buf,num);
228 return(-1);
229 }
230
231int RAND_pseudo_bytes(unsigned char *buf, int num)
232 {
233 const RAND_METHOD *meth = RAND_get_rand_method();
234 if (meth && meth->pseudorand)
235 return meth->pseudorand(buf,num);
236 return(-1);
237 }
238
239int RAND_status(void)
240 {
241 const RAND_METHOD *meth = RAND_get_rand_method();
242 if (meth && meth->status)
243 return meth->status();
244 return 0;
245 }
diff --git a/src/lib/libcrypto/rand/rand_os2.c b/src/lib/libcrypto/rand/rand_os2.c
new file mode 100644
index 0000000000..c3e36d4e5e
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_os2.c
@@ -0,0 +1,147 @@
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
81APIRET APIENTRY(*DosPerfSysCall) (ULONG ulCommand, ULONG ulParm1, ULONG ulParm2, ULONG ulParm3) = NULL;
82APIRET APIENTRY(*DosQuerySysState) (ULONG func, ULONG arg1, ULONG pid, ULONG _res_, PVOID buf, ULONG bufsz) = NULL;
83HMODULE hDoscalls = 0;
84
85int RAND_poll(void)
86{
87 char failed_module[20];
88 QWORD qwTime;
89 ULONG SysVars[QSV_FOREGROUND_PROCESS];
90
91 if (hDoscalls == 0) {
92 ULONG rc = DosLoadModule(failed_module, sizeof(failed_module), "DOSCALLS", &hDoscalls);
93
94 if (rc == 0) {
95 rc = DosQueryProcAddr(hDoscalls, 976, NULL, (PFN *)&DosPerfSysCall);
96
97 if (rc)
98 DosPerfSysCall = NULL;
99
100 rc = DosQueryProcAddr(hDoscalls, 368, NULL, (PFN *)&DosQuerySysState);
101
102 if (rc)
103 DosQuerySysState = NULL;
104 }
105 }
106
107 /* Sample the hi-res timer, runs at around 1.1 MHz */
108 DosTmrQueryTime(&qwTime);
109 RAND_add(&qwTime, sizeof(qwTime), 2);
110
111 /* Sample a bunch of system variables, includes various process & memory statistics */
112 DosQuerySysInfo(1, QSV_FOREGROUND_PROCESS, SysVars, sizeof(SysVars));
113 RAND_add(SysVars, sizeof(SysVars), 4);
114
115 /* If available, sample CPU registers that count at CPU MHz
116 * Only fairly new CPUs (PPro & K6 onwards) & OS/2 versions support this
117 */
118 if (DosPerfSysCall) {
119 CPUUTIL util;
120
121 if (DosPerfSysCall(CMD_KI_RDCNT, (ULONG)&util, 0, 0) == 0) {
122 RAND_add(&util, sizeof(util), 10);
123 }
124 else {
125 DosPerfSysCall = NULL;
126 }
127 }
128
129 /* DosQuerySysState() gives us a huge quantity of process, thread, memory & handle stats */
130 if (DosQuerySysState) {
131 char *buffer = OPENSSL_malloc(256 * 1024);
132
133 if (DosQuerySysState(0x1F, 0, 0, 0, buffer, 256 * 1024) == 0) {
134 /* First 4 bytes in buffer is a pointer to the thread count
135 * there should be at least 1 byte of entropy per thread
136 */
137 RAND_add(buffer, 256 * 1024, **(ULONG **)buffer);
138 }
139
140 OPENSSL_free(buffer);
141 return 1;
142 }
143
144 return 0;
145}
146
147#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..964d25833c
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_unix.c
@@ -0,0 +1,324 @@
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#ifdef __OpenBSD__
137int RAND_poll(void)
138{
139 unsigned char buf[ENTROPY_NEEDED];
140
141 arc4random_buf(buf, sizeof(buf));
142 RAND_add(buf, sizeof(buf), sizeof(buf));
143 memset(buf, 0, sizeof(buf));
144
145 return 1;
146}
147#else /* !defined(__OpenBSD__) */
148int RAND_poll(void)
149{
150 unsigned long l;
151 pid_t curr_pid = getpid();
152#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
153 unsigned char tmpbuf[ENTROPY_NEEDED];
154 int n = 0;
155#endif
156#ifdef DEVRANDOM
157 static const char *randomfiles[] = { DEVRANDOM };
158 struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])];
159 int fd;
160 size_t i;
161#endif
162#ifdef DEVRANDOM_EGD
163 static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
164 const char **egdsocket = NULL;
165#endif
166
167#ifdef DEVRANDOM
168 memset(randomstats,0,sizeof(randomstats));
169 /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD
170 * have this. Use /dev/urandom if you can as /dev/random may block
171 * if it runs out of random entries. */
172
173 for (i=0; i<sizeof(randomfiles)/sizeof(randomfiles[0]) && n < ENTROPY_NEEDED; i++)
174 {
175 if ((fd = open(randomfiles[i], O_RDONLY
176#ifdef O_NONBLOCK
177 |O_NONBLOCK
178#endif
179#ifdef O_BINARY
180 |O_BINARY
181#endif
182#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it
183 our controlling tty */
184 |O_NOCTTY
185#endif
186 )) >= 0)
187 {
188 int usec = 10*1000; /* spend 10ms on each file */
189 int r;
190 size_t j;
191 struct stat *st=&randomstats[i];
192
193 /* Avoid using same input... Used to be O_NOFOLLOW
194 * above, but it's not universally appropriate... */
195 if (fstat(fd,st) != 0) { close(fd); continue; }
196 for (j=0;j<i;j++)
197 {
198 if (randomstats[j].st_ino==st->st_ino &&
199 randomstats[j].st_dev==st->st_dev)
200 break;
201 }
202 if (j<i) { close(fd); continue; }
203
204 do
205 {
206 int try_read = 0;
207
208#if defined(OPENSSL_SYS_LINUX)
209 /* use poll() */
210 struct pollfd pset;
211
212 pset.fd = fd;
213 pset.events = POLLIN;
214 pset.revents = 0;
215
216 if (poll(&pset, 1, usec / 1000) < 0)
217 usec = 0;
218 else
219 try_read = (pset.revents & POLLIN) != 0;
220
221#else
222 /* use select() */
223 fd_set fset;
224 struct timeval t;
225
226 t.tv_sec = 0;
227 t.tv_usec = usec;
228
229 if (FD_SETSIZE > 0 && fd >= FD_SETSIZE)
230 {
231 /* can't use select, so just try to read once anyway */
232 try_read = 1;
233 }
234 else
235 {
236 FD_ZERO(&fset);
237 FD_SET(fd, &fset);
238
239 if (select(fd+1,&fset,NULL,NULL,&t) >= 0)
240 {
241 usec = t.tv_usec;
242 if (FD_ISSET(fd, &fset))
243 try_read = 1;
244 }
245 else
246 usec = 0;
247 }
248#endif
249
250 if (try_read)
251 {
252 r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n);
253 if (r > 0)
254 n += r;
255 }
256 else
257 r = -1;
258
259 /* Some Unixen will update t in select(), some
260 won't. For those who won't, or if we
261 didn't use select() in the first place,
262 give up here, otherwise, we will do
263 this once again for the remaining
264 time. */
265 if (usec == 10*1000)
266 usec = 0;
267 }
268 while ((r > 0 ||
269 (errno == EINTR || errno == EAGAIN)) && usec != 0 && n < ENTROPY_NEEDED);
270
271 close(fd);
272 }
273 }
274#endif /* defined(DEVRANDOM) */
275
276#ifdef DEVRANDOM_EGD
277 /* Use an EGD socket to read entropy from an EGD or PRNGD entropy
278 * collecting daemon. */
279
280 for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++)
281 {
282 int r;
283
284 r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n,
285 ENTROPY_NEEDED-n);
286 if (r > 0)
287 n += r;
288 }
289#endif /* defined(DEVRANDOM_EGD) */
290
291#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
292 if (n > 0)
293 {
294 RAND_add(tmpbuf,sizeof tmpbuf,(double)n);
295 OPENSSL_cleanse(tmpbuf,n);
296 }
297#endif
298
299 /* put in some default random data, we need more than just this */
300 l=curr_pid;
301 RAND_add(&l,sizeof(l),0.0);
302 l=getuid();
303 RAND_add(&l,sizeof(l),0.0);
304
305 l=time(NULL);
306 RAND_add(&l,sizeof(l),0.0);
307
308#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
309 return 1;
310#else
311 return 0;
312#endif
313}
314
315#endif /* defined(__OpenBSD__) */
316#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)) */
317
318
319#if defined(OPENSSL_SYS_VXWORKS)
320int RAND_poll(void)
321 {
322 return 0;
323 }
324#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..1267a3acae
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_vms.c
@@ -0,0 +1,136 @@
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
72static struct items_data_st
73 {
74 short length, code; /* length is amount of bytes */
75 } items_data[] =
76 { { 4, JPI$_BUFIO },
77 { 4, JPI$_CPUTIM },
78 { 4, JPI$_DIRIO },
79 { 8, JPI$_LOGINTIM },
80 { 4, JPI$_PAGEFLTS },
81 { 4, JPI$_PID },
82 { 4, JPI$_WSSIZE },
83 { 0, 0 }
84 };
85
86int RAND_poll(void)
87 {
88 long pid, iosb[2];
89 int status = 0;
90 struct
91 {
92 short length, code;
93 long *buffer;
94 int *retlen;
95 } item[32], *pitem;
96 unsigned char data_buffer[256];
97 short total_length = 0;
98 struct items_data_st *pitems_data;
99
100 pitems_data = items_data;
101 pitem = item;
102
103 /* Setup */
104 while (pitems_data->length
105 && (total_length + pitems_data->length <= 256))
106 {
107 pitem->length = pitems_data->length;
108 pitem->code = pitems_data->code;
109 pitem->buffer = (long *)&data_buffer[total_length];
110 pitem->retlen = 0;
111 total_length += pitems_data->length;
112 pitems_data++;
113 pitem++;
114 }
115 pitem->length = pitem->code = 0;
116
117 /*
118 * Scan through all the processes in the system and add entropy with
119 * results from the processes that were possible to look at.
120 * However, view the information as only half trustable.
121 */
122 pid = -1; /* search context */
123 while ((status = sys$getjpiw(0, &pid, 0, item, iosb, 0, 0))
124 != SS$_NOMOREPROC)
125 {
126 if (status == SS$_NORMAL)
127 {
128 RAND_add(data_buffer, total_length, total_length/2);
129 }
130 }
131 sys$gettim(iosb);
132 RAND_add((unsigned char *)iosb, sizeof(iosb), sizeof(iosb)/2);
133 return 1;
134}
135
136#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..00dbe4232c
--- /dev/null
+++ b/src/lib/libcrypto/rand/rand_win.c
@@ -0,0 +1,758 @@
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 stoptime = 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 hlist.dwSize = sizeof(HEAPLIST32);
498 if (good) stoptime = GetTickCount() + MAXDELAY;
499 if (heaplist_first(handle, &hlist))
500 do
501 {
502 RAND_add(&hlist, hlist.dwSize, 3);
503 hentry.dwSize = sizeof(HEAPENTRY32);
504 if (heap_first(&hentry,
505 hlist.th32ProcessID,
506 hlist.th32HeapID))
507 {
508 int entrycnt = 80;
509 do
510 RAND_add(&hentry,
511 hentry.dwSize, 5);
512 while (heap_next(&hentry)
513 && --entrycnt > 0);
514 }
515 } while (heaplist_next(handle,
516 &hlist) && GetTickCount() < stoptime);
517
518 /* process walking */
519 /* PROCESSENTRY32 contains 9 fields that will change
520 * with each entry. Consider each field a source of
521 * 1 byte of entropy.
522 */
523 p.dwSize = sizeof(PROCESSENTRY32);
524
525 if (good) stoptime = GetTickCount() + MAXDELAY;
526 if (process_first(handle, &p))
527 do
528 RAND_add(&p, p.dwSize, 9);
529 while (process_next(handle, &p) && GetTickCount() < stoptime);
530
531 /* thread walking */
532 /* THREADENTRY32 contains 6 fields that will change
533 * with each entry. Consider each field a source of
534 * 1 byte of entropy.
535 */
536 t.dwSize = sizeof(THREADENTRY32);
537 if (good) stoptime = GetTickCount() + MAXDELAY;
538 if (thread_first(handle, &t))
539 do
540 RAND_add(&t, t.dwSize, 6);
541 while (thread_next(handle, &t) && GetTickCount() < stoptime);
542
543 /* module walking */
544 /* MODULEENTRY32 contains 9 fields that will change
545 * with each entry. Consider each field a source of
546 * 1 byte of entropy.
547 */
548 m.dwSize = sizeof(MODULEENTRY32);
549 if (good) stoptime = GetTickCount() + MAXDELAY;
550 if (module_first(handle, &m))
551 do
552 RAND_add(&m, m.dwSize, 9);
553 while (module_next(handle, &m)
554 && (GetTickCount() < stoptime));
555 if (close_snap)
556 close_snap(handle);
557 else
558 CloseHandle(handle);
559
560 }
561
562 FreeLibrary(kernel);
563 }
564 }
565#endif /* !OPENSSL_SYS_WINCE */
566
567 /* timer data */
568 readtimer();
569
570 /* memory usage statistics */
571 GlobalMemoryStatus(&m);
572 RAND_add(&m, sizeof(m), 1);
573
574 /* process ID */
575 w = GetCurrentProcessId();
576 RAND_add(&w, sizeof(w), 1);
577
578#if 0
579 printf("Exiting RAND_poll\n");
580#endif
581
582 return(1);
583}
584
585int RAND_event(UINT iMsg, WPARAM wParam, LPARAM lParam)
586 {
587 double add_entropy=0;
588
589 switch (iMsg)
590 {
591 case WM_KEYDOWN:
592 {
593 static WPARAM key;
594 if (key != wParam)
595 add_entropy = 0.05;
596 key = wParam;
597 }
598 break;
599 case WM_MOUSEMOVE:
600 {
601 static int lastx,lasty,lastdx,lastdy;
602 int x,y,dx,dy;
603
604 x=LOWORD(lParam);
605 y=HIWORD(lParam);
606 dx=lastx-x;
607 dy=lasty-y;
608 if (dx != 0 && dy != 0 && dx-lastdx != 0 && dy-lastdy != 0)
609 add_entropy=.2;
610 lastx=x, lasty=y;
611 lastdx=dx, lastdy=dy;
612 }
613 break;
614 }
615
616 readtimer();
617 RAND_add(&iMsg, sizeof(iMsg), add_entropy);
618 RAND_add(&wParam, sizeof(wParam), 0);
619 RAND_add(&lParam, sizeof(lParam), 0);
620
621 return (RAND_status());
622 }
623
624
625void RAND_screen(void) /* function available for backward compatibility */
626{
627 RAND_poll();
628 readscreen();
629}
630
631
632/* feed timing information to the PRNG */
633static void readtimer(void)
634{
635 DWORD w;
636 LARGE_INTEGER l;
637 static int have_perfc = 1;
638#if defined(_MSC_VER) && defined(_M_X86)
639 static int have_tsc = 1;
640 DWORD cyclecount;
641
642 if (have_tsc) {
643 __try {
644 __asm {
645 _emit 0x0f
646 _emit 0x31
647 mov cyclecount, eax
648 }
649 RAND_add(&cyclecount, sizeof(cyclecount), 1);
650 } __except(EXCEPTION_EXECUTE_HANDLER) {
651 have_tsc = 0;
652 }
653 }
654#else
655# define have_tsc 0
656#endif
657
658 if (have_perfc) {
659 if (QueryPerformanceCounter(&l) == 0)
660 have_perfc = 0;
661 else
662 RAND_add(&l, sizeof(l), 0);
663 }
664
665 if (!have_tsc && !have_perfc) {
666 w = GetTickCount();
667 RAND_add(&w, sizeof(w), 0);
668 }
669}
670
671/* feed screen contents to PRNG */
672/*****************************************************************************
673 *
674 * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
675 *
676 * Code adapted from
677 * <URL:http://support.microsoft.com/default.aspx?scid=kb;[LN];97193>;
678 * the original copyright message is:
679 *
680 * (C) Copyright Microsoft Corp. 1993. All rights reserved.
681 *
682 * You have a royalty-free right to use, modify, reproduce and
683 * distribute the Sample Files (and/or any modified version) in
684 * any way you find useful, provided that you agree that
685 * Microsoft has no warranty obligations or liability for any
686 * Sample Application Files which are modified.
687 */
688
689static void readscreen(void)
690{
691#if !defined(OPENSSL_SYS_WINCE) && !defined(OPENSSL_SYS_WIN32_CYGWIN)
692 HDC hScrDC; /* screen DC */
693 HDC hMemDC; /* memory DC */
694 HBITMAP hBitmap; /* handle for our bitmap */
695 HBITMAP hOldBitmap; /* handle for previous bitmap */
696 BITMAP bm; /* bitmap properties */
697 unsigned int size; /* size of bitmap */
698 char *bmbits; /* contents of bitmap */
699 int w; /* screen width */
700 int h; /* screen height */
701 int y; /* y-coordinate of screen lines to grab */
702 int n = 16; /* number of screen lines to grab at a time */
703
704 if (GetVersion() >= 0x80000000 || !OPENSSL_isservice())
705 return;
706
707 /* Create a screen DC and a memory DC compatible to screen DC */
708 hScrDC = CreateDC(TEXT("DISPLAY"), NULL, NULL, NULL);
709 hMemDC = CreateCompatibleDC(hScrDC);
710
711 /* Get screen resolution */
712 w = GetDeviceCaps(hScrDC, HORZRES);
713 h = GetDeviceCaps(hScrDC, VERTRES);
714
715 /* Create a bitmap compatible with the screen DC */
716 hBitmap = CreateCompatibleBitmap(hScrDC, w, n);
717
718 /* Select new bitmap into memory DC */
719 hOldBitmap = SelectObject(hMemDC, hBitmap);
720
721 /* Get bitmap properties */
722 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
723 size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes;
724
725 bmbits = OPENSSL_malloc(size);
726 if (bmbits) {
727 /* Now go through the whole screen, repeatedly grabbing n lines */
728 for (y = 0; y < h-n; y += n)
729 {
730 unsigned char md[MD_DIGEST_LENGTH];
731
732 /* Bitblt screen DC to memory DC */
733 BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY);
734
735 /* Copy bitmap bits from memory DC to bmbits */
736 GetBitmapBits(hBitmap, size, bmbits);
737
738 /* Get the hash of the bitmap */
739 MD(bmbits,size,md);
740
741 /* Seed the random generator with the hash value */
742 RAND_add(md, MD_DIGEST_LENGTH, 0);
743 }
744
745 OPENSSL_free(bmbits);
746 }
747
748 /* Select old bitmap back into memory DC */
749 hBitmap = SelectObject(hMemDC, hOldBitmap);
750
751 /* Clean up */
752 DeleteObject(hBitmap);
753 DeleteDC(hMemDC);
754 DeleteDC(hScrDC);
755#endif /* !OPENSSL_SYS_WINCE */
756}
757
758#endif
diff --git a/src/lib/libcrypto/rand/randfile.c b/src/lib/libcrypto/rand/randfile.c
new file mode 100644
index 0000000000..f63fbc1731
--- /dev/null
+++ b/src/lib/libcrypto/rand/randfile.c
@@ -0,0 +1,313 @@
1/* crypto/rand/randfile.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/* We need to define this to get macros like S_IFBLK and S_IFCHR */
60#define _XOPEN_SOURCE 500
61
62#include <errno.h>
63#include <stdio.h>
64#include <stdlib.h>
65#include <string.h>
66
67#include "e_os.h"
68#include <openssl/crypto.h>
69#include <openssl/rand.h>
70#include <openssl/buffer.h>
71
72#ifdef OPENSSL_SYS_VMS
73#include <unixio.h>
74#endif
75#ifndef NO_SYS_TYPES_H
76# include <sys/types.h>
77#endif
78#ifdef MAC_OS_pre_X
79# include <stat.h>
80#else
81# include <sys/stat.h>
82#endif
83
84#ifdef _WIN32
85#define stat _stat
86#define chmod _chmod
87#define open _open
88#define fdopen _fdopen
89#endif
90
91#undef BUFSIZE
92#define BUFSIZE 1024
93#define RAND_DATA 1024
94
95#ifdef OPENSSL_SYS_VMS
96/* This declaration is a nasty hack to get around vms' extension to fopen
97 * for passing in sharing options being disabled by our /STANDARD=ANSI89 */
98static FILE *(*const vms_fopen)(const char *, const char *, ...) =
99 (FILE *(*)(const char *, const char *, ...))fopen;
100#define VMS_OPEN_ATTRS "shr=get,put,upd,del","ctx=bin,stm","rfm=stm","rat=none","mrs=0"
101#endif
102
103/* #define RFILE ".rnd" - defined in ../../e_os.h */
104
105/* Note that these functions are intended for seed files only.
106 * Entropy devices and EGD sockets are handled in rand_unix.c */
107
108int RAND_load_file(const char *file, long bytes)
109 {
110 /* If bytes >= 0, read up to 'bytes' bytes.
111 * if bytes == -1, read complete file. */
112
113 MS_STATIC unsigned char buf[BUFSIZE];
114 struct stat sb;
115 int i,ret=0,n;
116 FILE *in;
117
118 if (file == NULL) return(0);
119
120 if (stat(file,&sb) < 0) return(0);
121 RAND_add(&sb,sizeof(sb),0.0);
122 if (bytes == 0) return(ret);
123
124#ifdef OPENSSL_SYS_VMS
125 in=vms_fopen(file,"rb",VMS_OPEN_ATTRS);
126#else
127 in=fopen(file,"rb");
128#endif
129 if (in == NULL) goto err;
130#if defined(S_IFBLK) && defined(S_IFCHR)
131 if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
132 /* this file is a device. we don't want read an infinite number
133 * of bytes from a random device, nor do we want to use buffered
134 * I/O because we will waste system entropy.
135 */
136 bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
137 setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
138 }
139#endif
140 for (;;)
141 {
142 if (bytes > 0)
143 n = (bytes < BUFSIZE)?(int)bytes:BUFSIZE;
144 else
145 n = BUFSIZE;
146 i=fread(buf,1,n,in);
147 if (i <= 0) break;
148#ifdef PURIFY
149 RAND_add(buf,i,(double)i);
150#else
151 /* even if n != i, use the full array */
152 RAND_add(buf,n,(double)i);
153#endif
154 ret+=i;
155 if (bytes > 0)
156 {
157 bytes-=n;
158 if (bytes <= 0) break;
159 }
160 }
161 fclose(in);
162 OPENSSL_cleanse(buf,BUFSIZE);
163err:
164 return(ret);
165 }
166
167int RAND_write_file(const char *file)
168 {
169 unsigned char buf[BUFSIZE];
170 int i,ret=0,rand_err=0;
171 FILE *out = NULL;
172 int n;
173 struct stat sb;
174
175 i=stat(file,&sb);
176 if (i != -1) {
177#if defined(S_IFBLK) && defined(S_IFCHR)
178 if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
179 /* this file is a device. we don't write back to it.
180 * we "succeed" on the assumption this is some sort
181 * of random device. Otherwise attempting to write to
182 * and chmod the device causes problems.
183 */
184 return(1);
185 }
186#endif
187 }
188
189#if defined(O_CREAT) && !defined(OPENSSL_SYS_WIN32) && !defined(OPENSSL_SYS_VMS)
190 {
191 /* For some reason Win32 can't write to files created this way */
192
193 /* chmod(..., 0600) is too late to protect the file,
194 * permissions should be restrictive from the start */
195 int fd = open(file, O_CREAT, 0600);
196 if (fd != -1)
197 out = fdopen(fd, "wb");
198 }
199#endif
200
201#ifdef OPENSSL_SYS_VMS
202 /* VMS NOTE: Prior versions of this routine created a _new_
203 * version of the rand file for each call into this routine, then
204 * deleted all existing versions named ;-1, and finally renamed
205 * the current version as ';1'. Under concurrent usage, this
206 * resulted in an RMS race condition in rename() which could
207 * orphan files (see vms message help for RMS$_REENT). With the
208 * fopen() calls below, openssl/VMS now shares the top-level
209 * version of the rand file. Note that there may still be
210 * conditions where the top-level rand file is locked. If so, this
211 * code will then create a new version of the rand file. Without
212 * the delete and rename code, this can result in ascending file
213 * versions that stop at version 32767, and this routine will then
214 * return an error. The remedy for this is to recode the calling
215 * application to avoid concurrent use of the rand file, or
216 * synchronize usage at the application level. Also consider
217 * whether or not you NEED a persistent rand file in a concurrent
218 * use situation.
219 */
220
221 out = vms_fopen(file,"rb+",VMS_OPEN_ATTRS);
222 if (out == NULL)
223 out = vms_fopen(file,"wb",VMS_OPEN_ATTRS);
224#else
225 if (out == NULL)
226 out = fopen(file,"wb");
227#endif
228 if (out == NULL) goto err;
229
230#ifndef NO_CHMOD
231 chmod(file,0600);
232#endif
233 n=RAND_DATA;
234 for (;;)
235 {
236 i=(n > BUFSIZE)?BUFSIZE:n;
237 n-=BUFSIZE;
238 if (RAND_bytes(buf,i) <= 0)
239 rand_err=1;
240 i=fwrite(buf,1,i,out);
241 if (i <= 0)
242 {
243 ret=0;
244 break;
245 }
246 ret+=i;
247 if (n <= 0) break;
248 }
249
250 fclose(out);
251 OPENSSL_cleanse(buf,BUFSIZE);
252err:
253 return (rand_err ? -1 : ret);
254 }
255
256const char *RAND_file_name(char *buf, size_t size)
257 {
258 char *s=NULL;
259 int ok = 0;
260#ifdef __OpenBSD__
261 struct stat sb;
262#endif
263
264 if (issetugid() == 0)
265 s=getenv("RANDFILE");
266 if (s != NULL && *s && strlen(s) + 1 < size)
267 {
268 if (BUF_strlcpy(buf,s,size) >= size)
269 return NULL;
270 }
271 else
272 {
273 if (issetugid() == 0)
274 s=getenv("HOME");
275#ifdef DEFAULT_HOME
276 if (s == NULL)
277 {
278 s = DEFAULT_HOME;
279 }
280#endif
281 if (s && *s && strlen(s)+strlen(RFILE)+2 < size)
282 {
283 BUF_strlcpy(buf,s,size);
284#ifndef OPENSSL_SYS_VMS
285 BUF_strlcat(buf,"/",size);
286#endif
287 BUF_strlcat(buf,RFILE,size);
288 ok = 1;
289 }
290 else
291 buf[0] = '\0'; /* no file name */
292 }
293
294#ifdef __OpenBSD__
295 /* given that all random loads just fail if the file can't be
296 * seen on a stat, we stat the file we're returning, if it
297 * fails, use /dev/arandom instead. this allows the user to
298 * use their own source for good random data, but defaults
299 * to something hopefully decent if that isn't available.
300 */
301
302 if (!ok)
303 if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
304 return(NULL);
305 }
306 if (stat(buf,&sb) == -1)
307 if (BUF_strlcpy(buf,"/dev/arandom",size) >= size) {
308 return(NULL);
309 }
310
311#endif
312 return(buf);
313 }
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 }