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