build: Fix build with !HAVE_PTHREAD
[libgcrypt.git] / random / rndlinux.c
1 /* rndlinux.c  -  raw random number for OSes with /dev/random
2  * Copyright (C) 1998, 2001, 2002, 2003, 2007,
3  *               2009  Free Software Foundation, Inc.
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser General Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <errno.h>
26 #include <sys/time.h>
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #ifdef HAVE_GETTIMEOFDAY
30 # include <sys/times.h>
31 #endif
32 #include <string.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #if defined(__linux__) || !defined(HAVE_GETENTROPY)
36 #ifdef HAVE_SYSCALL
37 # include <sys/syscall.h>
38 # ifdef __NR_getrandom
39 # define getentropy(buf,buflen) syscall (__NR_getrandom, buf, buflen, 0)
40 # endif
41 #endif
42 #endif
43
44 #include "types.h"
45 #include "g10lib.h"
46 #include "rand-internal.h"
47
48 static int open_device (const char *name, int retry);
49
50
51 static int
52 set_cloexec_flag (int fd)
53 {
54   int oldflags;
55
56   oldflags= fcntl (fd, F_GETFD, 0);
57   if (oldflags < 0)
58     return oldflags;
59   oldflags |= FD_CLOEXEC;
60   return fcntl (fd, F_SETFD, oldflags);
61 }
62
63
64
65 /*
66  * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it
67  * exists)).  If RETRY is true, the function does not terminate with
68  * a fatal error but retries until it is able to reopen the device.
69  */
70 static int
71 open_device (const char *name, int retry)
72 {
73   int fd;
74
75   if (retry)
76     _gcry_random_progress ("open_dev_random", 'X', 1, 0);
77  again:
78   fd = open (name, O_RDONLY);
79   if (fd == -1 && retry)
80     {
81       struct timeval tv;
82
83       tv.tv_sec = 5;
84       tv.tv_usec = 0;
85       _gcry_random_progress ("wait_dev_random", 'X', 0, (int)tv.tv_sec);
86       select (0, NULL, NULL, NULL, &tv);
87       goto again;
88     }
89   if (fd == -1)
90     log_fatal ("can't open %s: %s\n", name, strerror(errno) );
91
92   if (set_cloexec_flag (fd))
93     log_error ("error setting FD_CLOEXEC on fd %d: %s\n",
94                fd, strerror (errno));
95
96   /* We used to do the following check, however it turned out that this
97      is not portable since more OSes provide a random device which is
98      sometimes implemented as another device type.
99
100      struct stat sb;
101
102      if( fstat( fd, &sb ) )
103         log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
104      if( (!S_ISCHR(sb.st_mode)) && (!S_ISFIFO(sb.st_mode)) )
105         log_fatal("invalid random device!\n" );
106   */
107   return fd;
108 }
109
110
111 /* Note that the caller needs to make sure that this function is only
112  * called by one thread at a time.  The function returns 0 on success
113  * or true on failure (in which case the caller will signal a fatal
114  * error).  This function should be entered only by one thread at a
115  * time. */
116 int
117 _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
118                                           enum random_origins),
119                               enum random_origins origin,
120                               size_t length, int level )
121 {
122   static int fd_urandom = -1;
123   static int fd_random = -1;
124   static int only_urandom = -1;
125   static unsigned char ever_opened;
126   static volatile pid_t my_pid; /* The volatile is there to make sure
127                                  * the compiler does not optimize the
128                                  * code away in case the getpid
129                                  * function is badly attributed. */
130   volatile pid_t apid;
131   int fd;
132   int n;
133   byte buffer[768];
134   size_t n_hw;
135   size_t want = length;
136   size_t last_so_far = 0;
137   int any_need_entropy = 0;
138   int delay;
139
140   /* On the first call read the conf file to check whether we want to
141    * use only urandom.  */
142   if (only_urandom == -1)
143     {
144       my_pid = getpid ();
145       if ((_gcry_random_read_conf () & RANDOM_CONF_ONLY_URANDOM))
146         only_urandom = 1;
147       else
148         only_urandom = 0;
149     }
150
151   if (!add)
152     {
153       /* Special mode to close the descriptors.  */
154       if (fd_random != -1)
155         {
156           close (fd_random);
157           fd_random = -1;
158         }
159       if (fd_urandom != -1)
160         {
161           close (fd_urandom);
162           fd_urandom = -1;
163         }
164
165       _gcry_rndjent_fini ();
166       return 0;
167     }
168
169   /* Detect a fork and close the devices so that we don't use the old
170    * file descriptors.  Note that open_device will be called in retry
171    * mode if the devices was opened by the parent process.  */
172   apid = getpid ();
173   if (my_pid != apid)
174     {
175       if (fd_random != -1)
176         {
177           close (fd_random);
178           fd_random = -1;
179         }
180       if (fd_urandom != -1)
181         {
182           close (fd_urandom);
183           fd_urandom = -1;
184         }
185       my_pid = apid;
186     }
187
188
189   /* First read from a hardware source.  However let it account only
190      for up to 50% (or 25% for RDRAND) of the requested bytes.  */
191   n_hw = _gcry_rndhw_poll_slow (add, origin);
192   if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND))
193     {
194       if (n_hw > length/4)
195         n_hw = length/4;
196     }
197   else
198     {
199       if (n_hw > length/2)
200         n_hw = length/2;
201     }
202   if (length > 1)
203     length -= n_hw;
204
205   /* When using a blocking random generator try to get some entropy
206    * from the jitter based RNG.  In this case we take up to 50% of the
207    * remaining requested bytes.  */
208   if (level >= GCRY_VERY_STRONG_RANDOM)
209     {
210       n_hw = _gcry_rndjent_poll (add, origin, length/2);
211       if (n_hw > length/2)
212         n_hw = length/2;
213       if (length > 1)
214         length -= n_hw;
215     }
216
217
218   /* Open the requested device.  The first time a device is to be
219      opened we fail with a fatal error if the device does not exists.
220      In case the device has ever been closed, further open requests
221      will however retry indefinitely.  The rationale for this behaviour is
222      that we always require the device to be existent but want a more
223      graceful behaviour if the rarely needed close operation has been
224      used and the device needs to be re-opened later. */
225   if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom)
226     {
227       if (fd_random == -1)
228         {
229           fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1));
230           ever_opened |= 1;
231         }
232       fd = fd_random;
233     }
234   else
235     {
236       if (fd_urandom == -1)
237         {
238           fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2));
239           ever_opened |= 2;
240         }
241       fd = fd_urandom;
242     }
243
244   /* Enter the read loop.  */
245   delay = 0;  /* Start with 0 seconds so that we do no block on the
246                  first iteration and in turn call the progress function
247                  before blocking.  To give the OS a better chance to
248                  return with something we will actually use 100ms. */
249   while (length)
250     {
251       fd_set rfds;
252       struct timeval tv;
253       int rc;
254
255       /* If we have a modern operating system, we first try to use the new
256        * getentropy function.  That call guarantees that the kernel's
257        * RNG has been properly seeded before returning any data.  This
258        * is different from /dev/urandom which may, due to its
259        * non-blocking semantics, return data even if the kernel has
260        * not been properly seeded.  And it differs from /dev/random by never
261        * blocking once the kernel is seeded.  */
262 #if defined(HAVE_GETENTROPY) || defined(__NR_getrandom)
263         {
264           long ret;
265           size_t nbytes;
266
267           do
268             {
269               nbytes = length < sizeof(buffer)? length : sizeof(buffer);
270               if (nbytes > 256)
271                 nbytes = 256;
272               _gcry_pre_syscall ();
273               ret = getentropy (buffer, nbytes);
274               _gcry_post_syscall ();
275             }
276           while (ret == -1 && errno == EINTR);
277           if (ret == -1 && errno == ENOSYS)
278             ; /* getentropy is not supported - fallback to pulling from fd.  */
279           else
280             { /* getentropy is supported.  Some sanity checks.  */
281               if (ret == -1)
282                 log_fatal ("unexpected error from getentropy: %s\n",
283                            strerror (errno));
284 #ifdef __NR_getrandom
285               else if (ret != nbytes)
286                 log_fatal ("getentropy returned only"
287                            " %ld of %zu requested bytes\n", ret, nbytes);
288 #endif
289
290               (*add)(buffer, nbytes, origin);
291               length -= nbytes;
292               continue; /* until LENGTH is zero.  */
293             }
294         }
295 #endif
296
297       /* If we collected some bytes update the progress indicator.  We
298          do this always and not just if the select timed out because
299          often just a few bytes are gathered within the timeout
300          period.  */
301       if (any_need_entropy || last_so_far != (want - length) )
302         {
303           last_so_far = want - length;
304           _gcry_random_progress ("need_entropy", 'X',
305                                  (int)last_so_far, (int)want);
306           any_need_entropy = 1;
307         }
308
309       /* If the system has no limit on the number of file descriptors
310          and we encounter an fd which is larger than the fd_set size,
311          we don't use the select at all.  The select code is only used
312          to emit progress messages.  A better solution would be to
313          fall back to poll() if available.  */
314 #ifdef FD_SETSIZE
315       if (fd < FD_SETSIZE)
316 #endif
317         {
318           FD_ZERO(&rfds);
319           FD_SET(fd, &rfds);
320           tv.tv_sec = delay;
321           tv.tv_usec = delay? 0 : 100000;
322           _gcry_pre_syscall ();
323           rc = select (fd+1, &rfds, NULL, NULL, &tv);
324           _gcry_post_syscall ();
325           if (!rc)
326             {
327               any_need_entropy = 1;
328               delay = 3; /* Use 3 seconds henceforth.  */
329               continue;
330             }
331           else if( rc == -1 )
332             {
333               log_error ("select() error: %s\n", strerror(errno));
334               if (!delay)
335                 delay = 1; /* Use 1 second if we encounter an error before
336                               we have ever blocked.  */
337               continue;
338             }
339         }
340
341       do
342         {
343           size_t nbytes;
344
345           nbytes = length < sizeof(buffer)? length : sizeof(buffer);
346           n = read (fd, buffer, nbytes);
347           if (n >= 0 && n > nbytes)
348             {
349               log_error("bogus read from random device (n=%d)\n", n );
350               n = nbytes;
351             }
352         }
353       while (n == -1 && errno == EINTR);
354       if  (n == -1)
355         log_fatal("read error on random device: %s\n", strerror(errno));
356       (*add)(buffer, n, origin);
357       length -= n;
358     }
359   wipememory (buffer, sizeof buffer);
360
361   if (any_need_entropy)
362     _gcry_random_progress ("need_entropy", 'X', (int)want, (int)want);
363
364   return 0; /* success */
365 }