28fb1f2c600b284f271b6be13daebb2b4478d942
[openssl.git] / crypto / rand / rand_egd.c
1 /* crypto/rand/rand_egd.c */
2 /* Written by Ulf Moeller for the OpenSSL project. */
3 /* ====================================================================
4  * Copyright (c) 1998-2000 The OpenSSL Project.  All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * 3. All advertising materials mentioning features or use of this
19  *    software must display the following acknowledgment:
20  *    "This product includes software developed by the OpenSSL Project
21  *    for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
22  *
23  * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
24  *    endorse or promote products derived from this software without
25  *    prior written permission. For written permission, please contact
26  *    openssl-core@openssl.org.
27  *
28  * 5. Products derived from this software may not be called "OpenSSL"
29  *    nor may "OpenSSL" appear in their names without prior written
30  *    permission of the OpenSSL Project.
31  *
32  * 6. Redistributions of any form whatsoever must retain the following
33  *    acknowledgment:
34  *    "This product includes software developed by the OpenSSL Project
35  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
36  *
37  * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
38  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
39  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
40  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
41  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
42  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
43  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
44  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
45  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
46  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
47  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
48  * OF THE POSSIBILITY OF SUCH DAMAGE.
49  * ====================================================================
50  *
51  * This product includes cryptographic software written by Eric Young
52  * (eay@cryptsoft.com).  This product includes software written by Tim
53  * Hudson (tjh@cryptsoft.com).
54  *
55  */
56
57 #include <openssl/rand.h>
58
59 /* Query the EGD <URL: http://www.lothar.com/tech/crypto/>.
60  */
61
62 #if defined(WIN32) || defined(VMS) || defined(__VMS)
63 int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
64         {
65         return(-1);
66         }
67 int RAND_egd(const char *path)
68         {
69         return(-1);
70         }
71
72 int RAND_egd_bytes(const char *path,int bytes)
73         {
74         return(-1);
75         }
76 #else
77 #include <openssl/opensslconf.h>
78 #include OPENSSL_UNISTD
79 #include <sys/types.h>
80 #include <sys/socket.h>
81 #include <sys/un.h>
82 #include <string.h>
83
84 #ifndef offsetof
85 #  define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
86 #endif
87
88 int RAND_query_egd_bytes(const char *path, unsigned char *buf, int bytes)
89         {
90         int ret = 0;
91         struct sockaddr_un addr;
92         int len, num;
93         int fd = -1;
94         unsigned char egdbuf[2];
95
96         memset(&addr, 0, sizeof(addr));
97         addr.sun_family = AF_UNIX;
98         if (strlen(path) > sizeof(addr.sun_path))
99                 return (-1);
100         strcpy(addr.sun_path,path);
101         len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
102         fd = socket(AF_UNIX, SOCK_STREAM, 0);
103         if (fd == -1) return (-1);
104         if (connect(fd, (struct sockaddr *)&addr, len) == -1) goto err;
105
106         while(bytes > 0)
107             {
108             egdbuf[0] = 1;
109             egdbuf[1] = bytes < 255 ? bytes : 255;
110             write(fd, egdbuf, 2);
111             if (read(fd, egdbuf, 1) != 1)
112                 {
113                 ret=-1;
114                 goto err;
115                 }
116             if(egdbuf[0] == 0)
117                 goto err;
118             num = read(fd, buf + ret, egdbuf[0]);
119             if (num < 1)
120                 {
121                 ret=-1;
122                 goto err;
123                 }
124             ret += num;
125             bytes-=num;
126             }
127  err:
128         if (fd != -1) close(fd);
129         return(ret);
130         }
131
132 int RAND_egd(const char *path)
133         {
134         int num, ret;
135         unsigned char buf[256];
136
137         num = RAND_query_egd_bytes(path, buf, 255);
138         if (num < 1) goto err;
139         RAND_seed(buf, num);
140         if (RAND_status() == 1)
141                 ret = num;
142  err:
143         return(ret);
144         }
145
146 int RAND_egd_bytes(const char *path,int bytes)
147         {
148         int ret = 0;
149         struct sockaddr_un addr;
150         int len, num;
151         int fd = -1;
152         unsigned char buf[255];
153
154         memset(&addr, 0, sizeof(addr));
155         addr.sun_family = AF_UNIX;
156         if (strlen(path) > sizeof(addr.sun_path))
157                 return (-1);
158         strcpy(addr.sun_path,path);
159         len = offsetof(struct sockaddr_un, sun_path) + strlen(path);
160         fd = socket(AF_UNIX, SOCK_STREAM, 0);
161         if (fd == -1) return (-1);
162         if (connect(fd, (struct sockaddr *)&addr, len) == -1) goto err;
163
164         while(bytes > 0)
165             {
166             buf[0] = 1;
167             buf[1] = bytes < 255 ? bytes : 255;
168             write(fd, buf, 2);
169             if (read(fd, buf, 1) != 1)
170                 {
171                 ret=-1;
172                 goto err;
173                 }
174             if(buf[0] == 0)
175                 goto err;
176             num = read(fd, buf, buf[0]);
177             if (num < 1)
178                 {
179                 ret=-1;
180                 goto err;
181                 }
182             RAND_seed(buf, num);
183             if (RAND_status() != 1)
184                 {
185                 ret=-1;
186                 goto err;
187                 }
188             ret += num;
189             bytes-=num;
190             }
191  err:
192         if (fd != -1) close(fd);
193         return(ret);
194         }
195
196
197 #endif