Restructure oaep_decode to match the description in rfc-3447.
[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
791    We encode the value in this way:
792
793      0  2  RND(n bytes)  0  VALUE
794
795    0   is a marker we unfortunately can't encode because we return an
796        MPI which strips all leading zeroes.
797    2   is the block type.
798    RND are non-zero random bytes.
799
800    (Note that OpenPGP includes the cipher algorithm and a checksum in
801    VALUE; the caller needs to prepare the value accordingly.)
802   */
803 static gcry_err_code_t
804 pkcs1_encode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
805                              const unsigned char *value, size_t valuelen)
806 {
807   gcry_err_code_t rc = 0;
808   gcry_error_t err;
809   unsigned char *frame = NULL;
810   size_t nframe = (nbits+7) / 8;
811   int i;
812   size_t n;
813   unsigned char *p;
814
815   if (valuelen + 7 > nframe || !nframe)
816     {
817       /* Can't encode a VALUELEN value in a NFRAME bytes frame.  */
818       return GPG_ERR_TOO_SHORT; /* The key is too short.  */
819     }
820
821   if ( !(frame = gcry_malloc_secure (nframe)))
822     return gpg_err_code_from_syserror ();
823
824   n = 0;
825   frame[n++] = 0;
826   frame[n++] = 2; /* block type */
827   i = nframe - 3 - valuelen;
828   gcry_assert (i > 0);
829   p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
830   /* Replace zero bytes by new values. */
831   for (;;)
832     {
833       int j, k;
834       unsigned char *pp;
835
836       /* Count the zero bytes. */
837       for (j=k=0; j < i; j++)
838         {
839           if (!p[j])
840             k++;
841         }
842       if (!k)
843         break; /* Okay: no (more) zero bytes. */
844
845       k += k/128 + 3; /* Better get some more. */
846       pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
847       for (j=0; j < i && k; )
848         {
849           if (!p[j])
850             p[j] = pp[--k];
851           if (p[j])
852             j++;
853         }
854       gcry_free (pp);
855     }
856   memcpy (frame+n, p, i);
857   n += i;
858   gcry_free (p);
859
860   frame[n++] = 0;
861   memcpy (frame+n, value, valuelen);
862   n += valuelen;
863   gcry_assert (n == nframe);
864
865   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
866   if (err)
867     rc = gcry_err_code (err);
868   else if (DBG_CIPHER)
869     log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
870   gcry_free (frame);
871
872   return rc;
873 }
874
875
876 /* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
877    NBITS is the size of the secret key.  On success the result is
878    stored as a newly allocated buffer at R_RESULT and its valid length at
879    R_RESULTLEN.  On error NULL is stored at R_RESULT.  */
880 static gcry_err_code_t
881 pkcs1_decode_for_encryption (unsigned char **r_result, size_t *r_resultlen,
882                              unsigned int nbits, gcry_mpi_t value)
883 {
884   gcry_error_t err;
885   unsigned char *frame = NULL;
886   size_t nframe = (nbits+7) / 8;
887   size_t n;
888
889   *r_result = NULL;
890
891   if ( !(frame = gcry_malloc_secure (nframe)))
892     return gpg_err_code_from_syserror ();
893
894   err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
895   if (err)
896     {
897       gcry_free (frame);
898       return gcry_err_code (err);
899     }
900
901   nframe = n; /* Set NFRAME to the actual length.  */
902
903   /* FRAME = 0x00 || 0x02 || PS || 0x00 || M
904
905      pkcs#1 requires that the first byte is zero.  Our MPIs usually
906      strip leading zero bytes; thus we are not able to detect them.
907      However due to the way gcry_mpi_print is implemented we may see
908      leading zero bytes nevertheless.  We handle this by making the
909      first zero byte optional.  */
910   if (nframe < 4)
911     {
912       gcry_free (frame);
913       return GPG_ERR_ENCODING_PROBLEM;  /* Too short.  */
914     }
915   n = 0;
916   if (!frame[0])
917     n++;
918   if (frame[n++] != 0x02)
919     {
920       gcry_free (frame);
921       return GPG_ERR_ENCODING_PROBLEM;  /* Wrong block type.  */
922     }
923
924   /* Skip the non-zero random bytes and the terminating zero byte.  */
925   for (; n < nframe && frame[n] != 0x00; n++)
926     ;
927   if (n+1 >= nframe)
928     {
929       gcry_free (frame);
930       return GPG_ERR_ENCODING_PROBLEM; /* No zero byte.  */
931     }
932   n++; /* Skip the zero byte.  */
933
934   /* To avoid an extra allocation we reuse the frame buffer.  The only
935      caller of this function will anyway free the result soon.  */
936   memmove (frame, frame + n, nframe - n);
937   *r_result = frame;
938   *r_resultlen = nframe - n;
939
940   if (DBG_CIPHER)
941     log_printhex ("value extracted from PKCS#1 block type 2 encoded data:",
942                   *r_result, *r_resultlen);
943
944   return 0;
945 }
946
947
948 /* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO
949    using the pkcs#1 block type 1 padding.  On success the result is
950    stored as a new MPI at R_RESULT.  On error the value at R_RESULT is
951    undefined.
952
953    We encode the value in this way:
954
955      0  1  PAD(n bytes)  0  ASN(asnlen bytes) VALUE(valuelen bytes)
956
957    0   is a marker we unfortunately can't encode because we return an
958        MPI which strips all leading zeroes.
959    1   is the block type.
960    PAD consists of 0xff bytes.
961    0   marks the end of the padding.
962    ASN is the DER encoding of the hash algorithm; along with the VALUE
963        it yields a valid DER encoding.
964
965    (Note that PGP prior to version 2.3 encoded the message digest as:
966       0   1   MD(16 bytes)   0   PAD(n bytes)   1
967     The MD is always 16 bytes here because it's always MD5.  GnuPG
968     does not not support pre-v2.3 signatures, but I'm including this
969     comment so the information is easily found if needed.)
970 */
971 static gcry_err_code_t
972 pkcs1_encode_for_signature (gcry_mpi_t *r_result, unsigned int nbits,
973                             const unsigned char *value, size_t valuelen,
974                             int algo)
975 {
976   gcry_err_code_t rc = 0;
977   gcry_error_t err;
978   byte asn[100];
979   byte *frame = NULL;
980   size_t nframe = (nbits+7) / 8;
981   int i;
982   size_t n;
983   size_t asnlen, dlen;
984
985   asnlen = DIM(asn);
986   dlen = gcry_md_get_algo_dlen (algo);
987
988   if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
989     {
990       /* We don't have yet all of the above algorithms.  */
991       return GPG_ERR_NOT_IMPLEMENTED;
992     }
993
994   if ( valuelen != dlen )
995     {
996       /* Hash value does not match the length of digest for
997          the given algorithm.  */
998       return GPG_ERR_CONFLICT;
999     }
1000
1001   if ( !dlen || dlen + asnlen + 4 > nframe)
1002     {
1003       /* Can't encode an DLEN byte digest MD into an NFRAME byte
1004          frame.  */
1005       return GPG_ERR_TOO_SHORT;
1006     }
1007
1008   if ( !(frame = gcry_malloc (nframe)) )
1009     return gpg_err_code_from_syserror ();
1010
1011   /* Assemble the pkcs#1 block type 1. */
1012   n = 0;
1013   frame[n++] = 0;
1014   frame[n++] = 1; /* block type */
1015   i = nframe - valuelen - asnlen - 3 ;
1016   gcry_assert (i > 1);
1017   memset (frame+n, 0xff, i );
1018   n += i;
1019   frame[n++] = 0;
1020   memcpy (frame+n, asn, asnlen);
1021   n += asnlen;
1022   memcpy (frame+n, value, valuelen );
1023   n += valuelen;
1024   gcry_assert (n == nframe);
1025
1026   /* Convert it into an MPI. */
1027   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
1028   if (err)
1029     rc = gcry_err_code (err);
1030   else if (DBG_CIPHER)
1031     log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
1032   gcry_free (frame);
1033
1034   return rc;
1035 }
1036
1037
1038 /* Mask generation function for OAEP.  See RFC-3447 B.2.1.  */
1039 static gcry_err_code_t
1040 mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
1041       int algo)
1042 {
1043   size_t dlen, nbytes, n;
1044   int idx;
1045   gcry_md_hd_t hd;
1046   gcry_error_t err;
1047
1048   err = gcry_md_open (&hd, algo, 0);
1049   if (err)
1050     return gpg_err_code (err);
1051
1052   dlen = gcry_md_get_algo_dlen (algo);
1053
1054   /* We skip step 1 which would be assert(OUTLEN <= 2^32).  The loop
1055      in step 3 is merged with step 4 by concatenating no more octets
1056      than what would fit into OUTPUT.  The ceiling for the counter IDX
1057      is implemented indirectly.  */
1058   nbytes = 0;  /* Step 2.  */
1059   idx = 0;
1060   while ( nbytes < outlen )
1061     {
1062       unsigned char c[4], *digest;
1063
1064       if (idx)
1065         gcry_md_reset (hd);
1066
1067       c[0] = (idx >> 24) & 0xFF;
1068       c[1] = (idx >> 16) & 0xFF;
1069       c[2] = (idx >> 8) & 0xFF;
1070       c[3] = idx & 0xFF;
1071       idx++;
1072
1073       gcry_md_write (hd, seed, seedlen);
1074       gcry_md_write (hd, c, 4);
1075       digest = gcry_md_read (hd, 0);
1076
1077       n = (outlen - nbytes < dlen)? (outlen - nbytes) : dlen;
1078       memcpy (output+nbytes, digest, n);
1079       nbytes += n;
1080     }
1081
1082   gcry_md_close (hd);
1083   return GPG_ERR_NO_ERROR;
1084 }
1085
1086
1087 /* RFC-3447 (pkcs#1 v2.1) OAEP encoding.  NBITS is the length of the
1088    key measured in bits.  ALGO is the hash function; it must be a
1089    valid and usable algorithm.  {VALUE,VALUELEN} is the message to
1090    encrypt.  {LABEL,LABELLEN} is the optional label to be associated
1091    with the message, if LABEL is NULL the default is to use the empty
1092    string as label.  On success the encoded ciphertext is returned at
1093    R_RESULT.
1094
1095    Here is figure 1 from the RFC depicting the process:
1096
1097                              +----------+---------+-------+
1098                         DB = |  lHash   |    PS   |   M   |
1099                              +----------+---------+-------+
1100                                             |
1101                   +----------+              V
1102                   |   seed   |--> MGF ---> xor
1103                   +----------+              |
1104                         |                   |
1105                +--+     V                   |
1106                |00|    xor <----- MGF <-----|
1107                +--+     |                   |
1108                  |      |                   |
1109                  V      V                   V
1110                +--+----------+----------------------------+
1111          EM =  |00|maskedSeed|          maskedDB          |
1112                +--+----------+----------------------------+
1113   */
1114 static gcry_err_code_t
1115 oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
1116              const unsigned char *value, size_t valuelen,
1117              const unsigned char *label, size_t labellen)
1118 {
1119   gcry_err_code_t rc = 0;
1120   gcry_error_t err;
1121   unsigned char *frame = NULL;
1122   size_t nframe = (nbits+7) / 8;
1123   unsigned char *p;
1124   size_t hlen;
1125   size_t n;
1126
1127   *r_result = NULL;
1128
1129   /* Set defaults for LABEL.  */
1130   if (!label || !labellen)
1131     {
1132       label = (const unsigned char*)"";
1133       labellen = 0;
1134     }
1135
1136   hlen = gcry_md_get_algo_dlen (algo);
1137
1138   /* We skip step 1a which would be to check that LABELLEN is not
1139      greater than 2^61-1.  See rfc-3447 7.1.1. */
1140
1141   /* Step 1b.  Note that the obsolete rfc-2437 uses the check:
1142      valuelen > nframe - 2 * hlen - 1 .  */
1143   if (valuelen > nframe - 2 * hlen - 2 || !nframe)
1144     {
1145       /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
1146       return GPG_ERR_TOO_SHORT; /* The key is too short.  */
1147     }
1148
1149   /* Allocate the frame.  */
1150   frame = gcry_calloc_secure (1, nframe);
1151   if (!frame)
1152     return gpg_err_code_from_syserror ();
1153
1154   /* Step 2a: Compute the hash of the label.  We store it in the frame
1155      where later the maskedDB will commence.  */
1156   gcry_md_hash_buffer (algo, frame + 1 + hlen, label, labellen);
1157
1158   /* Step 2b: Set octet string to zero.  */
1159   /* This has already been done while allocating FRAME.  */
1160
1161   /* Step 2c: Create DB by concatenating lHash, PS, 0x01 and M.  */
1162   n = nframe - valuelen - 1;
1163   frame[n] = 0x01;
1164   memcpy (frame + n + 1, value, valuelen);
1165
1166   /* Step 3d: Generate seed.  We store it where the maskedSeed will go
1167      later. */
1168   gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
1169
1170   /* Step 2e and 2f: Create maskedDB.  */
1171   {
1172     unsigned char *dmask;
1173
1174     dmask = gcry_malloc_secure (nframe - hlen - 1);
1175     if (!dmask)
1176       {
1177         rc = gpg_err_code_from_syserror ();
1178         gcry_free (frame);
1179         return rc;
1180       }
1181     rc = mgf1 (dmask, nframe - hlen - 1, frame+1, hlen, algo);
1182     if (rc)
1183       {
1184         gcry_free (dmask);
1185         gcry_free (frame);
1186         return rc;
1187       }
1188     for (n = 1 + hlen, p = dmask; n < nframe; n++)
1189       frame[n] ^= *p++;
1190     gcry_free (dmask);
1191   }
1192
1193   /* Step 2g and 2h: Create maskedSeed.  */
1194   {
1195     unsigned char *smask;
1196
1197     smask = gcry_malloc_secure (hlen);
1198     if (!smask)
1199       {
1200         rc = gpg_err_code_from_syserror ();
1201         gcry_free (frame);
1202         return rc;
1203       }
1204     rc = mgf1 (smask, hlen, frame + 1 + hlen, nframe - hlen - 1, algo);
1205     if (rc)
1206       {
1207         gcry_free (smask);
1208         gcry_free (frame);
1209         return rc;
1210       }
1211     for (n = 1, p = smask; n < 1 + hlen; n++)
1212       frame[n] ^= *p++;
1213     gcry_free (smask);
1214   }
1215
1216   /* Step 2i: Concatenate 0x00, maskedSeed and maskedDB.  */
1217   /* This has already been done by using in-place operations.  */
1218
1219   /* Convert the stuff into an MPI as expected by the caller.  */
1220   err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL);
1221   if (err)
1222     rc = gcry_err_code (err);
1223   else if (DBG_CIPHER)
1224     log_mpidump ("OAEP encoded data", *r_result);
1225   gcry_free (frame);
1226
1227   return rc;
1228 }
1229
1230
1231 /* RFC-3447 (pkcs#1 v2.1) OAEP decoding.  NBITS is the length of the
1232    key measured in bits.  ALGO is the hash function; it must be a
1233    valid and usable algorithm.  VALUE is the raw decrypted message
1234    {LABEL,LABELLEN} is the optional label to be associated with the
1235    message, if LABEL is NULL the default is to use the empty string as
1236    label.  On success the plaintext is returned as a newly allocated
1237    buffer at R_RESULT; its valid length is stored at R_RESULTLEN.  On
1238    error NULL is stored at R_RESULT.  */
1239 static gcry_err_code_t
1240 oaep_decode (unsigned char **r_result, size_t *r_resultlen,
1241              unsigned int nbits, int algo,
1242              gcry_mpi_t value, const unsigned char *label, size_t labellen)
1243 {
1244   gcry_err_code_t rc;
1245   unsigned char *frame = NULL; /* Encoded messages (EM).  */
1246   unsigned char *masked_seed;  /* Points into FRAME.  */
1247   unsigned char *masked_db;    /* Points into FRAME.  */
1248   unsigned char *seed = NULL;  /* Allocated space for the seed and DB.  */
1249   unsigned char *db;           /* Points into SEED.  */
1250   unsigned char *lhash = NULL; /* Hash of the label.  */
1251   size_t nframe;               /* Length of the ciphertext (EM).  */
1252   size_t hlen;                 /* Length of the hash digest.  */
1253   size_t db_len;               /* Length of DB and masked_db.  */
1254   size_t nkey = (nbits+7)/8;   /* Length of the key in bytes.  */
1255   int failed = 0;              /* Error indicator.  */
1256   size_t noff, n;
1257
1258   *r_result = NULL;
1259
1260   /* This code is implemented as described by rfc-3447 7.1.2.  */
1261
1262   /* Set defaults for LABEL.  */
1263   if (!label || !labellen)
1264     {
1265       label = (const unsigned char*)"";
1266       labellen = 0;
1267     }
1268
1269   /* Get the length of the digest.  */
1270   hlen = gcry_md_get_algo_dlen (algo);
1271
1272   /* Hash the label right away.  */
1273   lhash = gcry_malloc (hlen);
1274   if (!lhash)
1275     return gpg_err_code_from_syserror ();
1276   gcry_md_hash_buffer (algo, lhash, label, labellen);
1277
1278   /* Turn the MPI into an octet string.  If the octet string is
1279      shorter than the key we pad it to the left with zeroes.  This may
1280      happen due to the leading zero in OAEP frames and due to the
1281      following random octets (seed^mask) which may have leading zero
1282      bytes.  This all is needed to cope with our leading zeroes
1283      suppressing MPI implementation.  The code implictly implements
1284      Step 1b (bail out if NFRAME != N).  */
1285   rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG,
1286                                       NULL, 0, &nframe, value));
1287   if (rc || nframe > nkey)
1288     {
1289       gcry_free (lhash);
1290       return GPG_ERR_ENCODING_PROBLEM;
1291     }
1292   noff = (nframe < nkey)? nkey - nframe : 0;
1293   n = nframe + noff;
1294   frame = mpi_is_secure (value)? gcry_malloc_secure (n) : gcry_malloc (n);
1295   if (!frame)
1296     {
1297       rc = gpg_error_from_syserror ();
1298       gcry_free (lhash);
1299       return rc;
1300     }
1301   if (noff)
1302     memset (frame, 0, noff);
1303   nframe += noff;
1304   rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG,
1305                                       frame+noff, nframe-noff, NULL, value));
1306   if (rc)
1307     {
1308       gcry_free (frame);
1309       gcry_free (lhash);
1310       return rc;
1311     }
1312
1313   /* Step 1c: Check that the key is long enough.  */
1314   if ( nframe < 2 * hlen + 2 )
1315     {
1316       gcry_free (frame);
1317       gcry_free (lhash);
1318       return GPG_ERR_ENCODING_PROBLEM;
1319     }
1320
1321   /* Step 2 has already been done by the caller and the
1322      gcry_mpi_aprint above.  */
1323
1324   /* Allocate space for SEED and DB.  */
1325   seed = gcry_malloc_secure (nframe - 1);
1326   if (!seed)
1327     {
1328       rc = gpg_err_code_from_syserror ();
1329       gcry_free (frame);
1330       gcry_free (lhash);
1331       return rc;
1332     }
1333   db = seed + hlen;
1334
1335   /* To avoid choosen ciphertext attacks from now on we make sure to
1336      run all code even in the error case; this avoids possible timing
1337      attacks as described by Manger.  */
1338
1339   /* Step 3a: Hash the label.  */
1340   /* This has already been done.  */
1341
1342   /* Step 3b: Separate the encoded message.  */
1343   masked_seed = frame + 1;
1344   masked_db   = frame + 1 + hlen;
1345   db_len      = nframe - 1 - hlen;
1346
1347   /* Step 3c and 3d: seed = maskedSeed ^ mgf(maskedDB, hlen).  */
1348   if (mgf1 (seed, hlen, masked_db, db_len, algo))
1349     failed = 1;
1350   for (n = 0; n < hlen; n++)
1351     seed[n] ^= masked_seed[n];
1352
1353   /* Step 3e and 3f: db = maskedDB ^ mgf(seed, db_len).  */
1354   if (mgf1 (db, db_len, seed, hlen, algo))
1355     failed = 1;
1356   for (n = 0; n < db_len; n++)
1357     db[n] ^= masked_db[n];
1358
1359   /* Step 3g: Check lhash, an possible empty padding string terminated
1360      by 0x01 and the first byte of EM being 0.  */
1361   if (memcmp (lhash, db, hlen))
1362     failed = 1;
1363   for (n = hlen; n < db_len; n++)
1364     if (db[n] == 0x01)
1365       break;
1366   if (n == db_len)
1367     failed = 1;
1368   if (frame[0])
1369     failed = 1;
1370
1371   gcry_free (lhash);
1372   gcry_free (frame);
1373   if (failed)
1374     {
1375       gcry_free (seed);
1376       return GPG_ERR_ENCODING_PROBLEM;
1377     }
1378
1379   /* Step 4: Output M.  */
1380   /* To avoid an extra allocation we reuse the seed buffer.  The only
1381      caller of this function will anyway free the result soon.  */
1382   n++;
1383   memmove (seed, db + n, db_len - n);
1384   *r_result = seed;
1385   *r_resultlen = db_len - n;
1386   seed = NULL;
1387
1388   if (DBG_CIPHER)
1389     log_printhex ("value extracted from OAEP encoded data:",
1390                   *r_result, *r_resultlen);
1391
1392   return 0;
1393 }
1394
1395
1396 /* Internal function.   */
1397 static gcry_err_code_t
1398 sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
1399                        gcry_mpi_t *elements, const char *algo_name)
1400 {
1401   gcry_err_code_t err = 0;
1402   int i, idx;
1403   const char *name;
1404   gcry_sexp_t list;
1405
1406   for (name = element_names, idx = 0; *name && !err; name++, idx++)
1407     {
1408       list = gcry_sexp_find_token (key_sexp, name, 1);
1409       if (!list)
1410         elements[idx] = NULL;
1411       else
1412         {
1413           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
1414           gcry_sexp_release (list);
1415           if (!elements[idx])
1416             err = GPG_ERR_INV_OBJ;
1417         }
1418     }
1419
1420   if (!err)
1421     {
1422       /* Check that all elements are available.  */
1423       for (name = element_names, idx = 0; *name; name++, idx++)
1424         if (!elements[idx])
1425           break;
1426       if (*name)
1427         {
1428           err = GPG_ERR_NO_OBJ;
1429           /* Some are missing.  Before bailing out we test for
1430              optional parameters.  */
1431           if (algo_name && !strcmp (algo_name, "RSA")
1432               && !strcmp (element_names, "nedpqu") )
1433             {
1434               /* This is RSA.  Test whether we got N, E and D and that
1435                  the optional P, Q and U are all missing.  */
1436               if (elements[0] && elements[1] && elements[2]
1437                   && !elements[3] && !elements[4] && !elements[5])
1438                 err = 0;
1439             }
1440         }
1441     }
1442
1443
1444   if (err)
1445     {
1446       for (i = 0; i < idx; i++)
1447         if (elements[i])
1448           gcry_free (elements[i]);
1449     }
1450   return err;
1451 }
1452
1453
1454 /* Internal function used for ecc.  Note, that this function makes use
1455    of its intimate knowledge about the ECC parameters from ecc.c. */
1456 static gcry_err_code_t
1457 sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
1458                            gcry_mpi_t *elements, pk_extra_spec_t *extraspec)
1459
1460 {
1461   gcry_err_code_t err = 0;
1462   int idx;
1463   const char *name;
1464   gcry_sexp_t list;
1465
1466   /* Clear the array for easier error cleanup. */
1467   for (name = element_names, idx = 0; *name; name++, idx++)
1468     elements[idx] = NULL;
1469   gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements
1470                              (params only) or 6 (full public key).  */
1471   if (idx == 5)
1472     elements[5] = NULL;   /* Extra clear for the params only case.  */
1473
1474
1475   /* Init the array with the available curve parameters. */
1476   for (name = element_names, idx = 0; *name && !err; name++, idx++)
1477     {
1478       list = gcry_sexp_find_token (key_sexp, name, 1);
1479       if (!list)
1480         elements[idx] = NULL;
1481       else
1482         {
1483           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
1484           gcry_sexp_release (list);
1485           if (!elements[idx])
1486             {
1487               err = GPG_ERR_INV_OBJ;
1488               goto leave;
1489             }
1490         }
1491     }
1492
1493   /* Check whether a curve parameter has been given and then fill any
1494      missing elements.  */
1495   list = gcry_sexp_find_token (key_sexp, "curve", 5);
1496   if (list)
1497     {
1498       if (extraspec->get_param)
1499         {
1500           char *curve;
1501           gcry_mpi_t params[6];
1502
1503           for (idx = 0; idx < DIM(params); idx++)
1504             params[idx] = NULL;
1505
1506           curve = _gcry_sexp_nth_string (list, 1);
1507           gcry_sexp_release (list);
1508           if (!curve)
1509             {
1510               /* No curve name given (or out of core). */
1511               err = GPG_ERR_INV_OBJ;
1512               goto leave;
1513             }
1514           err = extraspec->get_param (curve, params);
1515           gcry_free (curve);
1516           if (err)
1517             goto leave;
1518
1519           for (idx = 0; idx < DIM(params); idx++)
1520             {
1521               if (!elements[idx])
1522                 elements[idx] = params[idx];
1523               else
1524                 mpi_free (params[idx]);
1525             }
1526         }
1527       else
1528         {
1529           gcry_sexp_release (list);
1530           err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
1531           goto leave;
1532         }
1533     }
1534
1535   /* Check that all parameters are known.  */
1536   for (name = element_names, idx = 0; *name; name++, idx++)
1537     if (!elements[idx])
1538       {
1539         err = GPG_ERR_NO_OBJ;
1540         goto leave;
1541       }
1542
1543  leave:
1544   if (err)
1545     {
1546       for (name = element_names, idx = 0; *name; name++, idx++)
1547         if (elements[idx])
1548           gcry_free (elements[idx]);
1549     }
1550   return err;
1551 }
1552
1553
1554
1555 /****************
1556  * Convert a S-Exp with either a private or a public key to our
1557  * internal format. Currently we do only support the following
1558  * algorithms:
1559  *    dsa
1560  *    rsa
1561  *    openpgp-dsa
1562  *    openpgp-rsa
1563  *    openpgp-elg
1564  *    openpgp-elg-sig
1565  *    ecdsa
1566  *    ecdh
1567  * Provide a SE with the first element be either "private-key" or
1568  * or "public-key". It is followed by a list with its first element
1569  * be one of the above algorithm identifiers and the remaning
1570  * elements are pairs with parameter-id and value.
1571  * NOTE: we look through the list to find a list beginning with
1572  * "private-key" or "public-key" - the first one found is used.
1573  *
1574  * If OVERRIDE_ELEMS is not NULL those elems override the parameter
1575  * specification taken from the module.  This ise used by
1576  * gcry_pk_get_curve.
1577  *
1578  * Returns: A pointer to an allocated array of MPIs if the return value is
1579  *          zero; the caller has to release this array.
1580  *
1581  * Example of a DSA public key:
1582  *  (private-key
1583  *    (dsa
1584  *      (p <mpi>)
1585  *      (g <mpi>)
1586  *      (y <mpi>)
1587  *      (x <mpi>)
1588  *    )
1589  *  )
1590  * The <mpi> are expected to be in GCRYMPI_FMT_USG
1591  */
1592 static gcry_err_code_t
1593 sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
1594              gcry_mpi_t **retarray, gcry_module_t *retalgo)
1595 {
1596   gcry_err_code_t err = 0;
1597   gcry_sexp_t list, l2;
1598   char *name;
1599   const char *elems;
1600   gcry_mpi_t *array;
1601   gcry_module_t module;
1602   gcry_pk_spec_t *pubkey;
1603   pk_extra_spec_t *extraspec;
1604   int is_ecc;
1605
1606   /* Check that the first element is valid.  */
1607   list = gcry_sexp_find_token (sexp,
1608                                want_private? "private-key":"public-key", 0);
1609   if (!list)
1610     return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
1611
1612   l2 = gcry_sexp_cadr( list );
1613   gcry_sexp_release ( list );
1614   list = l2;
1615   name = _gcry_sexp_nth_string (list, 0);
1616   if (!name)
1617     {
1618       gcry_sexp_release ( list );
1619       return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
1620     }
1621
1622   ath_mutex_lock (&pubkeys_registered_lock);
1623   module = gcry_pk_lookup_name (name);
1624   ath_mutex_unlock (&pubkeys_registered_lock);
1625
1626   /* Fixme: We should make sure that an ECC key is always named "ecc"
1627      and not "ecdsa".  "ecdsa" should be used for the signature
1628      itself.  We need a function to test whether an algorithm given
1629      with a key is compatible with an application of the key (signing,
1630      encryption).  For RSA this is easy, but ECC is the first
1631      algorithm which has many flavours.  */
1632   is_ecc = ( !strcmp (name, "ecdsa")
1633              || !strcmp (name, "ecdh")
1634              || !strcmp (name, "ecc") );
1635   gcry_free (name);
1636
1637   if (!module)
1638     {
1639       gcry_sexp_release (list);
1640       return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
1641     }
1642   else
1643     {
1644       pubkey = (gcry_pk_spec_t *) module->spec;
1645       extraspec = module->extraspec;
1646     }
1647
1648   if (override_elems)
1649     elems = override_elems;
1650   else if (want_private)
1651     elems = pubkey->elements_skey;
1652   else
1653     elems = pubkey->elements_pkey;
1654   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
1655   if (!array)
1656     err = gpg_err_code_from_syserror ();
1657   if (!err)
1658     {
1659       if (is_ecc)
1660         err = sexp_elements_extract_ecc (list, elems, array, extraspec);
1661       else
1662         err = sexp_elements_extract (list, elems, array, pubkey->name);
1663     }
1664
1665   gcry_sexp_release (list);
1666
1667   if (err)
1668     {
1669       gcry_free (array);
1670
1671       ath_mutex_lock (&pubkeys_registered_lock);
1672       _gcry_module_release (module);
1673       ath_mutex_unlock (&pubkeys_registered_lock);
1674     }
1675   else
1676     {
1677       *retarray = array;
1678       *retalgo = module;
1679     }
1680
1681   return err;
1682 }
1683
1684
1685 static gcry_err_code_t
1686 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
1687              gcry_module_t *retalgo)
1688 {
1689   gcry_err_code_t err = 0;
1690   gcry_sexp_t list, l2;
1691   char *name;
1692   const char *elems;
1693   gcry_mpi_t *array;
1694   gcry_module_t module;
1695   gcry_pk_spec_t *pubkey;
1696
1697   /* Check that the first element is valid.  */
1698   list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
1699   if (!list)
1700     return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
1701
1702   l2 = gcry_sexp_nth (list, 1);
1703   if (!l2)
1704     {
1705       gcry_sexp_release (list);
1706       return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
1707     }
1708   name = _gcry_sexp_nth_string (l2, 0);
1709   if (!name)
1710     {
1711       gcry_sexp_release (list);
1712       gcry_sexp_release (l2);
1713       return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
1714     }
1715   else if (!strcmp (name, "flags"))
1716     {
1717       /* Skip flags, since they are not used but here just for the
1718          sake of consistent S-expressions.  */
1719       gcry_free (name);
1720       gcry_sexp_release (l2);
1721       l2 = gcry_sexp_nth (list, 2);
1722       if (!l2)
1723         {
1724           gcry_sexp_release (list);
1725           return GPG_ERR_INV_OBJ;
1726         }
1727       name = _gcry_sexp_nth_string (l2, 0);
1728     }
1729
1730   ath_mutex_lock (&pubkeys_registered_lock);
1731   module = gcry_pk_lookup_name (name);
1732   ath_mutex_unlock (&pubkeys_registered_lock);
1733   gcry_free (name);
1734   name = NULL;
1735
1736   if (!module)
1737     {
1738       gcry_sexp_release (l2);
1739       gcry_sexp_release (list);
1740       return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
1741     }
1742   else
1743     pubkey = (gcry_pk_spec_t *) module->spec;
1744
1745   elems = pubkey->elements_sig;
1746   array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
1747   if (!array)
1748     err = gpg_err_code_from_syserror ();
1749
1750   if (!err)
1751     err = sexp_elements_extract (list, elems, array, NULL);
1752
1753   gcry_sexp_release (l2);
1754   gcry_sexp_release (list);
1755
1756   if (err)
1757     {
1758       ath_mutex_lock (&pubkeys_registered_lock);
1759       _gcry_module_release (module);
1760       ath_mutex_unlock (&pubkeys_registered_lock);
1761
1762       gcry_free (array);
1763     }
1764   else
1765     {
1766       *retarray = array;
1767       *retalgo = module;
1768     }
1769
1770   return err;
1771 }
1772
1773 static inline int
1774 get_hash_algo (const char *s, size_t n)
1775 {
1776   static const struct { const char *name; int algo; } hashnames[] = {
1777     { "sha1",   GCRY_MD_SHA1 },
1778     { "md5",    GCRY_MD_MD5 },
1779     { "sha256", GCRY_MD_SHA256 },
1780     { "ripemd160", GCRY_MD_RMD160 },
1781     { "rmd160", GCRY_MD_RMD160 },
1782     { "sha384", GCRY_MD_SHA384 },
1783     { "sha512", GCRY_MD_SHA512 },
1784     { "sha224", GCRY_MD_SHA224 },
1785     { "md2",    GCRY_MD_MD2 },
1786     { "md4",    GCRY_MD_MD4 },
1787     { "tiger",  GCRY_MD_TIGER },
1788     { "haval",  GCRY_MD_HAVAL },
1789     { NULL, 0 }
1790   };
1791   int algo;
1792   int i;
1793
1794   for (i=0; hashnames[i].name; i++)
1795     {
1796       if ( strlen (hashnames[i].name) == n
1797            && !memcmp (hashnames[i].name, s, n))
1798         break;
1799     }
1800   if (hashnames[i].name)
1801     algo = hashnames[i].algo;
1802   else
1803     {
1804       /* In case of not listed or dynamically allocated hash
1805          algorithm we fall back to this somewhat slower
1806          method.  Further, it also allows to use OIDs as
1807          algorithm names. */
1808       char *tmpname;
1809
1810       tmpname = gcry_malloc (n+1);
1811       if (!tmpname)
1812         algo = 0;  /* Out of core - silently give up.  */
1813       else
1814         {
1815           memcpy (tmpname, s, n);
1816           tmpname[n] = 0;
1817           algo = gcry_md_map_name (tmpname);
1818           gcry_free (tmpname);
1819         }
1820     }
1821   return algo;
1822 }
1823
1824
1825 /****************
1826  * Take sexp and return an array of MPI as used for our internal decrypt
1827  * function.
1828  * s_data = (enc-val
1829  *           [(flags [raw, pkcs1, oaep, no-blinding])]
1830  *           [(hash-algo <algo>)]
1831  *           [(label <label>)]
1832  *            (<algo>
1833  *              (<param_name1> <mpi>)
1834  *              ...
1835  *              (<param_namen> <mpi>)
1836  *            ))
1837  * HASH-ALGO and LABEL are specific to OAEP.
1838  * RET_MODERN is set to true when at least an empty flags list has been found.
1839  * CTX is used to return encoding information; it may be NULL in which
1840  * case raw encoding is used.
1841  */
1842 static gcry_err_code_t
1843 sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
1844              int *ret_modern, int *flags, struct pk_encoding_ctx *ctx)
1845 {
1846   gcry_err_code_t err = 0;
1847   gcry_sexp_t list = NULL, l2 = NULL;
1848   gcry_pk_spec_t *pubkey = NULL;
1849   gcry_module_t module = NULL;
1850   char *name = NULL;
1851   size_t n;
1852   int parsed_flags = 0;
1853   const char *elems;
1854   gcry_mpi_t *array = NULL;
1855   struct pk_encoding_ctx dummy_ctx;
1856
1857   *ret_modern = 0;
1858
1859   if (!ctx)
1860     ctx = &dummy_ctx;
1861   ctx->encoding = PUBKEY_ENC_RAW;
1862   ctx->hash_algo = GCRY_MD_SHA1;
1863   ctx->label = NULL;
1864   ctx->labellen = 0;
1865
1866   /* Check that the first element is valid.  */
1867   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
1868   if (!list)
1869     {
1870       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
1871       goto leave;
1872     }
1873
1874   l2 = gcry_sexp_nth (list, 1);
1875   if (!l2)
1876     {
1877       err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
1878       goto leave;
1879     }
1880
1881   /* Extract identifier of sublist.  */
1882   name = _gcry_sexp_nth_string (l2, 0);
1883   if (!name)
1884     {
1885       err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
1886       goto leave;
1887     }
1888
1889   if (!strcmp (name, "flags"))
1890     {
1891       /* There is a flags element - process it.  */
1892       const char *s;
1893       int i;
1894
1895       *ret_modern = 1;
1896       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
1897         {
1898           s = gcry_sexp_nth_data (l2, i, &n);
1899           if (! s)
1900             ; /* Not a data element - ignore.  */
1901           else if (n == 3 && !memcmp (s, "raw", 3)
1902                    && ctx->encoding == PUBKEY_ENC_RAW)
1903             ; /* This is just a dummy as it is the default.  */
1904           else if (n == 5 && !memcmp (s, "pkcs1", 5)
1905                    && ctx->encoding == PUBKEY_ENC_RAW)
1906             ctx->encoding = PUBKEY_ENC_PKCS1;
1907           else if (n == 4 && !memcmp (s, "oaep", 4)
1908                    && ctx->encoding == PUBKEY_ENC_RAW)
1909             ctx->encoding = PUBKEY_ENC_OAEP;
1910           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1911             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1912           else
1913             {
1914               err = GPG_ERR_INV_FLAG;
1915               goto leave;
1916             }
1917         }
1918       gcry_sexp_release (l2);
1919
1920       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
1921       if (ctx->encoding == PUBKEY_ENC_OAEP)
1922         {
1923           /* Get HASH-ALGO. */
1924           l2 = gcry_sexp_find_token (list, "hash-algo", 0);
1925           if (l2)
1926             {
1927               s = gcry_sexp_nth_data (l2, 1, &n);
1928               if (!s)
1929                 err = GPG_ERR_NO_OBJ;
1930               else
1931                 {
1932                   ctx->hash_algo = get_hash_algo (s, n);
1933                   if (!ctx->hash_algo)
1934                     err = GPG_ERR_DIGEST_ALGO;
1935                 }
1936               gcry_sexp_release (l2);
1937               if (err)
1938                 goto leave;
1939             }
1940
1941           /* Get LABEL. */
1942           l2 = gcry_sexp_find_token (list, "label", 0);
1943           if (l2)
1944             {
1945               s = gcry_sexp_nth_data (l2, 1, &n);
1946               if (!s)
1947                 err = GPG_ERR_NO_OBJ;
1948               else if (n > 0)
1949                 {
1950                   ctx->label = gcry_malloc (n);
1951                   if (!ctx->label)
1952                     err = gpg_err_code_from_syserror ();
1953                   else
1954                     {
1955                       memcpy (ctx->label, s, n);
1956                       ctx->labellen = n;
1957                     }
1958                 }
1959               gcry_sexp_release (l2);
1960               if (err)
1961                 goto leave;
1962             }
1963         }
1964
1965       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
1966       for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
1967         {
1968           s = gcry_sexp_nth_data (l2, 0, &n);
1969           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
1970               && !(n == 5 && !memcmp (s, "label", 5)))
1971             break;
1972           gcry_sexp_release (l2);
1973         }
1974
1975       if (!l2)
1976         {
1977           err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
1978           goto leave;
1979         }
1980
1981       /* Extract sublist identifier.  */
1982       gcry_free (name);
1983       name = _gcry_sexp_nth_string (l2, 0);
1984       if (!name)
1985         {
1986           err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
1987           goto leave;
1988         }
1989
1990       gcry_sexp_release (list);
1991       list = l2;
1992       l2 = NULL;
1993     }
1994
1995   ath_mutex_lock (&pubkeys_registered_lock);
1996   module = gcry_pk_lookup_name (name);
1997   ath_mutex_unlock (&pubkeys_registered_lock);
1998
1999   if (!module)
2000     {
2001       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
2002       goto leave;
2003     }
2004   pubkey = (gcry_pk_spec_t *) module->spec;
2005
2006   elems = pubkey->elements_enc;
2007   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
2008   if (!array)
2009     {
2010       err = gpg_err_code_from_syserror ();
2011       goto leave;
2012     }
2013
2014   err = sexp_elements_extract (list, elems, array, NULL);
2015
2016  leave:
2017   gcry_sexp_release (list);
2018   gcry_sexp_release (l2);
2019   gcry_free (name);
2020
2021   if (err)
2022     {
2023       ath_mutex_lock (&pubkeys_registered_lock);
2024       _gcry_module_release (module);
2025       ath_mutex_unlock (&pubkeys_registered_lock);
2026       gcry_free (array);
2027       gcry_free (ctx->label);
2028       ctx->label = NULL;
2029     }
2030   else
2031     {
2032       *retarray = array;
2033       *retalgo = module;
2034       *flags = parsed_flags;
2035     }
2036
2037   return err;
2038 }
2039
2040 /* Take the hash value and convert into an MPI, suitable for
2041    passing to the low level functions.  We currently support the
2042    old style way of passing just a MPI and the modern interface which
2043    allows to pass flags so that we can choose between raw and pkcs1
2044    padding - may be more padding options later.
2045
2046    (<mpi>)
2047    or
2048    (data
2049     [(flags [raw, pkcs1, oaep, no-blinding])]
2050     [(hash <algo> <value>)]
2051     [(value <text>)]
2052     [(hash-algo <algo>)]
2053     [(label <label>)]
2054    )
2055
2056    Either the VALUE or the HASH element must be present for use
2057    with signatures.  VALUE is used for encryption.
2058
2059    HASH-ALGO and LABEL are specific to OAEP.
2060
2061    NBITS is the length of the key in bits.
2062
2063 */
2064 static gcry_err_code_t
2065 sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
2066                   int for_encryption, int *flags, struct pk_encoding_ctx *ctx)
2067 {
2068   gcry_err_code_t rc = 0;
2069   gcry_sexp_t ldata, lhash, lvalue;
2070   int i;
2071   size_t n;
2072   const char *s;
2073   int unknown_flag=0;
2074   int parsed_flags = 0, dummy_flags;
2075   struct pk_encoding_ctx dummy_ctx;
2076
2077   if (! flags)
2078     flags = &dummy_flags;
2079
2080   if (! ctx)
2081     ctx = &dummy_ctx;
2082
2083   ctx->encoding = PUBKEY_ENC_UNKNOWN;
2084   ctx->hash_algo = GCRY_MD_SHA1;
2085   ctx->label = NULL;
2086   ctx->labellen = 0;
2087
2088   *ret_mpi = NULL;
2089   ldata = gcry_sexp_find_token (input, "data", 0);
2090   if (!ldata)
2091     { /* assume old style */
2092       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
2093       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
2094     }
2095
2096   /* see whether there is a flags object */
2097   {
2098     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
2099     if (lflags)
2100       { /* parse the flags list. */
2101         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
2102           {
2103             s = gcry_sexp_nth_data (lflags, i, &n);
2104             if (!s)
2105               ; /* not a data element*/
2106             else if ( n == 3 && !memcmp (s, "raw", 3)
2107                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
2108               ctx->encoding = PUBKEY_ENC_RAW;
2109             else if ( n == 5 && !memcmp (s, "pkcs1", 5)
2110                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
2111               ctx->encoding = PUBKEY_ENC_PKCS1;
2112             else if ( n == 4 && !memcmp (s, "oaep", 4)
2113                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
2114               ctx->encoding = PUBKEY_ENC_OAEP;
2115             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
2116               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
2117             else
2118               unknown_flag = 1;
2119           }
2120         gcry_sexp_release (lflags);
2121       }
2122   }
2123
2124   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
2125     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
2126
2127   /* Get HASH or MPI */
2128   lhash = gcry_sexp_find_token (ldata, "hash", 0);
2129   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
2130
2131   if (!(!lhash ^ !lvalue))
2132     rc = GPG_ERR_INV_OBJ; /* none or both given */
2133   else if (unknown_flag)
2134     rc = GPG_ERR_INV_FLAG;
2135   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
2136     {
2137       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
2138       if (!*ret_mpi)
2139         rc = GPG_ERR_INV_OBJ;
2140     }
2141   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue && for_encryption)
2142     {
2143       const void * value;
2144       size_t valuelen;
2145
2146       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
2147         rc = GPG_ERR_INV_OBJ;
2148       else
2149         rc = pkcs1_encode_for_encryption (ret_mpi, nbits, value, valuelen);
2150     }
2151   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash && !for_encryption)
2152     {
2153       if (gcry_sexp_length (lhash) != 3)
2154         rc = GPG_ERR_INV_OBJ;
2155       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
2156         rc = GPG_ERR_INV_OBJ;
2157       else
2158         {
2159           int algo;
2160           const void * value;
2161           size_t valuelen;
2162
2163           algo = get_hash_algo (s, n);
2164
2165           if (!algo)
2166             rc = GPG_ERR_DIGEST_ALGO;
2167           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
2168                     || !valuelen )
2169             rc = GPG_ERR_INV_OBJ;
2170           else
2171             rc = pkcs1_encode_for_signature (ret_mpi, nbits, value, valuelen,
2172                                              algo);
2173         }
2174     }
2175   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue && for_encryption)
2176     {
2177       const void * value;
2178       size_t valuelen;
2179
2180       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
2181         rc = GPG_ERR_INV_OBJ;
2182       else
2183         {
2184           gcry_sexp_t list;
2185
2186           /* Get HASH-ALGO. */
2187           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
2188           if (list)
2189             {
2190               s = gcry_sexp_nth_data (list, 1, &n);
2191               if (!s)
2192                 rc = GPG_ERR_NO_OBJ;
2193               else
2194                 {
2195                   ctx->hash_algo = get_hash_algo (s, n);
2196                   if (!ctx->hash_algo)
2197                     rc = GPG_ERR_DIGEST_ALGO;
2198                 }
2199               gcry_sexp_release (list);
2200               if (rc)
2201                 goto leave;
2202             }
2203
2204           /* Get LABEL. */
2205           list = gcry_sexp_find_token (ldata, "label", 0);
2206           if (list)
2207             {
2208               s = gcry_sexp_nth_data (list, 1, &n);
2209               if (!s)
2210                 rc = GPG_ERR_NO_OBJ;
2211               else if (n > 0)
2212                 {
2213                   ctx->label = gcry_malloc (n);
2214                   if (!ctx->label)
2215                     rc = gpg_err_code_from_syserror ();
2216                   else
2217                     {
2218                       memcpy (ctx->label, s, n);
2219                       ctx->labellen = n;
2220                     }
2221                 }
2222               gcry_sexp_release (list);
2223               if (rc)
2224                 goto leave;
2225             }
2226
2227           rc = oaep_encode (ret_mpi, nbits, ctx->hash_algo, value, valuelen,
2228                             ctx->label, ctx->labellen);
2229         }
2230     }
2231   else
2232     rc = GPG_ERR_CONFLICT;
2233
2234  leave:
2235   gcry_sexp_release (ldata);
2236   gcry_sexp_release (lhash);
2237   gcry_sexp_release (lvalue);
2238
2239   if (!rc)
2240     *flags = parsed_flags;
2241   else
2242     {
2243       gcry_free (ctx->label);
2244       ctx->label = NULL;
2245     }
2246
2247   return rc;
2248 }
2249
2250
2251 /*
2252    Do a PK encrypt operation
2253
2254    Caller has to provide a public key as the SEXP pkey and data as a
2255    SEXP with just one MPI in it. Alternatively S_DATA might be a
2256    complex S-Expression, similar to the one used for signature
2257    verification.  This provides a flag which allows to handle PKCS#1
2258    block type 2 padding.  The function returns a a sexp which may be
2259    passed to to pk_decrypt.
2260
2261    Returns: 0 or an errorcode.
2262
2263    s_data = See comment for sexp_data_to_mpi
2264    s_pkey = <key-as-defined-in-sexp_to_key>
2265    r_ciph = (enc-val
2266                (<algo>
2267                  (<param_name1> <mpi>)
2268                  ...
2269                  (<param_namen> <mpi>)
2270                ))
2271
2272 */
2273 gcry_error_t
2274 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
2275 {
2276   gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
2277   const char *algo_name, *algo_elems;
2278   int flags;
2279   struct pk_encoding_ctx ctx;
2280   gcry_err_code_t rc;
2281   gcry_pk_spec_t *pubkey = NULL;
2282   gcry_module_t module = NULL;
2283
2284   *r_ciph = NULL;
2285
2286   REGISTER_DEFAULT_PUBKEYS;
2287
2288   memset (&ctx, 0, sizeof(struct pk_encoding_ctx));
2289   /* Get the key. */
2290   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module);
2291   if (rc)
2292     goto leave;
2293
2294   gcry_assert (module);
2295   pubkey = (gcry_pk_spec_t *) module->spec;
2296
2297   /* If aliases for the algorithm name exists, take the first one
2298      instead of the regular name to adhere to SPKI conventions.  We
2299      assume that the first alias name is the lowercase version of the
2300      regular one.  This change is required for compatibility with
2301      1.1.12 generated S-expressions. */
2302   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2303   if (!algo_name || !*algo_name)
2304     algo_name = pubkey->name;
2305
2306   algo_elems = pubkey->elements_enc;
2307
2308   /* Get the stuff we want to encrypt. */
2309   rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
2310                          &flags, &ctx);
2311   if (rc)
2312     goto leave;
2313
2314   /* Now we can encrypt DATA to CIPH. */
2315   ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
2316   if (!ciph)
2317     {
2318       rc = gpg_err_code_from_syserror ();
2319       goto leave;
2320     }
2321   rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
2322   mpi_free (data);
2323   data = NULL;
2324   if (rc)
2325     goto leave;
2326
2327   /* We did it.  Now build the return list */
2328   {
2329     char *string, *p;
2330     int i;
2331     size_t nelem = strlen (algo_elems);
2332     size_t needed = 19 + strlen (algo_name) + (nelem * 5);
2333     void **arg_list;
2334
2335     /* Build the string.  */
2336     string = p = gcry_malloc (needed);
2337     if (!string)
2338       {
2339         rc = gpg_err_code_from_syserror ();
2340         goto leave;
2341       }
2342     p = stpcpy ( p, "(enc-val(" );
2343     p = stpcpy ( p, algo_name );
2344     for (i=0; algo_elems[i]; i++ )
2345       {
2346         *p++ = '(';
2347         *p++ = algo_elems[i];
2348         p = stpcpy ( p, "%m)" );
2349       }
2350     strcpy ( p, "))" );
2351
2352     /* And now the ugly part: We don't have a function to pass an
2353      * array to a format string, so we have to do it this way :-(.  */
2354     /* FIXME: There is now such a format specifier, so we can
2355        change the code to be more clear. */
2356     arg_list = malloc (nelem * sizeof *arg_list);
2357     if (!arg_list)
2358       {
2359         rc = gpg_err_code_from_syserror ();
2360         goto leave;
2361       }
2362
2363     for (i = 0; i < nelem; i++)
2364       arg_list[i] = ciph + i;
2365
2366     rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
2367     free (arg_list);
2368     if (rc)
2369       BUG ();
2370     gcry_free (string);
2371   }
2372
2373  leave:
2374   if (pkey)
2375     {
2376       release_mpi_array (pkey);
2377       gcry_free (pkey);
2378     }
2379
2380   if (ciph)
2381     {
2382       release_mpi_array (ciph);
2383       gcry_free (ciph);
2384     }
2385
2386   if (module)
2387     {
2388       ath_mutex_lock (&pubkeys_registered_lock);
2389       _gcry_module_release (module);
2390       ath_mutex_unlock (&pubkeys_registered_lock);
2391     }
2392
2393   gcry_free (ctx.label);
2394
2395   return gcry_error (rc);
2396 }
2397
2398 /*
2399    Do a PK decrypt operation
2400
2401    Caller has to provide a secret key as the SEXP skey and data in a
2402    format as created by gcry_pk_encrypt.  For historic reasons the
2403    function returns simply an MPI as an S-expression part; this is
2404    deprecated and the new method should be used which returns a real
2405    S-expressionl this is selected by adding at least an empty flags
2406    list to S_DATA.
2407
2408    Returns: 0 or an errorcode.
2409
2410    s_data = (enc-val
2411               [(flags [raw, pkcs1, oaep])]
2412               (<algo>
2413                 (<param_name1> <mpi>)
2414                 ...
2415                 (<param_namen> <mpi>)
2416               ))
2417    s_skey = <key-as-defined-in-sexp_to_key>
2418    r_plain= Either an incomplete S-expression without the parentheses
2419             or if the flags list is used (even if empty) a real S-expression:
2420             (value PLAIN).  In raw mode (or no flags given) the returned value
2421             is to be interpreted as a signed MPI, thus it may have an extra
2422             leading zero octet even if not included in the original data.
2423             With pkcs1 or oaep decoding enabled the returned value is a
2424             verbatim octet string.
2425  */
2426 gcry_error_t
2427 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
2428 {
2429   gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
2430   unsigned char *unpad = NULL;
2431   size_t unpadlen = 0;
2432   int modern, flags;
2433   struct pk_encoding_ctx ctx;
2434   gcry_err_code_t rc;
2435   gcry_module_t module_enc = NULL, module_key = NULL;
2436
2437   *r_plain = NULL;
2438   ctx.label = NULL;
2439
2440   REGISTER_DEFAULT_PUBKEYS;
2441
2442   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key);
2443   if (rc)
2444     goto leave;
2445
2446   rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
2447   if (rc)
2448     goto leave;
2449
2450   if (module_key->mod_id != module_enc->mod_id)
2451     {
2452       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
2453       goto leave;
2454     }
2455
2456   rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
2457   if (rc)
2458     goto leave;
2459
2460   /* Do un-padding if necessary. */
2461   switch (ctx.encoding)
2462     {
2463     case PUBKEY_ENC_PKCS1:
2464       rc = pkcs1_decode_for_encryption (&unpad, &unpadlen,
2465                                         gcry_pk_get_nbits (s_skey), plain);
2466       mpi_free (plain);
2467       plain = NULL;
2468       if (!rc)
2469         rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
2470                                              (int)unpadlen, unpad));
2471       break;
2472
2473     case PUBKEY_ENC_OAEP:
2474       rc = oaep_decode (&unpad, &unpadlen,
2475                         gcry_pk_get_nbits (s_skey), ctx.hash_algo,
2476                         plain, ctx.label, ctx.labellen);
2477       mpi_free (plain);
2478       plain = NULL;
2479       if (!rc)
2480         rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
2481                                              (int)unpadlen, unpad));
2482       break;
2483
2484     default:
2485       /* Raw format.  For backward compatibility we need to assume a
2486          signed mpi by using the sexp format string "%m".  */
2487       rc = gcry_err_code (gcry_sexp_build
2488                           (r_plain, NULL, modern? "(value %m)" : "%m", plain));
2489       break;
2490     }
2491
2492  leave:
2493   gcry_free (unpad);
2494
2495   if (skey)
2496     {
2497       release_mpi_array (skey);
2498       gcry_free (skey);
2499     }
2500
2501   mpi_free (plain);
2502
2503   if (data)
2504     {
2505       release_mpi_array (data);
2506       gcry_free (data);
2507     }
2508
2509   if (module_key || module_enc)
2510     {
2511       ath_mutex_lock (&pubkeys_registered_lock);
2512       if (module_key)
2513         _gcry_module_release (module_key);
2514       if (module_enc)
2515         _gcry_module_release (module_enc);
2516       ath_mutex_unlock (&pubkeys_registered_lock);
2517     }
2518
2519   gcry_free (ctx.label);
2520
2521   return gcry_error (rc);
2522 }
2523
2524
2525
2526 /*
2527    Create a signature.
2528
2529    Caller has to provide a secret key as the SEXP skey and data
2530    expressed as a SEXP list hash with only one element which should
2531    instantly be available as a MPI. Alternatively the structure given
2532    below may be used for S_HASH, it provides the abiliy to pass flags
2533    to the operation; the only flag defined by now is "pkcs1" which
2534    does PKCS#1 block type 1 style padding.
2535
2536    Returns: 0 or an errorcode.
2537             In case of 0 the function returns a new SEXP with the
2538             signature value; the structure of this signature depends on the
2539             other arguments but is always suitable to be passed to
2540             gcry_pk_verify
2541
2542    s_hash = See comment for sexp_data_to_mpi
2543
2544    s_skey = <key-as-defined-in-sexp_to_key>
2545    r_sig  = (sig-val
2546               (<algo>
2547                 (<param_name1> <mpi>)
2548                 ...
2549                 (<param_namen> <mpi>))
2550              [(hash algo)])
2551
2552   Note that (hash algo) in R_SIG is not used.
2553 */
2554 gcry_error_t
2555 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
2556 {
2557   gcry_mpi_t *skey = NULL, hash = NULL, *result = NULL;
2558   gcry_pk_spec_t *pubkey = NULL;
2559   gcry_module_t module = NULL;
2560   const char *algo_name, *algo_elems;
2561   int i;
2562   gcry_err_code_t rc;
2563
2564   *r_sig = NULL;
2565
2566   REGISTER_DEFAULT_PUBKEYS;
2567
2568   rc = sexp_to_key (s_skey, 1, NULL, &skey, &module);
2569   if (rc)
2570     goto leave;
2571
2572   gcry_assert (module);
2573   pubkey = (gcry_pk_spec_t *) module->spec;
2574   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2575   if (!algo_name || !*algo_name)
2576     algo_name = pubkey->name;
2577
2578   algo_elems = pubkey->elements_sig;
2579
2580   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
2581       work on a private key. */
2582   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
2583                              &hash, 0, NULL, NULL);
2584   if (rc)
2585     goto leave;
2586
2587   result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
2588   if (!result)
2589     {
2590       rc = gpg_err_code_from_syserror ();
2591       goto leave;
2592     }
2593   rc = pubkey_sign (module->mod_id, result, hash, skey);
2594   if (rc)
2595     goto leave;
2596
2597   {
2598     char *string, *p;
2599     size_t nelem, needed = strlen (algo_name) + 20;
2600     void **arg_list;
2601
2602     nelem = strlen (algo_elems);
2603
2604     /* Count elements, so that we can allocate enough space. */
2605     needed += 10 * nelem;
2606
2607     /* Build the string. */
2608     string = p = gcry_malloc (needed);
2609     if (!string)
2610       {
2611         rc = gpg_err_code_from_syserror ();
2612         goto leave;
2613       }
2614     p = stpcpy (p, "(sig-val(");
2615     p = stpcpy (p, algo_name);
2616     for (i = 0; algo_elems[i]; i++)
2617       {
2618         *p++ = '(';
2619         *p++ = algo_elems[i];
2620         p = stpcpy (p, "%m)");
2621       }
2622     strcpy (p, "))");
2623
2624     arg_list = malloc (nelem * sizeof *arg_list);
2625     if (!arg_list)
2626       {
2627         rc = gpg_err_code_from_syserror ();
2628         goto leave;
2629       }
2630
2631     for (i = 0; i < nelem; i++)
2632       arg_list[i] = result + i;
2633
2634     rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
2635     free (arg_list);
2636     if (rc)
2637       BUG ();
2638     gcry_free (string);
2639   }
2640
2641  leave:
2642   if (skey)
2643     {
2644       release_mpi_array (skey);
2645       gcry_free (skey);
2646     }
2647
2648   if (hash)
2649     mpi_free (hash);
2650
2651   if (result)
2652     {
2653       release_mpi_array (result);
2654       gcry_free (result);
2655     }
2656
2657   return gcry_error (rc);
2658 }
2659
2660
2661 /*
2662    Verify a signature.
2663
2664    Caller has to supply the public key pkey, the signature sig and his
2665    hashvalue data.  Public key has to be a standard public key given
2666    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
2667    must be an S-Exp like the one in sign too.  */
2668 gcry_error_t
2669 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
2670 {
2671   gcry_module_t module_key = NULL, module_sig = NULL;
2672   gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
2673   gcry_err_code_t rc;
2674
2675   REGISTER_DEFAULT_PUBKEYS;
2676
2677   rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module_key);
2678   if (rc)
2679     goto leave;
2680
2681   rc = sexp_to_sig (s_sig, &sig, &module_sig);
2682   if (rc)
2683     goto leave;
2684
2685   /* Fixme: Check that the algorithm of S_SIG is compatible to the one
2686      of S_PKEY.  */
2687
2688   if (module_key->mod_id != module_sig->mod_id)
2689     {
2690       rc = GPG_ERR_CONFLICT;
2691       goto leave;
2692     }
2693
2694   rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0, NULL);
2695   if (rc)
2696     goto leave;
2697
2698   rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
2699
2700  leave:
2701   if (pkey)
2702     {
2703       release_mpi_array (pkey);
2704       gcry_free (pkey);
2705     }
2706   if (sig)
2707     {
2708       release_mpi_array (sig);
2709       gcry_free (sig);
2710     }
2711   if (hash)
2712     mpi_free (hash);
2713
2714   if (module_key || module_sig)
2715     {
2716       ath_mutex_lock (&pubkeys_registered_lock);
2717       if (module_key)
2718         _gcry_module_release (module_key);
2719       if (module_sig)
2720         _gcry_module_release (module_sig);
2721       ath_mutex_unlock (&pubkeys_registered_lock);
2722     }
2723
2724   return gcry_error (rc);
2725 }
2726
2727
2728 /*
2729    Test a key.
2730
2731    This may be used either for a public or a secret key to see whether
2732    the internal structure is okay.
2733
2734    Returns: 0 or an errorcode.
2735
2736    s_key = <key-as-defined-in-sexp_to_key> */
2737 gcry_error_t
2738 gcry_pk_testkey (gcry_sexp_t s_key)
2739 {
2740   gcry_module_t module = NULL;
2741   gcry_mpi_t *key = NULL;
2742   gcry_err_code_t rc;
2743
2744   REGISTER_DEFAULT_PUBKEYS;
2745
2746   /* Note we currently support only secret key checking. */
2747   rc = sexp_to_key (s_key, 1, NULL, &key, &module);
2748   if (! rc)
2749     {
2750       rc = pubkey_check_secret_key (module->mod_id, key);
2751       release_mpi_array (key);
2752       gcry_free (key);
2753     }
2754   return gcry_error (rc);
2755 }
2756
2757
2758 /*
2759   Create a public key pair and return it in r_key.
2760   How the key is created depends on s_parms:
2761   (genkey
2762    (algo
2763      (parameter_name_1 ....)
2764       ....
2765      (parameter_name_n ....)
2766   ))
2767   The key is returned in a format depending on the
2768   algorithm. Both, private and secret keys are returned
2769   and optionally some additional informatin.
2770   For elgamal we return this structure:
2771   (key-data
2772    (public-key
2773      (elg
2774         (p <mpi>)
2775         (g <mpi>)
2776         (y <mpi>)
2777      )
2778    )
2779    (private-key
2780      (elg
2781         (p <mpi>)
2782         (g <mpi>)
2783         (y <mpi>)
2784         (x <mpi>)
2785      )
2786    )
2787    (misc-key-info
2788       (pm1-factors n1 n2 ... nn)
2789    ))
2790  */
2791 gcry_error_t
2792 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
2793 {
2794   gcry_pk_spec_t *pubkey = NULL;
2795   gcry_module_t module = NULL;
2796   gcry_sexp_t list = NULL;
2797   gcry_sexp_t l2 = NULL;
2798   gcry_sexp_t l3 = NULL;
2799   char *name = NULL;
2800   size_t n;
2801   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
2802   int i, j;
2803   const char *algo_name = NULL;
2804   int algo;
2805   const char *sec_elems = NULL, *pub_elems = NULL;
2806   gcry_mpi_t skey[12];
2807   gcry_mpi_t *factors = NULL;
2808   gcry_sexp_t extrainfo = NULL;
2809   unsigned int nbits = 0;
2810   unsigned long use_e = 0;
2811
2812   skey[0] = NULL;
2813   *r_key = NULL;
2814
2815   REGISTER_DEFAULT_PUBKEYS;
2816
2817   list = gcry_sexp_find_token (s_parms, "genkey", 0);
2818   if (!list)
2819     {
2820       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
2821       goto leave;
2822     }
2823
2824   l2 = gcry_sexp_cadr (list);
2825   gcry_sexp_release (list);
2826   list = l2;
2827   l2 = NULL;
2828   if (! list)
2829     {
2830       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
2831       goto leave;
2832     }
2833
2834   name = _gcry_sexp_nth_string (list, 0);
2835   if (!name)
2836     {
2837       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
2838       goto leave;
2839     }
2840
2841   ath_mutex_lock (&pubkeys_registered_lock);
2842   module = gcry_pk_lookup_name (name);
2843   ath_mutex_unlock (&pubkeys_registered_lock);
2844   gcry_free (name);
2845   name = NULL;
2846   if (!module)
2847     {
2848       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
2849       goto leave;
2850     }
2851
2852   pubkey = (gcry_pk_spec_t *) module->spec;
2853   algo = module->mod_id;
2854   algo_name = pubkey->aliases? *pubkey->aliases : NULL;
2855   if (!algo_name || !*algo_name)
2856     algo_name = pubkey->name;
2857   pub_elems = pubkey->elements_pkey;
2858   sec_elems = pubkey->elements_skey;
2859   if (strlen (sec_elems) >= DIM(skey))
2860     BUG ();
2861
2862   /* Handle the optional rsa-use-e element.  Actually this belong into
2863      the algorithm module but we have this parameter in the public
2864      module API, so we need to parse it right here.  */
2865   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
2866   if (l2)
2867     {
2868       char buf[50];
2869       const char *s;
2870
2871       s = gcry_sexp_nth_data (l2, 1, &n);
2872       if ( !s || n >= DIM (buf) - 1 )
2873         {
2874           rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
2875           goto leave;
2876         }
2877       memcpy (buf, s, n);
2878       buf[n] = 0;
2879       use_e = strtoul (buf, NULL, 0);
2880       gcry_sexp_release (l2);
2881       l2 = NULL;
2882     }
2883   else
2884     use_e = 65537; /* Not given, use the value generated by old versions. */
2885
2886
2887   /* Get the "nbits" parameter.  */
2888   l2 = gcry_sexp_find_token (list, "nbits", 0);
2889   if (l2)
2890     {
2891       char buf[50];
2892       const char *s;
2893
2894       s = gcry_sexp_nth_data (l2, 1, &n);
2895       if (!s || n >= DIM (buf) - 1 )
2896         {
2897           rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
2898           goto leave;
2899         }
2900       memcpy (buf, s, n);
2901       buf[n] = 0;
2902       nbits = (unsigned int)strtoul (buf, NULL, 0);
2903       gcry_sexp_release (l2); l2 = NULL;
2904     }
2905   else
2906     nbits = 0;
2907
2908   /* Pass control to the algorithm module. */
2909   rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
2910                         &factors, &extrainfo);
2911   gcry_sexp_release (list); list = NULL;
2912   if (rc)
2913     goto leave;
2914
2915   /* Key generation succeeded: Build an S-expression.  */
2916   {
2917     char *string, *p;
2918     size_t nelem=0, nelem_cp = 0, needed=0;
2919     gcry_mpi_t mpis[30];
2920     int percent_s_idx = -1;
2921
2922     /* Estimate size of format string.  */
2923     nelem = strlen (pub_elems) + strlen (sec_elems);
2924     if (factors)
2925       {
2926         for (i = 0; factors[i]; i++)
2927           nelem++;
2928       }
2929     nelem_cp = nelem;
2930
2931     needed += nelem * 10;
2932     /* (+5 is for EXTRAINFO ("%S")).  */
2933     needed += 2 * strlen (algo_name) + 300 + 5;
2934     if (nelem > DIM (mpis))
2935       BUG ();
2936
2937     /* Build the string. */
2938     nelem = 0;
2939     string = p = gcry_malloc (needed);
2940     if (!string)
2941       {
2942         rc = gpg_err_code_from_syserror ();
2943         goto leave;
2944       }
2945     p = stpcpy (p, "(key-data");
2946     p = stpcpy (p, "(public-key(");
2947     p = stpcpy (p, algo_name);
2948     for(i = 0; pub_elems[i]; i++)
2949       {
2950         *p++ = '(';
2951         *p++ = pub_elems[i];
2952         p = stpcpy (p, "%m)");
2953         mpis[nelem++] = skey[i];
2954       }
2955     if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
2956       {
2957         /* Very ugly hack to insert the used curve parameter into the
2958            list of public key parameters.  */
2959         percent_s_idx = nelem;
2960         p = stpcpy (p, "%S");
2961       }
2962     p = stpcpy (p, "))");
2963     p = stpcpy (p, "(private-key(");
2964     p = stpcpy (p, algo_name);
2965     for (i = 0; sec_elems[i]; i++)
2966       {
2967         *p++ = '(';
2968         *p++ = sec_elems[i];
2969         p = stpcpy (p, "%m)");
2970         mpis[nelem++] = skey[i];
2971       }
2972     p = stpcpy (p, "))");
2973
2974     /* Hack to make release_mpi_array() work.  */
2975     skey[i] = NULL;
2976
2977     if (extrainfo && percent_s_idx == -1)
2978       {
2979         /* If we have extrainfo we should not have any factors.  */
2980         p = stpcpy (p, "%S");
2981       }
2982     else if (factors && factors[0])
2983       {
2984         p = stpcpy (p, "(misc-key-info(pm1-factors");
2985         for(i = 0; factors[i]; i++)
2986           {
2987             p = stpcpy (p, "%m");
2988             mpis[nelem++] = factors[i];
2989           }
2990         p = stpcpy (p, "))");
2991       }
2992     strcpy (p, ")");
2993     gcry_assert (p - string < needed);
2994
2995     while (nelem < DIM (mpis))
2996       mpis[nelem++] = NULL;
2997
2998     {
2999       int elem_n = strlen (pub_elems) + strlen (sec_elems);
3000       void **arg_list;
3001
3002       /* Allocate one extra for EXTRAINFO ("%S").  */
3003       arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
3004       if (!arg_list)
3005         {
3006           rc = gpg_err_code_from_syserror ();
3007           goto leave;
3008         }
3009       for (i = j = 0; i < elem_n; i++)
3010         {
3011           if (i == percent_s_idx)
3012             arg_list[j++] = &extrainfo;
3013           arg_list[j++] = mpis + i;
3014         }
3015       if (extrainfo && percent_s_idx == -1)
3016         arg_list[j] = &extrainfo;
3017       else if (factors && factors[0])
3018         {
3019           for (; i < nelem_cp; i++)
3020             arg_list[j++] = factors + i - elem_n;
3021         }
3022       rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
3023       gcry_free (arg_list);
3024       if (rc)
3025         BUG ();
3026       gcry_assert (DIM (mpis) == 30); /* Reminder to make sure that
3027                                          the array gets increased if
3028                                          new parameters are added. */
3029     }
3030     gcry_free (string);
3031   }
3032
3033  leave:
3034   gcry_free (name);
3035   gcry_sexp_release (extrainfo);
3036   release_mpi_array (skey);
3037   /* Don't free SKEY itself, it is an stack allocated array. */
3038
3039   if (factors)
3040     {
3041       release_mpi_array ( factors );
3042       gcry_free (factors);
3043     }
3044
3045   gcry_sexp_release (l3);
3046   gcry_sexp_release (l2);
3047   gcry_sexp_release (list);
3048
3049   if (module)
3050     {
3051       ath_mutex_lock (&pubkeys_registered_lock);
3052       _gcry_module_release (module);
3053       ath_mutex_unlock (&pubkeys_registered_lock);
3054     }
3055
3056   return gcry_error (rc);
3057 }
3058
3059
3060 /*
3061    Get the number of nbits from the public key.
3062
3063    Hmmm: Should we have really this function or is it better to have a
3064    more general function to retrieve different properties of the key?  */
3065 unsigned int
3066 gcry_pk_get_nbits (gcry_sexp_t key)
3067 {
3068   gcry_module_t module = NULL;
3069   gcry_pk_spec_t *pubkey;
3070   gcry_mpi_t *keyarr = NULL;
3071   unsigned int nbits = 0;
3072   gcry_err_code_t rc;
3073
3074   REGISTER_DEFAULT_PUBKEYS;
3075
3076   rc = sexp_to_key (key, 0, NULL, &keyarr, &module);
3077   if (rc == GPG_ERR_INV_OBJ)
3078     rc = sexp_to_key (key, 1, NULL, &keyarr, &module);
3079   if (rc)
3080     return 0; /* Error - 0 is a suitable indication for that. */
3081
3082   pubkey = (gcry_pk_spec_t *) module->spec;
3083   nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
3084
3085   ath_mutex_lock (&pubkeys_registered_lock);
3086   _gcry_module_release (module);
3087   ath_mutex_unlock (&pubkeys_registered_lock);
3088
3089   release_mpi_array (keyarr);
3090   gcry_free (keyarr);
3091
3092   return nbits;
3093 }
3094
3095
3096 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
3097    key parameters expressed in a way depending on the algorithm.
3098
3099    ARRAY must either be 20 bytes long or NULL; in the latter case a
3100    newly allocated array of that size is returned, otherwise ARRAY or
3101    NULL is returned to indicate an error which is most likely an
3102    unknown algorithm.  The function accepts public or secret keys. */
3103 unsigned char *
3104 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
3105 {
3106   gcry_sexp_t list = NULL, l2 = NULL;
3107   gcry_pk_spec_t *pubkey = NULL;
3108   gcry_module_t module = NULL;
3109   pk_extra_spec_t *extraspec;
3110   const char *s;
3111   char *name = NULL;
3112   int idx;
3113   const char *elems;
3114   gcry_md_hd_t md = NULL;
3115   int okay = 0;
3116
3117   REGISTER_DEFAULT_PUBKEYS;
3118
3119   /* Check that the first element is valid. */
3120   list = gcry_sexp_find_token (key, "public-key", 0);
3121   if (! list)
3122     list = gcry_sexp_find_token (key, "private-key", 0);
3123   if (! list)
3124     list = gcry_sexp_find_token (key, "protected-private-key", 0);
3125   if (! list)
3126     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
3127   if (! list)
3128     return NULL; /* No public- or private-key object. */
3129
3130   l2 = gcry_sexp_cadr (list);
3131   gcry_sexp_release (list);
3132   list = l2;
3133   l2 = NULL;
3134
3135   name = _gcry_sexp_nth_string (list, 0);
3136   if (!name)
3137     goto fail; /* Invalid structure of object. */
3138
3139   ath_mutex_lock (&pubkeys_registered_lock);
3140   module = gcry_pk_lookup_name (name);
3141   ath_mutex_unlock (&pubkeys_registered_lock);
3142
3143   if (!module)
3144     goto fail; /* Unknown algorithm.  */
3145
3146   pubkey = (gcry_pk_spec_t *) module->spec;
3147   extraspec = module->extraspec;
3148
3149   elems = pubkey->elements_grip;
3150   if (!elems)
3151     goto fail; /* No grip parameter.  */
3152
3153   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
3154     goto fail;
3155
3156   if (extraspec && extraspec->comp_keygrip)
3157     {
3158       /* Module specific method to compute a keygrip.  */
3159       if (extraspec->comp_keygrip (md, list))
3160         goto fail;
3161     }
3162   else
3163     {
3164       /* Generic method to compute a keygrip.  */
3165       for (idx = 0, s = elems; *s; s++, idx++)
3166         {
3167           const char *data;
3168           size_t datalen;
3169           char buf[30];
3170
3171           l2 = gcry_sexp_find_token (list, s, 1);
3172           if (! l2)
3173             goto fail;
3174           data = gcry_sexp_nth_data (l2, 1, &datalen);
3175           if (! data)
3176             goto fail;
3177
3178           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
3179           gcry_md_write (md, buf, strlen (buf));
3180           gcry_md_write (md, data, datalen);
3181           gcry_sexp_release (l2);
3182           l2 = NULL;
3183           gcry_md_write (md, ")", 1);
3184         }
3185     }
3186
3187   if (!array)
3188     {
3189       array = gcry_malloc (20);
3190       if (! array)
3191         goto fail;
3192     }
3193
3194   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
3195   okay = 1;
3196
3197  fail:
3198   gcry_free (name);
3199   gcry_sexp_release (l2);
3200   gcry_md_close (md);
3201   gcry_sexp_release (list);
3202   return okay? array : NULL;
3203 }
3204
3205
3206 \f
3207 const char *
3208 gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
3209 {
3210   gcry_mpi_t *pkey = NULL;
3211   gcry_sexp_t list = NULL;
3212   gcry_sexp_t l2;
3213   gcry_module_t module = NULL;
3214   pk_extra_spec_t *extraspec;
3215   char *name = NULL;
3216   const char *result = NULL;
3217   int want_private = 1;
3218
3219   if (r_nbits)
3220     *r_nbits = 0;
3221
3222   REGISTER_DEFAULT_PUBKEYS;
3223
3224   if (key)
3225     {
3226       iterator = 0;
3227
3228       /* Check that the first element is valid. */
3229       list = gcry_sexp_find_token (key, "public-key", 0);
3230       if (list)
3231         want_private = 0;
3232       if (!list)
3233         list = gcry_sexp_find_token (key, "private-key", 0);
3234       if (!list)
3235         return NULL; /* No public- or private-key object. */
3236
3237       l2 = gcry_sexp_cadr (list);
3238       gcry_sexp_release (list);
3239       list = l2;
3240       l2 = NULL;
3241
3242       name = _gcry_sexp_nth_string (list, 0);
3243       if (!name)
3244         goto leave; /* Invalid structure of object. */
3245
3246       /* Get the key.  We pass the names of the parameters for
3247          override_elems; this allows to call this function without the
3248          actual public key parameter.  */
3249       if (sexp_to_key (key, want_private, "pabgn", &pkey, &module))
3250         goto leave;
3251     }
3252   else
3253     {
3254       ath_mutex_lock (&pubkeys_registered_lock);
3255       module = gcry_pk_lookup_name ("ecc");
3256       ath_mutex_unlock (&pubkeys_registered_lock);
3257       if (!module)
3258         goto leave;
3259     }
3260
3261   extraspec = module->extraspec;
3262   if (!extraspec || !extraspec->get_curve)
3263     goto leave;
3264
3265   result = extraspec->get_curve (pkey, iterator, r_nbits);
3266
3267  leave:
3268   if (pkey)
3269     {
3270       release_mpi_array (pkey);
3271       gcry_free (pkey);
3272     }
3273   if (module)
3274     {
3275       ath_mutex_lock (&pubkeys_registered_lock);
3276       _gcry_module_release (module);
3277       ath_mutex_unlock (&pubkeys_registered_lock);
3278     }
3279   gcry_free (name);
3280   gcry_sexp_release (list);
3281   return result;
3282 }
3283
3284
3285 \f
3286 gcry_sexp_t
3287 gcry_pk_get_param (int algo, const char *name)
3288 {
3289   gcry_module_t module = NULL;
3290   pk_extra_spec_t *extraspec;
3291   gcry_sexp_t result = NULL;
3292
3293   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
3294     return NULL;
3295
3296   REGISTER_DEFAULT_PUBKEYS;
3297
3298   ath_mutex_lock (&pubkeys_registered_lock);
3299   module = gcry_pk_lookup_name ("ecc");
3300   ath_mutex_unlock (&pubkeys_registered_lock);
3301   if (module)
3302     {
3303       extraspec = module->extraspec;
3304       if (extraspec && extraspec->get_curve_param)
3305         result = extraspec->get_curve_param (name);
3306
3307       ath_mutex_lock (&pubkeys_registered_lock);
3308       _gcry_module_release (module);
3309       ath_mutex_unlock (&pubkeys_registered_lock);
3310     }
3311   return result;
3312 }
3313
3314
3315 \f
3316 gcry_error_t
3317 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
3318 {
3319   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3320
3321   REGISTER_DEFAULT_PUBKEYS;
3322
3323   switch (cmd)
3324     {
3325     case GCRYCTL_DISABLE_ALGO:
3326       /* This one expects a buffer pointing to an integer with the
3327          algo number.  */
3328       if ((! buffer) || (buflen != sizeof (int)))
3329         err = GPG_ERR_INV_ARG;
3330       else
3331         disable_pubkey_algo (*((int *) buffer));
3332       break;
3333
3334     default:
3335       err = GPG_ERR_INV_OP;
3336     }
3337
3338   return gcry_error (err);
3339 }
3340
3341
3342 /* Return information about the given algorithm
3343
3344    WHAT selects the kind of information returned:
3345
3346     GCRYCTL_TEST_ALGO:
3347         Returns 0 when the specified algorithm is available for use.
3348         Buffer must be NULL, nbytes  may have the address of a variable
3349         with the required usage of the algorithm. It may be 0 for don't
3350         care or a combination of the GCRY_PK_USAGE_xxx flags;
3351
3352     GCRYCTL_GET_ALGO_USAGE:
3353         Return the usage flags for the given algo.  An invalid algo
3354         returns 0.  Disabled algos are ignored here because we
3355         only want to know whether the algo is at all capable of
3356         the usage.
3357
3358    Note: Because this function is in most cases used to return an
3359    integer value, we can make it easier for the caller to just look at
3360    the return value.  The caller will in all cases consult the value
3361    and thereby detecting whether a error occurred or not (i.e. while
3362    checking the block size) */
3363 gcry_error_t
3364 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
3365 {
3366   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3367
3368   switch (what)
3369     {
3370     case GCRYCTL_TEST_ALGO:
3371       {
3372         int use = nbytes ? *nbytes : 0;
3373         if (buffer)
3374           err = GPG_ERR_INV_ARG;
3375         else if (check_pubkey_algo (algorithm, use))
3376           err = GPG_ERR_PUBKEY_ALGO;
3377         break;
3378       }
3379
3380     case GCRYCTL_GET_ALGO_USAGE:
3381       {
3382         gcry_module_t pubkey;
3383         int use = 0;
3384
3385         REGISTER_DEFAULT_PUBKEYS;
3386
3387         ath_mutex_lock (&pubkeys_registered_lock);
3388         pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3389         if (pubkey)
3390           {
3391             use = ((gcry_pk_spec_t *) pubkey->spec)->use;
3392             _gcry_module_release (pubkey);
3393           }
3394         ath_mutex_unlock (&pubkeys_registered_lock);
3395
3396         /* FIXME? */
3397         *nbytes = use;
3398
3399         break;
3400       }
3401
3402     case GCRYCTL_GET_ALGO_NPKEY:
3403       {
3404         /* FIXME?  */
3405         int npkey = pubkey_get_npkey (algorithm);
3406         *nbytes = npkey;
3407         break;
3408       }
3409     case GCRYCTL_GET_ALGO_NSKEY:
3410       {
3411         /* FIXME?  */
3412         int nskey = pubkey_get_nskey (algorithm);
3413         *nbytes = nskey;
3414         break;
3415       }
3416     case GCRYCTL_GET_ALGO_NSIGN:
3417       {
3418         /* FIXME?  */
3419         int nsign = pubkey_get_nsig (algorithm);
3420         *nbytes = nsign;
3421         break;
3422       }
3423     case GCRYCTL_GET_ALGO_NENCR:
3424       {
3425         /* FIXME?  */
3426         int nencr = pubkey_get_nenc (algorithm);
3427         *nbytes = nencr;
3428         break;
3429       }
3430
3431     default:
3432       err = GPG_ERR_INV_OP;
3433     }
3434
3435   return gcry_error (err);
3436 }
3437
3438
3439 /* Explicitly initialize this module.  */
3440 gcry_err_code_t
3441 _gcry_pk_init (void)
3442 {
3443   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3444
3445   REGISTER_DEFAULT_PUBKEYS;
3446
3447   return err;
3448 }
3449
3450
3451 gcry_err_code_t
3452 _gcry_pk_module_lookup (int algorithm, gcry_module_t *module)
3453 {
3454   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3455   gcry_module_t pubkey;
3456
3457   REGISTER_DEFAULT_PUBKEYS;
3458
3459   ath_mutex_lock (&pubkeys_registered_lock);
3460   pubkey = _gcry_module_lookup_id (pubkeys_registered, algorithm);
3461   if (pubkey)
3462     *module = pubkey;
3463   else
3464     err = GPG_ERR_PUBKEY_ALGO;
3465   ath_mutex_unlock (&pubkeys_registered_lock);
3466
3467   return err;
3468 }
3469
3470
3471 void
3472 _gcry_pk_module_release (gcry_module_t module)
3473 {
3474   ath_mutex_lock (&pubkeys_registered_lock);
3475   _gcry_module_release (module);
3476   ath_mutex_unlock (&pubkeys_registered_lock);
3477 }
3478
3479 /* Get a list consisting of the IDs of the loaded pubkey modules.  If
3480    LIST is zero, write the number of loaded pubkey modules to
3481    LIST_LENGTH and return.  If LIST is non-zero, the first
3482    *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
3483    according size.  In case there are less pubkey modules than
3484    *LIST_LENGTH, *LIST_LENGTH is updated to the correct number.  */
3485 gcry_error_t
3486 gcry_pk_list (int *list, int *list_length)
3487 {
3488   gcry_err_code_t err = GPG_ERR_NO_ERROR;
3489
3490   ath_mutex_lock (&pubkeys_registered_lock);
3491   err = _gcry_module_list (pubkeys_registered, list, list_length);
3492   ath_mutex_unlock (&pubkeys_registered_lock);
3493
3494   return err;
3495 }
3496
3497
3498 /* Run the selftests for pubkey algorithm ALGO with optional reporting
3499    function REPORT.  */
3500 gpg_error_t
3501 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
3502 {
3503   gcry_module_t module = NULL;
3504   pk_extra_spec_t *extraspec = NULL;
3505   gcry_err_code_t ec = 0;
3506
3507   REGISTER_DEFAULT_PUBKEYS;
3508
3509   ath_mutex_lock (&pubkeys_registered_lock);
3510   module = _gcry_module_lookup_id (pubkeys_registered, algo);
3511   if (module && !(module->flags & FLAG_MODULE_DISABLED))
3512     extraspec = module->extraspec;
3513   ath_mutex_unlock (&pubkeys_registered_lock);
3514   if (extraspec && extraspec->selftest)
3515     ec = extraspec->selftest (algo, extended, report);
3516   else
3517     {
3518       ec = GPG_ERR_PUBKEY_ALGO;
3519       if (report)
3520         report ("pubkey", algo, "module",
3521                 module && !(module->flags & FLAG_MODULE_DISABLED)?
3522                 "no selftest available" :
3523                 module? "algorithm disabled" : "algorithm not found");
3524     }
3525
3526   if (module)
3527     {
3528       ath_mutex_lock (&pubkeys_registered_lock);
3529       _gcry_module_release (module);
3530       ath_mutex_unlock (&pubkeys_registered_lock);
3531     }
3532   return gpg_error (ec);
3533 }
3534
3535
3536 /* This function is only used by ac.c!  */
3537 gcry_err_code_t
3538 _gcry_pk_get_elements (int algo, char **enc, char **sig)
3539 {
3540   gcry_module_t pubkey;
3541   gcry_pk_spec_t *spec;
3542   gcry_err_code_t err;
3543   char *enc_cp;
3544   char *sig_cp;
3545
3546   REGISTER_DEFAULT_PUBKEYS;
3547
3548   enc_cp = NULL;
3549   sig_cp = NULL;
3550   spec = NULL;
3551
3552   pubkey = _gcry_module_lookup_id (pubkeys_registered, algo);
3553   if (! pubkey)
3554     {
3555       err = GPG_ERR_INTERNAL;
3556       goto out;
3557     }
3558   spec = pubkey->spec;
3559
3560   if (enc)
3561     {
3562       enc_cp = strdup (spec->elements_enc);
3563       if (! enc_cp)
3564         {
3565           err = gpg_err_code_from_syserror ();
3566           goto out;
3567         }
3568     }
3569
3570   if (sig)
3571     {
3572       sig_cp = strdup (spec->elements_sig);
3573       if (! sig_cp)
3574         {
3575           err = gpg_err_code_from_syserror ();
3576           goto out;
3577         }
3578     }
3579
3580   if (enc)
3581     *enc = enc_cp;
3582   if (sig)
3583     *sig = sig_cp;
3584   err = 0;
3585
3586  out:
3587
3588   _gcry_module_release (pubkey);
3589   if (err)
3590     {
3591       free (enc_cp);
3592       free (sig_cp);
3593     }
3594
3595   return err;
3596 }