From f1625f274acf5dcd5601f6cb5e29e233b2a441a3 Mon Sep 17 00:00:00 2001 From: djm <> Date: Sat, 6 Sep 2008 12:15:54 +0000 Subject: import of OpenSSL 0.9.8h --- src/lib/libcrypto/rand/rand_unix.c | 119 ++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 35 deletions(-) (limited to 'src/lib/libcrypto/rand/rand_unix.c') diff --git a/src/lib/libcrypto/rand/rand_unix.c b/src/lib/libcrypto/rand/rand_unix.c index 9376554fae..6c2be5cb96 100644 --- a/src/lib/libcrypto/rand/rand_unix.c +++ b/src/lib/libcrypto/rand/rand_unix.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2000 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -108,6 +108,7 @@ * Hudson (tjh@cryptsoft.com). * */ +#include #define USE_SOCKETS #include "e_os.h" @@ -115,7 +116,7 @@ #include #include "rand_lcl.h" -#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS)) +#if !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) #include #include @@ -124,6 +125,13 @@ #include #include #include +#if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually everywhere */ +# include +#endif +#include +#ifndef FD_SETSIZE +# define FD_SETSIZE (8*sizeof(fd_set)) +#endif #ifdef __OpenBSD__ int RAND_poll(void) @@ -142,7 +150,7 @@ int RAND_poll(void) return 1; } -#else +#else /* !defined(__OpenBSD__) */ int RAND_poll(void) { unsigned long l; @@ -154,7 +162,8 @@ int RAND_poll(void) #ifdef DEVRANDOM static const char *randomfiles[] = { DEVRANDOM }; struct stat randomstats[sizeof(randomfiles)/sizeof(randomfiles[0])]; - int fd,i; + int fd; + size_t i; #endif #ifdef DEVRANDOM_EGD static const char *egdsockets[] = { DEVRANDOM_EGD, NULL }; @@ -182,10 +191,9 @@ int RAND_poll(void) #endif )) >= 0) { - struct timeval t = { 0, 10*1000 }; /* Spend 10ms on - each file. */ - int r,j; - fd_set fset; + int usec = 10*1000; /* spend 10ms on each file */ + int r; + size_t j; struct stat *st=&randomstats[i]; /* Avoid using same input... Used to be O_NOFOLLOW @@ -201,35 +209,75 @@ int RAND_poll(void) do { - FD_ZERO(&fset); - FD_SET(fd, &fset); - r = -1; + int try_read = 0; - if (select(fd+1,&fset,NULL,NULL,&t) < 0) - t.tv_usec=0; - else if (FD_ISSET(fd, &fset)) +#if defined(OPENSSL_SYS_LINUX) + /* use poll() */ + struct pollfd pset; + + pset.fd = fd; + pset.events = POLLIN; + pset.revents = 0; + + if (poll(&pset, 1, usec / 1000) < 0) + usec = 0; + else + try_read = (pset.revents & POLLIN) != 0; + +#else + /* use select() */ + fd_set fset; + struct timeval t; + + t.tv_sec = 0; + t.tv_usec = usec; + + if (FD_SETSIZE > 0 && fd >= FD_SETSIZE) + { + /* can't use select, so just try to read once anyway */ + try_read = 1; + } + else + { + FD_ZERO(&fset); + FD_SET(fd, &fset); + + if (select(fd+1,&fset,NULL,NULL,&t) >= 0) + { + usec = t.tv_usec; + if (FD_ISSET(fd, &fset)) + try_read = 1; + } + else + usec = 0; + } +#endif + + if (try_read) { - r=read(fd,(unsigned char *)tmpbuf+n, - ENTROPY_NEEDED-n); + r = read(fd,(unsigned char *)tmpbuf+n, ENTROPY_NEEDED-n); if (r > 0) n += r; } - - /* Some Unixen will update t, some - won't. For those who won't, give - up here, otherwise, we will do + else + r = -1; + + /* Some Unixen will update t in select(), some + won't. For those who won't, or if we + didn't use select() in the first place, + give up here, otherwise, we will do this once again for the remaining time. */ - if (t.tv_usec == 10*1000) - t.tv_usec=0; + if (usec == 10*1000) + usec = 0; } - while ((r > 0 || (errno == EINTR || errno == EAGAIN)) - && t.tv_usec != 0 && n < ENTROPY_NEEDED); + while ((r > 0 || + (errno == EINTR || errno == EAGAIN)) && usec != 0 && n < ENTROPY_NEEDED); close(fd); } } -#endif +#endif /* defined(DEVRANDOM) */ #ifdef DEVRANDOM_EGD /* Use an EGD socket to read entropy from an EGD or PRNGD entropy @@ -244,24 +292,24 @@ int RAND_poll(void) if (r > 0) n += r; } -#endif +#endif /* defined(DEVRANDOM_EGD) */ #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) if (n > 0) { - RAND_add(tmpbuf,sizeof tmpbuf,n); + RAND_add(tmpbuf,sizeof tmpbuf,(double)n); OPENSSL_cleanse(tmpbuf,n); } #endif /* put in some default random data, we need more than just this */ l=curr_pid; - RAND_add(&l,sizeof(l),0); + RAND_add(&l,sizeof(l),0.0); l=getuid(); - RAND_add(&l,sizeof(l),0); + RAND_add(&l,sizeof(l),0.0); l=time(NULL); - RAND_add(&l,sizeof(l),0); + RAND_add(&l,sizeof(l),0.0); #if defined(DEVRANDOM) || defined(DEVRANDOM_EGD) return 1; @@ -270,12 +318,13 @@ int RAND_poll(void) #endif } -#endif -#endif +#endif /* defined(__OpenBSD__) */ +#endif /* !(defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_VXWORKS) || defined(OPENSSL_SYS_NETWARE)) */ + #if defined(OPENSSL_SYS_VXWORKS) int RAND_poll(void) -{ - return 0; -} + { + return 0; + } #endif -- cgit v1.2.3-55-g6feb