Support PSS.
[libgcrypt.git] / cipher / pubkey.c
1 /* pubkey.c  -  pubkey dispatcher
2  * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
3  *               2007, 2008, 2011 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 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26
27 #include "g10lib.h"
28 #include "mpi.h"
29 #include "cipher.h"
30 #include "ath.h"
31
32
33 static gcry_err_code_t pubkey_decrypt (int algo, gcry_mpi_t *result,
34                                        gcry_mpi_t *data, gcry_mpi_t *skey,
35                                        int flags);
36 static gcry_err_code_t pubkey_sign (int algo, gcry_mpi_t *resarr,
37                                     gcry_mpi_t hash, gcry_mpi_t *skey);
38 static gcry_err_code_t pubkey_verify (int algo, gcry_mpi_t hash,
39                                       gcry_mpi_t *data, gcry_mpi_t *pkey,
40                                      int (*cmp) (void *, gcry_mpi_t),
41                                       void *opaque);
42
43
44 /* A dummy extraspec so that we do not need to tests the extraspec
45    field from the module specification against NULL and instead
46    directly test the respective fields of extraspecs.  */
47 static pk_extra_spec_t dummy_extra_spec;
48
49
50 /* This is the list of the default public-key ciphers included in
51    libgcrypt.  FIPS_ALLOWED indicated whether the algorithm is used in
52    FIPS mode. */
53 static struct pubkey_table_entry
54 {
55   gcry_pk_spec_t *pubkey;
56   pk_extra_spec_t *extraspec;
57   unsigned int algorithm;
58   int fips_allowed;
59 } pubkey_table[] =
60   {
61 #if USE_RSA
62     { &_gcry_pubkey_spec_rsa,
63       &_gcry_pubkey_extraspec_rsa,   GCRY_PK_RSA, 1},
64 #endif
65 #if USE_ELGAMAL
66     { &_gcry_pubkey_spec_elg,
67       &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG   },
68     { &_gcry_pubkey_spec_elg,
69       &_gcry_pubkey_extraspec_elg,    GCRY_PK_ELG_E },
70 #endif
71 #if USE_DSA
72     { &_gcry_pubkey_spec_dsa,
73       &_gcry_pubkey_extraspec_dsa,   GCRY_PK_DSA, 1   },
74 #endif
75 #if USE_ECC
76     { &_gcry_pubkey_spec_ecdsa,
77       &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
78     { &_gcry_pubkey_spec_ecdh,
79       &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDH, 0 },
80 #endif
81     { NULL, 0 },
82   };
83
84 /* List of registered ciphers.  */
85 static gcry_module_t pubkeys_registered;
86
87 /* This is the lock protecting PUBKEYS_REGISTERED.  */
88 static ath_mutex_t pubkeys_registered_lock = ATH_MUTEX_INITIALIZER;;
89
90 /* Flag to check whether the default pubkeys have already been
91    registered.  */
92 static int default_pubkeys_registered;
93
94 /* Convenient macro for registering the default digests.  */
95 #define REGISTER_DEFAULT_PUBKEYS                   \
96   do                                               \
97     {                                              \
98       ath_mutex_lock (&pubkeys_registered_lock);   \
99       if (! default_pubkeys_registered)            \
100         {                                          \
101           pk_register_default ();                  \
102           default_pubkeys_registered = 1;          \
103         }                                          \
104       ath_mutex_unlock (&pubkeys_registered_lock); \
105     }                                              \
106   while (0)
107
108 /* These dummy functions are used in case a cipher implementation
109    refuses to provide it's own functions.  */
110
111 static gcry_err_code_t
112 dummy_generate (int algorithm, unsigned int nbits, unsigned long dummy,
113                 gcry_mpi_t *skey, gcry_mpi_t **retfactors)
114 {
115   (void)algorithm;
116   (void)nbits;
117   (void)dummy;
118   (void)skey;
119   (void)retfactors;
120   fips_signal_error ("using dummy public key function");
121   return GPG_ERR_NOT_IMPLEMENTED;
122 }
123
124 static gcry_err_code_t
125 dummy_check_secret_key (int algorithm, gcry_mpi_t *skey)
126 {
127   (void)algorithm;
128   (void)skey;
129   fips_signal_error ("using dummy public key function");
130   return GPG_ERR_NOT_IMPLEMENTED;
131 }
132
133 static gcry_err_code_t
134 dummy_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
135                gcry_mpi_t *pkey, int flags)
136 {
137   (void)algorithm;
138   (void)resarr;
139   (void)data;
140   (void)pkey;
141   (void)flags;
142   fips_signal_error ("using dummy public key function");
143   return GPG_ERR_NOT_IMPLEMENTED;
144 }
145
146 static gcry_err_code_t
147 dummy_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
148                gcry_mpi_t *skey, int flags)
149 {
150   (void)algorithm;
151   (void)result;
152   (void)data;
153   (void)skey;
154   (void)flags;
155   fips_signal_error ("using dummy public key function");
156   return GPG_ERR_NOT_IMPLEMENTED;
157 }
158
159 static gcry_err_code_t
160 dummy_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
161             gcry_mpi_t *skey)
162 {
163   (void)algorithm;
164   (void)resarr;
165   (void)data;
166   (void)skey;
167   fips_signal_error ("using dummy public key function");
168   return GPG_ERR_NOT_IMPLEMENTED;
169 }
170
171 static gcry_err_code_t
172 dummy_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
173               gcry_mpi_t *pkey,
174               int (*cmp) (void *, gcry_mpi_t), void *opaquev)
175 {
176   (void)algorithm;
177   (void)hash;
178   (void)data;
179   (void)pkey;
180   (void)cmp;
181   (void)opaquev;
182   fips_signal_error ("using dummy public key function");
183   return GPG_ERR_NOT_IMPLEMENTED;
184 }
185
186 static unsigned
187 dummy_get_nbits (int algorithm, gcry_mpi_t *pkey)
188 {
189   (void)algorithm;
190   (void)pkey;
191   fips_signal_error ("using dummy public key function");
192   return 0;
193 }
194
195 /* Internal function.  Register all the pubkeys included in
196    PUBKEY_TABLE.  Returns zero on success or an error code.  */
197 static void
198 pk_register_default (void)
199 {
200   gcry_err_code_t err = 0;
201   int i;
202
203   for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
204     {
205 #define pubkey_use_dummy(func)                       \
206       if (! pubkey_table[i].pubkey->func)            \
207         pubkey_table[i].pubkey->func = dummy_##func;
208
209       pubkey_use_dummy (generate);
210       pubkey_use_dummy (check_secret_key);
211       pubkey_use_dummy (encrypt);
212       pubkey_use_dummy (decrypt);
213       pubkey_use_dummy (sign);
214       pubkey_use_dummy (verify);
215       pubkey_use_dummy (get_nbits);
216 #undef pubkey_use_dummy
217
218       err = _gcry_module_add (&pubkeys_registered,
219                               pubkey_table[i].algorithm,
220                               (void *) pubkey_table[i].pubkey,
221                               (void *) pubkey_table[i].extraspec,
222                               NULL);
223     }
224
225   if (err)
226     BUG ();
227 }
228
229 /* Internal callback function.  Used via _gcry_module_lookup.  */
230 static int
231 gcry_pk_lookup_func_name (void *spec, void *data)
232 {
233   gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) spec;
234   char *name = (char *) data;
235   const char **aliases = pubkey->aliases;
236   int ret = stricmp (name, pubkey->name);
237
238   while (ret && *aliases)
239     ret = stricmp (name, *aliases++);
240
241   return ! ret;
242 }
243
244 /* Internal function.  Lookup a pubkey entry by it's name.  */
245 static gcry_module_t
246 gcry_pk_lookup_name (const char *name)
247 {
248   gcry_module_t pubkey;
249
250   pubkey = _gcry_module_lookup (pubkeys_registered, (void *) name,
251                                 gcry_pk_lookup_func_name);
252
253   return pubkey;
254 }
255
256 /* Register a new pubkey module whose specification can be found in
257    PUBKEY.  On success, a new algorithm ID is stored in ALGORITHM_ID
258    and a pointer representhing this module is stored in MODULE.  */
259 gcry_error_t
260 _gcry_pk_register (gcry_pk_spec_t *pubkey,
261                    pk_extra_spec_t *extraspec,
262                    unsigned int *algorithm_id,
263                    gcry_module_t *module)
264 {
265   gcry_err_code_t err = GPG_ERR_NO_ERROR;
266   gcry_module_t mod;
267
268   /* We do not support module loading in fips mode.  */
269   if (fips_mode ())
270     return gpg_error (GPG_ERR_NOT_SUPPORTED);
271
272   ath_mutex_lock (&pubkeys_registered_lock);
273   err = _gcry_module_add (&pubkeys_registered, 0,
274                           (void *) pubkey,
275                           (void *)(extraspec? extraspec : &dummy_extra_spec),
276                           &mod);
277   ath_mutex_unlock (&pubkeys_registered_lock);
278
279   if (! err)
280     {
281       *module = mod;
282       *algorithm_id = mod->mod_id;
283     }
284
285   return err;
286 }
287
288 /* Unregister the pubkey identified by ID, which must have been
289    registered with gcry_pk_register.  */
290 void
291 gcry_pk_unregister (gcry_module_t module)
292 {
293   ath_mutex_lock (&pubkeys_registered_lock);
294   _gcry_module_release (module);
295   ath_mutex_unlock (&pubkeys_registered_lock);
296 }
297
298 static void
299 release_mpi_array (gcry_mpi_t *array)
300 {
301   for (; *array; array++)
302     {
303       mpi_free(*array);
304       *array = NULL;
305     }
306 }
307
308 /****************
309  * Map a string to the pubkey algo
310  */
311 int
312 gcry_pk_map_name (const char *string)
313 {
314   gcry_module_t pubkey;
315   int algorithm = 0;
316
317   if (!string)
318     return 0;
319
320   REGISTER_DEFAULT_PUBKEYS;
321
322   ath_mutex_lock (&pubkeys_registered_lock);
323   pubkey = gcry_pk_lookup_name (string);
324   if (pubkey)
325     {
326       algorithm = pubkey->mod_id;
327       _gcry_module_release (pubkey);
328     }
329   ath_mutex_unlock (&pubkeys_registered_lock);
330
331   return algorithm;
332 }
333
334
335 /* Map the public key algorithm whose ID is contained in ALGORITHM to
336    a string representation of the algorithm name.  For unknown
337    algorithm IDs this functions returns "?". */
338 const char *
339 gcry_pk_algo_name (int algorithm)
340 {
341   gcry_module_t pubkey;
342   const char *name;
343
344   REGISTER_DEFAULT_PUBKEYS;
345
346   ath_mutex_lock (&pubkeys_registered_lock);
347   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
348   if (pubkey)
349     {
350       name = ((gcry_pk_spec_t *) pubkey->spec)->name;
351       _gcry_module_release (pubkey);
352     }
353   else
354     name = "?";
355   ath_mutex_unlock (&pubkeys_registered_lock);
356
357   return name;
358 }
359
360
361 /* A special version of gcry_pk_algo name to return the first aliased
362    name of the algorithm.  This is required to adhere to the spki
363    specs where the algorithm names are lowercase. */
364 const char *
365 _gcry_pk_aliased_algo_name (int algorithm)
366 {
367   const char *name = NULL;
368   gcry_module_t module;
369
370   REGISTER_DEFAULT_PUBKEYS;
371
372   ath_mutex_lock (&pubkeys_registered_lock);
373   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
374   if (module)
375     {
376       gcry_pk_spec_t *pubkey = (gcry_pk_spec_t *) module->spec;
377
378       name = pubkey->aliases? *pubkey->aliases : NULL;
379       if (!name || !*name)
380         name = pubkey->name;
381       _gcry_module_release (module);
382     }
383   ath_mutex_unlock (&pubkeys_registered_lock);
384
385   return name;
386 }
387
388
389 static void
390 disable_pubkey_algo (int algorithm)
391 {
392   gcry_module_t pubkey;
393
394   ath_mutex_lock (&pubkeys_registered_lock);
395   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
396   if (pubkey)
397     {
398       if (! (pubkey-> flags & FLAG_MODULE_DISABLED))
399         pubkey->flags |= FLAG_MODULE_DISABLED;
400       _gcry_module_release (pubkey);
401     }
402   ath_mutex_unlock (&pubkeys_registered_lock);
403 }
404
405
406 /****************
407  * A USE of 0 means: don't care.
408  */
409 static gcry_err_code_t
410 check_pubkey_algo (int algorithm, unsigned use)
411 {
412   gcry_err_code_t err = GPG_ERR_NO_ERROR;
413   gcry_pk_spec_t *pubkey;
414   gcry_module_t module;
415
416   REGISTER_DEFAULT_PUBKEYS;
417
418   ath_mutex_lock (&pubkeys_registered_lock);
419   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
420   if (module)
421     {
422       pubkey = (gcry_pk_spec_t *) module->spec;
423
424       if (((use & GCRY_PK_USAGE_SIGN)
425            && (! (pubkey->use & GCRY_PK_USAGE_SIGN)))
426           || ((use & GCRY_PK_USAGE_ENCR)
427               && (! (pubkey->use & GCRY_PK_USAGE_ENCR))))
428         err = GPG_ERR_WRONG_PUBKEY_ALGO;
429       else if (module->flags & FLAG_MODULE_DISABLED)
430         err = GPG_ERR_PUBKEY_ALGO;
431       _gcry_module_release (module);
432     }
433   else
434     err = GPG_ERR_PUBKEY_ALGO;
435   ath_mutex_unlock (&pubkeys_registered_lock);
436
437   return err;
438 }
439
440
441 /****************
442  * Return the number of public key material numbers
443  */
444 static int
445 pubkey_get_npkey (int algorithm)
446 {
447   gcry_module_t pubkey;
448   int npkey = 0;
449
450   REGISTER_DEFAULT_PUBKEYS;
451
452   ath_mutex_lock (&pubkeys_registered_lock);
453   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
454   if (pubkey)
455     {
456       npkey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_pkey);
457       _gcry_module_release (pubkey);
458     }
459   ath_mutex_unlock (&pubkeys_registered_lock);
460
461   return npkey;
462 }
463
464 /****************
465  * Return the number of secret key material numbers
466  */
467 static int
468 pubkey_get_nskey (int algorithm)
469 {
470   gcry_module_t pubkey;
471   int nskey = 0;
472
473   REGISTER_DEFAULT_PUBKEYS;
474
475   ath_mutex_lock (&pubkeys_registered_lock);
476   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
477   if (pubkey)
478     {
479       nskey = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_skey);
480       _gcry_module_release (pubkey);
481     }
482   ath_mutex_unlock (&pubkeys_registered_lock);
483
484   return nskey;
485 }
486
487 /****************
488  * Return the number of signature material numbers
489  */
490 static int
491 pubkey_get_nsig (int algorithm)
492 {
493   gcry_module_t pubkey;
494   int nsig = 0;
495
496   REGISTER_DEFAULT_PUBKEYS;
497
498   ath_mutex_lock (&pubkeys_registered_lock);
499   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
500   if (pubkey)
501     {
502       nsig = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_sig);
503       _gcry_module_release (pubkey);
504     }
505   ath_mutex_unlock (&pubkeys_registered_lock);
506
507   return nsig;
508 }
509
510 /****************
511  * Return the number of encryption material numbers
512  */
513 static int
514 pubkey_get_nenc (int algorithm)
515 {
516   gcry_module_t pubkey;
517   int nenc = 0;
518
519   REGISTER_DEFAULT_PUBKEYS;
520
521   ath_mutex_lock (&pubkeys_registered_lock);
522   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
523   if (pubkey)
524     {
525       nenc = strlen (((gcry_pk_spec_t *) pubkey->spec)->elements_enc);
526       _gcry_module_release (pubkey);
527     }
528   ath_mutex_unlock (&pubkeys_registered_lock);
529
530   return nenc;
531 }
532
533
534 /* Generate a new public key with algorithm ALGORITHM of size NBITS
535    and return it at SKEY.  USE_E depends on the ALGORITHM.  GENPARMS
536    is passed to the algorithm module if it features an extended
537    generation function.  RETFACTOR is used by some algorithms to
538    return certain additional information which are in general not
539    required.
540
541    The function returns the error code number or 0 on success. */
542 static gcry_err_code_t
543 pubkey_generate (int algorithm,
544                  unsigned int nbits,
545                  unsigned long use_e,
546                  gcry_sexp_t genparms,
547                  gcry_mpi_t *skey, gcry_mpi_t **retfactors,
548                  gcry_sexp_t *r_extrainfo)
549 {
550   gcry_err_code_t ec = GPG_ERR_PUBKEY_ALGO;
551   gcry_module_t pubkey;
552
553   REGISTER_DEFAULT_PUBKEYS;
554
555   ath_mutex_lock (&pubkeys_registered_lock);
556   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
557   if (pubkey)
558     {
559       pk_extra_spec_t *extraspec = pubkey->extraspec;
560
561       if (extraspec && extraspec->ext_generate)
562         {
563           /* Use the extended generate function.  */
564           ec = extraspec->ext_generate
565             (algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
566         }
567       else
568         {
569           /* Use the standard generate function.  */
570           ec = ((gcry_pk_spec_t *) pubkey->spec)->generate
571             (algorithm, nbits, use_e, skey, retfactors);
572         }
573       _gcry_module_release (pubkey);
574     }
575   ath_mutex_unlock (&pubkeys_registered_lock);
576
577   return ec;
578 }
579
580
581 static gcry_err_code_t
582 pubkey_check_secret_key (int algorithm, gcry_mpi_t *skey)
583 {
584   gcry_err_code_t err = GPG_ERR_PUBKEY_ALGO;
585   gcry_module_t pubkey;
586
587   REGISTER_DEFAULT_PUBKEYS;
588
589   ath_mutex_lock (&pubkeys_registered_lock);
590   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
591   if (pubkey)
592     {
593       err = ((gcry_pk_spec_t *) pubkey->spec)->check_secret_key
594         (algorithm, skey);
595       _gcry_module_release (pubkey);
596     }
597   ath_mutex_unlock (&pubkeys_registered_lock);
598
599   return err;
600 }
601
602
603 /****************
604  * This is the interface to the public key encryption.  Encrypt DATA
605  * with PKEY and put it into RESARR which should be an array of MPIs
606  * of size PUBKEY_MAX_NENC (or less if the algorithm allows this -
607  * check with pubkey_get_nenc() )
608  */
609 static gcry_err_code_t
610 pubkey_encrypt (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
611                 gcry_mpi_t *pkey, int flags)
612 {
613   gcry_pk_spec_t *pubkey;
614   gcry_module_t module;
615   gcry_err_code_t rc;
616   int i;
617
618   /* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
619      an extra failsafe protection we explicitly test for fips mode
620      here. */
621   if (DBG_CIPHER && !fips_mode ())
622     {
623       log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
624       for(i = 0; i < pubkey_get_npkey (algorithm); i++)
625         log_mpidump ("  pkey:", pkey[i]);
626       log_mpidump ("  data:", data);
627     }
628
629   ath_mutex_lock (&pubkeys_registered_lock);
630   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
631   if (module)
632     {
633       pubkey = (gcry_pk_spec_t *) module->spec;
634       rc = pubkey->encrypt (algorithm, resarr, data, pkey, flags);
635       _gcry_module_release (module);
636       goto ready;
637     }
638   rc = GPG_ERR_PUBKEY_ALGO;
639
640  ready:
641   ath_mutex_unlock (&pubkeys_registered_lock);
642
643   if (!rc && DBG_CIPHER && !fips_mode ())
644     {
645       for(i = 0; i < pubkey_get_nenc (algorithm); i++)
646         log_mpidump("  encr:", resarr[i] );
647     }
648   return rc;
649 }
650
651
652 /****************
653  * This is the interface to the public key decryption.
654  * ALGO gives the algorithm to use and this implicitly determines
655  * the size of the arrays.
656  * result is a pointer to a mpi variable which will receive a
657  * newly allocated mpi or NULL in case of an error.
658  */
659 static gcry_err_code_t
660 pubkey_decrypt (int algorithm, gcry_mpi_t *result, gcry_mpi_t *data,
661                 gcry_mpi_t *skey, int flags)
662 {
663   gcry_pk_spec_t *pubkey;
664   gcry_module_t module;
665   gcry_err_code_t rc;
666   int i;
667
668   *result = NULL; /* so the caller can always do a mpi_free */
669   if (DBG_CIPHER && !fips_mode ())
670     {
671       log_debug ("pubkey_decrypt: algo=%d\n", algorithm);
672       for(i = 0; i < pubkey_get_nskey (algorithm); i++)
673         log_mpidump ("  skey:", skey[i]);
674       for(i = 0; i < pubkey_get_nenc (algorithm); i++)
675         log_mpidump ("  data:", data[i]);
676     }
677
678   ath_mutex_lock (&pubkeys_registered_lock);
679   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
680   if (module)
681     {
682       pubkey = (gcry_pk_spec_t *) module->spec;
683       rc = pubkey->decrypt (algorithm, result, data, skey, flags);
684       _gcry_module_release (module);
685       goto ready;
686     }
687
688   rc = GPG_ERR_PUBKEY_ALGO;
689
690  ready:
691   ath_mutex_unlock (&pubkeys_registered_lock);
692
693   if (!rc && DBG_CIPHER && !fips_mode ())
694     log_mpidump (" plain:", *result);
695
696   return rc;
697 }
698
699
700 /****************
701  * This is the interface to the public key signing.
702  * Sign data with skey and put the result into resarr which
703  * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the
704  * algorithm allows this - check with pubkey_get_nsig() )
705  */
706 static gcry_err_code_t
707 pubkey_sign (int algorithm, gcry_mpi_t *resarr, gcry_mpi_t data,
708              gcry_mpi_t *skey)
709 {
710   gcry_pk_spec_t *pubkey;
711   gcry_module_t module;
712   gcry_err_code_t rc;
713   int i;
714
715   if (DBG_CIPHER && !fips_mode ())
716     {
717       log_debug ("pubkey_sign: algo=%d\n", algorithm);
718       for(i = 0; i < pubkey_get_nskey (algorithm); i++)
719         log_mpidump ("  skey:", skey[i]);
720       log_mpidump("  data:", data );
721     }
722
723   ath_mutex_lock (&pubkeys_registered_lock);
724   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
725   if (module)
726     {
727       pubkey = (gcry_pk_spec_t *) module->spec;
728       rc = pubkey->sign (algorithm, resarr, data, skey);
729       _gcry_module_release (module);
730       goto ready;
731     }
732
733   rc = GPG_ERR_PUBKEY_ALGO;
734
735  ready:
736   ath_mutex_unlock (&pubkeys_registered_lock);
737
738   if (!rc && DBG_CIPHER && !fips_mode ())
739     for (i = 0; i < pubkey_get_nsig (algorithm); i++)
740       log_mpidump ("   sig:", resarr[i]);
741
742   return rc;
743 }
744
745 /****************
746  * Verify a public key signature.
747  * Return 0 if the signature is good
748  */
749 static gcry_err_code_t
750 pubkey_verify (int algorithm, gcry_mpi_t hash, gcry_mpi_t *data,
751                gcry_mpi_t *pkey,
752                int (*cmp)(void *, gcry_mpi_t), void *opaquev)
753 {
754   gcry_pk_spec_t *pubkey;
755   gcry_module_t module;
756   gcry_err_code_t rc;
757   int i;
758
759   if (DBG_CIPHER && !fips_mode ())
760     {
761       log_debug ("pubkey_verify: algo=%d\n", algorithm);
762       for (i = 0; i < pubkey_get_npkey (algorithm); i++)
763         log_mpidump ("  pkey", pkey[i]);
764       for (i = 0; i < pubkey_get_nsig (algorithm); i++)
765         log_mpidump ("   sig", data[i]);
766       log_mpidump ("  hash", hash);
767     }
768
769   ath_mutex_lock (&pubkeys_registered_lock);
770   module = _gcry_module_lookup_id (pubkeys_registered, algorithm);
771   if (module)
772     {
773       pubkey = (gcry_pk_spec_t *) module->spec;
774       rc = pubkey->verify (algorithm, hash, data, pkey, cmp, opaquev);
775       _gcry_module_release (module);
776       goto ready;
777     }
778
779   rc = GPG_ERR_PUBKEY_ALGO;
780
781  ready:
782   ath_mutex_unlock (&pubkeys_registered_lock);
783   return rc;
784 }
785
786
787 /* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
788    type 2 padding.  On sucess the result is stored as a new MPI at
789    R_RESULT.  On error the value at R_RESULT is undefined.  */
790 static gcry_err_code_t
791 pkcs1_encode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
792                              const unsigned char *value, size_t valuelen)
793 {
794   gcry_err_code_t rc = 0;
795   gcry_error_t err;
796   unsigned char *frame = NULL;
797   size_t nframe = (nbits+7) / 8;
798   int i;
799   size_t n;
800   unsigned char *p;
801
802   if (valuelen + 7 > nframe || !nframe)
803     {
804       /* Can't encode a VALUELEN value in a NFRAME bytes frame.  */
805       return GPG_ERR_TOO_SHORT; /* The key is too short.  */
806     }
807
808   if ( !(frame = gcry_malloc_secure (nframe)))
809     return gpg_err_code_from_syserror ();
810
811   n = 0;
812   frame[n++] = 0;
813   frame[n++] = 2; /* block type */
814   i = nframe - 3 - valuelen;
815   gcry_assert (i > 0);
816   p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
817   /* Replace zero bytes by new values. */
818   for (;;)
819     {
820       int j, k;
821       unsigned char *pp;
822
823       /* Count the zero bytes. */
824       for (j=k=0; j < i; j++)
825         {
826           if (!p[j])
827             k++;
828         }
829       if (!k)
830         break; /* Okay: no (more) zero bytes. */
831
832       k += k/128 + 3; /* Better get some more. */
833       pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
834       for (j=0; j < i && k; )
835         {
836           if (!p[j])
837             p[j] = pp[--k];
838           if (p[j])
839             j++;
840         }
841       gcry_free (pp);
842     }
843   memcpy (frame+n, p, i);
844   n += i;
845   gcry_free (p);
846
847   frame[n++] = 0;
848   memcpy (frame+n, value, valuelen);
849   n += valuelen;
850   gcry_assert (n == nframe);
851
852   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
853   if (err)
854     rc = gcry_err_code (err);
855   else if (DBG_CIPHER)
856     log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
857   gcry_free (frame);
858
859   return rc;
860 }
861
862
863 /* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
864    NBITS is the size of the secret key.  On sucess the result is
865    stored as a new MPI at R_RESULT.  On error the value at R_RESULT is
866    undefined.  */
867 static gcry_err_code_t
868 pkcs1_decode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
869                              gcry_mpi_t value)
870 {
871   gcry_err_code_t rc = 0;
872   gcry_error_t err;
873   unsigned char *frame = NULL;
874   size_t nframe = (nbits+7) / 8;
875   size_t n;
876
877   if ( !(frame = gcry_malloc_secure (nframe)))
878     return gpg_err_code_from_syserror ();
879
880   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
881   if (err)
882     {
883       gcry_free (frame);
884       return gcry_err_code (err);
885     }
886
887   if (n < nframe)
888     {
889       memmove (frame + (nframe - n), frame, n);
890       memset (frame, 0, (nframe - n));
891     }
892
893   /* FRAME = 0x00 || 0x02 || PS || 0x00 || M */
894   n = 0;
895   if (frame[n++] != 0x00 || frame[n++] != 0x02)
896     {
897       gcry_free (frame);
898       return GPG_ERR_ENCODING_PROBLEM;
899     }
900
901   for (; frame[n] != 0x00 && n < nframe; n++)
902     ;
903   if (n == nframe)
904     {
905       gcry_free (frame);
906       return GPG_ERR_ENCODING_PROBLEM;
907     }
908
909   n++;
910   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, &frame[n], nframe - n, NULL);
911   if (err)
912     rc = gcry_err_code (err);
913   else if (DBG_CIPHER)
914     log_mpidump ("value extracted from PKCS#1 block type 2 encoded data",
915                  *r_result);
916   gcry_free (frame);
917
918   return rc;
919 }
920
921
922 /* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO
923    using the pkcs#1 block type 1 padding.  On sucess the result is
924    stored as a new MPI at R_RESULT.  On error the value at R_RESULT is
925    undefined.  */
926 static gcry_err_code_t
927 pkcs1_encode_for_signature (gcry_mpi_t *r_result, unsigned int nbits,
928                             const unsigned char *value, size_t valuelen,
929                             int algo)
930 {
931   gcry_err_code_t rc = 0;
932   gcry_error_t err;
933   byte asn[100];
934   byte *frame = NULL;
935   size_t nframe = (nbits+7) / 8;
936   int i;
937   size_t n;
938   size_t asnlen, dlen;
939
940   asnlen = DIM(asn);
941   dlen = gcry_md_get_algo_dlen (algo);
942
943   if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
944     {
945       /* We don't have yet all of the above algorithms.  */
946       return GPG_ERR_NOT_IMPLEMENTED;
947     }
948
949   if ( valuelen != dlen )
950     {
951       /* Hash value does not match the length of digest for
952          the given algorithm.  */
953       return GPG_ERR_CONFLICT;
954     }
955
956   if ( !dlen || dlen + asnlen + 4 > nframe)
957     {
958       /* Can't encode an DLEN byte digest MD into an NFRAME byte
959          frame.  */
960       return GPG_ERR_TOO_SHORT;
961     }
962
963   if ( !(frame = gcry_malloc (nframe)) )
964     return gpg_err_code_from_syserror ();
965
966   /* Assemble the pkcs#1 block type 1. */
967   n = 0;
968   frame[n++] = 0;
969   frame[n++] = 1; /* block type */
970   i = nframe - valuelen - asnlen - 3 ;
971   gcry_assert (i > 1);
972   memset (frame+n, 0xff, i );
973   n += i;
974   frame[n++] = 0;
975   memcpy (frame+n, asn, asnlen);
976   n += asnlen;
977   memcpy (frame+n, value, valuelen );
978   n += valuelen;
979   gcry_assert (n == nframe);
980
981   /* Convert it into an MPI. */
982   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
983   if (err)
984     rc = gcry_err_code (err);
985   else if (DBG_CIPHER)
986     log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
987   gcry_free (frame);
988
989   return rc;
990 }
991
992
993 static gcry_err_code_t
994 mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
995       int algo)
996 {
997   size_t dlen;
998   int idx;
999   gcry_md_hd_t hd;
1000   gcry_error_t err;
1001   unsigned char *p;
1002
1003   err = gcry_md_open (&hd, algo, 0);
1004   if (err)
1005     return gpg_err_code (err);
1006
1007   memset (output, 0, outlen);
1008   dlen = gcry_md_get_algo_dlen (algo);
1009   for (idx = 0, p = output; idx < (outlen + dlen - 1) / dlen; idx++, p += dlen)
1010     {
1011       unsigned char c[4], *digest;
1012
1013       c[0] = (idx >> 24) & 0xFF;
1014       c[1] = (idx >> 16) & 0xFF;
1015       c[2] = (idx >> 8) & 0xFF;
1016       c[3] = idx & 0xFF;
1017
1018       gcry_md_reset (hd);
1019       gcry_md_write (hd, seed, seedlen);
1020       gcry_md_write (hd, c, 4);
1021       digest = gcry_md_read (hd, 0);
1022       if (outlen - (p - output) >= dlen)
1023         memcpy (p, digest, dlen);
1024       else
1025         memcpy (p, digest, outlen - (p - output));
1026     }
1027   gcry_md_close (hd);
1028   return GPG_ERR_NO_ERROR;
1029 }
1030
1031 static gcry_err_code_t
1032 oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1033              const unsigned char *value, size_t valuelen,
1034              const unsigned char *label, size_t labellen)
1035 {
1036   gcry_err_code_t rc = 0;
1037   gcry_error_t err;
1038   unsigned char *frame = NULL;
1039   size_t nframe = (nbits+7) / 8;
1040   unsigned char *dmask, *smask, *p;
1041   size_t dlen;
1042   gcry_md_hd_t hd;
1043   size_t n;
1044
1045   dlen = gcry_md_get_algo_dlen (algo);
1046   if (valuelen > nframe - 2 * dlen - 1 || !nframe)
1047     /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1048     return GPG_ERR_TOO_SHORT; /* the key is too short */
1049   if ( !(frame = gcry_malloc_secure (nframe)))
1050     return gpg_err_code_from_syserror ();
1051
1052   /* FRAME = 00 || SEED || DB */
1053   memset (frame, 0, nframe);
1054   n = 0;
1055   frame[n++] = 0;
1056   gcry_randomize (&frame[n], dlen, GCRY_STRONG_RANDOM);
1057
1058   n += dlen;
1059   gcry_md_open (&hd, algo, 0);
1060   gcry_md_write (hd, label, labellen);
1061   memcpy (&frame[n], gcry_md_read (hd, 0), dlen);
1062   gcry_md_close (hd);
1063   n = nframe - valuelen - 1;
1064   frame[n++] = 1;
1065   memcpy (&frame[n], value, valuelen);
1066
1067   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1068     {
1069       rc = gpg_err_code_from_syserror ();
1070       gcry_free (frame);
1071       return rc;
1072     }
1073   mgf1 (dmask, nframe - dlen - 1, &frame[1], dlen, algo);
1074   for (n = 1 + dlen, p = dmask; n < nframe; n++)
1075     frame[n] ^= *p++;
1076   gcry_free (dmask);
1077   n += valuelen;
1078
1079   if ( !(smask = gcry_malloc_secure (dlen)))
1080     {
1081       rc = gpg_err_code_from_syserror ();
1082       gcry_free (frame);
1083       return rc;
1084     }
1085   mgf1 (smask, dlen, &frame[1 + dlen], nframe - dlen - 1, algo);
1086   for (n = 1, p = smask; n < 1 + dlen; n++)
1087     frame[n] ^= *p++;
1088   gcry_free (smask);
1089   n = nframe;
1090
1091   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
1092   if (err)
1093     rc = gcry_err_code (err);
1094   else if (DBG_CIPHER)
1095     log_mpidump ("OAEP encoded data", *r_result);
1096   gcry_free (frame);
1097
1098   return rc;
1099 }
1100
1101 static gcry_err_code_t
1102 oaep_decode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1103              gcry_mpi_t value, const unsigned char *label, size_t labellen)
1104 {
1105   gcry_err_code_t rc = 0;
1106   gcry_error_t err;
1107   unsigned char *frame = NULL, *dmask, *smask, *p;
1108   size_t nframe = (nbits+7) / 8;
1109   size_t dlen;
1110   gcry_md_hd_t hd;
1111   size_t n;
1112
1113   if ( !(frame = gcry_malloc_secure (nframe)))
1114     return gpg_err_code_from_syserror ();
1115
1116   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
1117   if (err)
1118     {
1119       gcry_free (frame);
1120       return gcry_err_code (err);
1121     }
1122   if (n < nframe)
1123     {
1124       memmove (frame + (nframe - n), frame, n);
1125       memset (frame, 0, (nframe - n));
1126     }
1127
1128   /* FRAME = 00 || MASKED_SEED || MASKED_DB */
1129   if (frame[0])
1130     {
1131       gcry_free (frame);
1132       return GPG_ERR_ENCODING_PROBLEM;
1133     }
1134
1135   dlen = gcry_md_get_algo_dlen (algo);
1136   if (nframe < 1 + 2 * dlen + 1)
1137     {
1138       gcry_free (frame);
1139       return GPG_ERR_TOO_SHORT;
1140     }
1141   if ( !(smask = gcry_malloc_secure (dlen)))
1142     {
1143       rc = gpg_err_code_from_syserror ();
1144       gcry_free (frame);
1145       return rc;
1146     }
1147   mgf1 (smask, dlen, &frame[1 + dlen], nframe - dlen - 1, algo);
1148   for (n = 1, p = smask; n < 1 + dlen; n++)
1149     frame[n] ^= *p++;
1150   gcry_free (smask);
1151
1152   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1153     {
1154       rc = gpg_err_code_from_syserror ();
1155       gcry_free (frame);
1156       return rc;
1157     }
1158   mgf1 (dmask, nframe - dlen - 1, &frame[1], dlen, algo);
1159   for (n = 1 + dlen, p = dmask; n < nframe; n++)
1160     frame[n] ^= *p++;
1161   gcry_free (dmask);
1162
1163   gcry_md_open (&hd, algo, 0);
1164   gcry_md_write (hd, label, labellen);
1165   memcpy (&frame[1], gcry_md_read (hd, 0), dlen);
1166   gcry_md_close (hd);
1167
1168   if (memcmp (&frame[1], &frame[1 + dlen], dlen))
1169     {
1170       gcry_free (frame);
1171       return GPG_ERR_ENCODING_PROBLEM;
1172     }
1173
1174   for (n = 1 + dlen * 2; n < nframe && !frame[n]; n++)
1175     ;
1176   if (n < nframe && frame[n] != 1)
1177     {
1178       gcry_free (frame);
1179       return GPG_ERR_ENCODING_PROBLEM;
1180     }
1181
1182   n++;
1183   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, &frame[n], nframe - n, NULL);
1184   if (err)
1185     rc = gcry_err_code (err);
1186   else if (DBG_CIPHER)
1187     log_mpidump ("value extracted from OAEP encoded data", *r_result);
1188   gcry_free (frame);
1189
1190   return rc;
1191 }
1192
1193
1194 /* Encode {VALUE,VALUELEN} for an NBITS keys using the PSS padding.
1195    ALGO is a hash algorithm and SALTLEN is a length of salt used
1196    internally.  On sucess the result is stored as a new MPI at
1197    R_RESULT.  On error the value at R_RESULT is undefined.  */
1198 static gcry_err_code_t
1199 pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1200             const unsigned char *value, size_t valuelen,
1201             int saltlen)
1202 {
1203   gcry_err_code_t rc = 0;
1204   gcry_error_t err;
1205   unsigned char *frame = NULL, *buf = NULL, *dmask = NULL, *h = NULL, *salt, *p;
1206   size_t nframe = (nbits+7) / 8;
1207   size_t dlen;
1208   gcry_md_hd_t hd = NULL;
1209   size_t n;
1210
1211   err = gcry_md_open (&hd, algo, 0);
1212   if (err)
1213     {
1214       rc = gpg_err_code (err);
1215       goto leave;
1216     }
1217   dlen = gcry_md_get_algo_dlen (algo);
1218
1219   if (nframe < dlen + saltlen + 2)
1220     {
1221       /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1222       rc = GPG_ERR_TOO_SHORT; /* the key is too short */
1223       goto leave;
1224     }
1225
1226   if ( !(frame = gcry_calloc_secure (nframe, sizeof *frame)))
1227     {
1228       rc = gpg_err_code_from_syserror ();
1229       goto leave;
1230     }
1231
1232   if ( !(buf = gcry_calloc_secure (8 + dlen + saltlen, sizeof *buf)))
1233     {
1234       rc = gpg_err_code_from_syserror ();
1235       goto leave;
1236     }
1237
1238   /* M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
1239   n = 8;
1240   gcry_md_reset (hd);
1241   gcry_md_write (hd, value, valuelen);
1242   memcpy (&buf[n], gcry_md_read (hd, 0), dlen);
1243   n += dlen;
1244   salt = &buf[n];
1245   gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
1246   n += saltlen;
1247
1248   /* H = Hash(M') */
1249   if ( !(h = gcry_malloc_secure (dlen)))
1250     {
1251       rc = gpg_err_code_from_syserror ();
1252       goto leave;
1253     }
1254   gcry_md_reset (hd);
1255   gcry_md_write (hd, buf, n);
1256   memcpy (h, gcry_md_read (hd, 0), dlen);
1257
1258   /* DB = PS || 0x01 || salt */
1259   n = nframe - saltlen - dlen - 2;
1260   frame[n++] = 1;
1261   memcpy (&frame[n], salt, saltlen);
1262   n += saltlen;
1263
1264   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1265     {
1266       rc = gpg_err_code_from_syserror ();
1267       goto leave;
1268     }
1269
1270   /* DMASK = MGF(H, NFRAME - DLEN - 1) */
1271   mgf1 (dmask, nframe - dlen - 1, h, dlen, algo);
1272
1273   /* FRAME = DB xor DMASK || H || 0xbc */
1274   for (n = 0, p = dmask; n < nframe - dlen - 1; n++)
1275     frame[n] ^= *p++;
1276
1277   memcpy (&frame[n], h, dlen);
1278   n += dlen;
1279   frame[n++] = 0xbc;
1280   gcry_assert (n == nframe);
1281
1282   frame[0] &= 0xFF >> (8 * nframe - nbits);
1283
1284   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL);
1285   if (err)
1286     rc = gcry_err_code (err);
1287   else if (DBG_CIPHER)
1288     log_mpidump ("PSS encoded data", *r_result);
1289
1290  leave:
1291   gcry_md_close (hd);
1292   gcry_free (frame);
1293   gcry_free (buf);
1294   gcry_free (dmask);
1295   gcry_free (h);
1296   return rc;
1297 }
1298
1299
1300 /* Verify a signature in VALUE assuming PSS padding.  NBITS is the
1301    size of the secret key.  ALGO is a hash algorithm and SALTLEN is a
1302    length of salt used internally.  On sucess it returns
1303    GPG_ERR_NO_ERROR; on error otherwise.  */
1304 static gcry_err_code_t
1305 pss_verify (gcry_mpi_t value, gcry_mpi_t encoded, unsigned int nbits, int algo,
1306             size_t saltlen)
1307 {
1308   gcry_err_code_t rc = 0;
1309   gcry_error_t err;
1310   unsigned char *frame = NULL, *mhash = NULL, *buf = NULL, *dmask = NULL;
1311   unsigned char *h = NULL, *salt;
1312   size_t nframe = (nbits+7) / 8, valuelen;
1313   size_t dlen;
1314   gcry_md_hd_t hd = NULL;
1315   size_t n;
1316
1317   if ( !(frame = gcry_malloc_secure (nframe)))
1318     {
1319       rc = gpg_err_code_from_syserror ();
1320       goto leave;
1321     }
1322
1323   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &valuelen, value);
1324   if (err)
1325     {
1326       rc = gcry_err_code (err);
1327       goto leave;
1328     }
1329
1330   err = gcry_md_open (&hd, algo, 0);
1331   if (err)
1332     {
1333       rc = gpg_err_code (err);
1334       goto leave;
1335     }
1336   dlen = gcry_md_get_algo_dlen (algo);
1337
1338   if ( !(mhash = gcry_malloc_secure (dlen)))
1339     {
1340       rc = gpg_err_code_from_syserror ();
1341       goto leave;
1342     }
1343
1344   gcry_md_write (hd, frame, valuelen);
1345   memcpy (mhash, gcry_md_read (hd, 0), dlen);
1346
1347   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, encoded);
1348   if (err)
1349     {
1350       rc = gcry_err_code (err);
1351       goto leave;
1352     }
1353   if (n < nframe)
1354     {
1355       memmove (frame + (nframe - n), frame, n);
1356       memset (frame, 0, (nframe - n));
1357     }
1358
1359   if (nframe < dlen + saltlen + 2)
1360     {
1361       /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1362       rc = GPG_ERR_TOO_SHORT; /* the sig is too short */
1363       goto leave;
1364     }
1365
1366   if (frame[nframe - 1] != 0xbc)
1367     {
1368       rc = GPG_ERR_BAD_SIGNATURE;
1369       goto leave;
1370     }
1371
1372   if ( !(buf = gcry_malloc_secure (nframe - dlen - 1)))
1373     {
1374       rc = gpg_err_code_from_syserror ();
1375       goto leave;
1376     }
1377   memcpy (buf, frame, nframe - dlen - 1);
1378
1379   if ((buf[0] & ~(0xFF >> (8 * nframe - nbits))) != 0)
1380     {
1381       rc = GPG_ERR_BAD_SIGNATURE;
1382       goto leave;
1383     }
1384
1385   if ( !(h = gcry_malloc_secure (dlen)))
1386     {
1387       rc = gpg_err_code_from_syserror ();
1388       goto leave;
1389     }
1390   memcpy (h, &frame[nframe - dlen - 1], dlen);
1391
1392   if ( !(dmask = gcry_malloc_secure (nframe - dlen - 1)))
1393     {
1394       rc = gpg_err_code_from_syserror ();
1395       goto leave;
1396     }
1397
1398   /* DMASK = MGF(H, NFRAME - DLEN - 1) */
1399   mgf1 (dmask, nframe - dlen - 1, h, dlen, algo);
1400
1401   for (n = 0; n < nframe - dlen - 1; n++)
1402     buf[n] ^= dmask[n];
1403
1404   buf[0] &= 0xFF >> (8 * nframe - nbits);
1405
1406   for (n = 0; n < nframe - dlen - saltlen - 2 && buf[n] == 0; n++)
1407     ;
1408   if (n != nframe - dlen - saltlen - 2 || buf[n++] != 1)
1409     {
1410       rc = GPG_ERR_BAD_SIGNATURE;
1411       goto leave;
1412     }
1413   salt = &buf[n];
1414
1415   /* M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
1416   n = 0;
1417   memset (frame, 0, 8);
1418   n += 8;
1419   memcpy (&frame[n], mhash, dlen);
1420   n += dlen;
1421   memcpy (&frame[n], salt, saltlen);
1422   n += saltlen;
1423
1424   /* H' = Hash(M') */
1425   gcry_md_reset (hd);
1426   gcry_md_write (hd, frame, n);
1427   memcpy (buf, gcry_md_read (hd, 0), dlen);
1428
1429   rc = memcmp (buf, h, dlen) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
1430
1431  leave:
1432   gcry_md_close (hd);
1433   gcry_free (frame);
1434   gcry_free (buf);
1435   gcry_free (dmask);
1436   gcry_free (mhash);
1437   gcry_free (h);
1438   return rc;
1439 }
1440
1441 static int
1442 pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
1443 {
1444   struct pk_encoding_ctx *ctx = opaque;
1445   gcry_mpi_t hash = ctx->verify_arg;
1446
1447   return pss_verify (hash, tmp, ctx->nbits - 1, ctx->hash_algo, ctx->saltlen);
1448 }
1449
1450 /* Internal function.   */
1451 static gcry_err_code_t
1452 sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
1453                        gcry_mpi_t *elements, const char *algo_name)
1454 {
1455   gcry_err_code_t err = 0;
1456   int i, idx;
1457   const char *name;
1458   gcry_sexp_t list;
1459
1460   for (name = element_names, idx = 0; *name && !err; name++, idx++)
1461     {
1462       list = gcry_sexp_find_token (key_sexp, name, 1);
1463       if (!list)
1464         elements[idx] = NULL;
1465       else
1466         {
1467           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
1468           gcry_sexp_release (list);
1469           if (!elements[idx])
1470             err = GPG_ERR_INV_OBJ;
1471         }
1472     }
1473
1474   if (!err)
1475     {
1476       /* Check that all elements are available.  */
1477       for (name = element_names, idx = 0; *name; name++, idx++)
1478         if (!elements[idx])
1479           break;
1480       if (*name)
1481         {
1482           err = GPG_ERR_NO_OBJ;
1483           /* Some are missing.  Before bailing out we test for
1484              optional parameters.  */
1485           if (algo_name && !strcmp (algo_name, "RSA")
1486               && !strcmp (element_names, "nedpqu") )
1487             {
1488               /* This is RSA.  Test whether we got N, E and D and that
1489                  the optional P, Q and U are all missing.  */
1490               if (elements[0] && elements[1] && elements[2]
1491                   && !elements[3] && !elements[4] && !elements[5])
1492                 err = 0;
1493             }
1494         }
1495     }
1496
1497
1498   if (err)
1499     {
1500       for (i = 0; i < idx; i++)
1501         if (elements[i])
1502           gcry_free (elements[i]);
1503     }
1504   return err;
1505 }
1506
1507
1508 /* Internal function used for ecc.  Note, that this function makes use
1509    of its intimate knowledge about the ECC parameters from ecc.c. */
1510 static gcry_err_code_t
1511 sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
1512                            gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
1513
1514 {
1515   gcry_err_code_t err = 0;
1516   int idx;
1517   const char *name;
1518   gcry_sexp_t list;
1519
1520   /* Clear the array for easier error cleanup. */
1521   for (name = element_names, idx = 0; *name; name++, idx++)
1522     elements[idx] = NULL;
1523   gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements
1524                              (params only) or 6 (full public key).  */
1525   if (idx == 5)
1526     elements[5] = NULL;   /* Extra clear for the params only case.  */
1527
1528
1529   /* Init the array with the available curve parameters. */
1530   for (name = element_names, idx = 0; *name && !err; name++, idx++)
1531     {
1532       list = gcry_sexp_find_token (key_sexp, name, 1);
1533       if (!list)
1534         elements[idx] = NULL;
1535       else
1536         {
1537           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
1538           gcry_sexp_release (list);
1539           if (!elements[idx])
1540             {
1541               err = GPG_ERR_INV_OBJ;
1542               goto leave;
1543             }
1544         }
1545     }
1546
1547   /* Check whether a curve parameter has been given and then fill any
1548      missing elements.  */
1549   list = gcry_sexp_find_token (key_sexp, "curve", 5);
1550   if (list)
1551     {
1552       if (extraspec->get_param)
1553         {
1554           char *curve;
1555           gcry_mpi_t params[6];
1556
1557           for (idx = 0; idx < DIM(params); idx++)
1558             params[idx] = NULL;
1559
1560           curve = _gcry_sexp_nth_string (list, 1);
1561           gcry_sexp_release (list);
1562           if (!curve)
1563             {
1564               /* No curve name given (or out of core). */
1565               err = GPG_ERR_INV_OBJ;
1566               goto leave;
1567             }
1568           err = extraspec->get_param (curve, params);
1569           gcry_free (curve);
1570           if (err)
1571             goto leave;
1572
1573           for (idx = 0; idx < DIM(params); idx++)
1574             {
1575               if (!elements[idx])
1576                 elements[idx] = params[idx];
1577               else
1578                 mpi_free (params[idx]);
1579             }
1580         }
1581       else
1582         {
1583           gcry_sexp_release (list);
1584           err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
1585           goto leave;
1586         }
1587     }
1588
1589   /* Check that all parameters are known.  */
1590   for (name = element_names, idx = 0; *name; name++, idx++)
1591     if (!elements[idx])
1592       {
1593         err = GPG_ERR_NO_OBJ;
1594         goto leave;
1595       }
1596
1597  leave:
1598   if (err)
1599     {
1600       for (name = element_names, idx = 0; *name; name++, idx++)
1601         if (elements[idx])
1602           gcry_free (elements[idx]);
1603     }
1604   return err;
1605 }
1606
1607
1608
1609 /****************
1610  * Convert a S-Exp with either a private or a public key to our
1611  * internal format. Currently we do only support the following
1612  * algorithms:
1613  *    dsa
1614  *    rsa
1615  *    openpgp-dsa
1616  *    openpgp-rsa
1617  *    openpgp-elg
1618  *    openpgp-elg-sig
1619  *    ecdsa
1620  *    ecdh
1621  * Provide a SE with the first element be either "private-key" or
1622  * or "public-key". It is followed by a list with its first element
1623  * be one of the above algorithm identifiers and the remaning
1624  * elements are pairs with parameter-id and value.
1625  * NOTE: we look through the list to find a list beginning with
1626  * "private-key" or "public-key" - the first one found is used.
1627  *
1628  * If OVERRIDE_ELEMS is not NULL those elems override the parameter
1629  * specification taken from the module.  This ise used by
1630  * gcry_pk_get_curve.
1631  *
1632  * Returns: A pointer to an allocated array of MPIs if the return value is
1633  *          zero; the caller has to release this array.
1634  *
1635  * Example of a DSA public key:
1636  *  (private-key
1637  *    (dsa
1638  *      (p <mpi>)
1639  *      (g <mpi>)
1640  *      (y <mpi>)
1641  *      (x <mpi>)
1642  *    )
1643  *  )
1644  * The <mpi> are expected to be in GCRYMPI_FMT_USG
1645  */
1646 static gcry_err_code_t
1647 sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
1648              gcry_mpi_t **retarray, gcry_module_t *retalgo)
1649 {
1650   gcry_err_code_t err = 0;
1651   gcry_sexp_t list, l2;
1652   char *name;
1653   const char *elems;
1654   gcry_mpi_t *array;
1655   gcry_module_t module;
1656   gcry_pk_spec_t *pubkey;
1657   pk_extra_spec_t *extraspec;
1658   int is_ecc;
1659
1660   /* Check that the first element is valid.  */
1661   list = gcry_sexp_find_token (sexp,
1662                                want_private? "private-key":"public-key", 0);
1663   if (!list)
1664     return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
1665
1666   l2 = gcry_sexp_cadr( list );
1667   gcry_sexp_release ( list );
1668   list = l2;
1669   name = _gcry_sexp_nth_string (list, 0);
1670   if (!name)
1671     {
1672       gcry_sexp_release ( list );
1673       return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
1674     }
1675
1676   ath_mutex_lock (&pubkeys_registered_lock);
1677   module = gcry_pk_lookup_name (name);
1678   ath_mutex_unlock (&pubkeys_registered_lock);
1679
1680   /* Fixme: We should make sure that an ECC key is always named "ecc"
1681      and not "ecdsa".  "ecdsa" should be used for the signature
1682      itself.  We need a function to test whether an algorithm given
1683      with a key is compatible with an application of the key (signing,
1684      encryption).  For RSA this is easy, but ECC is the first
1685      algorithm which has many flavours.  */
1686   is_ecc = ( !strcmp (name, "ecdsa")
1687              || !strcmp (name, "ecdh")
1688              || !strcmp (name, "ecc") );
1689   gcry_free (name);
1690
1691   if (!module)
1692     {
1693       gcry_sexp_release (list);
1694       return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
1695     }
1696   else
1697     {
1698       pubkey = (gcry_pk_spec_t *) module->spec;
1699       extraspec = module->extraspec;
1700     }
1701
1702   if (override_elems)
1703     elems = override_elems;
1704   else if (want_private)
1705     elems = pubkey->elements_skey;
1706   else
1707     elems = pubkey->elements_pkey;
1708   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1709   if (!array)
1710     err = gpg_err_code_from_syserror ();
1711   if (!err)
1712     {
1713       if (is_ecc)
1714         err = sexp_elements_extract_ecc (list, elems, array, extraspec);
1715       else
1716         err = sexp_elements_extract (list, elems, array, pubkey->name);
1717     }
1718
1719   gcry_sexp_release (list);
1720
1721   if (err)
1722     {
1723       gcry_free (array);
1724
1725       ath_mutex_lock (&pubkeys_registered_lock);
1726       _gcry_module_release (module);
1727       ath_mutex_unlock (&pubkeys_registered_lock);
1728     }
1729   else
1730     {
1731       *retarray = array;
1732       *retalgo = module;
1733     }
1734
1735   return err;
1736 }
1737
1738
1739 static gcry_err_code_t
1740 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
1741              gcry_module_t *retalgo)
1742 {
1743   gcry_err_code_t err = 0;
1744   gcry_sexp_t list, l2;
1745   char *name;
1746   const char *elems;
1747   gcry_mpi_t *array;
1748   gcry_module_t module;
1749   gcry_pk_spec_t *pubkey;
1750
1751   /* Check that the first element is valid.  */
1752   list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
1753   if (!list)
1754     return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
1755
1756   l2 = gcry_sexp_nth (list, 1);
1757   if (!l2)
1758     {
1759       gcry_sexp_release (list);
1760       return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
1761     }
1762   name = _gcry_sexp_nth_string (l2, 0);
1763   if (!name)
1764     {
1765       gcry_sexp_release (list);
1766       gcry_sexp_release (l2);
1767       return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
1768     }
1769   else if (!strcmp (name, "flags"))
1770     {
1771       /* Skip flags, since they are not used but here just for the
1772          sake of consistent S-expressions.  */
1773       gcry_free (name);
1774       gcry_sexp_release (l2);
1775       l2 = gcry_sexp_nth (list, 2);
1776       if (!l2)
1777         {
1778           gcry_sexp_release (list);
1779           return GPG_ERR_INV_OBJ;
1780         }
1781       name = _gcry_sexp_nth_string (l2, 0);
1782     }
1783
1784   ath_mutex_lock (&pubkeys_registered_lock);
1785   module = gcry_pk_lookup_name (name);
1786   ath_mutex_unlock (&pubkeys_registered_lock);
1787   gcry_free (name);
1788   name = NULL;
1789
1790   if (!module)
1791     {
1792       gcry_sexp_release (l2);
1793       gcry_sexp_release (list);
1794       return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
1795     }
1796   else
1797     pubkey = (gcry_pk_spec_t *) module->spec;
1798
1799   elems = pubkey->elements_sig;
1800   array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
1801   if (!array)
1802     err = gpg_err_code_from_syserror ();
1803
1804   if (!err)
1805     err = sexp_elements_extract (list, elems, array, NULL);
1806
1807   gcry_sexp_release (l2);
1808   gcry_sexp_release (list);
1809
1810   if (err)
1811     {
1812       ath_mutex_lock (&pubkeys_registered_lock);
1813       _gcry_module_release (module);
1814       ath_mutex_unlock (&pubkeys_registered_lock);
1815
1816       gcry_free (array);
1817     }
1818   else
1819     {
1820       *retarray = array;
1821       *retalgo = module;
1822     }
1823
1824   return err;
1825 }
1826
1827 static inline int
1828 get_hash_algo (const char *s, size_t n)
1829 {
1830   static const struct { const char *name; int algo; } hashnames[] = {
1831     { "sha1",   GCRY_MD_SHA1 },
1832     { "md5",    GCRY_MD_MD5 },
1833     { "sha256", GCRY_MD_SHA256 },
1834     { "ripemd160", GCRY_MD_RMD160 },
1835     { "rmd160", GCRY_MD_RMD160 },
1836     { "sha384", GCRY_MD_SHA384 },
1837     { "sha512", GCRY_MD_SHA512 },
1838     { "sha224", GCRY_MD_SHA224 },
1839     { "md2",    GCRY_MD_MD2 },
1840     { "md4",    GCRY_MD_MD4 },
1841     { "tiger",  GCRY_MD_TIGER },
1842     { "haval",  GCRY_MD_HAVAL },
1843     { NULL, 0 }
1844   };
1845   int algo;
1846   int i;
1847
1848   for (i=0; hashnames[i].name; i++)
1849     {
1850       if ( strlen (hashnames[i].name) == n
1851            && !memcmp (hashnames[i].name, s, n))
1852         break;
1853     }
1854   if (hashnames[i].name)
1855     algo = hashnames[i].algo;
1856   else
1857     {
1858       /* In case of not listed or dynamically allocated hash
1859          algorithm we fall back to this somewhat slower
1860          method.  Further, it also allows to use OIDs as
1861          algorithm names. */
1862       char *tmpname;
1863
1864       tmpname = gcry_malloc (n+1);
1865       if (!tmpname)
1866         algo = 0;  /* Out of core - silently give up.  */
1867       else
1868         {
1869           memcpy (tmpname, s, n);
1870           tmpname[n] = 0;
1871           algo = gcry_md_map_name (tmpname);
1872           gcry_free (tmpname);
1873         }
1874     }
1875   return algo;
1876 }
1877
1878
1879 /****************
1880  * Take sexp and return an array of MPI as used for our internal decrypt
1881  * function.
1882  * s_data = (enc-val
1883  *           [(flags [raw, pkcs1, oaep, no-blinding])]
1884  *           [(hash-algo <algo>)]
1885  *           [(label <label>)]
1886  *            (<algo>
1887  *              (<param_name1> <mpi>)
1888  *              ...
1889  *              (<param_namen> <mpi>)
1890  *            ))
1891  * HASH-ALGO and LABEL are specific to OAEP.
1892  * RET_MODERN is set to true when at least an empty flags list has been found.
1893  * CTX is used to return encoding information; it may be NULL in which
1894  * case raw encoding is used.
1895  */
1896 static gcry_err_code_t
1897 sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
1898              int *ret_modern, int *flags, struct pk_encoding_ctx *ctx)
1899 {
1900   gcry_err_code_t err = 0;
1901   gcry_sexp_t list = NULL, l2 = NULL;
1902   gcry_pk_spec_t *pubkey = NULL;
1903   gcry_module_t module = NULL;
1904   char *name = NULL;
1905   size_t n;
1906   int parsed_flags = 0;
1907   const char *elems;
1908   gcry_mpi_t *array = NULL;
1909
1910   *ret_modern = 0;
1911
1912   /* Check that the first element is valid.  */
1913   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
1914   if (!list)
1915     {
1916       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
1917       goto leave;
1918     }
1919
1920   l2 = gcry_sexp_nth (list, 1);
1921   if (!l2)
1922     {
1923       err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
1924       goto leave;
1925     }
1926
1927   /* Extract identifier of sublist.  */
1928   name = _gcry_sexp_nth_string (l2, 0);
1929   if (!name)
1930     {
1931       err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
1932       goto leave;
1933     }
1934
1935   if (!strcmp (name, "flags"))
1936     {
1937       /* There is a flags element - process it.  */
1938       const char *s;
1939       int i;
1940
1941       *ret_modern = 1;
1942       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
1943         {
1944           s = gcry_sexp_nth_data (l2, i, &n);
1945           if (! s)
1946             ; /* Not a data element - ignore.  */
1947           else if (n == 3 && !memcmp (s, "raw", 3)
1948                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1949             ctx->encoding = PUBKEY_ENC_RAW;
1950           else if (n == 5 && !memcmp (s, "pkcs1", 5)
1951                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1952             ctx->encoding = PUBKEY_ENC_PKCS1;
1953           else if (n == 4 && !memcmp (s, "oaep", 4)
1954                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1955             ctx->encoding = PUBKEY_ENC_OAEP;
1956           else if (n == 3 && !memcmp (s, "pss", 3)
1957                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1958             {
1959               err = GPG_ERR_CONFLICT;
1960               goto leave;
1961             }
1962           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1963             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1964           else
1965             {
1966               err = GPG_ERR_INV_FLAG;
1967               goto leave;
1968             }
1969         }
1970       gcry_sexp_release (l2);
1971
1972       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
1973       if (ctx->encoding == PUBKEY_ENC_OAEP)
1974         {
1975           /* Get HASH-ALGO. */
1976           l2 = gcry_sexp_find_token (list, "hash-algo", 0);
1977           if (l2)
1978             {
1979               s = gcry_sexp_nth_data (l2, 1, &n);
1980               if (!s)
1981                 err = GPG_ERR_NO_OBJ;
1982               else
1983                 {
1984                   ctx->hash_algo = get_hash_algo (s, n);
1985                   if (!ctx->hash_algo)
1986                     err = GPG_ERR_DIGEST_ALGO;
1987                 }
1988               gcry_sexp_release (l2);
1989               if (err)
1990                 goto leave;
1991             }
1992
1993           /* Get LABEL. */
1994           l2 = gcry_sexp_find_token (list, "label", 0);
1995           if (l2)
1996             {
1997               s = gcry_sexp_nth_data (l2, 1, &n);
1998               if (!s)
1999                 err = GPG_ERR_NO_OBJ;
2000               else if (n > 0)
2001                 {
2002                   ctx->label = gcry_malloc (n);
2003                   if (!ctx->label)
2004                     err = gpg_err_code_from_syserror ();
2005                   else
2006                     {
2007                       memcpy (ctx->label, s, n);
2008                       ctx->labellen = n;
2009                     }
2010                 }
2011               gcry_sexp_release (l2);
2012               if (err)
2013                 goto leave;
2014             }
2015         }
2016
2017       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
2018       for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
2019         {
2020           s = gcry_sexp_nth_data (l2, 0, &n);
2021           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
2022               && !(n == 5 && !memcmp (s, "label", 5)))
2023             break;
2024           gcry_sexp_release (l2);
2025         }
2026
2027       if (!l2)
2028         {
2029           err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
2030           goto leave;
2031         }
2032
2033       /* Extract sublist identifier.  */
2034       gcry_free (name);
2035       name = _gcry_sexp_nth_string (l2, 0);
2036       if (!name)
2037         {
2038           err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
2039           goto leave;
2040         }
2041
2042       gcry_sexp_release (list);
2043       list = l2;
2044       l2 = NULL;
2045     }
2046
2047   ath_mutex_lock (&pubkeys_registered_lock);
2048   module = gcry_pk_lookup_name (name);
2049   ath_mutex_unlock (&pubkeys_registered_lock);
2050
2051   if (!module)
2052     {
2053       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
2054       goto leave;
2055     }
2056   pubkey = (gcry_pk_spec_t *) module->spec;
2057
2058   elems = pubkey->elements_enc;
2059   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
2060   if (!array)
2061     {
2062       err = gpg_err_code_from_syserror ();
2063       goto leave;
2064     }
2065
2066   err = sexp_elements_extract (list, elems, array, NULL);
2067
2068  leave:
2069   gcry_sexp_release (list);
2070   gcry_sexp_release (l2);
2071   gcry_free (name);
2072
2073   if (err)
2074     {
2075       ath_mutex_lock (&pubkeys_registered_lock);
2076       _gcry_module_release (module);
2077       ath_mutex_unlock (&pubkeys_registered_lock);
2078       gcry_free (array);
2079       gcry_free (ctx->label);
2080       ctx->label = NULL;
2081     }
2082   else
2083     {
2084       *retarray = array;
2085       *retalgo = module;
2086       *flags = parsed_flags;
2087     }
2088
2089   return err;
2090 }
2091
2092 /* Take the hash value and convert into an MPI, suitable for
2093    passing to the low level functions.  We currently support the
2094    old style way of passing just a MPI and the modern interface which
2095    allows to pass flags so that we can choose between raw and pkcs1
2096    padding - may be more padding options later.
2097
2098    (<mpi>)
2099    or
2100    (data
2101     [(flags [raw, pkcs1, oaep, pss, no-blinding])]
2102     [(hash <algo> <value>)]
2103     [(value <text>)]
2104     [(hash-algo <algo>)]
2105     [(label <label>)]
2106     [(salt-length <length>)]
2107    )
2108
2109    Either the VALUE or the HASH element must be present for use
2110    with signatures.  VALUE is used for encryption.
2111
2112    HASH-ALGO and LABEL are specific to OAEP.
2113
2114    SALT-LENGTH is for PSS.
2115
2116 */
2117 static gcry_err_code_t
2118 sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
2119                   struct pk_encoding_ctx *ctx)
2120 {
2121   gcry_err_code_t rc = 0;
2122   gcry_sexp_t ldata, lhash, lvalue;
2123   int i;
2124   size_t n;
2125   const char *s;
2126   int unknown_flag=0;
2127   int parsed_flags = 0;
2128
2129   *ret_mpi = NULL;
2130   ldata = gcry_sexp_find_token (input, "data", 0);
2131   if (!ldata)
2132     { /* assume old style */
2133       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
2134       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
2135     }
2136
2137   /* see whether there is a flags object */
2138   {
2139     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
2140     if (lflags)
2141       { /* parse the flags list. */
2142         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
2143           {
2144             s = gcry_sexp_nth_data (lflags, i, &n);
2145             if (!s)
2146               ; /* not a data element*/
2147             else if ( n == 3 && !memcmp (s, "raw", 3)
2148                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
2149               ctx->encoding = PUBKEY_ENC_RAW;
2150             else if ( n == 5 && !memcmp (s, "pkcs1", 5)
2151                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
2152               ctx->encoding = PUBKEY_ENC_PKCS1;
2153             else if ( n == 4 && !memcmp (s, "oaep", 4)
2154                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
2155               ctx->encoding = PUBKEY_ENC_OAEP;
2156             else if ( n == 3 && !memcmp (s, "pss", 3)
2157                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
2158               ctx->encoding = PUBKEY_ENC_PSS;
2159             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
2160               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
2161             else
2162               unknown_flag = 1;
2163           }
2164         gcry_sexp_release (lflags);
2165       }
2166   }
2167
2168   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
2169     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
2170
2171   /* Get HASH or MPI */
2172   lhash = gcry_sexp_find_token (ldata, "hash", 0);
2173   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
2174
2175   if (!(!lhash ^ !lvalue))
2176     rc = GPG_ERR_INV_OBJ; /* none or both given */
2177   else if (unknown_flag)
2178     rc = GPG_ERR_INV_FLAG;
2179   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
2180     {
2181       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
2182       if (!*ret_mpi)
2183         rc = GPG_ERR_INV_OBJ;
2184     }
2185   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
2186            && ctx->op == PUBKEY_OP_ENCRYPT)
2187     {
2188       const void * value;
2189       size_t valuelen;
2190
2191       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
2192         rc = GPG_ERR_INV_OBJ;
2193       else
2194         rc = pkcs1_encode_for_encryption (ret_mpi, ctx->nbits, value, valuelen);
2195     }
2196   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
2197            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
2198     {
2199       if (gcry_sexp_length (lhash) != 3)
2200         rc = GPG_ERR_INV_OBJ;
2201       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
2202         rc = GPG_ERR_INV_OBJ;
2203       else
2204         {
2205           const void * value;
2206           size_t valuelen;
2207
2208           ctx->hash_algo = get_hash_algo (s, n);
2209
2210           if (!ctx->hash_algo)
2211             rc = GPG_ERR_DIGEST_ALGO;
2212           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
2213                     || !valuelen )
2214             rc = GPG_ERR_INV_OBJ;
2215           else
2216             rc = pkcs1_encode_for_signature (ret_mpi, ctx->nbits,
2217                                              value, valuelen,
2218                                              ctx->hash_algo);
2219         }
2220     }
2221   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
2222            && ctx->op == PUBKEY_OP_ENCRYPT)
2223     {
2224       const void * value;
2225       size_t valuelen;
2226
2227       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
2228         rc = GPG_ERR_INV_OBJ;
2229       else
2230         {
2231           gcry_sexp_t list;
2232
2233           /* Get HASH-ALGO. */
2234           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
2235           if (list)
2236             {
2237               s = gcry_sexp_nth_data (list, 1, &n);
2238               if (!s)
2239                 rc = GPG_ERR_NO_OBJ;
2240               else
2241                 {
2242                   ctx->hash_algo = get_hash_algo (s, n);
2243                   if (!ctx->hash_algo)
2244                     rc = GPG_ERR_DIGEST_ALGO;
2245                 }
2246               gcry_sexp_release (list);
2247               if (rc)
2248                 goto leave;
2249             }
2250
2251           /* Get LABEL. */
2252           list = gcry_sexp_find_token (ldata, "label", 0);
2253           if (list)
2254             {
2255               s = gcry_sexp_nth_data (list, 1, &n);
2256               if (!s)
2257                 rc = GPG_ERR_NO_OBJ;
2258               else if (n > 0)
2259                 {
2260                   ctx->label = gcry_malloc (n);
2261                   if (!ctx->label)
2262                     rc = gpg_err_code_from_syserror ();
2263                   else
2264                     {
2265                       memcpy (ctx->label, s, n);
2266                       ctx->labellen = n;
2267                     }
2268                 }
2269               gcry_sexp_release (list);
2270               if (rc)
2271                 goto leave;
2272             }
2273
2274           rc = oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
2275                             value, valuelen,
2276                             ctx->label, ctx->labellen);
2277         }
2278     }
2279   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
2280            && ctx->op == PUBKEY_OP_SIGN)
2281     {
2282       if (gcry_sexp_length (lhash) != 3)
2283         rc = GPG_ERR_INV_OBJ;
2284       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
2285         rc = GPG_ERR_INV_OBJ;
2286       else
2287         {
2288           const void * value;
2289           size_t valuelen;
2290
2291           ctx->hash_algo = get_hash_algo (s, n);
2292
2293           if (!ctx->hash_algo)
2294             rc = GPG_ERR_DIGEST_ALGO;
2295           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
2296                     || !valuelen )
2297             rc = GPG_ERR_INV_OBJ;
2298           else
2299             {
2300               gcry_sexp_t list;
2301
2302               /* Get SALT-LENGTH. */
2303               list = gcry_sexp_find_token (ldata, "salt-length", 0);
2304               if (list)
2305                 {
2306                   s = gcry_sexp_nth_data (list, 1, &n);
2307                   if (!s)
2308                     {
2309                       rc = GPG_ERR_NO_OBJ;
2310                       goto leave;
2311                     }
2312                   ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
2313                   gcry_sexp_release (list);
2314                 }
2315               rc = pss_encode (ret_mpi, ctx->nbits - 1, ctx->hash_algo,
2316                                value, valuelen,
2317                                ctx->saltlen);
2318             }
2319         }
2320     }
2321   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
2322            && ctx->op == PUBKEY_OP_VERIFY)
2323     {
2324       if (gcry_sexp_length (lhash) != 3)
2325         rc = GPG_ERR_INV_OBJ;
2326       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
2327         rc = GPG_ERR_INV_OBJ;
2328       else
2329         {
2330           ctx->hash_algo = get_hash_algo (s, n);
2331
2332           if (!ctx->hash_algo)
2333             rc = GPG_ERR_DIGEST_ALGO;
2334           else
2335             {
2336               *ret_mpi = gcry_sexp_nth_mpi (lhash, 2, 0);
2337               if (!*ret_mpi)
2338                 rc = GPG_ERR_INV_OBJ;
2339               ctx->verify_cmp = pss_verify_cmp;
2340               ctx->verify_arg = *ret_mpi;
2341             }
2342         }
2343     }
2344   else
2345     rc = GPG_ERR_CONFLICT;
2346
2347  leave:
2348   gcry_sexp_release (ldata);
2349   gcry_sexp_release (lhash);
2350   gcry_sexp_release (lvalue);
2351
2352   if (!rc)
2353     ctx->flags = parsed_flags;
2354   else
2355     {
2356       gcry_free (ctx->label);
2357       ctx->label = NULL;
2358     }
2359
2360   return rc;
2361 }
2362
2363 static void
2364 init_encoding_ctx (struct pk_encoding_ctx *ctx, enum pk_operation op,
2365                    unsigned int nbits)
2366 {
2367   ctx->op = op;
2368   ctx->nbits = nbits;
2369   ctx->encoding = PUBKEY_ENC_UNKNOWN;
2370   ctx->flags = 0;
2371   ctx->hash_algo = GCRY_MD_SHA1;
2372   ctx->label = NULL;
2373   ctx->labellen = 0;
2374   ctx->saltlen = 20;
2375   ctx->verify_cmp = NULL;
2376   ctx->verify_arg = NULL;
2377 }
2378
2379
2380 /*
2381    Do a PK encrypt operation
2382
2383    Caller has to provide a public key as the SEXP pkey and data as a
2384    SEXP with just one MPI in it. Alternatively S_DATA might be a
2385    complex S-Expression, similar to the one used for signature
2386    verification.  This provides a flag which allows to handle PKCS#1
2387    block type 2 padding.  The function returns a a sexp which may be
2388    passed to to pk_decrypt.
2389
2390    Returns: 0 or an errorcode.
2391
2392    s_data = See comment for sexp_data_to_mpi
2393    s_pkey = <key-as-defined-in-sexp_to_key>
2394    r_ciph = (enc-val
2395                (<algo>
2396                  (<param_name1> <mpi>)
2397                  ...
2398                  (<param_namen> <mpi>)
2399                ))
2400
2401 */
2402 gcry_error_t
2403 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
2404 {
2405   gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
2406   const char *algo_name, *algo_elems;
2407   struct pk_encoding_ctx ctx;
2408   gcry_err_code_t rc;
2409   gcry_pk_spec_t *pubkey = NULL;
2410   gcry_module_t module = NULL;
2411
2412   *r_ciph = NULL;
2413
2414   REGISTER_DEFAULT_PUBKEYS;
2415
2416   /* Get the key. */
2417   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module);
2418   if (rc)
2419     goto leave;
2420
2421   gcry_assert (module);
2422   pubkey = (gcry_pk_spec_t *) module->spec;
2423
2424   /* If aliases for the algorithm name exists, take the first one
2425      instead of the regular name to adhere to SPKI conventions.  We
2426      assume that the first alias name is the lowercase version of the
2427      regular one.  This change is required for compatibility with
2428      1.1.12 generated S-expressions. */
2429   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2430   if (!algo_name || !*algo_name)
2431     algo_name = pubkey->name;
2432
2433   algo_elems = pubkey->elements_enc;
2434
2435   /* Get the stuff we want to encrypt. */
2436   init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
2437   rc = sexp_data_to_mpi (s_data, &data, &ctx);
2438   if (rc)
2439     goto leave;
2440
2441   /* Now we can encrypt DATA to CIPH. */
2442   ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
2443   if (!ciph)
2444     {
2445       rc = gpg_err_code_from_syserror ();
2446       goto leave;
2447     }
2448   rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, ctx.flags);
2449   mpi_free (data);
2450   data = NULL;
2451   if (rc)
2452     goto leave;
2453
2454   /* We did it.  Now build the return list */
2455   {
2456     char *string, *p;
2457     int i;
2458     size_t nelem = strlen (algo_elems);
2459     size_t needed = 19 + strlen (algo_name) + (nelem * 5);
2460     void **arg_list;
2461
2462     /* Build the string.  */
2463     string = p = gcry_malloc (needed);
2464     if (!string)
2465       {
2466         rc = gpg_err_code_from_syserror ();
2467         goto leave;
2468       }
2469     p = stpcpy ( p, "(enc-val(" );
2470     p = stpcpy ( p, algo_name );
2471     for (i=0; algo_elems[i]; i++ )
2472       {
2473         *p++ = '(';
2474         *p++ = algo_elems[i];
2475         p = stpcpy ( p, "%m)" );
2476       }
2477     strcpy ( p, "))" );
2478
2479     /* And now the ugly part: We don't have a function to pass an
2480      * array to a format string, so we have to do it this way :-(.  */
2481     /* FIXME: There is now such a format specifier, so we can
2482        change the code to be more clear. */
2483     arg_list = malloc (nelem * sizeof *arg_list);
2484     if (!arg_list)
2485       {
2486         rc = gpg_err_code_from_syserror ();
2487         goto leave;
2488       }
2489
2490     for (i = 0; i < nelem; i++)
2491       arg_list[i] = ciph + i;
2492
2493     rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
2494     free (arg_list);
2495     if (rc)
2496       BUG ();
2497     gcry_free (string);
2498   }
2499
2500  leave:
2501   if (pkey)
2502     {
2503       release_mpi_array (pkey);
2504       gcry_free (pkey);
2505     }
2506
2507   if (ciph)
2508     {
2509       release_mpi_array (ciph);
2510       gcry_free (ciph);
2511     }
2512
2513   if (module)
2514     {
2515       ath_mutex_lock (&pubkeys_registered_lock);
2516       _gcry_module_release (module);
2517       ath_mutex_unlock (&pubkeys_registered_lock);
2518     }
2519
2520   gcry_free (ctx.label);
2521
2522   return gcry_error (rc);
2523 }
2524
2525 /*
2526    Do a PK decrypt operation
2527
2528    Caller has to provide a secret key as the SEXP skey and data in a
2529    format as created by gcry_pk_encrypt.  For historic reasons the
2530    function returns simply an MPI as an S-expression part; this is
2531    deprecated and the new method should be used which returns a real
2532    S-expressionl this is selected by adding at least an empty flags
2533    list to S_DATA.
2534
2535    Returns: 0 or an errorcode.
2536
2537    s_data = (enc-val
2538               [(flags [raw, pkcs1, oaep])]
2539               (<algo>
2540                 (<param_name1> <mpi>)
2541                 ...
2542                 (<param_namen> <mpi>)
2543               ))
2544    s_skey = <key-as-defined-in-sexp_to_key>
2545    r_plain= Either an incomplete S-expression without the parentheses
2546             or if the flags list is used (even if empty) a real S-expression:
2547             (value PLAIN).
2548  */
2549 gcry_error_t
2550 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
2551 {
2552   gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL, unpad = NULL;
2553   int modern, flags;
2554   struct pk_encoding_ctx ctx;
2555   gcry_err_code_t rc;
2556   gcry_module_t module_enc = NULL, module_key = NULL;
2557
2558   *r_plain = NULL;
2559   ctx.label = NULL;
2560
2561   REGISTER_DEFAULT_PUBKEYS;
2562
2563   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key);
2564   if (rc)
2565     goto leave;
2566
2567   init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, gcry_pk_get_nbits (s_skey));
2568   rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
2569   if (rc)
2570     goto leave;
2571
2572   if (module_key->mod_id != module_enc->mod_id)
2573     {
2574       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
2575       goto leave;
2576     }
2577
2578   rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
2579   if (rc)
2580     goto leave;
2581
2582   /* Do un-padding if necessary. */
2583   switch (ctx.encoding)
2584     {
2585     case PUBKEY_ENC_PKCS1:
2586       rc = pkcs1_decode_for_encryption (&unpad, gcry_pk_get_nbits (s_skey),
2587                                         plain);
2588       mpi_free (plain);
2589       if (rc)
2590         goto leave;
2591       plain = unpad;
2592       break;
2593     case PUBKEY_ENC_OAEP:
2594       rc = oaep_decode (&unpad, gcry_pk_get_nbits (s_skey), ctx.hash_algo,
2595                         plain, ctx.label, ctx.labellen);
2596       mpi_free (plain);
2597       if (rc)
2598         goto leave;
2599       plain = unpad;
2600       break;
2601     default:
2602       break;
2603     }
2604
2605   if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
2606     BUG ();
2607
2608  leave:
2609   if (skey)
2610     {
2611       release_mpi_array (skey);
2612       gcry_free (skey);
2613     }
2614
2615   if (plain)
2616     mpi_free (plain);
2617
2618   if (data)
2619     {
2620       release_mpi_array (data);
2621       gcry_free (data);
2622     }
2623
2624   if (module_key || module_enc)
2625     {
2626       ath_mutex_lock (&pubkeys_registered_lock);
2627       if (module_key)
2628         _gcry_module_release (module_key);
2629       if (module_enc)
2630         _gcry_module_release (module_enc);
2631       ath_mutex_unlock (&pubkeys_registered_lock);
2632     }
2633
2634   gcry_free (ctx.label);
2635
2636   return gcry_error (rc);
2637 }
2638
2639
2640
2641 /*
2642    Create a signature.
2643
2644    Caller has to provide a secret key as the SEXP skey and data
2645    expressed as a SEXP list hash with only one element which should
2646    instantly be available as a MPI. Alternatively the structure given
2647    below may be used for S_HASH, it provides the abiliy to pass flags
2648    to the operation; the only flag defined by now is "pkcs1" which
2649    does PKCS#1 block type 1 style padding.
2650
2651    Returns: 0 or an errorcode.
2652             In case of 0 the function returns a new SEXP with the
2653             signature value; the structure of this signature depends on the
2654             other arguments but is always suitable to be passed to
2655             gcry_pk_verify
2656
2657    s_hash = See comment for sexp_data_to_mpi
2658
2659    s_skey = <key-as-defined-in-sexp_to_key>
2660    r_sig  = (sig-val
2661               (<algo>
2662                 (<param_name1> <mpi>)
2663                 ...
2664                 (<param_namen> <mpi>))
2665              [(hash algo)])
2666
2667   Note that (hash algo) in R_SIG is not used.
2668 */
2669 gcry_error_t
2670 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
2671 {
2672   gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
2673   gcry_pk_spec_t *pubkey = NULL;
2674   gcry_module_t module = NULL;
2675   const char *algo_name, *algo_elems;
2676   struct pk_encoding_ctx ctx;
2677   int i;
2678   gcry_err_code_t rc;
2679
2680   *r_sig = NULL;
2681
2682   REGISTER_DEFAULT_PUBKEYS;
2683
2684   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module);
2685   if (rc)
2686     goto leave;
2687
2688   gcry_assert (module);
2689   pubkey = (gcry_pk_spec_t *) module->spec;
2690   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2691   if (!algo_name || !*algo_name)
2692     algo_name = pubkey->name;
2693
2694   algo_elems = pubkey->elements_sig;
2695
2696   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
2697       work on a private key. */
2698   init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, gcry_pk_get_nbits (s_skey));
2699   rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
2700   if (rc)
2701     goto leave;
2702
2703   result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
2704   if (!result)
2705     {
2706       rc = gpg_err_code_from_syserror ();
2707       goto leave;
2708     }
2709   rc = pubkey_sign (module->mod_id, result, hash, skey);
2710   if (rc)
2711     goto leave;
2712
2713   {
2714     char *string, *p;
2715     size_t nelem, needed = strlen (algo_name) + 20;
2716     void **arg_list;
2717
2718     nelem = strlen (algo_elems);
2719
2720     /* Count elements, so that we can allocate enough space. */
2721     needed += 10 * nelem;
2722
2723     /* Build the string. */
2724     string = p = gcry_malloc (needed);
2725     if (!string)
2726       {
2727         rc = gpg_err_code_from_syserror ();
2728         goto leave;
2729       }
2730     p = stpcpy (p, "(sig-val(");
2731     p = stpcpy (p, algo_name);
2732     for (i = 0; algo_elems[i]; i++)
2733       {
2734         *p++ = '(';
2735         *p++ = algo_elems[i];
2736         p = stpcpy (p, "%m)");
2737       }
2738     strcpy (p, "))");
2739
2740     arg_list = malloc (nelem * sizeof *arg_list);
2741     if (!arg_list)
2742       {
2743         rc = gpg_err_code_from_syserror ();
2744         goto leave;
2745       }
2746
2747     for (i = 0; i < nelem; i++)
2748       arg_list[i] = result + i;
2749
2750     rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
2751     free (arg_list);
2752     if (rc)
2753       BUG ();
2754     gcry_free (string);
2755   }
2756
2757  leave:
2758   if (skey)
2759     {
2760       release_mpi_array (skey);
2761       gcry_free (skey);
2762     }
2763
2764   if (hash)
2765     mpi_free (hash);
2766
2767   if (result)
2768     {
2769       release_mpi_array (result);
2770       gcry_free (result);
2771     }
2772
2773   return gcry_error (rc);
2774 }
2775
2776
2777 /*
2778    Verify a signature.
2779
2780    Caller has to supply the public key pkey, the signature sig and his
2781    hashvalue data.  Public key has to be a standard public key given
2782    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
2783    must be an S-Exp like the one in sign too.  */
2784 gcry_error_t
2785 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
2786 {
2787   gcry_module_t module_key = NULL, module_sig = NULL;
2788   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
2789   struct pk_encoding_ctx ctx;
2790   gcry_err_code_t rc;
2791
2792   REGISTER_DEFAULT_PUBKEYS;
2793
2794   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module_key);
2795   if (rc)
2796     goto leave;
2797
2798   rc = sexp_to_sig (s_sig, &sig, &module_sig);
2799   if (rc)
2800     goto leave;
2801
2802   /* Fixme: Check that the algorithm of S_SIG is compatible to the one
2803      of S_PKEY.  */
2804
2805   if (module_key->mod_id != module_sig->mod_id)
2806     {
2807       rc = GPG_ERR_CONFLICT;
2808       goto leave;
2809     }
2810
2811   /* Get the stuff we want to verify. */
2812   init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, gcry_pk_get_nbits (s_pkey));
2813   rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
2814   if (rc)
2815     goto leave;
2816
2817   rc = pubkey_verify (module_key->mod_id, hash, sig, pkey,
2818                       ctx.verify_cmp, &ctx);
2819
2820  leave:
2821   if (pkey)
2822     {
2823       release_mpi_array (pkey);
2824       gcry_free (pkey);
2825     }
2826   if (sig)
2827     {
2828       release_mpi_array (sig);
2829       gcry_free (sig);
2830     }
2831   if (hash)
2832     mpi_free (hash);
2833
2834   if (module_key || module_sig)
2835     {
2836       ath_mutex_lock (&pubkeys_registered_lock);
2837       if (module_key)
2838         _gcry_module_release (module_key);
2839       if (module_sig)
2840         _gcry_module_release (module_sig);
2841       ath_mutex_unlock (&pubkeys_registered_lock);
2842     }
2843
2844   return gcry_error (rc);
2845 }
2846
2847
2848 /*
2849    Test a key.
2850
2851    This may be used either for a public or a secret key to see whether
2852    the internal structure is okay.
2853
2854    Returns: 0 or an errorcode.
2855
2856    s_key = <key-as-defined-in-sexp_to_key> */
2857 gcry_error_t
2858 gcry_pk_testkey (gcry_sexp_t s_key)
2859 {
2860   gcry_module_t module = NULL;
2861   gcry_mpi_t *key = NULL;
2862   gcry_err_code_t rc;
2863
2864   REGISTER_DEFAULT_PUBKEYS;
2865
2866   /* Note we currently support only secret key checking. */
2867   rc = sexp_to_key (s_key, 1, NULL, &key, &module);
2868   if (! rc)
2869     {
2870       rc = pubkey_check_secret_key (module->mod_id, key);
2871       release_mpi_array (key);
2872       gcry_free (key);
2873     }
2874   return gcry_error (rc);
2875 }
2876
2877
2878 /*
2879   Create a public key pair and return it in r_key.
2880   How the key is created depends on s_parms:
2881   (genkey
2882    (algo
2883      (parameter_name_1 ....)
2884       ....
2885      (parameter_name_n ....)
2886   ))
2887   The key is returned in a format depending on the
2888   algorithm. Both, private and secret keys are returned
2889   and optionally some additional informatin.
2890   For elgamal we return this structure:
2891   (key-data
2892    (public-key
2893      (elg
2894         (p <mpi>)
2895         (g <mpi>)
2896         (y <mpi>)
2897      )
2898    )
2899    (private-key
2900      (elg
2901         (p <mpi>)
2902         (g <mpi>)
2903         (y <mpi>)
2904         (x <mpi>)
2905      )
2906    )
2907    (misc-key-info
2908       (pm1-factors n1 n2 ... nn)
2909    ))
2910  */
2911 gcry_error_t
2912 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
2913 {
2914   gcry_pk_spec_t *pubkey = NULL;
2915   gcry_module_t module = NULL;
2916   gcry_sexp_t list = NULL;
2917   gcry_sexp_t l2 = NULL;
2918   gcry_sexp_t l3 = NULL;
2919   char *name = NULL;
2920   size_t n;
2921   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
2922   int i, j;
2923   const char *algo_name = NULL;
2924   int algo;
2925   const char *sec_elems = NULL, *pub_elems = NULL;
2926   gcry_mpi_t skey[12];
2927   gcry_mpi_t *factors = NULL;
2928   gcry_sexp_t extrainfo = NULL;
2929   unsigned int nbits = 0;
2930   unsigned long use_e = 0;
2931
2932   skey[0] = NULL;
2933   *r_key = NULL;
2934
2935   REGISTER_DEFAULT_PUBKEYS;
2936
2937   list = gcry_sexp_find_token (s_parms, "genkey", 0);
2938   if (!list)
2939     {
2940       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
2941       goto leave;
2942     }
2943
2944   l2 = gcry_sexp_cadr (list);
2945   gcry_sexp_release (list);
2946   list = l2;
2947   l2 = NULL;
2948   if (! list)
2949     {
2950       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
2951       goto leave;
2952     }
2953
2954   name = _gcry_sexp_nth_string (list, 0);
2955   if (!name)
2956     {
2957       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
2958       goto leave;
2959     }
2960
2961   ath_mutex_lock (&pubkeys_registered_lock);
2962   module = gcry_pk_lookup_name (name);
2963   ath_mutex_unlock (&pubkeys_registered_lock);
2964   gcry_free (name);
2965   name = NULL;
2966   if (!module)
2967     {
2968       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
2969       goto leave;
2970     }
2971
2972   pubkey = (gcry_pk_spec_t *) module->spec;
2973   algo = module->mod_id;
2974   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2975   if (!algo_name || !*algo_name)
2976     algo_name = pubkey->name;
2977   pub_elems = pubkey->elements_pkey;
2978   sec_elems = pubkey->elements_skey;
2979   if (strlen (sec_elems) >= DIM(skey))
2980     BUG ();
2981
2982   /* Handle the optional rsa-use-e element.  Actually this belong into
2983      the algorithm module but we have this parameter in the public
2984      module API, so we need to parse it right here.  */
2985   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
2986   if (l2)
2987     {
2988       char buf[50];
2989       const char *s;
2990
2991       s = gcry_sexp_nth_data (l2, 1, &n);
2992       if ( !s || n >= DIM (buf) - 1 )
2993         {
2994           rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
2995           goto leave;
2996         }
2997       memcpy (buf, s, n);
2998       buf[n] = 0;
2999       use_e = strtoul (buf, NULL, 0);
3000       gcry_sexp_release (l2);
3001       l2 = NULL;
3002     }
3003   else
3004     use_e = 65537; /* Not given, use the value generated by old versions. */
3005
3006
3007   /* Get the "nbits" parameter.  */
3008   l2 = gcry_sexp_find_token (list, "nbits", 0);
3009   if (l2)
3010     {
3011       char buf[50];
3012       const char *s;
3013
3014       s = gcry_sexp_nth_data (l2, 1, &n);
3015       if (!s || n >= DIM (buf) - 1 )
3016         {
3017           rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
3018           goto leave;
3019         }
3020       memcpy (buf, s, n);
3021       buf[n] = 0;
3022       nbits = (unsigned int)strtoul (buf, NULL, 0);
3023       gcry_sexp_release (l2); l2 = NULL;
3024     }
3025   else
3026     nbits = 0;
3027
3028   /* Pass control to the algorithm module. */
3029   rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
3030                         &factors, &extrainfo);
3031   gcry_sexp_release (list); list = NULL;
3032   if (rc)
3033     goto leave;
3034
3035   /* Key generation succeeded: Build an S-expression.  */
3036   {
3037     char *string, *p;
3038     size_t nelem=0, nelem_cp = 0, needed=0;
3039     gcry_mpi_t mpis[30];
3040     int percent_s_idx = -1;
3041
3042     /* Estimate size of format string.  */
3043     nelem = strlen (pub_elems) + strlen (sec_elems);
3044     if (factors)
3045       {
3046         for (i = 0; factors[i]; i++)
3047           nelem++;
3048       }
3049     nelem_cp = nelem;
3050
3051     needed += nelem * 10;
3052     /* (+5 is for EXTRAINFO ("%S")).  */
3053     needed += 2 * strlen (algo_name) + 300 + 5;
3054     if (nelem > DIM (mpis))
3055       BUG ();
3056
3057     /* Build the string. */
3058     nelem = 0;
3059     string = p = gcry_malloc (needed);
3060     if (!string)
3061       {
3062         rc = gpg_err_code_from_syserror ();
3063         goto leave;
3064       }
3065     p = stpcpy (p, "(key-data");
3066     p = stpcpy (p, "(public-key(");
3067     p = stpcpy (p, algo_name);
3068     for(i = 0; pub_elems[i]; i++)
3069       {
3070         *p++ = '(';
3071         *p++ = pub_elems[i];
3072         p = stpcpy (p, "%m)");
3073         mpis[nelem++] = skey[i];
3074       }
3075     if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
3076       {
3077         /* Very ugly hack to insert the used curve parameter into the
3078            list of public key parameters.  */
3079         percent_s_idx = nelem;
3080         p = stpcpy (p, "%S");
3081       }
3082     p = stpcpy (p, "))");
3083     p = stpcpy (p, "(private-key(");
3084     p = stpcpy (p, algo_name);
3085     for (i = 0; sec_elems[i]; i++)
3086       {
3087         *p++ = '(';
3088         *p++ = sec_elems[i];
3089         p = stpcpy (p, "%m)");
3090         mpis[nelem++] = skey[i];
3091       }
3092     p = stpcpy (p, "))");
3093
3094     /* Hack to make release_mpi_array() work.  */
3095     skey[i] = NULL;
3096
3097     if (extrainfo && percent_s_idx == -1)
3098       {
3099         /* If we have extrainfo we should not have any factors.  */
3100         p = stpcpy (p, "%S");
3101       }
3102     else if (factors && factors[0])
3103       {
3104         p = stpcpy (p, "(misc-key-info(pm1-factors");
3105         for(i = 0; factors[i]; i++)
3106           {
3107             p = stpcpy (p, "%m");
3108             mpis[nelem++] = factors[i];
3109           }
3110         p = stpcpy (p, "))");
3111       }
3112     strcpy (p, ")");
3113     gcry_assert (p - string < needed);
3114
3115     while (nelem < DIM (mpis))
3116       mpis[nelem++] = NULL;
3117
3118     {
3119       int elem_n = strlen (pub_elems) + strlen (sec_elems);
3120       void **arg_list;
3121
3122       /* Allocate one extra for EXTRAINFO ("%S").  */
3123       arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
3124       if (!arg_list)
3125         {
3126           rc = gpg_err_code_from_syserror ();
3127           goto leave;
3128         }
3129       for (i = j = 0; i < elem_n; i++)
3130         {
3131           if (i == percent_s_idx)
3132             arg_list[j++] = &extrainfo;
3133           arg_list[j++] = mpis + i;
3134         }
3135       if (extrainfo && percent_s_idx == -1)
3136         arg_list[j] = &extrainfo;
3137       else if (factors && factors[0])
3138         {
3139           for (; i < nelem_cp; i++)
3140             arg_list[j++] = factors + i - elem_n;
3141         }
3142       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
3143       gcry_free (arg_list);
3144       if (rc)
3145         BUG ();
3146       gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
3147                                          the array gets increased if
3148                                          new parameters are added. */
3149     }
3150     gcry_free (string);
3151   }
3152
3153  leave:
3154   gcry_free (name);
3155   gcry_sexp_release (extrainfo);
3156   release_mpi_array (skey);
3157   /* Don't free SKEY itself, it is an stack allocated array. */
3158
3159   if (factors)
3160     {
3161       release_mpi_array ( factors );
3162       gcry_free (factors);
3163     }
3164
3165   gcry_sexp_release (l3);
3166   gcry_sexp_release (l2);
3167   gcry_sexp_release (list);
3168
3169   if (module)
3170     {
3171       ath_mutex_lock (&pubkeys_registered_lock);
3172       _gcry_module_release (module);
3173       ath_mutex_unlock (&pubkeys_registered_lock);
3174     }
3175
3176   return gcry_error (rc);
3177 }
3178
3179
3180 /*
3181    Get the number of nbits from the public key.
3182
3183    Hmmm: Should we have really this function or is it better to have a
3184    more general function to retrieve different properties of the key?  */
3185 unsigned int
3186 gcry_pk_get_nbits (gcry_sexp_t key)
3187 {
3188   gcry_module_t module = NULL;
3189   gcry_pk_spec_t *pubkey;
3190   gcry_mpi_t *keyarr = NULL;
3191   unsigned int nbits = 0;
3192   gcry_err_code_t rc;
3193
3194   REGISTER_DEFAULT_PUBKEYS;
3195
3196   rc = sexp_to_key (key, 0, NULL, &keyarr, &module);
3197   if (rc == GPG_ERR_INV_OBJ)
3198     rc = sexp_to_key (key, 1, NULL, &keyarr, &module);
3199   if (rc)
3200     return 0; /* Error - 0 is a suitable indication for that. */
3201
3202   pubkey = (gcry_pk_spec_t *) module->spec;
3203   nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
3204
3205   ath_mutex_lock (&pubkeys_registered_lock);
3206   _gcry_module_release (module);
3207   ath_mutex_unlock (&pubkeys_registered_lock);
3208
3209   release_mpi_array (keyarr);
3210   gcry_free (keyarr);
3211
3212   return nbits;
3213 }
3214
3215
3216 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
3217    key parameters expressed in a way depending on the algorithm.
3218
3219    ARRAY must either be 20 bytes long or NULL; in the latter case a
3220    newly allocated array of that size is returned, otherwise ARRAY or
3221    NULL is returned to indicate an error which is most likely an
3222    unknown algorithm.  The function accepts public or secret keys. */
3223 unsigned char *
3224 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
3225 {
3226   gcry_sexp_t list = NULL, l2 = NULL;
3227   gcry_pk_spec_t *pubkey = NULL;
3228   gcry_module_t module = NULL;
3229   pk_extra_spec_t *extraspec;
3230   const char *s;
3231   char *name = NULL;
3232   int idx;
3233   const char *elems;
3234   gcry_md_hd_t md = NULL;
3235   int okay = 0;
3236
3237   REGISTER_DEFAULT_PUBKEYS;
3238
3239   /* Check that the first element is valid. */
3240   list = gcry_sexp_find_token (key, "public-key", 0);
3241   if (! list)
3242     list = gcry_sexp_find_token (key, "private-key", 0);
3243   if (! list)
3244     list = gcry_sexp_find_token (key, "protected-private-key", 0);
3245   if (! list)
3246     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
3247   if (! list)
3248     return NULL; /* No public- or private-key object. */
3249
3250   l2 = gcry_sexp_cadr (list);
3251   gcry_sexp_release (list);
3252   list = l2;
3253   l2 = NULL;
3254
3255   name = _gcry_sexp_nth_string (list, 0);
3256   if (!name)
3257     goto fail; /* Invalid structure of object. */
3258
3259   ath_mutex_lock (&pubkeys_registered_lock);
3260   module = gcry_pk_lookup_name (name);
3261   ath_mutex_unlock (&pubkeys_registered_lock);
3262
3263   if (!module)
3264     goto fail; /* Unknown algorithm.  */
3265
3266   pubkey = (gcry_pk_spec_t *) module->spec;
3267   extraspec = module->extraspec;
3268
3269   elems = pubkey->elements_grip;
3270   if (!elems)
3271     goto fail; /* No grip parameter.  */
3272
3273   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
3274     goto fail;
3275
3276   if (extraspec && extraspec->comp_keygrip)
3277     {
3278       /* Module specific method to compute a keygrip.  */
3279       if (extraspec->comp_keygrip (md, list))
3280         goto fail;
3281     }
3282   else
3283     {
3284       /* Generic method to compute a keygrip.  */
3285       for (idx = 0, s = elems; *s; s++, idx++)
3286         {
3287           const char *data;
3288           size_t datalen;
3289           char buf[30];
3290
3291           l2 = gcry_sexp_find_token (list, s, 1);
3292           if (! l2)
3293             goto fail;
3294           data = gcry_sexp_nth_data (l2, 1, &datalen);
3295           if (! data)
3296             goto fail;
3297
3298           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
3299           gcry_md_write (md, buf, strlen (buf));
3300           gcry_md_write (md, data, datalen);
3301           gcry_sexp_release (l2);
3302           l2 = NULL;
3303           gcry_md_write (md, ")", 1);
3304         }
3305     }
3306
3307   if (!array)
3308     {
3309       array = gcry_malloc (20);
3310       if (! array)
3311         goto fail;
3312     }
3313
3314   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
3315   okay = 1;
3316
3317  fail:
3318   gcry_free (name);
3319   gcry_sexp_release (l2);
3320   gcry_md_close (md);
3321   gcry_sexp_release (list);
3322   return okay? array : NULL;
3323 }
3324
3325
3326 \f
3327 const char *
3328 gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
3329 {
3330   gcry_mpi_t *pkey = NULL;
3331   gcry_sexp_t list = NULL;
3332   gcry_sexp_t l2;
3333   gcry_module_t module = NULL;
3334   pk_extra_spec_t *extraspec;
3335   char *name = NULL;
3336   const char *result = NULL;
3337   int want_private = 1;
3338
3339   if (r_nbits)
3340     *r_nbits = 0;
3341
3342   REGISTER_DEFAULT_PUBKEYS;
3343
3344   if (key)
3345     {
3346       iterator = 0;
3347
3348       /* Check that the first element is valid. */
3349       list = gcry_sexp_find_token (key, "public-key", 0);
3350       if (list)
3351         want_private = 0;
3352       if (!list)
3353         list = gcry_sexp_find_token (key, "private-key", 0);
3354       if (!list)
3355         return NULL; /* No public- or private-key object. */
3356
3357       l2 = gcry_sexp_cadr (list);
3358       gcry_sexp_release (list);
3359       list = l2;
3360       l2 = NULL;
3361
3362       name = _gcry_sexp_nth_string (list, 0);
3363       if (!name)
3364         goto leave; /* Invalid structure of object. */
3365
3366       /* Get the key.  We pass the names of the parameters for
3367          override_elems; this allows to call this function without the
3368          actual public key parameter.  */
3369       if (sexp_to_key (key, want_private, "pabgn", &pkey, &module))
3370         goto leave;
3371     }
3372   else
3373     {
3374       ath_mutex_lock (&pubkeys_registered_lock);
3375       module = gcry_pk_lookup_name ("ecc");
3376       ath_mutex_unlock (&pubkeys_registered_lock);
3377       if (!module)
3378         goto leave;
3379     }
3380
3381   extraspec = module->extraspec;
3382   if (!extraspec || !extraspec->get_curve)
3383     goto leave;
3384
3385   result = extraspec->get_curve (pkey, iterator, r_nbits);
3386
3387  leave:
3388   if (pkey)
3389     {
3390       release_mpi_array (pkey);
3391       gcry_free (pkey);
3392     }
3393   if (module)
3394     {
3395       ath_mutex_lock (&pubkeys_registered_lock);
3396       _gcry_module_release (module);
3397       ath_mutex_unlock (&pubkeys_registered_lock);
3398     }
3399   gcry_free (name);
3400   gcry_sexp_release (list);
3401   return result;
3402 }
3403
3404
3405 \f
3406 gcry_sexp_t
3407 gcry_pk_get_param (int algo, const char *name)
3408 {
3409   gcry_module_t module = NULL;
3410   pk_extra_spec_t *extraspec;
3411   gcry_sexp_t result = NULL;
3412
3413   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
3414     return NULL;
3415
3416   REGISTER_DEFAULT_PUBKEYS;
3417
3418   ath_mutex_lock (&pubkeys_registered_lock);
3419   module = gcry_pk_lookup_name ("ecc");
3420   ath_mutex_unlock (&pubkeys_registered_lock);
3421   if (module)
3422     {
3423       extraspec = module->extraspec;
3424       if (extraspec && extraspec->get_curve_param)
3425         result = extraspec->get_curve_param (name);
3426
3427       ath_mutex_lock (&pubkeys_registered_lock);
3428       _gcry_module_release (module);
3429       ath_mutex_unlock (&pubkeys_registered_lock);
3430     }
3431   return result;
3432 }
3433
3434
3435 \f
3436 gcry_error_t
3437 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
3438 {
3439   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3440
3441   REGISTER_DEFAULT_PUBKEYS;
3442
3443   switch (cmd)
3444     {
3445     case GCRYCTL_DISABLE_ALGO:
3446       /* This one expects a buffer pointing to an integer with the
3447          algo number.  */
3448       if ((! buffer) || (buflen != sizeof (int)))
3449         err = GPG_ERR_INV_ARG;
3450       else
3451         disable_pubkey_algo (*((int *) buffer));
3452       break;
3453
3454     default:
3455       err = GPG_ERR_INV_OP;
3456     }
3457
3458   return gcry_error (err);
3459 }
3460
3461
3462 /* Return information about the given algorithm
3463
3464    WHAT selects the kind of information returned:
3465
3466     GCRYCTL_TEST_ALGO:
3467         Returns 0 when the specified algorithm is available for use.
3468         Buffer must be NULL, nbytes  may have the address of a variable
3469         with the required usage of the algorithm. It may be 0 for don't
3470         care or a combination of the GCRY_PK_USAGE_xxx flags;
3471
3472     GCRYCTL_GET_ALGO_USAGE:
3473         Return the usage flags for the given algo.  An invalid algo
3474         returns 0.  Disabled algos are ignored here because we
3475         only want to know whether the algo is at all capable of
3476         the usage.
3477
3478    Note: Because this function is in most cases used to return an
3479    integer value, we can make it easier for the caller to just look at
3480    the return value.  The caller will in all cases consult the value
3481    and thereby detecting whether a error occurred or not (i.e. while
3482    checking the block size) */
3483 gcry_error_t
3484 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
3485 {
3486   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3487
3488   switch (what)
3489     {
3490     case GCRYCTL_TEST_ALGO:
3491       {
3492         int use = nbytes ? *nbytes : 0;
3493         if (buffer)
3494           err = GPG_ERR_INV_ARG;
3495         else if (check_pubkey_algo (algorithm, use))
3496           err = GPG_ERR_PUBKEY_ALGO;
3497         break;
3498       }
3499
3500     case GCRYCTL_GET_ALGO_USAGE:
3501       {
3502         gcry_module_t pubkey;
3503         int use = 0;
3504
3505         REGISTER_DEFAULT_PUBKEYS;
3506
3507         ath_mutex_lock (&pubkeys_registered_lock);
3508         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3509         if (pubkey)
3510           {
3511             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
3512             _gcry_module_release (pubkey);
3513           }
3514         ath_mutex_unlock (&pubkeys_registered_lock);
3515
3516         /* FIXME? */
3517         *nbytes = use;
3518
3519         break;
3520       }
3521
3522     case GCRYCTL_GET_ALGO_NPKEY:
3523       {
3524         /* FIXME?  */
3525         int npkey = pubkey_get_npkey (algorithm);
3526         *nbytes = npkey;
3527         break;
3528       }
3529     case GCRYCTL_GET_ALGO_NSKEY:
3530       {
3531         /* FIXME?  */
3532         int nskey = pubkey_get_nskey (algorithm);
3533         *nbytes = nskey;
3534         break;
3535       }
3536     case GCRYCTL_GET_ALGO_NSIGN:
3537       {
3538         /* FIXME?  */
3539         int nsign = pubkey_get_nsig (algorithm);
3540         *nbytes = nsign;
3541         break;
3542       }
3543     case GCRYCTL_GET_ALGO_NENCR:
3544       {
3545         /* FIXME?  */
3546         int nencr = pubkey_get_nenc (algorithm);
3547         *nbytes = nencr;
3548         break;
3549       }
3550
3551     default:
3552       err = GPG_ERR_INV_OP;
3553     }
3554
3555   return gcry_error (err);
3556 }
3557
3558
3559 /* Explicitly initialize this module.  */
3560 gcry_err_code_t
3561 _gcry_pk_init (void)
3562 {
3563   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3564
3565   REGISTER_DEFAULT_PUBKEYS;
3566
3567   return err;
3568 }
3569
3570
3571 gcry_err_code_t
3572 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
3573 {
3574   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3575   gcry_module_t pubkey;
3576
3577   REGISTER_DEFAULT_PUBKEYS;
3578
3579   ath_mutex_lock (&pubkeys_registered_lock);
3580   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3581   if (pubkey)
3582     *module = pubkey;
3583   else
3584     err = GPG_ERR_PUBKEY_ALGO;
3585   ath_mutex_unlock (&pubkeys_registered_lock);
3586
3587   return err;
3588 }
3589
3590
3591 void
3592 _gcry_pk_module_release (gcry_module_t module)
3593 {
3594   ath_mutex_lock (&pubkeys_registered_lock);
3595   _gcry_module_release (module);
3596   ath_mutex_unlock (&pubkeys_registered_lock);
3597 }
3598
3599 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
3600    LIST is zero, write the number of loaded pubkey modules to
3601    LIST_LENGTH and return.  If LIST is non-zero, the first
3602    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
3603    according size.  In case there are less pubkey modules than
3604    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
3605 gcry_error_t
3606 gcry_pk_list (int *list, int *list_length)
3607 {
3608   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3609
3610   ath_mutex_lock (&pubkeys_registered_lock);
3611   err = _gcry_module_list (pubkeys_registered, list, list_length);
3612   ath_mutex_unlock (&pubkeys_registered_lock);
3613
3614   return err;
3615 }
3616
3617
3618 /* Run the selftests for pubkey algorithm ALGO with optional reporting
3619    function REPORT.  */
3620 gpg_error_t
3621 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
3622 {
3623   gcry_module_t module = NULL;
3624   pk_extra_spec_t *extraspec = NULL;
3625   gcry_err_code_t ec = 0;
3626
3627   REGISTER_DEFAULT_PUBKEYS;
3628
3629   ath_mutex_lock (&pubkeys_registered_lock);
3630   module = _gcry_module_lookup_id (pubkeys_registered, algo);
3631   if (module && !(module->flags & FLAG_MODULE_DISABLED))
3632     extraspec = module->extraspec;
3633   ath_mutex_unlock (&pubkeys_registered_lock);
3634   if (extraspec && extraspec->selftest)
3635     ec = extraspec->selftest (algo, extended, report);
3636   else
3637     {
3638       ec = GPG_ERR_PUBKEY_ALGO;
3639       if (report)
3640         report ("pubkey", algo, "module",
3641                 module && !(module->flags & FLAG_MODULE_DISABLED)?
3642                 "no selftest available" :
3643                 module? "algorithm disabled" : "algorithm not found");
3644     }
3645
3646   if (module)
3647     {
3648       ath_mutex_lock (&pubkeys_registered_lock);
3649       _gcry_module_release (module);
3650       ath_mutex_unlock (&pubkeys_registered_lock);
3651     }
3652   return gpg_error (ec);
3653 }
3654
3655
3656 /* This function is only used by ac.c!  */
3657 gcry_err_code_t
3658 _gcry_pk_get_elements (int algo, char **enc, char **sig)
3659 {
3660   gcry_module_t pubkey;
3661   gcry_pk_spec_t *spec;
3662   gcry_err_code_t err;
3663   char *enc_cp;
3664   char *sig_cp;
3665
3666   REGISTER_DEFAULT_PUBKEYS;
3667
3668   enc_cp = NULL;
3669   sig_cp = NULL;
3670   spec = NULL;
3671
3672   pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
3673   if (! pubkey)
3674     {
3675       err = GPG_ERR_INTERNAL;
3676       goto out;
3677     }
3678   spec = pubkey->spec;
3679
3680   if (enc)
3681     {
3682       enc_cp = strdup (spec->elements_enc);
3683       if (! enc_cp)
3684         {
3685           err = gpg_err_code_from_syserror ();
3686           goto out;
3687         }
3688     }
3689
3690   if (sig)
3691     {
3692       sig_cp = strdup (spec->elements_sig);
3693       if (! sig_cp)
3694         {
3695           err = gpg_err_code_from_syserror ();
3696           goto out;
3697         }
3698     }
3699
3700   if (enc)
3701     *enc = enc_cp;
3702   if (sig)
3703     *sig = sig_cp;
3704   err = 0;
3705
3706  out:
3707
3708   _gcry_module_release (pubkey);
3709   if (err)
3710     {
3711       free (enc_cp);
3712       free (sig_cp);
3713     }
3714
3715   return err;
3716 }