rand_unix.c revision 109998
1109998Smarkm/* crypto/rand/rand_unix.c */ 2109998Smarkm/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 3109998Smarkm * All rights reserved. 4109998Smarkm * 5109998Smarkm * This package is an SSL implementation written 6109998Smarkm * by Eric Young (eay@cryptsoft.com). 7109998Smarkm * The implementation was written so as to conform with Netscapes SSL. 8109998Smarkm * 9109998Smarkm * This library is free for commercial and non-commercial use as long as 10109998Smarkm * the following conditions are aheared to. The following conditions 11109998Smarkm * apply to all code found in this distribution, be it the RC4, RSA, 12109998Smarkm * lhash, DES, etc., code; not just the SSL code. The SSL documentation 13109998Smarkm * included with this distribution is covered by the same copyright terms 14109998Smarkm * except that the holder is Tim Hudson (tjh@cryptsoft.com). 15109998Smarkm * 16109998Smarkm * Copyright remains Eric Young's, and as such any Copyright notices in 17109998Smarkm * the code are not to be removed. 18109998Smarkm * If this package is used in a product, Eric Young should be given attribution 19109998Smarkm * as the author of the parts of the library used. 20109998Smarkm * This can be in the form of a textual message at program startup or 21109998Smarkm * in documentation (online or textual) provided with the package. 22109998Smarkm * 23109998Smarkm * Redistribution and use in source and binary forms, with or without 24109998Smarkm * modification, are permitted provided that the following conditions 25109998Smarkm * are met: 26109998Smarkm * 1. Redistributions of source code must retain the copyright 27109998Smarkm * notice, this list of conditions and the following disclaimer. 28109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 29109998Smarkm * notice, this list of conditions and the following disclaimer in the 30109998Smarkm * documentation and/or other materials provided with the distribution. 31109998Smarkm * 3. All advertising materials mentioning features or use of this software 32109998Smarkm * must display the following acknowledgement: 33109998Smarkm * "This product includes cryptographic software written by 34109998Smarkm * Eric Young (eay@cryptsoft.com)" 35109998Smarkm * The word 'cryptographic' can be left out if the rouines from the library 36109998Smarkm * being used are not cryptographic related :-). 37109998Smarkm * 4. If you include any Windows specific code (or a derivative thereof) from 38109998Smarkm * the apps directory (application code) you must include an acknowledgement: 39109998Smarkm * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" 40109998Smarkm * 41109998Smarkm * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND 42109998Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 43109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 44109998Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 45109998Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 46109998Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 47109998Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 48109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 49109998Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 50109998Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 51109998Smarkm * SUCH DAMAGE. 52109998Smarkm * 53109998Smarkm * The licence and distribution terms for any publically available version or 54109998Smarkm * derivative of this code cannot be changed. i.e. this code cannot simply be 55109998Smarkm * copied and put under another distribution licence 56109998Smarkm * [including the GNU Public Licence.] 57109998Smarkm */ 58109998Smarkm/* ==================================================================== 59109998Smarkm * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. 60109998Smarkm * 61109998Smarkm * Redistribution and use in source and binary forms, with or without 62109998Smarkm * modification, are permitted provided that the following conditions 63109998Smarkm * are met: 64109998Smarkm * 65109998Smarkm * 1. Redistributions of source code must retain the above copyright 66109998Smarkm * notice, this list of conditions and the following disclaimer. 67109998Smarkm * 68109998Smarkm * 2. Redistributions in binary form must reproduce the above copyright 69109998Smarkm * notice, this list of conditions and the following disclaimer in 70109998Smarkm * the documentation and/or other materials provided with the 71109998Smarkm * distribution. 72109998Smarkm * 73109998Smarkm * 3. All advertising materials mentioning features or use of this 74109998Smarkm * software must display the following acknowledgment: 75109998Smarkm * "This product includes software developed by the OpenSSL Project 76109998Smarkm * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 77109998Smarkm * 78109998Smarkm * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 79109998Smarkm * endorse or promote products derived from this software without 80109998Smarkm * prior written permission. For written permission, please contact 81109998Smarkm * openssl-core@openssl.org. 82109998Smarkm * 83109998Smarkm * 5. Products derived from this software may not be called "OpenSSL" 84109998Smarkm * nor may "OpenSSL" appear in their names without prior written 85109998Smarkm * permission of the OpenSSL Project. 86109998Smarkm * 87109998Smarkm * 6. Redistributions of any form whatsoever must retain the following 88109998Smarkm * acknowledgment: 89109998Smarkm * "This product includes software developed by the OpenSSL Project 90109998Smarkm * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 91109998Smarkm * 92109998Smarkm * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 93109998Smarkm * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 94109998Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 95109998Smarkm * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 96109998Smarkm * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 97109998Smarkm * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 98109998Smarkm * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 99109998Smarkm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 100109998Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 101109998Smarkm * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 102109998Smarkm * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 103109998Smarkm * OF THE POSSIBILITY OF SUCH DAMAGE. 104109998Smarkm * ==================================================================== 105109998Smarkm * 106109998Smarkm * This product includes cryptographic software written by Eric Young 107109998Smarkm * (eay@cryptsoft.com). This product includes software written by Tim 108109998Smarkm * Hudson (tjh@cryptsoft.com). 109109998Smarkm * 110109998Smarkm */ 111109998Smarkm 112109998Smarkm#define USE_SOCKETS 113109998Smarkm#include "e_os.h" 114109998Smarkm#include "cryptlib.h" 115109998Smarkm#include <openssl/rand.h> 116109998Smarkm#include "rand_lcl.h" 117109998Smarkm 118109998Smarkm#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS)) 119109998Smarkm 120109998Smarkm#include <sys/types.h> 121109998Smarkm#include <sys/time.h> 122109998Smarkm#include <sys/times.h> 123109998Smarkm#include <fcntl.h> 124109998Smarkm#include <unistd.h> 125109998Smarkm#include <time.h> 126109998Smarkm 127109998Smarkmint RAND_poll(void) 128109998Smarkm{ 129109998Smarkm unsigned long l; 130109998Smarkm pid_t curr_pid = getpid(); 131109998Smarkm#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) 132109998Smarkm unsigned char tmpbuf[ENTROPY_NEEDED]; 133109998Smarkm int n = 0; 134109998Smarkm#endif 135109998Smarkm#ifdef DEVRANDOM 136109998Smarkm static const char *randomfiles[] = { DEVRANDOM, NULL }; 137109998Smarkm const char **randomfile = NULL; 138109998Smarkm int fd; 139109998Smarkm#endif 140109998Smarkm#ifdef DEVRANDOM_EGD 141109998Smarkm static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; 142109998Smarkm const char **egdsocket = NULL; 143109998Smarkm#endif 144109998Smarkm 145109998Smarkm#ifdef DEVRANDOM 146109998Smarkm /* Use a random entropy pool device. Linux, FreeBSD and OpenBSD 147109998Smarkm * have this. Use /dev/urandom if you can as /dev/random may block 148109998Smarkm * if it runs out of random entries. */ 149109998Smarkm 150109998Smarkm for (randomfile = randomfiles; *randomfile && n < ENTROPY_NEEDED; randomfile++) 151109998Smarkm { 152109998Smarkm if ((fd = open(*randomfile, O_RDONLY|O_NONBLOCK 153109998Smarkm#ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do not make it 154109998Smarkm our controlling tty */ 155109998Smarkm |O_NOCTTY 156109998Smarkm#endif 157109998Smarkm#ifdef O_NOFOLLOW /* Fail if the file is a symbolic link */ 158109998Smarkm |O_NOFOLLOW 159109998Smarkm#endif 160109998Smarkm )) >= 0) 161109998Smarkm { 162109998Smarkm struct timeval t = { 0, 10*1000 }; /* Spend 10ms on 163109998Smarkm each file. */ 164109998Smarkm int r; 165109998Smarkm fd_set fset; 166109998Smarkm 167109998Smarkm do 168109998Smarkm { 169109998Smarkm FD_ZERO(&fset); 170109998Smarkm FD_SET(fd, &fset); 171109998Smarkm r = -1; 172109998Smarkm 173109998Smarkm if (select(fd+1,&fset,NULL,NULL,&t) < 0) 174109998Smarkm t.tv_usec=0; 175109998Smarkm else if (FD_ISSET(fd, &fset)) 176109998Smarkm { 177109998Smarkm r=read(fd,(unsigned char *)tmpbuf+n, 178109998Smarkm ENTROPY_NEEDED-n); 179109998Smarkm if (r > 0) 180109998Smarkm n += r; 181109998Smarkm } 182109998Smarkm 183109998Smarkm /* Some Unixen will update t, some 184109998Smarkm won't. For those who won't, give 185109998Smarkm up here, otherwise, we will do 186109998Smarkm this once again for the remaining 187109998Smarkm time. */ 188109998Smarkm if (t.tv_usec == 10*1000) 189109998Smarkm t.tv_usec=0; 190109998Smarkm } 191109998Smarkm while ((r > 0 || (errno == EINTR || errno == EAGAIN)) 192109998Smarkm && t.tv_usec != 0 && n < ENTROPY_NEEDED); 193109998Smarkm 194109998Smarkm close(fd); 195109998Smarkm } 196109998Smarkm } 197109998Smarkm#endif 198109998Smarkm 199109998Smarkm#ifdef DEVRANDOM_EGD 200109998Smarkm /* Use an EGD socket to read entropy from an EGD or PRNGD entropy 201109998Smarkm * collecting daemon. */ 202109998Smarkm 203109998Smarkm for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED; egdsocket++) 204109998Smarkm { 205109998Smarkm int r; 206109998Smarkm 207109998Smarkm r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf+n, 208109998Smarkm ENTROPY_NEEDED-n); 209109998Smarkm if (r > 0) 210109998Smarkm n += r; 211109998Smarkm } 212109998Smarkm#endif 213109998Smarkm 214109998Smarkm#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) 215109998Smarkm if (n > 0) 216109998Smarkm { 217109998Smarkm RAND_add(tmpbuf,sizeof tmpbuf,n); 218109998Smarkm OPENSSL_cleanse(tmpbuf,n); 219109998Smarkm } 220109998Smarkm#endif 221109998Smarkm 222109998Smarkm /* put in some default random data, we need more than just this */ 223109998Smarkm l=curr_pid; 224109998Smarkm RAND_add(&l,sizeof(l),0); 225109998Smarkm l=getuid(); 226109998Smarkm RAND_add(&l,sizeof(l),0); 227109998Smarkm 228109998Smarkm l=time(NULL); 229109998Smarkm RAND_add(&l,sizeof(l),0); 230109998Smarkm 231109998Smarkm#if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) 232109998Smarkm return 1; 233109998Smarkm#else 234109998Smarkm return 0; 235109998Smarkm#endif 236109998Smarkm} 237109998Smarkm 238109998Smarkm#endif 239109998Smarkm 240109998Smarkm#if defined(OPENSSL_SYS_VXWORKS) 241109998Smarkmint RAND_poll(void) 242109998Smarkm{ 243109998Smarkm return 0; 244109998Smarkm} 245109998Smarkm#endif 246