Merge branch 'master' into LIBGCRYPT-1-7-BRANCH
[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_SYSCALL)
36 # include <sys/syscall.h>
37 #endif
38
39 #include "types.h"
40 #include "g10lib.h"
41 #include "rand-internal.h"
42
43 static int open_device (const char *name, int retry);
44
45
46 static int
47 set_cloexec_flag (int fd)
48 {
49   int oldflags;
50
51   oldflags= fcntl (fd, F_GETFD, 0);
52   if (oldflags < 0)
53     return oldflags;
54   oldflags |= FD_CLOEXEC;
55   return fcntl (fd, F_SETFD, oldflags);
56 }
57
58
59
60 /*
61  * Used to open the /dev/random devices (Linux, xBSD, Solaris (if it
62  * exists)).  If RETRY is true, the function does not terminate with
63  * a fatal error but retries until it is able to reopen the device.
64  */
65 static int
66 open_device (const char *name, int retry)
67 {
68   int fd;
69
70   if (retry)
71     _gcry_random_progress ("open_dev_random", 'X', 1, 0);
72  again:
73   fd = open (name, O_RDONLY);
74   if (fd == -1 && retry)
75     {
76       struct timeval tv;
77
78       tv.tv_sec = 5;
79       tv.tv_usec = 0;
80       _gcry_random_progress ("wait_dev_random", 'X', 0, (int)tv.tv_sec);
81       select (0, NULL, NULL, NULL, &tv);
82       goto again;
83     }
84   if (fd == -1)
85     log_fatal ("can't open %s: %s\n", name, strerror(errno) );
86
87   if (set_cloexec_flag (fd))
88     log_error ("error setting FD_CLOEXEC on fd %d: %s\n",
89                fd, strerror (errno));
90
91   /* We used to do the following check, however it turned out that this
92      is not portable since more OSes provide a random device which is
93      sometimes implemented as another device type.
94
95      struct stat sb;
96
97      if( fstat( fd, &sb ) )
98         log_fatal("stat() off %s failed: %s\n", name, strerror(errno) );
99      if( (!S_ISCHR(sb.st_mode)) && (!S_ISFIFO(sb.st_mode)) )
100         log_fatal("invalid random device!\n" );
101   */
102   return fd;
103 }
104
105
106 /* Note that the caller needs to make sure that this function is only
107    called by one thread at a time.  The function returns 0 on success
108    or true on failure (in which case the caller will signal a fatal
109    error).  */
110 int
111 _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
112                                           enum random_origins),
113                               enum random_origins origin,
114                               size_t length, int level )
115 {
116   static int fd_urandom = -1;
117   static int fd_random = -1;
118   static unsigned char ever_opened;
119   int fd;
120   int n;
121   byte buffer[768];
122   size_t n_hw;
123   size_t want = length;
124   size_t last_so_far = 0;
125   int any_need_entropy = 0;
126   int delay;
127
128   if (!add)
129     {
130       /* Special mode to close the descriptors.  */
131       if (fd_random != -1)
132         {
133           close (fd_random);
134           fd_random = -1;
135         }
136       if (fd_urandom != -1)
137         {
138           close (fd_urandom);
139           fd_urandom = -1;
140         }
141       return 0;
142     }
143
144
145   /* First read from a hardware source.  However let it account only
146      for up to 50% (or 25% for RDRAND) of the requested bytes.  */
147   n_hw = _gcry_rndhw_poll_slow (add, origin);
148   if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND))
149     {
150       if (n_hw > length/4)
151         n_hw = length/4;
152     }
153   else
154     {
155       if (n_hw > length/2)
156         n_hw = length/2;
157     }
158   if (length > 1)
159     length -= n_hw;
160
161   /* Open the requested device.  The first time a device is to be
162      opened we fail with a fatal error if the device does not exists.
163      In case the device has ever been closed, further open requests
164      will however retry indefinitely.  The rationale for this behaviour is
165      that we always require the device to be existent but want a more
166      graceful behaviour if the rarely needed close operation has been
167      used and the device needs to be re-opened later. */
168   if (level >= 2)
169     {
170       if (fd_random == -1)
171         {
172           fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1));
173           ever_opened |= 1;
174         }
175       fd = fd_random;
176     }
177   else
178     {
179       if (fd_urandom == -1)
180         {
181           fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2));
182           ever_opened |= 2;
183         }
184       fd = fd_urandom;
185     }
186
187   /* Enter the read loop.  */
188   delay = 0;  /* Start with 0 seconds so that we do no block on the
189                  first iteration and in turn call the progress function
190                  before blocking.  To give the OS a better chance to
191                  return with something we will actually use 100ms. */
192   while (length)
193     {
194       fd_set rfds;
195       struct timeval tv;
196       int rc;
197
198       /* If we collected some bytes update the progress indicator.  We
199          do this always and not just if the select timed out because
200          often just a few bytes are gathered within the timeout
201          period.  */
202       if (any_need_entropy || last_so_far != (want - length) )
203         {
204           last_so_far = want - length;
205           _gcry_random_progress ("need_entropy", 'X',
206                                  (int)last_so_far, (int)want);
207           any_need_entropy = 1;
208         }
209
210       /* If the system has no limit on the number of file descriptors
211          and we encounter an fd which is larger than the fd_set size,
212          we don't use the select at all.  The select code is only used
213          to emit progress messages.  A better solution would be to
214          fall back to poll() if available.  */
215 #ifdef FD_SETSIZE
216       if (fd < FD_SETSIZE)
217 #endif
218         {
219           FD_ZERO(&rfds);
220           FD_SET(fd, &rfds);
221           tv.tv_sec = delay;
222           tv.tv_usec = delay? 0 : 100000;
223           if ( !(rc=select(fd+1, &rfds, NULL, NULL, &tv)) )
224             {
225               any_need_entropy = 1;
226               delay = 3; /* Use 3 seconds henceforth.  */
227               continue;
228             }
229           else if( rc == -1 )
230             {
231               log_error ("select() error: %s\n", strerror(errno));
232               if (!delay)
233                 delay = 1; /* Use 1 second if we encounter an error before
234                               we have ever blocked.  */
235               continue;
236             }
237         }
238
239       /* If we have a modern Linux kernel and we want to read from the
240        * the non-blocking /dev/urandom, we first try to use the new
241        * getrandom syscall.  That call guarantees that the kernel's
242        * RNG has been properly seeded before returning any data.  This
243        * is different from /dev/urandom which may, due to its
244        * non-blocking semantics, return data even if the kernel has
245        * not been properly seeded.  Unfortunately we need to use a
246        * syscall and not a new device and thus we are not able to use
247        * select(2) to have a timeout. */
248 #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
249       if (fd == fd_urandom)
250         {
251           long ret;
252           size_t nbytes;
253
254           do
255             {
256               nbytes = length < sizeof(buffer)? length : sizeof(buffer);
257               if (nbytes > 256)
258                 nbytes = 256;
259               ret = syscall (__NR_getrandom,
260                              (void*)buffer, (size_t)nbytes, (unsigned int)0);
261             }
262           while (ret == -1 && errno == EINTR);
263           if (ret == -1 && errno == ENOSYS)
264             ; /* The syscall is not supported - fallback to /dev/urandom.  */
265           else
266             { /* The syscall is supported.  Some sanity checks.  */
267               if (ret == -1)
268                 log_fatal ("unexpected error from getrandom: %s\n",
269                            strerror (errno));
270               else if (ret != nbytes)
271                 log_fatal ("getrandom returned only"
272                            " %ld of %zu requested bytes\n", ret, nbytes);
273
274               (*add)(buffer, nbytes, origin);
275               length -= nbytes;
276               continue; /* until LENGTH is zero.  */
277             }
278         }
279 #endif
280
281       do
282         {
283           size_t nbytes;
284
285           nbytes = length < sizeof(buffer)? length : sizeof(buffer);
286           n = read (fd, buffer, nbytes);
287           if (n >= 0 && n > nbytes)
288             {
289               log_error("bogus read from random device (n=%d)\n", n );
290               n = nbytes;
291             }
292         }
293       while (n == -1 && errno == EINTR);
294       if  (n == -1)
295         log_fatal("read error on random device: %s\n", strerror(errno));
296       (*add)(buffer, n, origin);
297       length -= n;
298     }
299   wipememory (buffer, sizeof buffer);
300
301   if (any_need_entropy)
302     _gcry_random_progress ("need_entropy", 'X', (int)want, (int)want);
303
304   return 0; /* success */
305 }