summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/rand/md_rand.c
diff options
context:
space:
mode:
authorryker <>1998-10-05 20:13:15 +0000
committerryker <>1998-10-05 20:13:15 +0000
commit536c76cbb863bab152f19842ab88772c01e922c7 (patch)
treedfecec371a097b73d605aae665887946d9982219 /src/lib/libcrypto/rand/md_rand.c
downloadopenbsd-536c76cbb863bab152f19842ab88772c01e922c7.tar.gz
openbsd-536c76cbb863bab152f19842ab88772c01e922c7.tar.bz2
openbsd-536c76cbb863bab152f19842ab88772c01e922c7.zip
Import of SSLeay-0.9.0b with RSA and IDEA stubbed + OpenBSD build
functionality for shared libs. Note that routines such as sslv2_init and friends that use RSA will not work due to lack of RSA in this library. Needs documentation and help from ports for easy upgrade to full functionality where legally possible.
Diffstat (limited to 'src/lib/libcrypto/rand/md_rand.c')
-rw-r--r--src/lib/libcrypto/rand/md_rand.c405
1 files changed, 405 insertions, 0 deletions
diff --git a/src/lib/libcrypto/rand/md_rand.c b/src/lib/libcrypto/rand/md_rand.c
new file mode 100644
index 0000000000..f44b36a8b9
--- /dev/null
+++ b/src/lib/libcrypto/rand/md_rand.c
@@ -0,0 +1,405 @@
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#include <stdio.h>
60#include "cryptlib.h"
61#include <sys/types.h>
62#include <time.h>
63
64#if !defined(USE_MD5_RAND) && !defined(USE_SHA1_RAND) && !defined(USE_MDC2_RAND) && !defined(USE_MD2_RAND)
65#ifndef NO_MD5
66#define USE_MD5_RAND
67#elif !defined(NO_SHA1)
68#define USE_SHA1_RAND
69#elif !defined(NO_MDC2)
70#define USE_MDC2_RAND
71#elif !defined(NO_MD2)
72#define USE_MD2_RAND
73#else
74We need a message digest of some type
75#endif
76#endif
77
78/* Changed how the state buffer used. I now attempt to 'wrap' such
79 * that I don't run over the same locations the next time go through
80 * the 1023 bytes - many thanks to
81 * Robert J. LeBlanc <rjl@renaissoft.com> for his comments
82 */
83
84#if defined(USE_MD5_RAND)
85#include "md5.h"
86#define MD_DIGEST_LENGTH MD5_DIGEST_LENGTH
87#define MD_CTX MD5_CTX
88#define MD_Init(a) MD5_Init(a)
89#define MD_Update(a,b,c) MD5_Update(a,b,c)
90#define MD_Final(a,b) MD5_Final(a,b)
91#elif defined(USE_SHA1_RAND)
92#include "sha.h"
93#define MD_DIGEST_LENGTH SHA_DIGEST_LENGTH
94#define MD_CTX SHA_CTX
95#define MD_Init(a) SHA1_Init(a)
96#define MD_Update(a,b,c) SHA1_Update(a,b,c)
97#define MD_Final(a,b) SHA1_Final(a,b)
98#elif defined(USE_MDC2_RAND)
99#include "mdc2.h"
100#define MD_DIGEST_LENGTH MDC2_DIGEST_LENGTH
101#define MD_CTX MDC2_CTX
102#define MD_Init(a) MDC2_Init(a)
103#define MD_Update(a,b,c) MDC2_Update(a,b,c)
104#define MD_Final(a,b) MDC2_Final(a,b)
105#elif defined(USE_MD2_RAND)
106#include "md2.h"
107#define MD_DIGEST_LENGTH MD2_DIGEST_LENGTH
108#define MD_CTX MD2_CTX
109#define MD_Init(a) MD2_Init(a)
110#define MD_Update(a,b,c) MD2_Update(a,b,c)
111#define MD_Final(a,b) MD2_Final(a,b)
112#endif
113
114#include "rand.h"
115
116/*#define NORAND 1 */
117/*#define PREDICT 1 */
118
119#define STATE_SIZE 1023
120static int state_num=0,state_index=0;
121static unsigned char state[STATE_SIZE+MD_DIGEST_LENGTH];
122static unsigned char md[MD_DIGEST_LENGTH];
123static int md_count=0;
124
125char *RAND_version="RAND part of SSLeay 0.9.0b 29-Jun-1998";
126
127void RAND_cleanup()
128 {
129 memset(state,0,sizeof(state));
130 state_num=0;
131 state_index=0;
132 memset(md,0,MD_DIGEST_LENGTH);
133 md_count=0;
134 }
135
136void RAND_seed(buf,num)
137unsigned char *buf;
138int num;
139 {
140 int i,j,k,st_idx,st_num;
141 MD_CTX m;
142
143#ifdef NORAND
144 return;
145#endif
146
147 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
148 st_idx=state_index;
149 st_num=state_num;
150
151 state_index=(state_index+num);
152 if (state_index >= STATE_SIZE)
153 {
154 state_index%=STATE_SIZE;
155 state_num=STATE_SIZE;
156 }
157 else if (state_num < STATE_SIZE)
158 {
159 if (state_index > state_num)
160 state_num=state_index;
161 }
162 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
163
164 for (i=0; i<num; i+=MD_DIGEST_LENGTH)
165 {
166 j=(num-i);
167 j=(j > MD_DIGEST_LENGTH)?MD_DIGEST_LENGTH:j;
168
169 MD_Init(&m);
170 MD_Update(&m,md,MD_DIGEST_LENGTH);
171 k=(st_idx+j)-STATE_SIZE;
172 if (k > 0)
173 {
174 MD_Update(&m,&(state[st_idx]),j-k);
175 MD_Update(&m,&(state[0]),k);
176 }
177 else
178 MD_Update(&m,&(state[st_idx]),j);
179
180 MD_Update(&m,buf,j);
181 MD_Final(md,&m);
182
183 buf+=j;
184
185 for (k=0; k<j; k++)
186 {
187 state[st_idx++]^=md[k];
188 if (st_idx >= STATE_SIZE)
189 {
190 st_idx=0;
191 st_num=STATE_SIZE;
192 }
193 }
194 }
195 memset((char *)&m,0,sizeof(m));
196 }
197
198void RAND_bytes(buf,num)
199unsigned char *buf;
200int num;
201 {
202 int i,j,k,st_num,st_idx;
203 MD_CTX m;
204 static int init=1;
205 unsigned long l;
206#ifdef DEVRANDOM
207 FILE *fh;
208#endif
209
210#ifdef PREDICT
211 {
212 static unsigned char val=0;
213
214 for (i=0; i<num; i++)
215 buf[i]=val++;
216 return;
217 }
218#endif
219
220 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
221
222 if (init)
223 {
224 init=0;
225 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
226 /* put in some default random data, we need more than
227 * just this */
228 RAND_seed((unsigned char *)&m,sizeof(m));
229#ifndef MSDOS
230 l=getpid();
231 RAND_seed((unsigned char *)&l,sizeof(l));
232 l=getuid();
233 RAND_seed((unsigned char *)&l,sizeof(l));
234#endif
235 l=time(NULL);
236 RAND_seed((unsigned char *)&l,sizeof(l));
237
238/* #ifdef DEVRANDOM */
239 /*
240 * Use a random entropy pool device.
241 * Linux 1.3.x and FreeBSD-Current has
242 * this. Use /dev/urandom if you can
243 * as /dev/random will block if it runs out
244 * of random entries.
245 */
246 if ((fh = fopen(DEVRANDOM, "r")) != NULL)
247 {
248 unsigned char tmpbuf[32];
249
250 fread((unsigned char *)tmpbuf,1,32,fh);
251 /* we don't care how many bytes we read,
252 * we will just copy the 'stack' if there is
253 * nothing else :-) */
254 fclose(fh);
255 RAND_seed(tmpbuf,32);
256 memset(tmpbuf,0,32);
257 }
258/* #endif */
259#ifdef PURIFY
260 memset(state,0,STATE_SIZE);
261 memset(md,0,MD_DIGEST_LENGTH);
262#endif
263 CRYPTO_w_lock(CRYPTO_LOCK_RAND);
264 }
265
266 st_idx=state_index;
267 st_num=state_num;
268 state_index+=num;
269 if (state_index > state_num)
270 state_index=(state_index%state_num);
271
272 CRYPTO_w_unlock(CRYPTO_LOCK_RAND);
273
274 while (num > 0)
275 {
276 j=(num >= MD_DIGEST_LENGTH/2)?MD_DIGEST_LENGTH/2:num;
277 num-=j;
278 MD_Init(&m);
279 MD_Update(&m,&(md[MD_DIGEST_LENGTH/2]),MD_DIGEST_LENGTH/2);
280#ifndef PURIFY
281 MD_Update(&m,buf,j); /* purify complains */
282#endif
283 k=(st_idx+j)-st_num;
284 if (k > 0)
285 {
286 MD_Update(&m,&(state[st_idx]),j-k);
287 MD_Update(&m,&(state[0]),k);
288 }
289 else
290 MD_Update(&m,&(state[st_idx]),j);
291 MD_Final(md,&m);
292
293 for (i=0; i<j; i++)
294 {
295 if (st_idx >= st_num)
296 st_idx=0;
297 state[st_idx++]^=md[i];
298 *(buf++)=md[i+MD_DIGEST_LENGTH/2];
299 }
300 }
301
302 MD_Init(&m);
303 MD_Update(&m,(unsigned char *)&md_count,sizeof(md_count)); md_count++;
304 MD_Update(&m,md,MD_DIGEST_LENGTH);
305 MD_Final(md,&m);
306 memset(&m,0,sizeof(m));
307 }
308
309#ifdef WINDOWS
310#include <windows.h>
311#include <rand.h>
312
313/*****************************************************************************
314 * Initialisation function for the SSL random generator. Takes the contents
315 * of the screen as random seed.
316 *
317 * Created 960901 by Gertjan van Oosten, gertjan@West.NL, West Consulting B.V.
318 *
319 * Code adapted from
320 * <URL:http://www.microsoft.com/kb/developr/win_dk/q97193.htm>;
321 * the original copyright message is:
322 *
323// (C) Copyright Microsoft Corp. 1993. All rights reserved.
324//
325// You have a royalty-free right to use, modify, reproduce and
326// distribute the Sample Files (and/or any modified version) in
327// any way you find useful, provided that you agree that
328// Microsoft has no warranty obligations or liability for any
329// Sample Application Files which are modified.
330 */
331/*
332 * I have modified the loading of bytes via RAND_seed() mechanism since
333 * the origional would have been very very CPU intensive since RAND_seed()
334 * does an MD5 per 16 bytes of input. The cost to digest 16 bytes is the same
335 * as that to digest 56 bytes. So under the old system, a screen of
336 * 1024*768*256 would have been CPU cost of approximatly 49,000 56 byte MD5
337 * digests or digesting 2.7 mbytes. What I have put in place would
338 * be 48 16k MD5 digests, or efectivly 48*16+48 MD5 bytes or 816 kbytes
339 * or about 3.5 times as much.
340 * - eric
341 */
342void RAND_screen(void)
343{
344 HDC hScrDC; /* screen DC */
345 HDC hMemDC; /* memory DC */
346 HBITMAP hBitmap; /* handle for our bitmap */
347 HBITMAP hOldBitmap; /* handle for previous bitmap */
348 BITMAP bm; /* bitmap properties */
349 unsigned int size; /* size of bitmap */
350 char *bmbits; /* contents of bitmap */
351 int w; /* screen width */
352 int h; /* screen height */
353 int y; /* y-coordinate of screen lines to grab */
354 int n = 16; /* number of screen lines to grab at a time */
355
356 /* Create a screen DC and a memory DC compatible to screen DC */
357 hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
358 hMemDC = CreateCompatibleDC(hScrDC);
359
360 /* Get screen resolution */
361 w = GetDeviceCaps(hScrDC, HORZRES);
362 h = GetDeviceCaps(hScrDC, VERTRES);
363
364 /* Create a bitmap compatible with the screen DC */
365 hBitmap = CreateCompatibleBitmap(hScrDC, w, n);
366
367 /* Select new bitmap into memory DC */
368 hOldBitmap = SelectObject(hMemDC, hBitmap);
369
370 /* Get bitmap properties */
371 GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&bm);
372 size = (unsigned int)bm.bmWidthBytes * bm.bmHeight * bm.bmPlanes;
373
374 bmbits = Malloc(size);
375 if (bmbits) {
376 /* Now go through the whole screen, repeatedly grabbing n lines */
377 for (y = 0; y < h-n; y += n)
378 {
379 unsigned char md[MD_DIGEST_LENGTH];
380
381 /* Bitblt screen DC to memory DC */
382 BitBlt(hMemDC, 0, 0, w, n, hScrDC, 0, y, SRCCOPY);
383
384 /* Copy bitmap bits from memory DC to bmbits */
385 GetBitmapBits(hBitmap, size, bmbits);
386
387 /* Get the MD5 of the bitmap */
388 MD5(bmbits,size,md);
389
390 /* Seed the random generator with the MD5 digest */
391 RAND_seed(md, MD_DIGEST_LENGTH);
392 }
393
394 Free(bmbits);
395 }
396
397 /* Select old bitmap back into memory DC */
398 hBitmap = SelectObject(hMemDC, hOldBitmap);
399
400 /* Clean up */
401 DeleteObject(hBitmap);
402 DeleteDC(hMemDC);
403 DeleteDC(hScrDC);
404}
405#endif