Fixed a few warnings emitted by gcc 4.6.
[libgcrypt.git] / tests / random.c
1 /* random.c - part of the Libgcrypt test suite.
2    Copyright (C) 2005 Free Software Foundation, Inc.
3
4    This program is free software; you can redistribute it and/or
5    modify it under the terms of the GNU General Public License as
6    published by the Free Software Foundation; either version 2 of the
7    License, or (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful, but
10    WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program; if not, write to the Free Software
16    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17    USA.  */
18
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
22 #include <assert.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <errno.h>
27 #include <signal.h>
28 #include <unistd.h>
29 #include <sys/wait.h>
30
31 #include "../src/gcrypt.h"
32
33 static int verbose;
34
35 static void
36 die (const char *format, ...)
37 {
38   va_list arg_ptr;
39
40   va_start (arg_ptr, format);
41   vfprintf (stderr, format, arg_ptr);
42   va_end (arg_ptr);
43   exit (1);
44 }
45
46
47 static void
48 print_hex (const char *text, const void *buf, size_t n)
49 {
50   const unsigned char *p = buf;
51
52   fputs (text, stdout);
53   for (; n; n--, p++)
54     printf ("%02X", *p);
55   putchar ('\n');
56 }
57
58
59 static int
60 writen (int fd, const void *buf, size_t nbytes)
61 {
62   size_t nleft = nbytes;
63   int nwritten;
64
65   while (nleft > 0)
66     {
67       nwritten = write (fd, buf, nleft);
68       if (nwritten < 0)
69         {
70           if (errno == EINTR)
71             nwritten = 0;
72           else
73             return -1;
74         }
75       nleft -= nwritten;
76       buf = (const char*)buf + nwritten;
77     }
78
79   return 0;
80 }
81
82 static int
83 readn (int fd, void *buf, size_t buflen, size_t *ret_nread)
84 {
85   size_t nleft = buflen;
86   int nread;
87
88   while ( nleft > 0 )
89     {
90       nread = read ( fd, buf, nleft );
91       if (nread < 0)
92         {
93           if (nread == EINTR)
94             nread = 0;
95           else
96             return -1;
97         }
98       else if (!nread)
99         break; /* EOF */
100       nleft -= nread;
101       buf = (char*)buf + nread;
102     }
103   if (ret_nread)
104     *ret_nread = buflen - nleft;
105   return 0;
106 }
107
108
109
110 /* Check that forking won't return the same random. */
111 static void
112 check_forking (void)
113 {
114   pid_t pid;
115   int rp[2];
116   int i, status;
117   size_t nread;
118   char tmp1[16], tmp1c[16], tmp1p[16];
119
120   /* We better make sure that the RNG has been initialzied. */
121   gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
122   if (verbose)
123     print_hex ("initial random: ", tmp1, sizeof tmp1);
124
125   if (pipe (rp) == -1)
126     die ("pipe failed: %s\n", strerror (errno));
127
128   pid = fork ();
129   if (pid == (pid_t)(-1))
130     die ("fork failed: %s\n", strerror (errno));
131   if (!pid)
132     {
133       gcry_randomize (tmp1c, sizeof tmp1c, GCRY_STRONG_RANDOM);
134       if (writen (rp[1], tmp1c, sizeof tmp1c))
135         die ("write failed: %s\n", strerror (errno));
136       if (verbose)
137         {
138           print_hex ("  child random: ", tmp1c, sizeof tmp1c);
139           fflush (stdout);
140         }
141       _exit (0);
142     }
143   gcry_randomize (tmp1p, sizeof tmp1p, GCRY_STRONG_RANDOM);
144   if (verbose)
145     print_hex (" parent random: ", tmp1p, sizeof tmp1p);
146
147   close (rp[1]);
148   if (readn (rp[0], tmp1c, sizeof tmp1c, &nread))
149     die ("read failed: %s\n", strerror (errno));
150   if (nread != sizeof tmp1c)
151     die ("read too short\n");
152
153   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
154     ;
155   if (i != (pid_t)(-1)
156       && WIFEXITED (status) && !WEXITSTATUS (status))
157     ;
158   else
159     die ("child failed\n");
160
161   if (!memcmp (tmp1p, tmp1c, sizeof tmp1c))
162     die ("parent and child got the same random number\n");
163 }
164
165
166
167 /* Check that forking won't return the same nonce. */
168 static void
169 check_nonce_forking (void)
170 {
171   pid_t pid;
172   int rp[2];
173   int i, status;
174   size_t nread;
175   char nonce1[10], nonce1c[10], nonce1p[10];
176
177   /* We won't get the same nonce back if we never initialized the
178      nonce subsystem, thus we get one nonce here and forget about
179      it. */
180   gcry_create_nonce (nonce1, sizeof nonce1);
181   if (verbose)
182     print_hex ("initial nonce: ", nonce1, sizeof nonce1);
183
184   if (pipe (rp) == -1)
185     die ("pipe failed: %s\n", strerror (errno));
186
187   pid = fork ();
188   if (pid == (pid_t)(-1))
189     die ("fork failed: %s\n", strerror (errno));
190   if (!pid)
191     {
192       gcry_create_nonce (nonce1c, sizeof nonce1c);
193       if (writen (rp[1], nonce1c, sizeof nonce1c))
194         die ("write failed: %s\n", strerror (errno));
195       if (verbose)
196         {
197           print_hex ("  child nonce: ", nonce1c, sizeof nonce1c);
198           fflush (stdout);
199         }
200       _exit (0);
201     }
202   gcry_create_nonce (nonce1p, sizeof nonce1p);
203   if (verbose)
204     print_hex (" parent nonce: ", nonce1p, sizeof nonce1p);
205
206   close (rp[1]);
207   if (readn (rp[0], nonce1c, sizeof nonce1c, &nread))
208     die ("read failed: %s\n", strerror (errno));
209   if (nread != sizeof nonce1c)
210     die ("read too short\n");
211
212   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
213     ;
214   if (i != (pid_t)(-1)
215       && WIFEXITED (status) && !WEXITSTATUS (status))
216     ;
217   else
218     die ("child failed\n");
219
220   if (!memcmp (nonce1p, nonce1c, sizeof nonce1c))
221     die ("parent and child got the same nonce\n");
222 }
223
224
225
226
227
228
229 int
230 main (int argc, char **argv)
231 {
232   int debug = 0;
233
234   if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
235     verbose = 1;
236   else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
237     verbose = debug = 1;
238
239   signal (SIGPIPE, SIG_IGN);
240
241   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
242   if (!gcry_check_version (GCRYPT_VERSION))
243     die ("version mismatch\n");
244
245   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
246   if (debug)
247     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
248
249   check_forking ();
250   check_nonce_forking ();
251
252   return 0;
253 }