Fixed HMAC for SHA-384 and SHA-512 with keys longer than 64 bytes.
[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   char *p;
88   
89   p = buf;
90   while ( nleft > 0 )
91     {
92       nread = read ( fd, buf, nleft );
93       if (nread < 0)
94         {
95           if (nread == EINTR)
96             nread = 0;
97           else 
98             return -1;
99         }
100       else if (!nread)
101         break; /* EOF */
102       nleft -= nread;
103       buf = (char*)buf + nread;
104     }
105   if (ret_nread)
106     *ret_nread = buflen - nleft;
107   return 0;
108 }
109
110
111
112 /* Check that forking won't return the same random. */
113 static void
114 check_forking (void)
115 {
116   pid_t pid;
117   int rp[2];
118   int i, status;
119   size_t nread;
120   char tmp1[16], tmp1c[16], tmp1p[16];
121   
122   /* We better make sure that the RNG has been initialzied. */
123   gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM);
124   if (verbose)
125     print_hex ("initial random: ", tmp1, sizeof tmp1);
126
127   if (pipe (rp) == -1)
128     die ("pipe failed: %s\n", strerror (errno));
129
130   pid = fork ();
131   if (pid == (pid_t)(-1))
132     die ("fork failed: %s\n", strerror (errno));
133   if (!pid)
134     {
135       gcry_randomize (tmp1c, sizeof tmp1c, GCRY_STRONG_RANDOM);
136       if (writen (rp[1], tmp1c, sizeof tmp1c))
137         die ("write failed: %s\n", strerror (errno));
138       if (verbose)
139         {
140           print_hex ("  child random: ", tmp1c, sizeof tmp1c);
141           fflush (stdout);
142         }
143       _exit (0);
144     }
145   gcry_randomize (tmp1p, sizeof tmp1p, GCRY_STRONG_RANDOM);
146   if (verbose)
147     print_hex (" parent random: ", tmp1p, sizeof tmp1p);
148
149   close (rp[1]);
150   if (readn (rp[0], tmp1c, sizeof tmp1c, &nread))
151     die ("read failed: %s\n", strerror (errno)); 
152   if (nread != sizeof tmp1c)
153     die ("read too short\n");
154
155   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
156     ;
157   if (i != (pid_t)(-1)
158       && WIFEXITED (status) && !WEXITSTATUS (status))
159     ;
160   else
161     die ("child failed\n");
162
163   if (!memcmp (tmp1p, tmp1c, sizeof tmp1c))
164     die ("parent and child got the same random number\n");
165 }
166
167
168
169 /* Check that forking won't return the same nonce. */
170 static void
171 check_nonce_forking (void)
172 {
173   pid_t pid;
174   int rp[2];
175   int i, status;
176   size_t nread;
177   char nonce1[10], nonce1c[10], nonce1p[10];
178   
179   /* We won't get the same nonce back if we never initialized the
180      nonce subsystem, thus we get one nonce here and forget about
181      it. */
182   gcry_create_nonce (nonce1, sizeof nonce1);
183   if (verbose)
184     print_hex ("initial nonce: ", nonce1, sizeof nonce1);
185
186   if (pipe (rp) == -1)
187     die ("pipe failed: %s\n", strerror (errno));
188
189   pid = fork ();
190   if (pid == (pid_t)(-1))
191     die ("fork failed: %s\n", strerror (errno));
192   if (!pid)
193     {
194       gcry_create_nonce (nonce1c, sizeof nonce1c);
195       if (writen (rp[1], nonce1c, sizeof nonce1c))
196         die ("write failed: %s\n", strerror (errno));
197       if (verbose)
198         {
199           print_hex ("  child nonce: ", nonce1c, sizeof nonce1c);
200           fflush (stdout);
201         }
202       _exit (0);
203     }
204   gcry_create_nonce (nonce1p, sizeof nonce1p);
205   if (verbose)
206     print_hex (" parent nonce: ", nonce1p, sizeof nonce1p);
207
208   close (rp[1]);
209   if (readn (rp[0], nonce1c, sizeof nonce1c, &nread))
210     die ("read failed: %s\n", strerror (errno)); 
211   if (nread != sizeof nonce1c)
212     die ("read too short\n");
213
214   while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR)
215     ;
216   if (i != (pid_t)(-1)
217       && WIFEXITED (status) && !WEXITSTATUS (status))
218     ;
219   else
220     die ("child failed\n");
221
222   if (!memcmp (nonce1p, nonce1c, sizeof nonce1c))
223     die ("parent and child got the same nonce\n");
224 }
225
226
227
228
229
230
231 int
232 main (int argc, char **argv)
233 {
234   int debug = 0;
235
236   if ((argc > 1) && (! strcmp (argv[1], "--verbose")))
237     verbose = 1;
238   else if ((argc > 1) && (! strcmp (argv[1], "--debug")))
239     verbose = debug = 1;
240
241   signal (SIGPIPE, SIG_IGN);
242
243   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
244   if (!gcry_check_version (GCRYPT_VERSION))
245     die ("version mismatch\n");
246
247   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
248   if (debug)
249     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
250
251   check_forking ();
252   check_nonce_forking ();
253
254   return 0;
255 }