Fixed HMAC for SHA-384 and SHA-512 with keys longer than 64 bytes.
[libgcrypt.git] / tests / pubkey.c
1 /* pubkey.c - Public key encryption/decryption tests
2  *      Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
3  *
4  * This file is part of Libgcrypt.
5  *
6  * Libgcrypt is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU Lesser General Public License as
8  * published by the Free Software Foundation; either version 2.1 of
9  * the License, or (at your option) any later version.
10  *
11  * Libgcrypt is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #include <stdarg.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27
28
29 #include "../src/gcrypt.h"
30
31 /* Sample RSA keys, taken from basic.c.  */
32
33 static const char sample_private_key_1[] =
34 "(private-key\n"
35 " (openpgp-rsa\n"
36 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
37       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
38       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
39       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
40 "  (e #010001#)\n"
41 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
42       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
43       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
44       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
45 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
46       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
47 "  (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9"
48       "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n"
49 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
50       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
51 " )\n"
52 ")\n";
53
54 /* The same key as above but without p, q and u to test the non CRT case. */
55 static const char sample_private_key_1_1[] =
56 "(private-key\n"
57 " (openpgp-rsa\n"
58 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
59       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
60       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
61       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
62 "  (e #010001#)\n"
63 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
64       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
65       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
66       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
67 " )\n"
68 ")\n";
69
70 /* The same key as above but just without q to test the non CRT case.  This
71    should fail. */
72 static const char sample_private_key_1_2[] =
73 "(private-key\n"
74 " (openpgp-rsa\n"
75 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
76       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
77       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
78       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
79 "  (e #010001#)\n"
80 "  (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11"
81       "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD"
82       "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21"
83       "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n"
84 "  (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213"
85       "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n"
86 "  (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
87       "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n"
88 " )\n"
89 ")\n";
90
91 static const char sample_public_key_1[] =
92 "(public-key\n"
93 " (rsa\n"
94 "  (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
95       "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291"
96       "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7"
97       "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n"
98 "  (e #010001#)\n"
99 " )\n"
100 ")\n";
101
102
103 static int verbose;
104
105 static void
106 die (const char *format, ...)
107 {
108   va_list arg_ptr ;
109
110   va_start( arg_ptr, format ) ;
111   vfprintf (stderr, format, arg_ptr );
112   va_end(arg_ptr);
113   exit (1);
114 }
115
116 static void
117 check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey,
118                   gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code)
119 {
120   gcry_sexp_t plain1, cipher, l;
121   gcry_mpi_t x0, x1;
122   int rc;
123   int have_flags;
124
125   /* Extract data from plaintext.  */
126   l = gcry_sexp_find_token (plain0, "value", 0);
127   x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
128
129   /* Encrypt data.  */
130   rc = gcry_pk_encrypt (&cipher, plain0, pkey);
131   if (rc)
132     die ("encryption failed: %s\n", gcry_strerror (rc));
133
134   l = gcry_sexp_find_token (cipher, "flags", 0);
135   have_flags = !!l;
136   gcry_sexp_release (l);
137
138   /* Decrypt data.  */
139   rc = gcry_pk_decrypt (&plain1, cipher, skey);
140   gcry_sexp_release (cipher);
141   if (rc)
142     {
143       if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code)
144         return; /* This is the expected failure code.  */
145       die ("decryption failed: %s\n", gcry_strerror (rc));
146     }
147
148   /* Extract decrypted data.  Note that for compatibility reasons, the
149      output of gcry_pk_decrypt depends on whether a flags lists (even
150      if empty) occurs in its input data.  Because we passed the output
151      of encrypt directly to decrypt, such a flag value won't be there
152      as of today.  We check it anyway. */
153   l = gcry_sexp_find_token (plain1, "value", 0);
154   if (l)
155     {
156       if (!have_flags)
157         die ("compatibility mode of pk_decrypt broken\n");
158       gcry_sexp_release (plain1);
159       x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG);
160       gcry_sexp_release (l);
161     }
162   else
163     {
164       if (have_flags)
165         die ("compatibility mode of pk_decrypt broken\n");
166       x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG);
167       gcry_sexp_release (plain1);
168     }
169
170   /* Compare.  */
171   if (gcry_mpi_cmp (x0, x1))
172     die ("data corrupted\n");
173 }
174
175 static void
176 check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data,
177             gpg_err_code_t decrypt_fail_code)
178 {
179   gcry_sexp_t plain;
180   gcry_mpi_t x;
181   int rc;
182   
183   /* Create plain text.  */
184   x = gcry_mpi_new (nbits_data);
185   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
186   
187   rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x);
188   if (rc)
189     die ("converting data for encryption failed: %s\n",
190          gcry_strerror (rc));
191
192   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
193   gcry_sexp_release (plain);
194   gcry_mpi_release (x);
195
196   /* Create plain text.  */
197   x = gcry_mpi_new (nbits_data);
198   gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM);
199   
200   rc = gcry_sexp_build (&plain, NULL, 
201                         "(data (flags raw no-blinding) (value %m))", x);
202   if (rc)
203     die ("converting data for encryption failed: %s\n",
204          gcry_strerror (rc));
205
206   check_keys_crypt (pkey, skey, plain, decrypt_fail_code);
207   gcry_sexp_release (plain);
208 }
209
210 static void
211 get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant)
212 {
213   gcry_sexp_t pub_key, sec_key;
214   int rc;
215   static const char *secret;
216
217
218   switch (secret_variant)
219     {
220     case 0: secret = sample_private_key_1; break;
221     case 1: secret = sample_private_key_1_1; break;
222     case 2: secret = sample_private_key_1_2; break;
223     default: die ("BUG\n");
224     }
225
226   rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1,
227                         strlen (sample_public_key_1));
228   if (!rc)
229     rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret));
230   if (rc)
231     die ("converting sample keys failed: %s\n", gcry_strerror (rc));
232
233   *pkey = pub_key;
234   *skey = sec_key;
235 }
236
237 static void
238 get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey)
239 {
240   gcry_sexp_t key_spec, key, pub_key, sec_key;
241   int rc;
242   
243   rc = gcry_sexp_new (&key_spec,
244                       "(genkey (rsa (nbits 4:1024)))", 0, 1);
245   if (rc)
246     die ("error creating S-expression: %s\n", gcry_strerror (rc));
247   rc = gcry_pk_genkey (&key, key_spec);
248   gcry_sexp_release (key_spec);
249   if (rc)
250     die ("error generating RSA key: %s\n", gcry_strerror (rc));
251     
252   pub_key = gcry_sexp_find_token (key, "public-key", 0);
253   if (! pub_key)
254     die ("public part missing in key\n");
255
256   sec_key = gcry_sexp_find_token (key, "private-key", 0);
257   if (! sec_key)
258     die ("private part missing in key\n");
259
260   gcry_sexp_release (key);
261   *pkey = pub_key;
262   *skey = sec_key;
263 }
264
265
266 static void
267 get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x)
268 {
269   gcry_sexp_t key_spec, key, pub_key, sec_key;
270   int rc;
271
272   rc = gcry_sexp_new 
273     (&key_spec, 
274      (fixed_x
275       ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))"
276       : "(genkey (elg (nbits 3:512)))"),
277      0, 1);
278
279   if (rc)
280     die ("error creating S-expression: %s\n", gcry_strerror (rc));
281   rc = gcry_pk_genkey (&key, key_spec);
282   gcry_sexp_release (key_spec);
283   if (rc)
284     die ("error generating Elgamal key: %s\n", gcry_strerror (rc));
285     
286   pub_key = gcry_sexp_find_token (key, "public-key", 0);
287   if (!pub_key)
288     die ("public part missing in key\n");
289
290   sec_key = gcry_sexp_find_token (key, "private-key", 0);
291   if (!sec_key)
292     die ("private part missing in key\n");
293
294   gcry_sexp_release (key);
295   *pkey = pub_key;
296   *skey = sec_key;
297 }
298
299 static void
300 check_run (void)
301 {
302   gpg_error_t err;
303   gcry_sexp_t pkey, skey;
304   int variant;
305
306   for (variant=0; variant < 3; variant++)
307     {
308       if (verbose)
309         fprintf (stderr, "Checking sample key (%d).\n", variant);
310       get_keys_sample (&pkey, &skey, variant);
311       /* Check gcry_pk_testkey which requires all elements.  */
312       err = gcry_pk_testkey (skey);
313       if ((variant == 0 && err)
314           || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ))
315           die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err));
316       /* Run the usual check but expect an error from variant 2.  */
317       check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0);
318       gcry_sexp_release (pkey);
319       gcry_sexp_release (skey);
320     }
321
322   if (verbose)
323     fprintf (stderr, "Checking generated RSA key.\n");
324   get_keys_new (&pkey, &skey);
325   check_keys (pkey, skey, 800, 0);
326   gcry_sexp_release (pkey);
327   gcry_sexp_release (skey);
328
329   if (verbose)
330     fprintf (stderr, "Checking generated Elgamal key.\n");
331   get_elg_key_new (&pkey, &skey, 0);
332   check_keys (pkey, skey, 400, 0);
333   gcry_sexp_release (pkey);
334   gcry_sexp_release (skey);
335
336   if (verbose)
337     fprintf (stderr, "Checking passphrase generated Elgamal key.\n");
338   get_elg_key_new (&pkey, &skey, 1);
339   check_keys (pkey, skey, 800, 0);
340   gcry_sexp_release (pkey);
341   gcry_sexp_release (skey);
342 }
343
344
345 int
346 main (int argc, char **argv)
347 {
348   int debug = 0;
349   int i;
350
351   if (argc > 1 && !strcmp (argv[1], "--verbose"))
352     verbose = 1;
353   else if (argc > 1 && !strcmp (argv[1], "--debug"))
354     verbose = debug = 1;
355
356   gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
357   if (!gcry_check_version (GCRYPT_VERSION))
358     die ("version mismatch\n");
359   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
360   if (debug)
361     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0);
362   /* No valuable keys are create, so we can speed up our RNG. */
363   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
364
365   for (i=0; i < 2; i++)
366     check_run ();
367   
368   return 0;
369 }