rand_lib.c revision 109998
155714Skris/* crypto/rand/rand_lib.c */
255714Skris/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
355714Skris * All rights reserved.
455714Skris *
555714Skris * This package is an SSL implementation written
655714Skris * by Eric Young (eay@cryptsoft.com).
755714Skris * The implementation was written so as to conform with Netscapes SSL.
855714Skris *
955714Skris * This library is free for commercial and non-commercial use as long as
1055714Skris * the following conditions are aheared to.  The following conditions
1155714Skris * apply to all code found in this distribution, be it the RC4, RSA,
1255714Skris * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
1355714Skris * included with this distribution is covered by the same copyright terms
1455714Skris * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1555714Skris *
1655714Skris * Copyright remains Eric Young's, and as such any Copyright notices in
1755714Skris * the code are not to be removed.
1855714Skris * If this package is used in a product, Eric Young should be given attribution
1955714Skris * as the author of the parts of the library used.
2055714Skris * This can be in the form of a textual message at program startup or
2155714Skris * in documentation (online or textual) provided with the package.
2255714Skris *
2355714Skris * Redistribution and use in source and binary forms, with or without
2455714Skris * modification, are permitted provided that the following conditions
2555714Skris * are met:
2655714Skris * 1. Redistributions of source code must retain the copyright
2755714Skris *    notice, this list of conditions and the following disclaimer.
2855714Skris * 2. Redistributions in binary form must reproduce the above copyright
2955714Skris *    notice, this list of conditions and the following disclaimer in the
3055714Skris *    documentation and/or other materials provided with the distribution.
3155714Skris * 3. All advertising materials mentioning features or use of this software
3255714Skris *    must display the following acknowledgement:
3355714Skris *    "This product includes cryptographic software written by
3455714Skris *     Eric Young (eay@cryptsoft.com)"
3555714Skris *    The word 'cryptographic' can be left out if the rouines from the library
3655714Skris *    being used are not cryptographic related :-).
3755714Skris * 4. If you include any Windows specific code (or a derivative thereof) from
3855714Skris *    the apps directory (application code) you must include an acknowledgement:
3955714Skris *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
4055714Skris *
4155714Skris * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
4255714Skris * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
4355714Skris * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
4455714Skris * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
4555714Skris * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
4655714Skris * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
4755714Skris * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
4855714Skris * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
4955714Skris * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
5055714Skris * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
5155714Skris * SUCH DAMAGE.
5255714Skris *
5355714Skris * The licence and distribution terms for any publically available version or
5455714Skris * derivative of this code cannot be changed.  i.e. this code cannot simply be
5555714Skris * copied and put under another distribution licence
5655714Skris * [including the GNU Public Licence.]
5755714Skris */
5855714Skris
5955714Skris#include <stdio.h>
6055714Skris#include <time.h>
61109998Smarkm#include "cryptlib.h"
6255714Skris#include <openssl/rand.h>
63109998Smarkm#include <openssl/engine.h>
6455714Skris
65109998Smarkm/* non-NULL if default_RAND_meth is ENGINE-provided */
66109998Smarkmstatic ENGINE *funct_ref =NULL;
67109998Smarkmstatic const RAND_METHOD *default_RAND_meth = NULL;
6855714Skris
69109998Smarkmint RAND_set_rand_method(const RAND_METHOD *meth)
7055714Skris	{
71109998Smarkm	if(funct_ref)
72109998Smarkm		{
73109998Smarkm		ENGINE_finish(funct_ref);
74109998Smarkm		funct_ref = NULL;
75109998Smarkm		}
76109998Smarkm	default_RAND_meth = meth;
77109998Smarkm	return 1;
7855714Skris	}
7955714Skris
80109998Smarkmconst RAND_METHOD *RAND_get_rand_method(void)
8155714Skris	{
82109998Smarkm	if (!default_RAND_meth)
83109998Smarkm		{
84109998Smarkm		ENGINE *e = ENGINE_get_default_RAND();
85109998Smarkm		if(e)
86109998Smarkm			{
87109998Smarkm			default_RAND_meth = ENGINE_get_RAND(e);
88109998Smarkm			if(!default_RAND_meth)
89109998Smarkm				{
90109998Smarkm				ENGINE_finish(e);
91109998Smarkm				e = NULL;
92109998Smarkm				}
93109998Smarkm			}
94109998Smarkm		if(e)
95109998Smarkm			funct_ref = e;
96109998Smarkm		else
97109998Smarkm			default_RAND_meth = RAND_SSLeay();
98109998Smarkm		}
99109998Smarkm	return default_RAND_meth;
10055714Skris	}
10155714Skris
102109998Smarkmint RAND_set_rand_engine(ENGINE *engine)
103109998Smarkm	{
104109998Smarkm	const RAND_METHOD *tmp_meth = NULL;
105109998Smarkm	if(engine)
106109998Smarkm		{
107109998Smarkm		if(!ENGINE_init(engine))
108109998Smarkm			return 0;
109109998Smarkm		tmp_meth = ENGINE_get_RAND(engine);
110109998Smarkm		if(!tmp_meth)
111109998Smarkm			{
112109998Smarkm			ENGINE_finish(engine);
113109998Smarkm			return 0;
114109998Smarkm			}
115109998Smarkm		}
116109998Smarkm	/* This function releases any prior ENGINE so call it first */
117109998Smarkm	RAND_set_rand_method(tmp_meth);
118109998Smarkm	funct_ref = engine;
119109998Smarkm	return 1;
120109998Smarkm	}
121109998Smarkm
12255714Skrisvoid RAND_cleanup(void)
12355714Skris	{
124109998Smarkm	const RAND_METHOD *meth = RAND_get_rand_method();
125109998Smarkm	if (meth && meth->cleanup)
126109998Smarkm		meth->cleanup();
127109998Smarkm	RAND_set_rand_method(NULL);
12855714Skris	}
12955714Skris
13055714Skrisvoid RAND_seed(const void *buf, int num)
13155714Skris	{
132109998Smarkm	const RAND_METHOD *meth = RAND_get_rand_method();
133109998Smarkm	if (meth && meth->seed)
134109998Smarkm		meth->seed(buf,num);
13555714Skris	}
13655714Skris
13759191Skrisvoid RAND_add(const void *buf, int num, double entropy)
13855714Skris	{
139109998Smarkm	const RAND_METHOD *meth = RAND_get_rand_method();
140109998Smarkm	if (meth && meth->add)
141109998Smarkm		meth->add(buf,num,entropy);
14255714Skris	}
14355714Skris
14459191Skrisint RAND_bytes(unsigned char *buf, int num)
14559191Skris	{
146109998Smarkm	const RAND_METHOD *meth = RAND_get_rand_method();
147109998Smarkm	if (meth && meth->bytes)
148109998Smarkm		return meth->bytes(buf,num);
14959191Skris	return(-1);
15059191Skris	}
15159191Skris
15259191Skrisint RAND_pseudo_bytes(unsigned char *buf, int num)
15359191Skris	{
154109998Smarkm	const RAND_METHOD *meth = RAND_get_rand_method();
155109998Smarkm	if (meth && meth->pseudorand)
156109998Smarkm		return meth->pseudorand(buf,num);
15759191Skris	return(-1);
15859191Skris	}
15959191Skris
16059191Skrisint RAND_status(void)
16159191Skris	{
162109998Smarkm	const RAND_METHOD *meth = RAND_get_rand_method();
163109998Smarkm	if (meth && meth->status)
164109998Smarkm		return meth->status();
16559191Skris	return 0;
16659191Skris	}
167