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.
8280297Sjkim *
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).
15280297Sjkim *
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.
22280297Sjkim *
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 :-).
37280297Sjkim * 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)"
40280297Sjkim *
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.
52280297Sjkim *
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/* ====================================================================
59162911Ssimon * Copyright (c) 1998-2006 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
66280297Sjkim *    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 */
111160814Ssimon#include <stdio.h>
112109998Smarkm
113109998Smarkm#define USE_SOCKETS
114109998Smarkm#include "e_os.h"
115109998Smarkm#include "cryptlib.h"
116109998Smarkm#include <openssl/rand.h>
117109998Smarkm#include "rand_lcl.h"
118109998Smarkm
119162911Ssimon#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))
120109998Smarkm
121280297Sjkim# include <sys/types.h>
122280297Sjkim# include <sys/time.h>
123280297Sjkim# include <sys/times.h>
124280297Sjkim# include <sys/stat.h>
125280297Sjkim# include <fcntl.h>
126280297Sjkim# include <unistd.h>
127280297Sjkim# include <time.h>
128280297Sjkim# if defined(OPENSSL_SYS_LINUX) /* should actually be available virtually
129280297Sjkim                                 * everywhere */
130280297Sjkim#  include <poll.h>
131280297Sjkim# endif
132280297Sjkim# include <limits.h>
133280297Sjkim# ifndef FD_SETSIZE
134280297Sjkim#  define FD_SETSIZE (8*sizeof(fd_set))
135280297Sjkim# endif
136109998Smarkm
137280297Sjkim# if defined(OPENSSL_SYS_VOS)
138238405Sjkim
139280297Sjkim/*
140280297Sjkim * The following algorithm repeatedly samples the real-time clock (RTC) to
141280297Sjkim * generate a sequence of unpredictable data.  The algorithm relies upon the
142280297Sjkim * uneven execution speed of the code (due to factors such as cache misses,
143280297Sjkim * interrupts, bus activity, and scheduling) and upon the rather large
144280297Sjkim * relative difference between the speed of the clock and the rate at which
145280297Sjkim * it can be read.
146280297Sjkim *
147280297Sjkim * If this code is ported to an environment where execution speed is more
148280297Sjkim * constant or where the RTC ticks at a much slower rate, or the clock can be
149280297Sjkim * read with fewer instructions, it is likely that the results would be far
150280297Sjkim * more predictable.
151280297Sjkim *
152280297Sjkim * As a precaution, we generate 4 times the minimum required amount of seed
153280297Sjkim * data.
154280297Sjkim */
155238405Sjkim
156109998Smarkmint RAND_poll(void)
157109998Smarkm{
158280297Sjkim    short int code;
159280297Sjkim    gid_t curr_gid;
160280297Sjkim    pid_t curr_pid;
161280297Sjkim    uid_t curr_uid;
162280297Sjkim    int i, k;
163280297Sjkim    struct timespec ts;
164280297Sjkim    unsigned char v;
165238405Sjkim
166280297Sjkim#  ifdef OPENSSL_SYS_VOS_HPPA
167280297Sjkim    long duration;
168280297Sjkim    extern void s$sleep(long *_duration, short int *_code);
169280297Sjkim#  else
170280297Sjkim#   ifdef OPENSSL_SYS_VOS_IA32
171280297Sjkim    long long duration;
172280297Sjkim    extern void s$sleep2(long long *_duration, short int *_code);
173280297Sjkim#   else
174280297Sjkim#    error "Unsupported Platform."
175280297Sjkim#   endif                       /* OPENSSL_SYS_VOS_IA32 */
176280297Sjkim#  endif                        /* OPENSSL_SYS_VOS_HPPA */
177238405Sjkim
178280297Sjkim    /*
179280297Sjkim     * Seed with the gid, pid, and uid, to ensure *some* variation between
180280297Sjkim     * different processes.
181280297Sjkim     */
182238405Sjkim
183280297Sjkim    curr_gid = getgid();
184331638Sjkim    RAND_add(&curr_gid, sizeof(curr_gid), 1);
185280297Sjkim    curr_gid = 0;
186238405Sjkim
187280297Sjkim    curr_pid = getpid();
188331638Sjkim    RAND_add(&curr_pid, sizeof(curr_pid), 1);
189280297Sjkim    curr_pid = 0;
190238405Sjkim
191280297Sjkim    curr_uid = getuid();
192331638Sjkim    RAND_add(&curr_uid, sizeof(curr_uid), 1);
193280297Sjkim    curr_uid = 0;
194238405Sjkim
195280297Sjkim    for (i = 0; i < (ENTROPY_NEEDED * 4); i++) {
196280297Sjkim        /*
197280297Sjkim         * burn some cpu; hope for interrupts, cache collisions, bus
198280297Sjkim         * interference, etc.
199280297Sjkim         */
200280297Sjkim        for (k = 0; k < 99; k++)
201280297Sjkim            ts.tv_nsec = random();
202238405Sjkim
203280297Sjkim#  ifdef OPENSSL_SYS_VOS_HPPA
204280297Sjkim        /* sleep for 1/1024 of a second (976 us).  */
205280297Sjkim        duration = 1;
206280297Sjkim        s$sleep(&duration, &code);
207280297Sjkim#  else
208280297Sjkim#   ifdef OPENSSL_SYS_VOS_IA32
209280297Sjkim        /* sleep for 1/65536 of a second (15 us).  */
210280297Sjkim        duration = 1;
211280297Sjkim        s$sleep2(&duration, &code);
212280297Sjkim#   endif                       /* OPENSSL_SYS_VOS_IA32 */
213280297Sjkim#  endif                        /* OPENSSL_SYS_VOS_HPPA */
214238405Sjkim
215280297Sjkim        /* get wall clock time.  */
216280297Sjkim        clock_gettime(CLOCK_REALTIME, &ts);
217238405Sjkim
218280297Sjkim        /* take 8 bits */
219280297Sjkim        v = (unsigned char)(ts.tv_nsec % 256);
220331638Sjkim        RAND_add(&v, sizeof(v), 1);
221280297Sjkim        v = 0;
222280297Sjkim    }
223280297Sjkim    return 1;
224238405Sjkim}
225280297Sjkim# elif defined(__FreeBSD__) || defined(__OpenBSD__)
226238405Sjkimint RAND_poll(void)
227238405Sjkim{
228280297Sjkim    u_int32_t rnd = 0, i;
229280297Sjkim    unsigned char buf[ENTROPY_NEEDED];
230127128Snectar
231280297Sjkim    for (i = 0; i < sizeof(buf); i++) {
232280297Sjkim        if (i % 4 == 0)
233280297Sjkim            rnd = arc4random();
234280297Sjkim        buf[i] = rnd;
235280297Sjkim        rnd >>= 8;
236280297Sjkim    }
237280297Sjkim    RAND_add(buf, sizeof(buf), ENTROPY_NEEDED);
238306195Sjkim    OPENSSL_cleanse(buf, sizeof(buf));
239127128Snectar
240280297Sjkim    return 1;
241127128Snectar}
242280297Sjkim# else                          /* !(defined(__FreeBSD__) ||
243280297Sjkim                                 * defined(__OpenBSD__)) */
244127128Snectarint RAND_poll(void)
245127128Snectar{
246280297Sjkim    unsigned long l;
247280297Sjkim    pid_t curr_pid = getpid();
248280297Sjkim#  if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
249280297Sjkim    unsigned char tmpbuf[ENTROPY_NEEDED];
250280297Sjkim    int n = 0;
251280297Sjkim#  endif
252280297Sjkim#  ifdef DEVRANDOM
253280297Sjkim    static const char *randomfiles[] = { DEVRANDOM };
254280297Sjkim    struct stat randomstats[sizeof(randomfiles) / sizeof(randomfiles[0])];
255280297Sjkim    int fd;
256280297Sjkim    unsigned int i;
257280297Sjkim#  endif
258280297Sjkim#  ifdef DEVRANDOM_EGD
259280297Sjkim    static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
260280297Sjkim    const char **egdsocket = NULL;
261280297Sjkim#  endif
262109998Smarkm
263280297Sjkim#  ifdef DEVRANDOM
264280297Sjkim    memset(randomstats, 0, sizeof(randomstats));
265280297Sjkim    /*
266280297Sjkim     * Use a random entropy pool device. Linux, FreeBSD and OpenBSD have
267280297Sjkim     * this. Use /dev/urandom if you can as /dev/random may block if it runs
268280297Sjkim     * out of random entries.
269280297Sjkim     */
270109998Smarkm
271280297Sjkim    for (i = 0; (i < sizeof(randomfiles) / sizeof(randomfiles[0])) &&
272280297Sjkim         (n < ENTROPY_NEEDED); i++) {
273280297Sjkim        if ((fd = open(randomfiles[i], O_RDONLY
274280297Sjkim#   ifdef O_NONBLOCK
275280297Sjkim                       | O_NONBLOCK
276280297Sjkim#   endif
277280297Sjkim#   ifdef O_BINARY
278280297Sjkim                       | O_BINARY
279280297Sjkim#   endif
280280297Sjkim#   ifdef O_NOCTTY              /* If it happens to be a TTY (god forbid), do
281280297Sjkim                                 * not make it our controlling tty */
282280297Sjkim                       | O_NOCTTY
283280297Sjkim#   endif
284280297Sjkim             )) >= 0) {
285280297Sjkim            int usec = 10 * 1000; /* spend 10ms on each file */
286280297Sjkim            int r;
287280297Sjkim            unsigned int j;
288280297Sjkim            struct stat *st = &randomstats[i];
289109998Smarkm
290280297Sjkim            /*
291280297Sjkim             * Avoid using same input... Used to be O_NOFOLLOW above, but
292280297Sjkim             * it's not universally appropriate...
293280297Sjkim             */
294280297Sjkim            if (fstat(fd, st) != 0) {
295280297Sjkim                close(fd);
296280297Sjkim                continue;
297280297Sjkim            }
298280297Sjkim            for (j = 0; j < i; j++) {
299280297Sjkim                if (randomstats[j].st_ino == st->st_ino &&
300280297Sjkim                    randomstats[j].st_dev == st->st_dev)
301280297Sjkim                    break;
302280297Sjkim            }
303280297Sjkim            if (j < i) {
304280297Sjkim                close(fd);
305280297Sjkim                continue;
306280297Sjkim            }
307160814Ssimon
308280297Sjkim            do {
309280297Sjkim                int try_read = 0;
310109998Smarkm
311280297Sjkim#   if defined(OPENSSL_SYS_BEOS_R5)
312280297Sjkim                /*
313280297Sjkim                 * select() is broken in BeOS R5, so we simply try to read
314280297Sjkim                 * something and snooze if we couldn't
315280297Sjkim                 */
316280297Sjkim                try_read = 1;
317238405Sjkim
318280297Sjkim#   elif defined(OPENSSL_SYS_LINUX)
319280297Sjkim                /* use poll() */
320280297Sjkim                struct pollfd pset;
321162911Ssimon
322280297Sjkim                pset.fd = fd;
323280297Sjkim                pset.events = POLLIN;
324280297Sjkim                pset.revents = 0;
325162911Ssimon
326280297Sjkim                if (poll(&pset, 1, usec / 1000) < 0)
327280297Sjkim                    usec = 0;
328280297Sjkim                else
329280297Sjkim                    try_read = (pset.revents & POLLIN) != 0;
330162911Ssimon
331280297Sjkim#   else
332280297Sjkim                /* use select() */
333280297Sjkim                fd_set fset;
334280297Sjkim                struct timeval t;
335109998Smarkm
336280297Sjkim                t.tv_sec = 0;
337280297Sjkim                t.tv_usec = usec;
338109998Smarkm
339280297Sjkim                if (FD_SETSIZE > 0 && (unsigned)fd >= FD_SETSIZE) {
340280297Sjkim                    /*
341280297Sjkim                     * can't use select, so just try to read once anyway
342280297Sjkim                     */
343280297Sjkim                    try_read = 1;
344280297Sjkim                } else {
345280297Sjkim                    FD_ZERO(&fset);
346280297Sjkim                    FD_SET(fd, &fset);
347109998Smarkm
348280297Sjkim                    if (select(fd + 1, &fset, NULL, NULL, &t) >= 0) {
349280297Sjkim                        usec = t.tv_usec;
350280297Sjkim                        if (FD_ISSET(fd, &fset))
351280297Sjkim                            try_read = 1;
352280297Sjkim                    } else
353280297Sjkim                        usec = 0;
354280297Sjkim                }
355280297Sjkim#   endif
356109998Smarkm
357280297Sjkim                if (try_read) {
358280297Sjkim                    r = read(fd, (unsigned char *)tmpbuf + n,
359280297Sjkim                             ENTROPY_NEEDED - n);
360280297Sjkim                    if (r > 0)
361280297Sjkim                        n += r;
362280297Sjkim#   if defined(OPENSSL_SYS_BEOS_R5)
363280297Sjkim                    if (r == 0)
364280297Sjkim                        snooze(t.tv_usec);
365280297Sjkim#   endif
366280297Sjkim                } else
367280297Sjkim                    r = -1;
368109998Smarkm
369280297Sjkim                /*
370280297Sjkim                 * Some Unixen will update t in select(), some won't.  For
371280297Sjkim                 * those who won't, or if we didn't use select() in the first
372280297Sjkim                 * place, give up here, otherwise, we will do this once again
373280297Sjkim                 * for the remaining time.
374280297Sjkim                 */
375280297Sjkim                if (usec == 10 * 1000)
376280297Sjkim                    usec = 0;
377280297Sjkim            }
378280297Sjkim            while ((r > 0 ||
379280297Sjkim                    (errno == EINTR || errno == EAGAIN)) && usec != 0
380280297Sjkim                   && n < ENTROPY_NEEDED);
381109998Smarkm
382280297Sjkim            close(fd);
383280297Sjkim        }
384280297Sjkim    }
385280297Sjkim#  endif                        /* defined(DEVRANDOM) */
386109998Smarkm
387280297Sjkim#  ifdef DEVRANDOM_EGD
388280297Sjkim    /*
389280297Sjkim     * Use an EGD socket to read entropy from an EGD or PRNGD entropy
390280297Sjkim     * collecting daemon.
391280297Sjkim     */
392109998Smarkm
393280297Sjkim    for (egdsocket = egdsockets; *egdsocket && n < ENTROPY_NEEDED;
394280297Sjkim         egdsocket++) {
395280297Sjkim        int r;
396238405Sjkim
397280297Sjkim        r = RAND_query_egd_bytes(*egdsocket, (unsigned char *)tmpbuf + n,
398280297Sjkim                                 ENTROPY_NEEDED - n);
399280297Sjkim        if (r > 0)
400280297Sjkim            n += r;
401280297Sjkim    }
402280297Sjkim#  endif                        /* defined(DEVRANDOM_EGD) */
403280297Sjkim
404280297Sjkim#  if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
405280297Sjkim    if (n > 0) {
406331638Sjkim        RAND_add(tmpbuf, sizeof(tmpbuf), (double)n);
407280297Sjkim        OPENSSL_cleanse(tmpbuf, n);
408280297Sjkim    }
409280297Sjkim#  endif
410280297Sjkim
411280297Sjkim    /* put in some default random data, we need more than just this */
412280297Sjkim    l = curr_pid;
413280297Sjkim    RAND_add(&l, sizeof(l), 0.0);
414280297Sjkim    l = getuid();
415280297Sjkim    RAND_add(&l, sizeof(l), 0.0);
416280297Sjkim
417280297Sjkim    l = time(NULL);
418280297Sjkim    RAND_add(&l, sizeof(l), 0.0);
419280297Sjkim
420280297Sjkim#  if defined(OPENSSL_SYS_BEOS)
421280297Sjkim    {
422280297Sjkim        system_info sysInfo;
423280297Sjkim        get_system_info(&sysInfo);
424280297Sjkim        RAND_add(&sysInfo, sizeof(sysInfo), 0);
425280297Sjkim    }
426280297Sjkim#  endif
427280297Sjkim
428280297Sjkim#  if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
429280297Sjkim    return 1;
430280297Sjkim#  else
431280297Sjkim    return 0;
432280297Sjkim#  endif
433109998Smarkm}
434109998Smarkm
435280297Sjkim# endif                         /* defined(__FreeBSD__) ||
436280297Sjkim                                 * defined(__OpenBSD__) */
437280297Sjkim#endif                          /* !(defined(OPENSSL_SYS_WINDOWS) ||
438280297Sjkim                                 * defined(OPENSSL_SYS_WIN32) ||
439280297Sjkim                                 * defined(OPENSSL_SYS_VMS) ||
440280297Sjkim                                 * defined(OPENSSL_SYS_OS2) ||
441280297Sjkim                                 * defined(OPENSSL_SYS_VXWORKS) ||
442280297Sjkim                                 * defined(OPENSSL_SYS_NETWARE)) */
443109998Smarkm
444109998Smarkm#if defined(OPENSSL_SYS_VXWORKS)
445109998Smarkmint RAND_poll(void)
446280297Sjkim{
447280297Sjkim    return 0;
448280297Sjkim}
449109998Smarkm#endif
450