random: use getrandom() on Linux where available
[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).  This function should be entered only by one thread at a
110  * time. */
111 int
112 _gcry_rndlinux_gather_random (void (*add)(const void*, size_t,
113                                           enum random_origins),
114                               enum random_origins origin,
115                               size_t length, int level )
116 {
117   static int fd_urandom = -1;
118   static int fd_random = -1;
119   static int only_urandom = -1;
120   static unsigned char ever_opened;
121   static volatile pid_t my_pid; /* The volatile is there to make sure
122                                  * the compiler does not optimize the
123                                  * code away in case the getpid
124                                  * function is badly attributed. */
125   volatile pid_t apid;
126   int fd;
127   int n;
128   byte buffer[768];
129   size_t n_hw;
130   size_t want = length;
131   size_t last_so_far = 0;
132   int any_need_entropy = 0;
133   int delay;
134
135   /* On the first call read the conf file to check whether we want to
136    * use only urandom.  */
137   if (only_urandom == -1)
138     {
139       my_pid = getpid ();
140       if ((_gcry_random_read_conf () & RANDOM_CONF_ONLY_URANDOM))
141         only_urandom = 1;
142       else
143         only_urandom = 0;
144     }
145
146   if (!add)
147     {
148       /* Special mode to close the descriptors.  */
149       if (fd_random != -1)
150         {
151           close (fd_random);
152           fd_random = -1;
153         }
154       if (fd_urandom != -1)
155         {
156           close (fd_urandom);
157           fd_urandom = -1;
158         }
159       return 0;
160     }
161
162   /* Detect a fork and close the devices so that we don't use the old
163    * file descriptors.  Note that open_device will be called in retry
164    * mode if the devices was opened by the parent process.  */
165   apid = getpid ();
166   if (my_pid != apid)
167     {
168       if (fd_random != -1)
169         {
170           close (fd_random);
171           fd_random = -1;
172         }
173       if (fd_urandom != -1)
174         {
175           close (fd_urandom);
176           fd_urandom = -1;
177         }
178       my_pid = apid;
179     }
180
181
182   /* First read from a hardware source.  However let it account only
183      for up to 50% (or 25% for RDRAND) of the requested bytes.  */
184   n_hw = _gcry_rndhw_poll_slow (add, origin);
185   if ((_gcry_get_hw_features () & HWF_INTEL_RDRAND))
186     {
187       if (n_hw > length/4)
188         n_hw = length/4;
189     }
190   else
191     {
192       if (n_hw > length/2)
193         n_hw = length/2;
194     }
195   if (length > 1)
196     length -= n_hw;
197
198   /* When using a blocking random generator try to get some entropy
199    * from the jitter based RNG.  In this case we take up to 50% of the
200    * remaining requested bytes.  */
201   if (level >= GCRY_VERY_STRONG_RANDOM)
202     {
203       n_hw = _gcry_rndjent_poll (add, origin, length/2);
204       if (n_hw > length/2)
205         n_hw = length/2;
206       if (length > 1)
207         length -= n_hw;
208     }
209
210
211   /* Open the requested device.  The first time a device is to be
212      opened we fail with a fatal error if the device does not exists.
213      In case the device has ever been closed, further open requests
214      will however retry indefinitely.  The rationale for this behaviour is
215      that we always require the device to be existent but want a more
216      graceful behaviour if the rarely needed close operation has been
217      used and the device needs to be re-opened later. */
218   if (level >= GCRY_VERY_STRONG_RANDOM && !only_urandom)
219     {
220       if (fd_random == -1)
221         {
222           fd_random = open_device (NAME_OF_DEV_RANDOM, (ever_opened & 1));
223           ever_opened |= 1;
224         }
225       fd = fd_random;
226     }
227   else
228     {
229       if (fd_urandom == -1)
230         {
231           fd_urandom = open_device (NAME_OF_DEV_URANDOM, (ever_opened & 2));
232           ever_opened |= 2;
233         }
234       fd = fd_urandom;
235     }
236
237   /* Enter the read loop.  */
238   delay = 0;  /* Start with 0 seconds so that we do no block on the
239                  first iteration and in turn call the progress function
240                  before blocking.  To give the OS a better chance to
241                  return with something we will actually use 100ms. */
242   while (length)
243     {
244       fd_set rfds;
245       struct timeval tv;
246       int rc;
247
248       /* If we have a modern Linux kernel, we first try to use the new
249        * getrandom syscall.  That call guarantees that the kernel's
250        * RNG has been properly seeded before returning any data.  This
251        * is different from /dev/urandom which may, due to its
252        * non-blocking semantics, return data even if the kernel has
253        * not been properly seeded.  And it differs from /dev/random by never
254        * blocking once the kernel is seeded. Unfortunately we need to use a
255        * syscall and not a new device and thus we are not able to use
256        * select(2) to have a timeout. */
257 #if defined(__linux__) && defined(HAVE_SYSCALL) && defined(__NR_getrandom)
258         {
259           long ret;
260           size_t nbytes;
261
262           do
263             {
264               nbytes = length < sizeof(buffer)? length : sizeof(buffer);
265               if (nbytes > 256)
266                 nbytes = 256;
267               _gcry_pre_syscall ();
268               ret = syscall (__NR_getrandom,
269                              (void*)buffer, (size_t)nbytes, (unsigned int)0);
270               _gcry_post_syscall ();
271             }
272           while (ret == -1 && errno == EINTR);
273           if (ret == -1 && errno == ENOSYS)
274             ; /* The syscall is not supported - fallback to pulling from fd.  */
275           else
276             { /* The syscall is supported.  Some sanity checks.  */
277               if (ret == -1)
278                 log_fatal ("unexpected error from getrandom: %s\n",
279                            strerror (errno));
280               else if (ret != nbytes)
281                 log_fatal ("getrandom returned only"
282                            " %ld of %zu requested bytes\n", ret, nbytes);
283
284               (*add)(buffer, nbytes, origin);
285               length -= nbytes;
286               continue; /* until LENGTH is zero.  */
287             }
288         }
289 #endif
290
291       /* If we collected some bytes update the progress indicator.  We
292          do this always and not just if the select timed out because
293          often just a few bytes are gathered within the timeout
294          period.  */
295       if (any_need_entropy || last_so_far != (want - length) )
296         {
297           last_so_far = want - length;
298           _gcry_random_progress ("need_entropy", 'X',
299                                  (int)last_so_far, (int)want);
300           any_need_entropy = 1;
301         }
302
303       /* If the system has no limit on the number of file descriptors
304          and we encounter an fd which is larger than the fd_set size,
305          we don't use the select at all.  The select code is only used
306          to emit progress messages.  A better solution would be to
307          fall back to poll() if available.  */
308 #ifdef FD_SETSIZE
309       if (fd < FD_SETSIZE)
310 #endif
311         {
312           FD_ZERO(&rfds);
313           FD_SET(fd, &rfds);
314           tv.tv_sec = delay;
315           tv.tv_usec = delay? 0 : 100000;
316           _gcry_pre_syscall ();
317           rc = select (fd+1, &rfds, NULL, NULL, &tv);
318           _gcry_post_syscall ();
319           if (!rc)
320             {
321               any_need_entropy = 1;
322               delay = 3; /* Use 3 seconds henceforth.  */
323               continue;
324             }
325           else if( rc == -1 )
326             {
327               log_error ("select() error: %s\n", strerror(errno));
328               if (!delay)
329                 delay = 1; /* Use 1 second if we encounter an error before
330                               we have ever blocked.  */
331               continue;
332             }
333         }
334
335       do
336         {
337           size_t nbytes;
338
339           nbytes = length < sizeof(buffer)? length : sizeof(buffer);
340           n = read (fd, buffer, nbytes);
341           if (n >= 0 && n > nbytes)
342             {
343               log_error("bogus read from random device (n=%d)\n", n );
344               n = nbytes;
345             }
346         }
347       while (n == -1 && errno == EINTR);
348       if  (n == -1)
349         log_fatal("read error on random device: %s\n", strerror(errno));
350       (*add)(buffer, n, origin);
351       length -= n;
352     }
353   wipememory (buffer, sizeof buffer);
354
355   if (any_need_entropy)
356     _gcry_random_progress ("need_entropy", 'X', (int)want, (int)want);
357
358   return 0; /* success */
359 }