1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* crypto/rand/rand_lib.c */
2656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * All rights reserved.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This package is an SSL implementation written
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * by Eric Young (eay@cryptsoft.com).
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The implementation was written so as to conform with Netscapes SSL.
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This library is free for commercial and non-commercial use as long as
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the following conditions are aheared to.  The following conditions
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * apply to all code found in this distribution, be it the RC4, RSA,
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * included with this distribution is covered by the same copyright terms
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright remains Eric Young's, and as such any Copyright notices in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * the code are not to be removed.
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * If this package is used in a product, Eric Young should be given attribution
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * as the author of the parts of the library used.
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This can be in the form of a textual message at program startup or
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * in documentation (online or textual) provided with the package.
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the copyright
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    documentation and/or other materials provided with the distribution.
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this software
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    must display the following acknowledgement:
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes cryptographic software written by
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *     Eric Young (eay@cryptsoft.com)"
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    The word 'cryptographic' can be left out if the rouines from the library
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    being used are not cryptographic related :-).
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. If you include any Windows specific code (or a derivative thereof) from
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the apps directory (application code) you must include an acknowledgement:
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SUCH DAMAGE.
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The licence and distribution terms for any publically available version or
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * derivative of this code cannot be changed.  i.e. this code cannot simply be
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * copied and put under another distribution licence
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * [including the GNU Public Licence.]
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <time.h>
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/rand.h>
63392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/engine.h>
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
68392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
69392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/fips.h>
70392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#include <openssl/fips_rand.h>
71392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
72392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* non-NULL if default_RAND_meth is ENGINE-provided */
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic ENGINE *funct_ref =NULL;
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
77221304ee937bc0910948a8be1320cb8cc4eb6d36Brian Carlstromstatic const RAND_METHOD *default_RAND_meth = NULL;
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint RAND_set_rand_method(const RAND_METHOD *meth)
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(funct_ref)
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINE_finish(funct_ref);
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		funct_ref = NULL;
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	default_RAND_meth = meth;
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectconst RAND_METHOD *RAND_get_rand_method(void)
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (!default_RAND_meth)
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
96656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ENGINE *e = ENGINE_get_default_RAND();
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(e)
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			default_RAND_meth = ENGINE_get_RAND(e);
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(!default_RAND_meth)
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				{
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				ENGINE_finish(e);
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				e = NULL;
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project				}
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(e)
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			funct_ref = e;
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		else
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			default_RAND_meth = RAND_SSLeay();
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return default_RAND_meth;
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef OPENSSL_NO_ENGINE
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint RAND_set_rand_engine(ENGINE *engine)
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const RAND_METHOD *tmp_meth = NULL;
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(engine)
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		{
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!ENGINE_init(engine))
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		tmp_meth = ENGINE_get_RAND(engine);
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!tmp_meth)
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			{
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ENGINE_finish(engine);
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return 0;
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			}
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* This function releases any prior ENGINE so call it first */
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	RAND_set_rand_method(tmp_meth);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	funct_ref = engine;
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid RAND_cleanup(void)
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const RAND_METHOD *meth = RAND_get_rand_method();
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (meth && meth->cleanup)
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		meth->cleanup();
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	RAND_set_rand_method(NULL);
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid RAND_seed(const void *buf, int num)
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const RAND_METHOD *meth = RAND_get_rand_method();
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (meth && meth->seed)
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		meth->seed(buf,num);
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectvoid RAND_add(const void *buf, int num, double entropy)
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const RAND_METHOD *meth = RAND_get_rand_method();
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (meth && meth->add)
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		meth->add(buf,num,entropy);
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint RAND_bytes(unsigned char *buf, int num)
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const RAND_METHOD *meth = RAND_get_rand_method();
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (meth && meth->bytes)
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return meth->bytes(buf,num);
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(-1);
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint RAND_pseudo_bytes(unsigned char *buf, int num)
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const RAND_METHOD *meth = RAND_get_rand_method();
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (meth && meth->pseudorand)
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return meth->pseudorand(buf,num);
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return(-1);
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint RAND_status(void)
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	{
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	const RAND_METHOD *meth = RAND_get_rand_method();
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if (meth && meth->status)
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return meth->status();
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
183392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
184392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifdef OPENSSL_FIPS
185392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
186392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* FIPS DRBG initialisation code. This sets up the DRBG for use by the
187392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * rest of OpenSSL.
188392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */
189392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
190392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Entropy gatherer: use standard OpenSSL PRNG to seed (this will gather
191392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * entropy internally through RAND_poll().
192392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */
193392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
194392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic size_t drbg_get_entropy(DRBG_CTX *ctx, unsigned char **pout,
195392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom                                int entropy, size_t min_len, size_t max_len)
196392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom        {
197392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Round up request to multiple of block size */
198392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	min_len = ((min_len + 19) / 20) * 20;
199392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	*pout = OPENSSL_malloc(min_len);
200392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (!*pout)
201392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
202392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	if (RAND_SSLeay()->bytes(*pout, min_len) <= 0)
203392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
204392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		OPENSSL_free(*pout);
205392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		*pout = NULL;
206392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
207392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
208392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom        return min_len;
209392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom        }
210392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
211392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic void drbg_free_entropy(DRBG_CTX *ctx, unsigned char *out, size_t olen)
212392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
21304ef91b390dfcc6125913e2f2af502d23d7a5112Brian Carlstrom	if (out)
21404ef91b390dfcc6125913e2f2af502d23d7a5112Brian Carlstrom		{
21504ef91b390dfcc6125913e2f2af502d23d7a5112Brian Carlstrom		OPENSSL_cleanse(out, olen);
21604ef91b390dfcc6125913e2f2af502d23d7a5112Brian Carlstrom		OPENSSL_free(out);
21704ef91b390dfcc6125913e2f2af502d23d7a5112Brian Carlstrom		}
218392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
219392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
220392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* Set "additional input" when generating random data. This uses the
221392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * current PID, a time value and a counter.
222392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */
223392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
224392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic size_t drbg_get_adin(DRBG_CTX *ctx, unsigned char **pout)
225392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom    	{
226392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Use of static variables is OK as this happens under a lock */
227392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	static unsigned char buf[16];
228392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	static unsigned long counter;
229392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	FIPS_get_timevec(buf, &counter);
230392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	*pout = buf;
231392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return sizeof(buf);
232392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
233392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
234392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom/* RAND_add() and RAND_seed() pass through to OpenSSL PRNG so it is
235392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom * correctly seeded by RAND_poll().
236392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom */
237392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
238392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int drbg_rand_add(DRBG_CTX *ctx, const void *in, int inlen,
239392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				double entropy)
240392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
241392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	RAND_SSLeay()->add(in, inlen, entropy);
242392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
243392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
244392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
245392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int drbg_rand_seed(DRBG_CTX *ctx, const void *in, int inlen)
246392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
247392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	RAND_SSLeay()->seed(in, inlen);
248392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
249392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
250392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
251392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_DRBG_DEFAULT_TYPE
252392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define OPENSSL_DRBG_DEFAULT_TYPE	NID_aes_256_ctr
253392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
254392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#ifndef OPENSSL_DRBG_DEFAULT_FLAGS
255392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#define OPENSSL_DRBG_DEFAULT_FLAGS	DRBG_FLAG_CTR_USE_DF
256392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
257392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
258392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int fips_drbg_type = OPENSSL_DRBG_DEFAULT_TYPE;
259392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromstatic int fips_drbg_flags = OPENSSL_DRBG_DEFAULT_FLAGS;
260392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
261392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromvoid RAND_set_fips_drbg_type(int type, int flags)
262392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
263392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	fips_drbg_type = type;
264392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	fips_drbg_flags = flags;
265392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
266392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
267392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstromint RAND_init_fips(void)
268392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	{
269392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	DRBG_CTX *dctx;
270392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	size_t plen;
271392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	unsigned char pers[32], *p;
272ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root#ifndef OPENSSL_ALLOW_DUAL_EC_DRBG
273ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root	if (fips_drbg_type >> 16)
274ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		{
275ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_DUAL_EC_DRBG_DISABLED);
276ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		return 0;
277ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root		}
278ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root#endif
279ff41a4bc41ae1e1391f9b05117623ff70b985983Kenny Root
280392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	dctx = FIPS_get_default_drbg();
281392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom        if (FIPS_drbg_init(dctx, fips_drbg_type, fips_drbg_flags) <= 0)
282392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
283392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INITIALISING_DRBG);
284392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
285392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
286392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
287392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom        FIPS_drbg_set_callbacks(dctx,
288392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				drbg_get_entropy, drbg_free_entropy, 20,
289392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom				drbg_get_entropy, drbg_free_entropy);
290392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	FIPS_drbg_set_rand_callbacks(dctx, drbg_get_adin, 0,
291392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom					drbg_rand_seed, drbg_rand_add);
292392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	/* Personalisation string: a string followed by date time vector */
293392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	strcpy((char *)pers, "OpenSSL DRBG2.0");
294392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	plen = drbg_get_adin(dctx, &p);
295392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	memcpy(pers + 16, p, plen);
296392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
297392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom        if (FIPS_drbg_instantiate(dctx, pers, sizeof(pers)) <= 0)
298392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		{
299392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		RANDerr(RAND_F_RAND_INIT_FIPS, RAND_R_ERROR_INSTANTIATING_DRBG);
300392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		return 0;
301392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom		}
302392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom        FIPS_rand_set_method(FIPS_drbg_method());
303392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	return 1;
304392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom	}
305392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom
306392aa7cc7d2b122614c5393c3e357da07fd07af3Brian Carlstrom#endif
307