f70bc21859e4a0776d90438d8e2c29095bd45518
[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 and we want to read from the
249        * the non-blocking /dev/urandom, we first try to use the new
250        * getrandom syscall.  That call guarantees that the kernel's
251        * RNG has been properly seeded before returning any data.  This
252        * is different from /dev/urandom which may, due to its
253        * non-blocking semantics, return data even if the kernel has
254        * not been properly 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       if (fd == fd_urandom)
259         {
260           long ret;
261           size_t nbytes;
262
263           do
264             {
265               nbytes = length < sizeof(buffer)? length : sizeof(buffer);
266               if (nbytes > 256)
267                 nbytes = 256;
268               _gcry_pre_syscall ();
269               ret = syscall (__NR_getrandom,
270                              (void*)buffer, (size_t)nbytes, (unsigned int)0);
271               _gcry_post_syscall ();
272             }
273           while (ret == -1 && errno == EINTR);
274           if (ret == -1 && errno == ENOSYS)
275             ; /* The syscall is not supported - fallback to /dev/urandom.  */
276           else
277             { /* The syscall is supported.  Some sanity checks.  */
278               if (ret == -1)
279                 log_fatal ("unexpected error from getrandom: %s\n",
280                            strerror (errno));
281               else if (ret != nbytes)
282                 log_fatal ("getrandom returned only"
283                            " %ld of %zu requested bytes\n", ret, nbytes);
284
285               (*add)(buffer, nbytes, origin);
286               length -= nbytes;
287               continue; /* until LENGTH is zero.  */
288             }
289         }
290 #endif
291
292       /* If we collected some bytes update the progress indicator.  We
293          do this always and not just if the select timed out because
294          often just a few bytes are gathered within the timeout
295          period.  */
296       if (any_need_entropy || last_so_far != (want - length) )
297         {
298           last_so_far = want - length;
299           _gcry_random_progress ("need_entropy", 'X',
300                                  (int)last_so_far, (int)want);
301           any_need_entropy = 1;
302         }
303
304       /* If the system has no limit on the number of file descriptors
305          and we encounter an fd which is larger than the fd_set size,
306          we don't use the select at all.  The select code is only used
307          to emit progress messages.  A better solution would be to
308          fall back to poll() if available.  */
309 #ifdef FD_SETSIZE
310       if (fd < FD_SETSIZE)
311 #endif
312         {
313           FD_ZERO(&rfds);
314           FD_SET(fd, &rfds);
315           tv.tv_sec = delay;
316           tv.tv_usec = delay? 0 : 100000;
317           _gcry_pre_syscall ();
318           rc = select (fd+1, &rfds, NULL, NULL, &tv);
319           _gcry_post_syscall ();
320           if (!rc)
321             {
322               any_need_entropy = 1;
323               delay = 3; /* Use 3 seconds henceforth.  */
324               continue;
325             }
326           else if( rc == -1 )
327             {
328               log_error ("select() error: %s\n", strerror(errno));
329               if (!delay)
330                 delay = 1; /* Use 1 second if we encounter an error before
331                               we have ever blocked.  */
332               continue;
333             }
334         }
335
336       do
337         {
338           size_t nbytes;
339
340           nbytes = length < sizeof(buffer)? length : sizeof(buffer);
341           n = read (fd, buffer, nbytes);
342           if (n >= 0 && n > nbytes)
343             {
344               log_error("bogus read from random device (n=%d)\n", n );
345               n = nbytes;
346             }
347         }
348       while (n == -1 && errno == EINTR);
349       if  (n == -1)
350         log_fatal("read error on random device: %s\n", strerror(errno));
351       (*add)(buffer, n, origin);
352       length -= n;
353     }
354   wipememory (buffer, sizeof buffer);
355
356   if (any_need_entropy)
357     _gcry_random_progress ("need_entropy", 'X', (int)want, (int)want);
358
359   return 0; /* success */
360 }