rand_eng.c revision 225736
1247405Salfred/* crypto/rand/rand_lib.c */
2247405Salfred/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3126383Sphk * All rights reserved.
4116874Ssmkelly *
5116874Ssmkelly * This package is an SSL implementation written
6116874Ssmkelly * by Eric Young (eay@cryptsoft.com).
7116874Ssmkelly * The implementation was written so as to conform with Netscapes SSL.
8116874Ssmkelly *
9116874Ssmkelly * This library is free for commercial and non-commercial use as long as
10116874Ssmkelly * the following conditions are aheared to.  The following conditions
11116874Ssmkelly * apply to all code found in this distribution, be it the RC4, RSA,
12116874Ssmkelly * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13116874Ssmkelly * included with this distribution is covered by the same copyright terms
14116874Ssmkelly * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15116874Ssmkelly *
16116874Ssmkelly * Copyright remains Eric Young's, and as such any Copyright notices in
17116874Ssmkelly * the code are not to be removed.
18116874Ssmkelly * If this package is used in a product, Eric Young should be given attribution
19116874Ssmkelly * as the author of the parts of the library used.
20116874Ssmkelly * This can be in the form of a textual message at program startup or
21116874Ssmkelly * in documentation (online or textual) provided with the package.
22116874Ssmkelly *
23116874Ssmkelly * Redistribution and use in source and binary forms, with or without
24116874Ssmkelly * modification, are permitted provided that the following conditions
25116874Ssmkelly * are met:
26116874Ssmkelly * 1. Redistributions of source code must retain the copyright
27116874Ssmkelly *    notice, this list of conditions and the following disclaimer.
28116874Ssmkelly * 2. Redistributions in binary form must reproduce the above copyright
29116874Ssmkelly *    notice, this list of conditions and the following disclaimer in the
30253723Salfred *    documentation and/or other materials provided with the distribution.
31116874Ssmkelly * 3. All advertising materials mentioning features or use of this software
32116874Ssmkelly *    must display the following acknowledgement:
33116874Ssmkelly *    "This product includes cryptographic software written by
34116874Ssmkelly *     Eric Young (eay@cryptsoft.com)"
35130420Sru *    The word 'cryptographic' can be left out if the rouines from the library
36116874Ssmkelly *    being used are not cryptographic related :-).
37116874Ssmkelly * 4. If you include any Windows specific code (or a derivative thereof) from
38248744Smarkj *    the apps directory (application code) you must include an acknowledgement:
39247405Salfred *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40247405Salfred *
41247405Salfred * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42247405Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43247405Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44126383Sphk * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45116874Ssmkelly * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46126383Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47126383Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48247405Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49116874Ssmkelly * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50116874Ssmkelly * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51116874Ssmkelly * SUCH DAMAGE.
52126383Sphk *
53116874Ssmkelly * The licence and distribution terms for any publically available version or
54116874Ssmkelly * derivative of this code cannot be changed.  i.e. this code cannot simply be
55116874Ssmkelly * copied and put under another distribution licence
56116874Ssmkelly * [including the GNU Public Licence.]
57116874Ssmkelly */
58116874Ssmkelly
59128643Ssimon#include <stdio.h>
60126383Sphk#include <time.h>
61126383Sphk#include "cryptlib.h"
62126383Sphk#include "rand_lcl.h"
63126383Sphk#include <openssl/rand.h>
64130420Sru#ifdef OPENSSL_FIPS
65126383Sphk#include <openssl/fips.h>
66126383Sphk#include <openssl/fips_rand.h>
67126383Sphk#endif
68126383Sphk
69130420Sru#ifndef OPENSSL_NO_ENGINE
70126383Sphk#include <openssl/engine.h>
71126383Sphk#endif
72126383Sphk
73247405Salfred#if defined(OPENSSL_FIPS) && !defined(OPENSSL_NO_ENGINE)
74247405Salfred
75247405Salfred/* non-NULL if default_RAND_meth is ENGINE-provided */
76247405Salfredstatic ENGINE *funct_ref =NULL;
77247405Salfred
78247405Salfredint eng_RAND_set_rand_method(const RAND_METHOD *meth, const RAND_METHOD **pmeth)
79247405Salfred	{
80128643Ssimon	if(funct_ref)
81126383Sphk		{
82126383Sphk		ENGINE_finish(funct_ref);
83126383Sphk		funct_ref = NULL;
84126383Sphk		}
85128643Ssimon	*pmeth = meth;
86126383Sphk	return 1;
87161862Sphk	}
88126383Sphk
89116874Ssmkellyconst RAND_METHOD *eng_RAND_get_rand_method(const RAND_METHOD **pmeth)
90116874Ssmkelly	{
91116874Ssmkelly	if (!*pmeth)
92116874Ssmkelly		{
93116874Ssmkelly		ENGINE *e = ENGINE_get_default_RAND();
94116874Ssmkelly		if(e)
95116874Ssmkelly			{
96247405Salfred			*pmeth = ENGINE_get_RAND(e);
97247405Salfred			if(!*pmeth)
98247405Salfred				{
99247405Salfred				ENGINE_finish(e);
100247405Salfred				e = NULL;
101247405Salfred				}
102247405Salfred			}
103247417Sjoel		if(e)
104247405Salfred			funct_ref = e;
105247405Salfred		else
106116874Ssmkelly			if(FIPS_mode())
107116874Ssmkelly				*pmeth=FIPS_rand_method();
108116874Ssmkelly			else
109116874Ssmkelly			*pmeth = RAND_SSLeay();
110116874Ssmkelly		}
111116874Ssmkelly
112116874Ssmkelly	if(FIPS_mode()
113128643Ssimon		&& *pmeth != FIPS_rand_check())
114116874Ssmkelly	    {
115116874Ssmkelly	    RANDerr(RAND_F_ENG_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD);
116116874Ssmkelly	    return 0;
117116874Ssmkelly	    }
118253735Sjoel
119116874Ssmkelly	return *pmeth;
120130420Sru	}
121116874Ssmkelly
122116874Ssmkellyint RAND_set_rand_engine(ENGINE *engine)
123247405Salfred	{
124128643Ssimon	const RAND_METHOD *tmp_meth = NULL;
125116874Ssmkelly	if(engine)
126116874Ssmkelly		{
127116874Ssmkelly		if(!ENGINE_init(engine))
128247405Salfred			return 0;
129248744Smarkj		tmp_meth = ENGINE_get_RAND(engine);
130248744Smarkj		if(!tmp_meth)
131248744Smarkj			{
132248744Smarkj			ENGINE_finish(engine);
133248744Smarkj			return 0;
134248744Smarkj			}
135247405Salfred		}
136247405Salfred	/* This function releases any prior ENGINE so call it first */
137247405Salfred	RAND_set_rand_method(tmp_meth);
138247405Salfred	funct_ref = engine;
139247405Salfred	return 1;
140247405Salfred	}
141247416Sjoel
142247416Sjoelvoid int_RAND_init_engine_callbacks(void)
143247416Sjoel	{
144247416Sjoel	static int done = 0;
145247405Salfred	if (done)
146247405Salfred		return;
147247405Salfred	int_RAND_set_callbacks(eng_RAND_set_rand_method,
148247416Sjoel				 eng_RAND_get_rand_method);
149247417Sjoel	done = 1;
150247405Salfred	}
151247405Salfred
152247405Salfred#endif
153247405Salfred