rand_lib.c revision 194206
1181111Sdes/* crypto/rand/rand_lib.c */ 2107553Sdes/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 399059Sdes * All rights reserved. 4157020Sdes * 5157020Sdes * This package is an SSL implementation written 6157020Sdes * by Eric Young (eay@cryptsoft.com). 7124244Sdes * The implementation was written so as to conform with Netscapes SSL. 8157020Sdes * 9157020Sdes * This library is free for commercial and non-commercial use as long as 1099059Sdes * the following conditions are aheared to. The following conditions 11181111Sdes * apply to all code found in this distribution, be it the RC4, RSA, 12181111Sdes * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13181111Sdes * included with this distribution is covered by the same copyright terms 14157020Sdes * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15157020Sdes * 1699059Sdes * Copyright remains Eric Young's, and as such any Copyright notices in 17157020Sdes * the code are not to be removed. 18157020Sdes * If this package is used in a product, Eric Young should be given attribution 1999059Sdes * as the author of the parts of the library used. 20157020Sdes * This can be in the form of a textual message at program startup or 21157020Sdes * in documentation (online or textual) provided with the package. 22124244Sdes * 23157020Sdes * Redistribution and use in source and binary forms, with or without 24157020Sdes * modification, are permitted provided that the following conditions 25124244Sdes * are met: 26181111Sdes * 1. Redistributions of source code must retain the copyright 27181111Sdes * notice, this list of conditions and the following disclaimer. 28181111Sdes * 2. Redistributions in binary form must reproduce the above copyright 2999059Sdes * notice, this list of conditions and the following disclaimer in the 3099059Sdes * documentation and/or other materials provided with the distribution. 3199059Sdes * 3. All advertising materials mentioning features or use of this software 32157020Sdes * must display the following acknowledgement: 33157020Sdes * "This product includes cryptographic software written by 3499059Sdes * Eric Young (eay@cryptsoft.com)" 35157020Sdes * The word 'cryptographic' can be left out if the rouines from the library 36157020Sdes * being used are not cryptographic related :-). 3799059Sdes * 4. If you include any Windows specific code (or a derivative thereof) from 38157020Sdes * the apps directory (application code) you must include an acknowledgement: 39157020Sdes * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40157020Sdes * 4199059Sdes * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42181111Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43181111Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44181111Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 4599059Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 4699059Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 4799059Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48157020Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49157020Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 5099059Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51157020Sdes * SUCH DAMAGE. 52157020Sdes * 5399059Sdes * The licence and distribution terms for any publically available version or 54157020Sdes * derivative of this code cannot be changed. i.e. this code cannot simply be 55157020Sdes * copied and put under another distribution licence 5699059Sdes * [including the GNU Public Licence.] 57157020Sdes */ 58157020Sdes 59124244Sdes#include <stdio.h> 60157020Sdes#include <time.h> 61157020Sdes#include "cryptlib.h" 62128462Sdes#include <openssl/rand.h> 63157020Sdes#include "rand_lcl.h" 64157020Sdes#ifdef OPENSSL_FIPS 6599059Sdes#include <openssl/fips.h> 66181111Sdes#include <openssl/fips_rand.h> 67181111Sdes#endif 68181111Sdes 69157020Sdes#ifndef OPENSSL_NO_ENGINE 70157020Sdes#include <openssl/engine.h> 7199059Sdes#endif 72157020Sdes 73157020Sdesstatic const RAND_METHOD *default_RAND_meth = NULL; 7499059Sdes 75157020Sdes#ifdef OPENSSL_FIPS 76157020Sdes 7799059Sdesstatic int fips_RAND_set_rand_method(const RAND_METHOD *meth, 78157020Sdes const RAND_METHOD **pmeth) 79157020Sdes { 8099059Sdes *pmeth = meth; 81157020Sdes return 1; 82157020Sdes } 8399059Sdes 84157020Sdesstatic const RAND_METHOD *fips_RAND_get_rand_method(const RAND_METHOD **pmeth) 85157020Sdes { 8699059Sdes if (!*pmeth) 87157020Sdes { 88157020Sdes if(FIPS_mode()) 8999059Sdes *pmeth=FIPS_rand_method(); 90157020Sdes else 91157020Sdes *pmeth = RAND_SSLeay(); 9299059Sdes } 93157020Sdes 94157020Sdes if(FIPS_mode() 9599059Sdes && *pmeth != FIPS_rand_check()) 96157020Sdes { 97157020Sdes RANDerr(RAND_F_FIPS_RAND_GET_RAND_METHOD,RAND_R_NON_FIPS_METHOD); 9899059Sdes return 0; 9999059Sdes } 10099059Sdes 10199059Sdes return *pmeth; 10299059Sdes } 10399059Sdes 10499059Sdesstatic int (*RAND_set_rand_method_func)(const RAND_METHOD *meth, 10599059Sdes const RAND_METHOD **pmeth) 10699059Sdes = fips_RAND_set_rand_method; 10799059Sdesstatic const RAND_METHOD *(*RAND_get_rand_method_func) 108157020Sdes (const RAND_METHOD **pmeth) 109157020Sdes = fips_RAND_get_rand_method; 11099059Sdes 11199059Sdes#ifndef OPENSSL_NO_ENGINE 11299059Sdesvoid int_RAND_set_callbacks( 11399059Sdes int (*set_rand_func)(const RAND_METHOD *meth, 11499059Sdes const RAND_METHOD **pmeth), 11599059Sdes const RAND_METHOD *(*get_rand_func) 11699059Sdes (const RAND_METHOD **pmeth)) 11799059Sdes { 11899059Sdes RAND_set_rand_method_func = set_rand_func; 11999059Sdes RAND_get_rand_method_func = get_rand_func; 12099059Sdes } 12199059Sdes#endif 12299059Sdes 123157020Sdesint RAND_set_rand_method(const RAND_METHOD *meth) 124157020Sdes { 12599059Sdes return RAND_set_rand_method_func(meth, &default_RAND_meth); 126181111Sdes } 127181111Sdes 128181111Sdesconst RAND_METHOD *RAND_get_rand_method(void) 129157020Sdes { 130157020Sdes return RAND_get_rand_method_func(&default_RAND_meth); 13199059Sdes } 132157020Sdes 133157020Sdes#else 13499059Sdes 13599059Sdes#ifndef OPENSSL_NO_ENGINE 136159458Sdes/* non-NULL if default_RAND_meth is ENGINE-provided */ 13799059Sdesstatic ENGINE *funct_ref =NULL; 13899059Sdes#endif 139159458Sdes 14099059Sdesint RAND_set_rand_method(const RAND_METHOD *meth) 141157020Sdes { 142157020Sdes#ifndef OPENSSL_NO_ENGINE 14399059Sdes if(funct_ref) 144157020Sdes { 145157020Sdes ENGINE_finish(funct_ref); 146124244Sdes funct_ref = NULL; 147157020Sdes } 148157020Sdes#endif 14999059Sdes default_RAND_meth = meth; 150157020Sdes return 1; 151157020Sdes } 15299059Sdes 153157020Sdesconst RAND_METHOD *RAND_get_rand_method(void) 154157020Sdes { 15599059Sdes if (!default_RAND_meth) 156157020Sdes { 157157020Sdes#ifndef OPENSSL_NO_ENGINE 15899059Sdes ENGINE *e = ENGINE_get_default_RAND(); 159157020Sdes if(e) 160157020Sdes { 16199059Sdes default_RAND_meth = ENGINE_get_RAND(e); 162157020Sdes if(!default_RAND_meth) 163157020Sdes { 16499059Sdes ENGINE_finish(e); 165181111Sdes e = NULL; 166181111Sdes } 167181111Sdes } 168181111Sdes if(e) 169181111Sdes funct_ref = e; 170181111Sdes else 171157020Sdes#endif 172157020Sdes default_RAND_meth = RAND_SSLeay(); 17399059Sdes } 174157020Sdes return default_RAND_meth; 175157020Sdes } 17699059Sdes 177181111Sdes#ifndef OPENSSL_NO_ENGINE 178181111Sdesint RAND_set_rand_engine(ENGINE *engine) 179181111Sdes { 180149754Sdes const RAND_METHOD *tmp_meth = NULL; 181149754Sdes if(engine) 182149754Sdes { 183181111Sdes if(!ENGINE_init(engine)) 184181111Sdes return 0; 185181111Sdes tmp_meth = ENGINE_get_RAND(engine); 186107553Sdes if(!tmp_meth) 18799059Sdes { 18899059Sdes ENGINE_finish(engine); 189113912Sdes return 0; 190113912Sdes } 191113912Sdes } 192157020Sdes /* This function releases any prior ENGINE so call it first */ 193157020Sdes RAND_set_rand_method(tmp_meth); 194157020Sdes funct_ref = engine; 195107553Sdes return 1; 19699059Sdes } 19799059Sdes#endif 198107553Sdes 19999059Sdes#endif 20099059Sdes 201147006Sdesvoid RAND_cleanup(void) 202147006Sdes { 203147006Sdes const RAND_METHOD *meth = RAND_get_rand_method(); 204107553Sdes if (meth && meth->cleanup) 20599059Sdes meth->cleanup(); 20699059Sdes RAND_set_rand_method(NULL); 207107553Sdes } 20899059Sdes 20999059Sdesvoid RAND_seed(const void *buf, int num) 210157020Sdes { 211157020Sdes const RAND_METHOD *meth = RAND_get_rand_method(); 212157020Sdes if (meth && meth->seed) 213137019Sdes meth->seed(buf,num); 214137019Sdes } 215137019Sdes 216124244Sdesvoid RAND_add(const void *buf, int num, double entropy) 217147006Sdes { 218124244Sdes const RAND_METHOD *meth = RAND_get_rand_method(); 219157020Sdes if (meth && meth->add) 220157020Sdes meth->add(buf,num,entropy); 221157020Sdes } 222162860Sdes 223162860Sdesint RAND_bytes(unsigned char *buf, int num) 224162860Sdes { 225107553Sdes const RAND_METHOD *meth = RAND_get_rand_method(); 22699059Sdes if (meth && meth->bytes) 22799059Sdes return meth->bytes(buf,num); 228157020Sdes return(-1); 229157020Sdes } 230157020Sdes 231157020Sdesint RAND_pseudo_bytes(unsigned char *buf, int num) 232157020Sdes { 233157020Sdes const RAND_METHOD *meth = RAND_get_rand_method(); 234147006Sdes if (meth && meth->pseudorand) 235147006Sdes return meth->pseudorand(buf,num); 236147006Sdes return(-1); 237147006Sdes } 238162860Sdes 239162860Sdesint RAND_status(void) 240162860Sdes { 241162860Sdes const RAND_METHOD *meth = RAND_get_rand_method(); 242137019Sdes if (meth && meth->status) 243137019Sdes return meth->status(); 244137019Sdes return 0; 245137019Sdes } 246147006Sdes