pk: Move s-exp creation for gcry_pk_decrypt to the modules.
[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  * Copyright (C) 2013 g10 Code GmbH
5  *
6  * This file is part of Libgcrypt.
7  *
8  * Libgcrypt is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser general Public License as
10  * published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * Libgcrypt is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include "g10lib.h"
29 #include "mpi.h"
30 #include "cipher.h"
31 #include "ath.h"
32 #include "context.h"
33 #include "pubkey-internal.h"
34
35
36 /* This is the list of the public-key algorithms included in
37    Libgcrypt.  */
38 static gcry_pk_spec_t *pubkey_list[] =
39   {
40 #if USE_ECC
41     &_gcry_pubkey_spec_ecdsa,
42     &_gcry_pubkey_spec_ecdh,
43 #endif
44 #if USE_RSA
45     &_gcry_pubkey_spec_rsa,
46 #endif
47 #if USE_DSA
48     &_gcry_pubkey_spec_dsa,
49 #endif
50 #if USE_ELGAMAL
51     &_gcry_pubkey_spec_elg,
52     &_gcry_pubkey_spec_elg,
53 #endif
54     NULL
55   };
56
57
58 /* Return the spec structure for the public key algorithm ALGO.  For
59    an unknown algorithm NULL is returned.  */
60 static gcry_pk_spec_t *
61 spec_from_algo (int algo)
62 {
63   int idx;
64   gcry_pk_spec_t *spec;
65
66   for (idx = 0; (spec = pubkey_list[idx]); idx++)
67     if (algo == spec->algo)
68       return spec;
69   return NULL;
70 }
71
72
73 /* Return the spec structure for the public key algorithm with NAME.
74    For an unknown name NULL is returned.  */
75 static gcry_pk_spec_t *
76 spec_from_name (const char *name)
77 {
78   gcry_pk_spec_t *spec;
79   int idx;
80   const char **aliases;
81
82   for (idx=0; (spec = pubkey_list[idx]); idx++)
83     {
84       if (!stricmp (name, spec->name))
85         return spec;
86       for (aliases = spec->aliases; *aliases; aliases++)
87         if (!stricmp (name, *aliases))
88           return spec;
89     }
90
91   return NULL;
92 }
93
94
95 /* Disable the use of the algorithm ALGO.  This is not thread safe and
96    should thus be called early.  */
97 static void
98 disable_pubkey_algo (int algo)
99 {
100   gcry_pk_spec_t *spec = spec_from_algo (algo);
101
102   if (spec)
103     spec->flags.disabled = 1;
104 }
105
106
107 \f
108 /* Free the MPIs stored in the NULL terminated ARRAY of MPIs and set
109    the slots to NULL.  */
110 static void
111 release_mpi_array (gcry_mpi_t *array)
112 {
113   for (; *array; array++)
114     {
115       mpi_free(*array);
116       *array = NULL;
117     }
118 }
119
120
121 \f
122 /*
123  * Map a string to the pubkey algo
124  */
125 int
126 gcry_pk_map_name (const char *string)
127 {
128   gcry_pk_spec_t *spec;
129
130   if (!string)
131     return 0;
132   spec = spec_from_name (string);
133   if (!spec)
134     return 0;
135   if (spec->flags.disabled)
136     return 0;
137   return spec->algo;
138 }
139
140
141 /* Map the public key algorithm whose ID is contained in ALGORITHM to
142    a string representation of the algorithm name.  For unknown
143    algorithm IDs this functions returns "?". */
144 const char *
145 gcry_pk_algo_name (int algo)
146 {
147   gcry_pk_spec_t *spec;
148
149   spec = spec_from_algo (algo);
150   if (spec)
151     return spec->name;
152   return "?";
153 }
154
155
156 /****************
157  * A USE of 0 means: don't care.
158  */
159 static gcry_err_code_t
160 check_pubkey_algo (int algo, unsigned use)
161 {
162   gcry_err_code_t err = 0;
163   gcry_pk_spec_t *spec;
164
165   spec = spec_from_algo (algo);
166   if (spec)
167     {
168       if (((use & GCRY_PK_USAGE_SIGN)
169            && (! (spec->use & GCRY_PK_USAGE_SIGN)))
170           || ((use & GCRY_PK_USAGE_ENCR)
171               && (! (spec->use & GCRY_PK_USAGE_ENCR))))
172         err = GPG_ERR_WRONG_PUBKEY_ALGO;
173     }
174   else
175     err = GPG_ERR_PUBKEY_ALGO;
176
177   return err;
178 }
179
180
181 /****************
182  * Return the number of public key material numbers
183  */
184 static int
185 pubkey_get_npkey (int algo)
186 {
187   gcry_pk_spec_t *spec = spec_from_algo (algo);
188
189   return spec? strlen (spec->elements_pkey) : 0;
190 }
191
192
193 /****************
194  * Return the number of secret key material numbers
195  */
196 static int
197 pubkey_get_nskey (int algo)
198 {
199   gcry_pk_spec_t *spec = spec_from_algo (algo);
200
201   return spec? strlen (spec->elements_skey) : 0;
202 }
203
204
205 /****************
206  * Return the number of signature material numbers
207  */
208 static int
209 pubkey_get_nsig (int algo)
210 {
211   gcry_pk_spec_t *spec = spec_from_algo (algo);
212
213   return spec? strlen (spec->elements_sig) : 0;
214 }
215
216 /****************
217  * Return the number of encryption material numbers
218  */
219 static int
220 pubkey_get_nenc (int algo)
221 {
222   gcry_pk_spec_t *spec = spec_from_algo (algo);
223
224   return spec? strlen (spec->elements_enc) : 0;
225 }
226
227
228 static gcry_err_code_t
229 pubkey_check_secret_key (int algo, gcry_mpi_t *skey)
230 {
231   gcry_err_code_t rc;
232   gcry_pk_spec_t *spec = spec_from_algo (algo);
233
234   if (spec && spec->check_secret_key)
235     rc = spec->check_secret_key (algo, skey);
236   else if (spec)
237     rc = GPG_ERR_NOT_IMPLEMENTED;
238   else
239     rc = GPG_ERR_PUBKEY_ALGO;
240
241   return rc;
242 }
243
244
245 /* Internal function.   */
246 static gcry_err_code_t
247 sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
248                        gcry_mpi_t *elements, const char *algo_name, int opaque)
249 {
250   gcry_err_code_t err = 0;
251   int i, idx;
252   const char *name;
253   gcry_sexp_t list;
254
255   for (name = element_names, idx = 0; *name && !err; name++, idx++)
256     {
257       list = gcry_sexp_find_token (key_sexp, name, 1);
258       if (!list)
259         elements[idx] = NULL;
260       else if (opaque)
261         {
262           elements[idx] = _gcry_sexp_nth_opaque_mpi (list, 1);
263           gcry_sexp_release (list);
264           if (!elements[idx])
265             err = GPG_ERR_INV_OBJ;
266         }
267       else
268         {
269           elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_USG);
270           gcry_sexp_release (list);
271           if (!elements[idx])
272             err = GPG_ERR_INV_OBJ;
273         }
274     }
275
276   if (!err)
277     {
278       /* Check that all elements are available.  */
279       for (name = element_names, i = 0; *name; name++, i++)
280         if (!elements[i])
281           break;
282       if (*name)
283         {
284           err = GPG_ERR_NO_OBJ;
285           /* Some are missing.  Before bailing out we test for
286              optional parameters.  */
287           if (algo_name && !strcmp (algo_name, "RSA")
288               && !strcmp (element_names, "nedpqu") )
289             {
290               /* This is RSA.  Test whether we got N, E and D and that
291                  the optional P, Q and U are all missing.  */
292               if (elements[0] && elements[1] && elements[2]
293                   && !elements[3] && !elements[4] && !elements[5])
294                 err = 0;
295             }
296         }
297     }
298
299
300   if (err)
301     {
302       for (i = 0; i < idx; i++)
303         if (elements[i])
304           mpi_free (elements[i]);
305     }
306   return err;
307 }
308
309
310 /* Internal function used for ecc.  Note, that this function makes use
311    of its intimate knowledge about the ECC parameters from ecc.c. */
312 static gcry_err_code_t
313 sexp_elements_extract_ecc (gcry_sexp_t key_sexp, const char *element_names,
314                            gcry_mpi_t *elements, gcry_pk_spec_t *spec,
315                            int want_private)
316
317 {
318   gcry_err_code_t err = 0;
319   int idx;
320   const char *name;
321   gcry_sexp_t list;
322
323   /* Clear the array for easier error cleanup. */
324   for (name = element_names, idx = 0; *name; name++, idx++)
325     elements[idx] = NULL;
326   gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements
327                              (params only) or 6 (full public key).  */
328   if (idx == 5)
329     elements[5] = NULL;   /* Extra clear for the params only case.  */
330
331
332   /* Init the array with the available curve parameters. */
333   for (name = element_names, idx = 0; *name && !err; name++, idx++)
334     {
335       list = gcry_sexp_find_token (key_sexp, name, 1);
336       if (!list)
337         elements[idx] = NULL;
338       else
339         {
340           switch (idx)
341             {
342             case 5: /* The public and */
343             case 6: /* the secret key must to be passed opaque.  */
344               elements[idx] = _gcry_sexp_nth_opaque_mpi (list, 1);
345               break;
346             default:
347               elements[idx] = gcry_sexp_nth_mpi (list, 1, GCRYMPI_FMT_STD);
348               break;
349             }
350           gcry_sexp_release (list);
351           if (!elements[idx])
352             {
353               err = GPG_ERR_INV_OBJ;
354               goto leave;
355             }
356         }
357     }
358
359   /* Check whether a curve parameter has been given and then fill any
360      missing elements.  */
361   list = gcry_sexp_find_token (key_sexp, "curve", 5);
362   if (list)
363     {
364       if (spec->get_param)
365         {
366           char *curve;
367           gcry_mpi_t params[6];
368
369           for (idx = 0; idx < DIM(params); idx++)
370             params[idx] = NULL;
371
372           curve = _gcry_sexp_nth_string (list, 1);
373           gcry_sexp_release (list);
374           if (!curve)
375             {
376               /* No curve name given (or out of core). */
377               err = GPG_ERR_INV_OBJ;
378               goto leave;
379             }
380           err = spec->get_param (curve, params);
381           gcry_free (curve);
382           if (err)
383             goto leave;
384
385           for (idx = 0; idx < DIM(params); idx++)
386             {
387               if (!elements[idx])
388                 elements[idx] = params[idx];
389               else
390                 mpi_free (params[idx]);
391             }
392         }
393       else
394         {
395           gcry_sexp_release (list);
396           err = GPG_ERR_INV_OBJ; /* "curve" given but ECC not supported. */
397           goto leave;
398         }
399     }
400
401   /* Check that all parameters are known.  */
402   for (name = element_names, idx = 0; *name; name++, idx++)
403     if (!elements[idx])
404       {
405         if (want_private && *name == 'q')
406           ; /* Q is optional.  */
407         else
408           {
409             err = GPG_ERR_NO_OBJ;
410             goto leave;
411           }
412       }
413
414  leave:
415   if (err)
416     {
417       for (name = element_names, idx = 0; *name; name++, idx++)
418         if (elements[idx])
419           mpi_free (elements[idx]);
420     }
421   return err;
422 }
423
424
425
426 /****************
427  * Convert a S-Exp with either a private or a public key to our
428  * internal format. Currently we do only support the following
429  * algorithms:
430  *    dsa
431  *    rsa
432  *    openpgp-dsa
433  *    openpgp-rsa
434  *    openpgp-elg
435  *    openpgp-elg-sig
436  *    ecdsa
437  *    ecdh
438  * Provide a SE with the first element be either "private-key" or
439  * or "public-key". It is followed by a list with its first element
440  * be one of the above algorithm identifiers and the remaning
441  * elements are pairs with parameter-id and value.
442  * NOTE: we look through the list to find a list beginning with
443  * "private-key" or "public-key" - the first one found is used.
444  *
445  * If OVERRIDE_ELEMS is not NULL those elems override the parameter
446  * specification taken from the module.  This ise used by
447  * gcry_pk_get_curve.
448  *
449  * Returns: A pointer to an allocated array of MPIs if the return value is
450  *          zero; the caller has to release this array.
451  *
452  * Example of a DSA public key:
453  *  (private-key
454  *    (dsa
455  *      (p <mpi>)
456  *      (g <mpi>)
457  *      (y <mpi>)
458  *      (x <mpi>)
459  *    )
460  *  )
461  * The <mpi> are expected to be in GCRYMPI_FMT_USG
462  */
463 static gcry_err_code_t
464 sexp_to_key (gcry_sexp_t sexp, int want_private, int use,
465              const char *override_elems,
466              gcry_mpi_t **retarray, gcry_pk_spec_t **r_spec, int *r_is_ecc)
467 {
468   gcry_err_code_t err = 0;
469   gcry_sexp_t list, l2;
470   char *name;
471   const char *elems;
472   gcry_mpi_t *array;
473   gcry_pk_spec_t *spec;
474   int is_ecc;
475
476   /* Check that the first element is valid.  If we are looking for a
477      public key but a private key was supplied, we allow the use of
478      the private key anyway.  The rationale for this is that the
479      private key is a superset of the public key. */
480   list = gcry_sexp_find_token (sexp,
481                                want_private? "private-key":"public-key", 0);
482   if (!list && !want_private)
483     list = gcry_sexp_find_token (sexp, "private-key", 0);
484   if (!list)
485     return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
486
487   l2 = gcry_sexp_cadr( list );
488   gcry_sexp_release ( list );
489   list = l2;
490   name = _gcry_sexp_nth_string (list, 0);
491   if (!name)
492     {
493       gcry_sexp_release ( list );
494       return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
495     }
496
497   /* Fixme: We should make sure that an ECC key is always named "ecc"
498      and not "ecdsa".  "ecdsa" should be used for the signature
499      itself.  We need a function to test whether an algorithm given
500      with a key is compatible with an application of the key (signing,
501      encryption).  For RSA this is easy, but ECC is the first
502      algorithm which has many flavours.
503
504      We use an ugly hack here to decide whether to use ecdsa or ecdh.
505   */
506   if (!strcmp (name, "ecc"))
507     is_ecc = 2;
508   else if (!strcmp (name, "ecdsa") || !strcmp (name, "ecdh"))
509     is_ecc = 1;
510   else
511     is_ecc = 0;
512
513   if (is_ecc == 2 && (use & GCRY_PK_USAGE_SIGN))
514     spec = spec_from_name ("ecdsa");
515   else if (is_ecc == 2 && (use & GCRY_PK_USAGE_ENCR))
516     spec = spec_from_name ("ecdh");
517   else
518     spec = spec_from_name (name);
519
520   gcry_free (name);
521
522   if (!spec)
523     {
524       gcry_sexp_release (list);
525       return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
526     }
527
528   if (override_elems)
529     elems = override_elems;
530   else if (want_private)
531     elems = spec->elements_skey;
532   else
533     elems = spec->elements_pkey;
534   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
535   if (!array)
536     err = gpg_err_code_from_syserror ();
537   if (!err)
538     {
539       if (is_ecc)
540         err = sexp_elements_extract_ecc (list, elems, array, spec,
541                                          want_private);
542       else
543         err = sexp_elements_extract (list, elems, array, spec->name, 0);
544     }
545
546   gcry_sexp_release (list);
547
548   if (err)
549     {
550       gcry_free (array);
551     }
552   else
553     {
554       *retarray = array;
555       *r_spec = spec;
556       if (r_is_ecc)
557         *r_is_ecc = is_ecc;
558     }
559
560   return err;
561 }
562
563
564 /* Parse SEXP and store the elements into a newly allocated array of
565    MPIs which will be stored at RETARRAY.  If OPAQUE is set, store the
566    MPI as opaque data.  */
567 static gcry_err_code_t
568 sexp_to_sig (gcry_sexp_t sexp, gcry_mpi_t **retarray,
569              gcry_pk_spec_t **r_spec, int opaque)
570 {
571   gcry_err_code_t err = 0;
572   gcry_sexp_t list, l2;
573   char *name;
574   const char *elems;
575   gcry_mpi_t *array;
576   gcry_pk_spec_t *spec;
577
578   /* Check that the first element is valid.  */
579   list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
580   if (!list)
581     return GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
582
583   l2 = gcry_sexp_nth (list, 1);
584   if (!l2)
585     {
586       gcry_sexp_release (list);
587       return GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
588     }
589   name = _gcry_sexp_nth_string (l2, 0);
590   if (!name)
591     {
592       gcry_sexp_release (list);
593       gcry_sexp_release (l2);
594       return GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
595     }
596   else if (!strcmp (name, "flags"))
597     {
598       /* Skip flags, since they are not used but here just for the
599          sake of consistent S-expressions.  */
600       gcry_free (name);
601       gcry_sexp_release (l2);
602       l2 = gcry_sexp_nth (list, 2);
603       if (!l2)
604         {
605           gcry_sexp_release (list);
606           return GPG_ERR_INV_OBJ;
607         }
608       name = _gcry_sexp_nth_string (l2, 0);
609     }
610
611   spec = spec_from_name (name);
612   gcry_free (name);
613   name = NULL;
614
615   if (!spec)
616     {
617       gcry_sexp_release (l2);
618       gcry_sexp_release (list);
619       return GPG_ERR_PUBKEY_ALGO;  /* Unknown algorithm. */
620     }
621
622   elems = spec->elements_sig;
623   array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
624   if (!array)
625     err = gpg_err_code_from_syserror ();
626
627   if (!err)
628     err = sexp_elements_extract (list, elems, array, NULL, opaque);
629
630   gcry_sexp_release (l2);
631   gcry_sexp_release (list);
632
633   if (err)
634     {
635       gcry_free (array);
636     }
637   else
638     {
639       *retarray = array;
640       *r_spec = spec;
641     }
642
643   return err;
644 }
645
646 static inline int
647 get_hash_algo (const char *s, size_t n)
648 {
649   static const struct { const char *name; int algo; } hashnames[] = {
650     { "sha1",   GCRY_MD_SHA1 },
651     { "md5",    GCRY_MD_MD5 },
652     { "sha256", GCRY_MD_SHA256 },
653     { "ripemd160", GCRY_MD_RMD160 },
654     { "rmd160", GCRY_MD_RMD160 },
655     { "sha384", GCRY_MD_SHA384 },
656     { "sha512", GCRY_MD_SHA512 },
657     { "sha224", GCRY_MD_SHA224 },
658     { "md2",    GCRY_MD_MD2 },
659     { "md4",    GCRY_MD_MD4 },
660     { "tiger",  GCRY_MD_TIGER },
661     { "haval",  GCRY_MD_HAVAL },
662     { NULL, 0 }
663   };
664   int algo;
665   int i;
666
667   for (i=0; hashnames[i].name; i++)
668     {
669       if ( strlen (hashnames[i].name) == n
670            && !memcmp (hashnames[i].name, s, n))
671         break;
672     }
673   if (hashnames[i].name)
674     algo = hashnames[i].algo;
675   else
676     {
677       /* In case of not listed or dynamically allocated hash
678          algorithm we fall back to this somewhat slower
679          method.  Further, it also allows to use OIDs as
680          algorithm names. */
681       char *tmpname;
682
683       tmpname = gcry_malloc (n+1);
684       if (!tmpname)
685         algo = 0;  /* Out of core - silently give up.  */
686       else
687         {
688           memcpy (tmpname, s, n);
689           tmpname[n] = 0;
690           algo = gcry_md_map_name (tmpname);
691           gcry_free (tmpname);
692         }
693     }
694   return algo;
695 }
696
697
698 /****************
699  * Take sexp and return an array of MPI as used for our internal decrypt
700  * function.
701  * s_data = (enc-val
702  *           [(flags [raw, pkcs1, oaep, no-blinding])]
703  *           [(hash-algo <algo>)]
704  *           [(label <label>)]
705  *            (<algo>
706  *              (<param_name1> <mpi>)
707  *              ...
708  *              (<param_namen> <mpi>)
709  *            ))
710  * HASH-ALGO and LABEL are specific to OAEP.
711  * RET_MODERN is set to true when at least an empty flags list has been found.
712  * CTX is used to return encoding information; it may be NULL in which
713  * case raw encoding is used.
714  */
715 static gcry_err_code_t
716 sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_pk_spec_t **r_spec,
717              int *flags, struct pk_encoding_ctx *ctx)
718 {
719   gcry_err_code_t err = 0;
720   gcry_sexp_t list = NULL;
721   gcry_sexp_t l2 = NULL;
722   gcry_pk_spec_t *spec = NULL;
723   char *name = NULL;
724   size_t n;
725   int parsed_flags = 0;
726   const char *elems;
727   gcry_mpi_t *array = NULL;
728
729   /* Check that the first element is valid.  */
730   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
731   if (!list)
732     {
733       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
734       goto leave;
735     }
736
737   l2 = gcry_sexp_nth (list, 1);
738   if (!l2)
739     {
740       err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
741       goto leave;
742     }
743
744   /* Extract identifier of sublist.  */
745   name = _gcry_sexp_nth_string (l2, 0);
746   if (!name)
747     {
748       err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
749       goto leave;
750     }
751
752   if (!strcmp (name, "flags"))
753     {
754       /* There is a flags element - process it.  */
755       const char *s;
756       int i;
757
758       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
759         {
760           s = gcry_sexp_nth_data (l2, i, &n);
761           if (! s)
762             ; /* Not a data element - ignore.  */
763           else if (n == 3 && !memcmp (s, "raw", 3)
764                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
765             ctx->encoding = PUBKEY_ENC_RAW;
766           else if (n == 5 && !memcmp (s, "pkcs1", 5)
767                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
768             ctx->encoding = PUBKEY_ENC_PKCS1;
769           else if (n == 4 && !memcmp (s, "oaep", 4)
770                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
771             ctx->encoding = PUBKEY_ENC_OAEP;
772           else if (n == 3 && !memcmp (s, "pss", 3)
773                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
774             {
775               err = GPG_ERR_CONFLICT;
776               goto leave;
777             }
778           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
779             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
780           else
781             {
782               err = GPG_ERR_INV_FLAG;
783               goto leave;
784             }
785         }
786       gcry_sexp_release (l2);
787
788       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
789       if (ctx->encoding == PUBKEY_ENC_OAEP)
790         {
791           /* Get HASH-ALGO. */
792           l2 = gcry_sexp_find_token (list, "hash-algo", 0);
793           if (l2)
794             {
795               s = gcry_sexp_nth_data (l2, 1, &n);
796               if (!s)
797                 err = GPG_ERR_NO_OBJ;
798               else
799                 {
800                   ctx->hash_algo = get_hash_algo (s, n);
801                   if (!ctx->hash_algo)
802                     err = GPG_ERR_DIGEST_ALGO;
803                 }
804               gcry_sexp_release (l2);
805               if (err)
806                 goto leave;
807             }
808
809           /* Get LABEL. */
810           l2 = gcry_sexp_find_token (list, "label", 0);
811           if (l2)
812             {
813               s = gcry_sexp_nth_data (l2, 1, &n);
814               if (!s)
815                 err = GPG_ERR_NO_OBJ;
816               else if (n > 0)
817                 {
818                   ctx->label = gcry_malloc (n);
819                   if (!ctx->label)
820                     err = gpg_err_code_from_syserror ();
821                   else
822                     {
823                       memcpy (ctx->label, s, n);
824                       ctx->labellen = n;
825                     }
826                 }
827               gcry_sexp_release (l2);
828               if (err)
829                 goto leave;
830             }
831         }
832
833       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
834       for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
835         {
836           s = gcry_sexp_nth_data (l2, 0, &n);
837           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
838               && !(n == 5 && !memcmp (s, "label", 5))
839               && !(n == 15 && !memcmp (s, "random-override", 15)))
840             break;
841           gcry_sexp_release (l2);
842         }
843
844       if (!l2)
845         {
846           err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
847           goto leave;
848         }
849
850       /* Extract sublist identifier.  */
851       gcry_free (name);
852       name = _gcry_sexp_nth_string (l2, 0);
853       if (!name)
854         {
855           err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
856           goto leave;
857         }
858
859       gcry_sexp_release (list);
860       list = l2;
861       l2 = NULL;
862     }
863   else
864     parsed_flags |= PUBKEY_FLAG_LEGACYRESULT;
865
866   spec = spec_from_name (name);
867   if (!spec)
868     {
869       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
870       goto leave;
871     }
872
873   elems = spec->elements_enc;
874   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
875   if (!array)
876     {
877       err = gpg_err_code_from_syserror ();
878       goto leave;
879     }
880
881   err = sexp_elements_extract (list, elems, array, NULL, 0);
882
883  leave:
884   gcry_sexp_release (list);
885   gcry_sexp_release (l2);
886   gcry_free (name);
887
888   if (err)
889     {
890       gcry_free (array);
891       gcry_free (ctx->label);
892       ctx->label = NULL;
893     }
894   else
895     {
896       *retarray = array;
897       *r_spec = spec;
898       *flags = parsed_flags;
899     }
900
901   return err;
902 }
903
904
905 /* Callback for the pubkey algorithm code to verify PSS signatures.
906    OPAQUE is the data provided by the actual caller.  The meaning of
907    TMP depends on the actual algorithm (but there is only RSA); now
908    for RSA it is the output of running the public key function on the
909    input.  */
910 static int
911 pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
912 {
913   struct pk_encoding_ctx *ctx = opaque;
914   gcry_mpi_t hash = ctx->verify_arg;
915
916   return _gcry_rsa_pss_verify (hash, tmp, ctx->nbits - 1,
917                                ctx->hash_algo, ctx->saltlen);
918 }
919
920
921 /* Take the hash value and convert into an MPI, suitable for
922    passing to the low level functions.  We currently support the
923    old style way of passing just a MPI and the modern interface which
924    allows to pass flags so that we can choose between raw and pkcs1
925    padding - may be more padding options later.
926
927    (<mpi>)
928    or
929    (data
930     [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
931     [(hash <algo> <value>)]
932     [(value <text>)]
933     [(hash-algo <algo>)]
934     [(label <label>)]
935     [(salt-length <length>)]
936     [(random-override <data>)]
937    )
938
939    Either the VALUE or the HASH element must be present for use
940    with signatures.  VALUE is used for encryption.
941
942    HASH-ALGO is specific to OAEP and EDDSA.
943
944    LABEL is specific to OAEP.
945
946    SALT-LENGTH is for PSS.
947
948    RANDOM-OVERRIDE is used to replace random nonces for regression
949    testing.  */
950 static gcry_err_code_t
951 sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
952                   struct pk_encoding_ctx *ctx)
953 {
954   gcry_err_code_t rc = 0;
955   gcry_sexp_t ldata, lhash, lvalue;
956   int i;
957   size_t n;
958   const char *s;
959   int unknown_flag = 0;
960   int parsed_flags = 0;
961   int explicit_raw = 0;
962
963   *ret_mpi = NULL;
964   ldata = gcry_sexp_find_token (input, "data", 0);
965   if (!ldata)
966     { /* assume old style */
967       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
968       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
969     }
970
971   /* see whether there is a flags object */
972   {
973     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
974     if (lflags)
975       { /* parse the flags list. */
976         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
977           {
978             s = gcry_sexp_nth_data (lflags, i, &n);
979             if (!s)
980               ; /* not a data element*/
981             else if (n == 7 && !memcmp (s, "rfc6979", 7))
982               parsed_flags |= PUBKEY_FLAG_RFC6979;
983             else if (n == 5 && !memcmp (s, "eddsa", 5))
984               {
985                 ctx->encoding = PUBKEY_ENC_RAW;
986                 parsed_flags |= PUBKEY_FLAG_EDDSA;
987               }
988             else if ( n == 3 && !memcmp (s, "raw", 3)
989                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
990               {
991                 ctx->encoding = PUBKEY_ENC_RAW;
992                 explicit_raw = 1;
993               }
994             else if ( n == 5 && !memcmp (s, "pkcs1", 5)
995                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
996               {
997                 ctx->encoding = PUBKEY_ENC_PKCS1;
998                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
999               }
1000             else if ( n == 4 && !memcmp (s, "oaep", 4)
1001                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1002               {
1003                 ctx->encoding = PUBKEY_ENC_OAEP;
1004                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
1005               }
1006             else if ( n == 3 && !memcmp (s, "pss", 3)
1007                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1008               {
1009                 ctx->encoding = PUBKEY_ENC_PSS;
1010                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
1011               }
1012             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1013               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1014             else
1015               unknown_flag = 1;
1016           }
1017         gcry_sexp_release (lflags);
1018       }
1019   }
1020
1021   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
1022     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
1023
1024   /* Get HASH or MPI */
1025   lhash = gcry_sexp_find_token (ldata, "hash", 0);
1026   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1027
1028   if (!(!lhash ^ !lvalue))
1029     rc = GPG_ERR_INV_OBJ; /* none or both given */
1030   else if (unknown_flag)
1031     rc = GPG_ERR_INV_FLAG;
1032   else if (ctx->encoding == PUBKEY_ENC_RAW
1033            && (parsed_flags & PUBKEY_FLAG_EDDSA))
1034     {
1035       /* Prepare for EdDSA.  */
1036       gcry_sexp_t list;
1037       void *value;
1038       size_t valuelen;
1039
1040       if (!lvalue)
1041         {
1042           rc = GPG_ERR_INV_OBJ;
1043           goto leave;
1044         }
1045       /* Get HASH-ALGO. */
1046       list = gcry_sexp_find_token (ldata, "hash-algo", 0);
1047       if (list)
1048         {
1049           s = gcry_sexp_nth_data (list, 1, &n);
1050           if (!s)
1051             rc = GPG_ERR_NO_OBJ;
1052           else
1053             {
1054               ctx->hash_algo = get_hash_algo (s, n);
1055               if (!ctx->hash_algo)
1056                 rc = GPG_ERR_DIGEST_ALGO;
1057             }
1058           gcry_sexp_release (list);
1059         }
1060       else
1061         rc = GPG_ERR_INV_OBJ;
1062       if (rc)
1063         goto leave;
1064
1065       /* Get VALUE.  */
1066       value = gcry_sexp_nth_buffer (lvalue, 1, &valuelen);
1067       if (!value)
1068         {
1069           /* We assume that a zero length message is meant by
1070              "(value)".  This is commonly used by test vectors.  Note
1071              that S-expression do not allow zero length items. */
1072           valuelen = 0;
1073           value = gcry_malloc (1);
1074           if (!value)
1075             rc = gpg_err_code_from_syserror ();
1076         }
1077       else if ((valuelen * 8) < valuelen)
1078         {
1079           gcry_free (value);
1080           rc = GPG_ERR_TOO_LARGE;
1081         }
1082       if (rc)
1083         goto leave;
1084
1085       /* Note that mpi_set_opaque takes ownership of VALUE.  */
1086       *ret_mpi = gcry_mpi_set_opaque (NULL, value, valuelen*8);
1087     }
1088   else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
1089            && (explicit_raw || (parsed_flags & PUBKEY_FLAG_RFC6979)))
1090     {
1091       /* Raw encoding along with a hash element.  This is commonly
1092          used for DSA.  For better backward error compatibility we
1093          allow this only if either the rfc6979 flag has been given or
1094          the raw flags was explicitly given.  */
1095       if (gcry_sexp_length (lhash) != 3)
1096         rc = GPG_ERR_INV_OBJ;
1097       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1098         rc = GPG_ERR_INV_OBJ;
1099       else
1100         {
1101           void *value;
1102           size_t valuelen;
1103
1104           ctx->hash_algo = get_hash_algo (s, n);
1105           if (!ctx->hash_algo)
1106             rc = GPG_ERR_DIGEST_ALGO;
1107           else if (!(value=gcry_sexp_nth_buffer (lhash, 2, &valuelen)))
1108             rc = GPG_ERR_INV_OBJ;
1109           else if ((valuelen * 8) < valuelen)
1110             {
1111               gcry_free (value);
1112               rc = GPG_ERR_TOO_LARGE;
1113             }
1114           else
1115             *ret_mpi = gcry_mpi_set_opaque (NULL, value, valuelen*8);
1116         }
1117     }
1118   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
1119     {
1120       /* RFC6969 may only be used with the a hash value and not the
1121          MPI based value.  */
1122       if (parsed_flags & PUBKEY_FLAG_RFC6979)
1123         {
1124           rc = GPG_ERR_CONFLICT;
1125           goto leave;
1126         }
1127
1128       /* Get the value */
1129       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
1130       if (!*ret_mpi)
1131         rc = GPG_ERR_INV_OBJ;
1132     }
1133   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
1134            && ctx->op == PUBKEY_OP_ENCRYPT)
1135     {
1136       const void * value;
1137       size_t valuelen;
1138       gcry_sexp_t list;
1139       void *random_override = NULL;
1140       size_t random_override_len = 0;
1141
1142       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1143         rc = GPG_ERR_INV_OBJ;
1144       else
1145         {
1146           /* Get optional RANDOM-OVERRIDE.  */
1147           list = gcry_sexp_find_token (ldata, "random-override", 0);
1148           if (list)
1149             {
1150               s = gcry_sexp_nth_data (list, 1, &n);
1151               if (!s)
1152                 rc = GPG_ERR_NO_OBJ;
1153               else if (n > 0)
1154                 {
1155                   random_override = gcry_malloc (n);
1156                   if (!random_override)
1157                     rc = gpg_err_code_from_syserror ();
1158                   else
1159                     {
1160                       memcpy (random_override, s, n);
1161                       random_override_len = n;
1162                     }
1163                 }
1164               gcry_sexp_release (list);
1165               if (rc)
1166                 goto leave;
1167             }
1168
1169           rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
1170                                                value, valuelen,
1171                                                random_override,
1172                                                random_override_len);
1173           gcry_free (random_override);
1174         }
1175     }
1176   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
1177            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
1178     {
1179       if (gcry_sexp_length (lhash) != 3)
1180         rc = GPG_ERR_INV_OBJ;
1181       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1182         rc = GPG_ERR_INV_OBJ;
1183       else
1184         {
1185           const void * value;
1186           size_t valuelen;
1187
1188           ctx->hash_algo = get_hash_algo (s, n);
1189
1190           if (!ctx->hash_algo)
1191             rc = GPG_ERR_DIGEST_ALGO;
1192           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1193                     || !valuelen )
1194             rc = GPG_ERR_INV_OBJ;
1195           else
1196             rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
1197                                                  value, valuelen,
1198                                                  ctx->hash_algo);
1199         }
1200     }
1201   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
1202            && ctx->op == PUBKEY_OP_ENCRYPT)
1203     {
1204       const void * value;
1205       size_t valuelen;
1206
1207       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1208         rc = GPG_ERR_INV_OBJ;
1209       else
1210         {
1211           gcry_sexp_t list;
1212           void *random_override = NULL;
1213           size_t random_override_len = 0;
1214
1215           /* Get HASH-ALGO. */
1216           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
1217           if (list)
1218             {
1219               s = gcry_sexp_nth_data (list, 1, &n);
1220               if (!s)
1221                 rc = GPG_ERR_NO_OBJ;
1222               else
1223                 {
1224                   ctx->hash_algo = get_hash_algo (s, n);
1225                   if (!ctx->hash_algo)
1226                     rc = GPG_ERR_DIGEST_ALGO;
1227                 }
1228               gcry_sexp_release (list);
1229               if (rc)
1230                 goto leave;
1231             }
1232
1233           /* Get LABEL. */
1234           list = gcry_sexp_find_token (ldata, "label", 0);
1235           if (list)
1236             {
1237               s = gcry_sexp_nth_data (list, 1, &n);
1238               if (!s)
1239                 rc = GPG_ERR_NO_OBJ;
1240               else if (n > 0)
1241                 {
1242                   ctx->label = gcry_malloc (n);
1243                   if (!ctx->label)
1244                     rc = gpg_err_code_from_syserror ();
1245                   else
1246                     {
1247                       memcpy (ctx->label, s, n);
1248                       ctx->labellen = n;
1249                     }
1250                 }
1251               gcry_sexp_release (list);
1252               if (rc)
1253                 goto leave;
1254             }
1255           /* Get optional RANDOM-OVERRIDE.  */
1256           list = gcry_sexp_find_token (ldata, "random-override", 0);
1257           if (list)
1258             {
1259               s = gcry_sexp_nth_data (list, 1, &n);
1260               if (!s)
1261                 rc = GPG_ERR_NO_OBJ;
1262               else if (n > 0)
1263                 {
1264                   random_override = gcry_malloc (n);
1265                   if (!random_override)
1266                     rc = gpg_err_code_from_syserror ();
1267                   else
1268                     {
1269                       memcpy (random_override, s, n);
1270                       random_override_len = n;
1271                     }
1272                 }
1273               gcry_sexp_release (list);
1274               if (rc)
1275                 goto leave;
1276             }
1277
1278           rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
1279                                       value, valuelen,
1280                                       ctx->label, ctx->labellen,
1281                                       random_override, random_override_len);
1282
1283           gcry_free (random_override);
1284         }
1285     }
1286   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1287            && ctx->op == PUBKEY_OP_SIGN)
1288     {
1289       if (gcry_sexp_length (lhash) != 3)
1290         rc = GPG_ERR_INV_OBJ;
1291       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1292         rc = GPG_ERR_INV_OBJ;
1293       else
1294         {
1295           const void * value;
1296           size_t valuelen;
1297           void *random_override = NULL;
1298           size_t random_override_len = 0;
1299
1300           ctx->hash_algo = get_hash_algo (s, n);
1301
1302           if (!ctx->hash_algo)
1303             rc = GPG_ERR_DIGEST_ALGO;
1304           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1305                     || !valuelen )
1306             rc = GPG_ERR_INV_OBJ;
1307           else
1308             {
1309               gcry_sexp_t list;
1310
1311               /* Get SALT-LENGTH. */
1312               list = gcry_sexp_find_token (ldata, "salt-length", 0);
1313               if (list)
1314                 {
1315                   s = gcry_sexp_nth_data (list, 1, &n);
1316                   if (!s)
1317                     {
1318                       rc = GPG_ERR_NO_OBJ;
1319                       goto leave;
1320                     }
1321                   ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
1322                   gcry_sexp_release (list);
1323                 }
1324
1325               /* Get optional RANDOM-OVERRIDE.  */
1326               list = gcry_sexp_find_token (ldata, "random-override", 0);
1327               if (list)
1328                 {
1329                   s = gcry_sexp_nth_data (list, 1, &n);
1330                   if (!s)
1331                     rc = GPG_ERR_NO_OBJ;
1332                   else if (n > 0)
1333                     {
1334                       random_override = gcry_malloc (n);
1335                       if (!random_override)
1336                         rc = gpg_err_code_from_syserror ();
1337                       else
1338                         {
1339                           memcpy (random_override, s, n);
1340                           random_override_len = n;
1341                         }
1342                     }
1343                   gcry_sexp_release (list);
1344                   if (rc)
1345                     goto leave;
1346                 }
1347
1348               /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
1349               rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
1350                                          ctx->hash_algo,
1351                                          value, valuelen, ctx->saltlen,
1352                                          random_override, random_override_len);
1353
1354               gcry_free (random_override);
1355             }
1356         }
1357     }
1358   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1359            && ctx->op == PUBKEY_OP_VERIFY)
1360     {
1361       if (gcry_sexp_length (lhash) != 3)
1362         rc = GPG_ERR_INV_OBJ;
1363       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1364         rc = GPG_ERR_INV_OBJ;
1365       else
1366         {
1367           ctx->hash_algo = get_hash_algo (s, n);
1368
1369           if (!ctx->hash_algo)
1370             rc = GPG_ERR_DIGEST_ALGO;
1371           else
1372             {
1373               *ret_mpi = gcry_sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
1374               if (!*ret_mpi)
1375                 rc = GPG_ERR_INV_OBJ;
1376               ctx->verify_cmp = pss_verify_cmp;
1377               ctx->verify_arg = *ret_mpi;
1378             }
1379         }
1380     }
1381   else
1382     rc = GPG_ERR_CONFLICT;
1383
1384  leave:
1385   gcry_sexp_release (ldata);
1386   gcry_sexp_release (lhash);
1387   gcry_sexp_release (lvalue);
1388
1389   if (!rc)
1390     ctx->flags = parsed_flags;
1391   else
1392     {
1393       gcry_free (ctx->label);
1394       ctx->label = NULL;
1395     }
1396
1397   return rc;
1398 }
1399
1400 static void
1401 init_encoding_ctx (struct pk_encoding_ctx *ctx, enum pk_operation op,
1402                    unsigned int nbits)
1403 {
1404   ctx->op = op;
1405   ctx->nbits = nbits;
1406   ctx->encoding = PUBKEY_ENC_UNKNOWN;
1407   ctx->flags = 0;
1408   ctx->hash_algo = GCRY_MD_SHA1;
1409   ctx->label = NULL;
1410   ctx->labellen = 0;
1411   ctx->saltlen = 20;
1412   ctx->verify_cmp = NULL;
1413   ctx->verify_arg = NULL;
1414 }
1415
1416
1417 /*
1418    Do a PK encrypt operation
1419
1420    Caller has to provide a public key as the SEXP pkey and data as a
1421    SEXP with just one MPI in it. Alternatively S_DATA might be a
1422    complex S-Expression, similar to the one used for signature
1423    verification.  This provides a flag which allows to handle PKCS#1
1424    block type 2 padding.  The function returns a sexp which may be
1425    passed to to pk_decrypt.
1426
1427    Returns: 0 or an errorcode.
1428
1429    s_data = See comment for sexp_data_to_mpi
1430    s_pkey = <key-as-defined-in-sexp_to_key>
1431    r_ciph = (enc-val
1432                (<algo>
1433                  (<param_name1> <mpi>)
1434                  ...
1435                  (<param_namen> <mpi>)
1436                ))
1437
1438 */
1439 gcry_error_t
1440 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
1441 {
1442   gcry_err_code_t rc;
1443   gcry_mpi_t *pkey = NULL;
1444   gcry_mpi_t data = NULL;
1445   struct pk_encoding_ctx ctx;
1446   gcry_pk_spec_t *spec = NULL;
1447   int i;
1448
1449   *r_ciph = NULL;
1450
1451   /* Get the key. */
1452   rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_ENCR, NULL, &pkey, &spec, NULL);
1453   if (rc)
1454     goto leave;
1455
1456   gcry_assert (spec);
1457
1458   /* Get the stuff we want to encrypt. */
1459   init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
1460   rc = sexp_data_to_mpi (s_data, &data, &ctx);
1461   if (rc)
1462     goto leave;
1463
1464   /* In fips mode DBG_CIPHER will never evaluate to true but as an
1465      extra failsafe protection we explicitly test for fips mode
1466      here. */
1467   if (DBG_CIPHER && !fips_mode ())
1468     {
1469       log_debug ("pubkey_encrypt: algo=%d\n", spec->algo);
1470       for(i = 0; i < pubkey_get_npkey (spec->algo); i++)
1471         log_mpidump ("  pkey", pkey[i]);
1472       log_mpidump ("  data", data);
1473     }
1474
1475   if (spec->encrypt)
1476     rc = spec->encrypt (spec->algo, r_ciph, data, pkey, ctx.flags);
1477   else
1478     rc = GPG_ERR_NOT_IMPLEMENTED;
1479
1480
1481   /* if (DBG_CIPHER && !fips_mode ()) */
1482   /*   { */
1483   /*     for (i = 0; i < pubkey_get_nenc (spec->algo); i++) */
1484   /*       log_mpidump ("  encr", ciph[i]); */
1485   /*   } */
1486
1487  leave:
1488   mpi_free (data);
1489   if (pkey)
1490     {
1491       release_mpi_array (pkey);
1492       gcry_free (pkey);
1493     }
1494
1495   gcry_free (ctx.label);
1496
1497   return gcry_error (rc);
1498 }
1499
1500
1501 /*
1502    Do a PK decrypt operation
1503
1504    Caller has to provide a secret key as the SEXP skey and data in a
1505    format as created by gcry_pk_encrypt.  For historic reasons the
1506    function returns simply an MPI as an S-expression part; this is
1507    deprecated and the new method should be used which returns a real
1508    S-expressionl this is selected by adding at least an empty flags
1509    list to S_DATA.
1510
1511    Returns: 0 or an errorcode.
1512
1513    s_data = (enc-val
1514               [(flags [raw, pkcs1, oaep])]
1515               (<algo>
1516                 (<param_name1> <mpi>)
1517                 ...
1518                 (<param_namen> <mpi>)
1519               ))
1520    s_skey = <key-as-defined-in-sexp_to_key>
1521    r_plain= Either an incomplete S-expression without the parentheses
1522             or if the flags list is used (even if empty) a real S-expression:
1523             (value PLAIN).  In raw mode (or no flags given) the returned value
1524             is to be interpreted as a signed MPI, thus it may have an extra
1525             leading zero octet even if not included in the original data.
1526             With pkcs1 or oaep decoding enabled the returned value is a
1527             verbatim octet string.
1528  */
1529 gcry_error_t
1530 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
1531 {
1532   gcry_err_code_t rc;
1533   gcry_mpi_t *skey = NULL;
1534   gcry_mpi_t *data = NULL;
1535   int i;
1536   int flags;
1537   struct pk_encoding_ctx ctx;
1538   gcry_pk_spec_t *spec = NULL;
1539   gcry_pk_spec_t *spec_enc = NULL;
1540
1541   *r_plain = NULL;
1542   ctx.label = NULL;
1543
1544   rc = sexp_to_key (s_skey, 1, GCRY_PK_USAGE_ENCR, NULL,
1545                     &skey, &spec, NULL);
1546   if (rc)
1547     goto leave;
1548
1549   init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, gcry_pk_get_nbits (s_skey));
1550   rc = sexp_to_enc (s_data, &data, &spec_enc, &flags, &ctx);
1551   if (rc)
1552     goto leave;
1553
1554   if (spec->algo != spec_enc->algo)
1555     {
1556       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
1557       goto leave;
1558     }
1559
1560   if (DBG_CIPHER && !fips_mode ())
1561     {
1562       log_debug ("gcry_pk_decrypt: algo=%d\n", spec->algo);
1563       for(i = 0; i < pubkey_get_nskey (spec->algo); i++)
1564         log_mpidump ("  skey", skey[i]);
1565       for(i = 0; i < pubkey_get_nenc (spec->algo); i++)
1566         log_mpidump ("  data", data[i]);
1567     }
1568
1569   if (spec->decrypt)
1570     rc = spec->decrypt (spec->algo, r_plain, data, skey, flags,
1571                         ctx.encoding, ctx.hash_algo,
1572                         ctx.label, ctx.labellen);
1573   else
1574     rc = GPG_ERR_NOT_IMPLEMENTED;
1575   if (rc)
1576     goto leave;
1577
1578   /* if (DBG_CIPHER && !fips_mode ()) */
1579   /*   log_mpidump (" plain", plain); */
1580
1581
1582  leave:
1583   if (skey)
1584     {
1585       release_mpi_array (skey);
1586       gcry_free (skey);
1587     }
1588
1589   if (data)
1590     {
1591       release_mpi_array (data);
1592       gcry_free (data);
1593     }
1594
1595   gcry_free (ctx.label);
1596
1597   return gcry_error (rc);
1598 }
1599
1600
1601
1602 /*
1603    Create a signature.
1604
1605    Caller has to provide a secret key as the SEXP skey and data
1606    expressed as a SEXP list hash with only one element which should
1607    instantly be available as a MPI. Alternatively the structure given
1608    below may be used for S_HASH, it provides the abiliy to pass flags
1609    to the operation; the flags defined by now are "pkcs1" which does
1610    PKCS#1 block type 1 style padding and "pss" for PSS encoding.
1611
1612    Returns: 0 or an errorcode.
1613             In case of 0 the function returns a new SEXP with the
1614             signature value; the structure of this signature depends on the
1615             other arguments but is always suitable to be passed to
1616             gcry_pk_verify
1617
1618    s_hash = See comment for sexp_data_to_mpi
1619
1620    s_skey = <key-as-defined-in-sexp_to_key>
1621    r_sig  = (sig-val
1622               (<algo>
1623                 (<param_name1> <mpi>)
1624                 ...
1625                 (<param_namen> <mpi>))
1626              [(hash algo)])
1627
1628   Note that (hash algo) in R_SIG is not used.
1629 */
1630 gcry_error_t
1631 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
1632 {
1633   gcry_mpi_t *skey = NULL;
1634   gcry_mpi_t hash = NULL;
1635   gcry_pk_spec_t *spec = NULL;
1636   struct pk_encoding_ctx ctx;
1637   int i;
1638   int is_ecc;
1639   gcry_err_code_t rc;
1640
1641   *r_sig = NULL;
1642
1643   rc = sexp_to_key (s_skey, 1, GCRY_PK_USAGE_SIGN, NULL,
1644                     &skey, &spec, &is_ecc);
1645   if (rc)
1646     goto leave;
1647
1648   gcry_assert (spec);
1649
1650   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
1651      work on a private key.  We don't need the number of bits for ECC
1652      here, thus set it to 0 so that we don't need to parse it.  */
1653   init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
1654                      is_ecc? 0 : gcry_pk_get_nbits (s_skey));
1655   rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
1656   if (rc)
1657     goto leave;
1658
1659   if (DBG_CIPHER && !fips_mode ())
1660     {
1661       log_debug ("gcry_pk_sign: algo=%d\n", spec->algo);
1662       for(i = 0; i < pubkey_get_nskey (spec->algo); i++)
1663         log_mpidump ("  skey", skey[i]);
1664       log_mpidump("  data", hash);
1665     }
1666
1667   if (spec->sign)
1668     rc = spec->sign (spec->algo, r_sig, hash, skey, ctx.flags, ctx.hash_algo);
1669   else
1670     rc = GPG_ERR_NOT_IMPLEMENTED;
1671
1672   if (rc)
1673     goto leave;
1674
1675   /* Fixme: To print the result we need to print an sexp.  */
1676   /* if (!rc && DBG_CIPHER && !fips_mode ()) */
1677   /*   for (i = 0; i < pubkey_get_nsig (algo); i++) */
1678   /*     log_mpidump ("   sig", resarr[i]); */
1679
1680  leave:
1681   if (skey)
1682     {
1683       if (is_ecc)
1684         /* Q is optional and may be NULL, while there is D after Q.  */
1685         for (i = 0; i < 7; i++)
1686           {
1687             if (skey[i])
1688               mpi_free (skey[i]);
1689             skey[i] = NULL;
1690           }
1691       else
1692         release_mpi_array (skey);
1693       gcry_free (skey);
1694     }
1695
1696   mpi_free (hash);
1697
1698   return gcry_error (rc);
1699 }
1700
1701
1702 /*
1703    Verify a signature.
1704
1705    Caller has to supply the public key pkey, the signature sig and his
1706    hashvalue data.  Public key has to be a standard public key given
1707    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
1708    must be an S-Exp like the one in sign too.  */
1709 gcry_error_t
1710 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
1711 {
1712   gcry_err_code_t rc;
1713   gcry_pk_spec_t *spec = NULL;
1714   gcry_pk_spec_t *spec_sig = NULL;
1715   gcry_mpi_t *pkey = NULL;
1716   gcry_mpi_t hash = NULL;
1717   gcry_mpi_t *sig = NULL;
1718   struct pk_encoding_ctx ctx;
1719   int i;
1720
1721   rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_SIGN, NULL,
1722                     &pkey, &spec, NULL);
1723   if (rc)
1724     goto leave;
1725
1726   /* Get the stuff we want to verify. */
1727   init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, gcry_pk_get_nbits (s_pkey));
1728   rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
1729   if (rc)
1730     goto leave;
1731
1732   /* Get the signature.  */
1733   rc = sexp_to_sig (s_sig, &sig, &spec_sig,
1734                     !!(ctx.flags & PUBKEY_FLAG_EDDSA));
1735   if (rc)
1736     goto leave;
1737   /* Fixme: Check that the algorithm of S_SIG is compatible to the one
1738      of S_PKEY.  */
1739
1740   if (spec->algo != spec_sig->algo)
1741     {
1742       rc = GPG_ERR_CONFLICT;
1743       goto leave;
1744     }
1745
1746   if (DBG_CIPHER && !fips_mode ())
1747     {
1748       log_debug ("gcry_pk_verify: algo=%d\n", spec->algo);
1749       for (i = 0; i < pubkey_get_npkey (spec->algo); i++)
1750         log_mpidump ("  pkey", pkey[i]);
1751       for (i = 0; i < pubkey_get_nsig (spec->algo); i++)
1752         log_mpidump ("   sig", sig[i]);
1753       log_mpidump ("  hash", hash);
1754       }
1755
1756   if (spec->verify)
1757     rc = spec->verify (spec->algo, hash, sig, pkey,
1758                        ctx.verify_cmp, &ctx, ctx.flags, ctx.hash_algo);
1759   else
1760     rc = GPG_ERR_NOT_IMPLEMENTED;
1761
1762
1763  leave:
1764   if (pkey)
1765     {
1766       release_mpi_array (pkey);
1767       gcry_free (pkey);
1768     }
1769   if (sig)
1770     {
1771       release_mpi_array (sig);
1772       gcry_free (sig);
1773     }
1774   if (hash)
1775     mpi_free (hash);
1776
1777   return gcry_error (rc);
1778 }
1779
1780
1781 /*
1782    Test a key.
1783
1784    This may be used either for a public or a secret key to see whether
1785    the internal structure is okay.
1786
1787    Returns: 0 or an errorcode.
1788
1789    s_key = <key-as-defined-in-sexp_to_key> */
1790 gcry_error_t
1791 gcry_pk_testkey (gcry_sexp_t s_key)
1792 {
1793   gcry_pk_spec_t *spec = NULL;
1794   gcry_mpi_t *key = NULL;
1795   gcry_err_code_t rc;
1796
1797   /* Note we currently support only secret key checking. */
1798   rc = sexp_to_key (s_key, 1, 0, NULL, &key, &spec, NULL);
1799   if (!rc)
1800     {
1801       rc = pubkey_check_secret_key (spec->algo, key);
1802       release_mpi_array (key);
1803       gcry_free (key);
1804     }
1805   return gcry_error (rc);
1806 }
1807
1808
1809 /*
1810   Create a public key pair and return it in r_key.
1811   How the key is created depends on s_parms:
1812   (genkey
1813    (algo
1814      (parameter_name_1 ....)
1815       ....
1816      (parameter_name_n ....)
1817   ))
1818   The key is returned in a format depending on the
1819   algorithm. Both, private and secret keys are returned
1820   and optionally some additional informatin.
1821   For elgamal we return this structure:
1822   (key-data
1823    (public-key
1824      (elg
1825         (p <mpi>)
1826         (g <mpi>)
1827         (y <mpi>)
1828      )
1829    )
1830    (private-key
1831      (elg
1832         (p <mpi>)
1833         (g <mpi>)
1834         (y <mpi>)
1835         (x <mpi>)
1836      )
1837    )
1838    (misc-key-info
1839       (pm1-factors n1 n2 ... nn)
1840    ))
1841  */
1842 gcry_error_t
1843 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
1844 {
1845   gcry_pk_spec_t *spec = NULL;
1846   gcry_sexp_t list = NULL;
1847   gcry_sexp_t l2 = NULL;
1848   gcry_sexp_t l3 = NULL;
1849   char *name = NULL;
1850   size_t n;
1851   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
1852   unsigned int nbits = 0;
1853   unsigned long use_e = 0;
1854
1855   *r_key = NULL;
1856
1857   list = gcry_sexp_find_token (s_parms, "genkey", 0);
1858   if (!list)
1859     {
1860       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
1861       goto leave;
1862     }
1863
1864   l2 = gcry_sexp_cadr (list);
1865   gcry_sexp_release (list);
1866   list = l2;
1867   l2 = NULL;
1868   if (! list)
1869     {
1870       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
1871       goto leave;
1872     }
1873
1874   name = _gcry_sexp_nth_string (list, 0);
1875   if (!name)
1876     {
1877       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
1878       goto leave;
1879     }
1880
1881   spec = spec_from_name (name);
1882   gcry_free (name);
1883   name = NULL;
1884   if (!spec)
1885     {
1886       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
1887       goto leave;
1888     }
1889
1890   /* Handle the optional rsa-use-e element.  Actually this belong into
1891      the algorithm module but we have this parameter in the public
1892      module API, so we need to parse it right here.  */
1893   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
1894   if (l2)
1895     {
1896       char buf[50];
1897       const char *s;
1898
1899       s = gcry_sexp_nth_data (l2, 1, &n);
1900       if ( !s || n >= DIM (buf) - 1 )
1901         {
1902           rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
1903           goto leave;
1904         }
1905       memcpy (buf, s, n);
1906       buf[n] = 0;
1907       use_e = strtoul (buf, NULL, 0);
1908       gcry_sexp_release (l2);
1909       l2 = NULL;
1910     }
1911   else
1912     use_e = 65537; /* Not given, use the value generated by old versions. */
1913
1914
1915   /* Get the "nbits" parameter.  */
1916   l2 = gcry_sexp_find_token (list, "nbits", 0);
1917   if (l2)
1918     {
1919       char buf[50];
1920       const char *s;
1921
1922       s = gcry_sexp_nth_data (l2, 1, &n);
1923       if (!s || n >= DIM (buf) - 1 )
1924         {
1925           rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
1926           goto leave;
1927         }
1928       memcpy (buf, s, n);
1929       buf[n] = 0;
1930       nbits = (unsigned int)strtoul (buf, NULL, 0);
1931       gcry_sexp_release (l2); l2 = NULL;
1932     }
1933   else
1934     nbits = 0;
1935
1936   if (spec->generate)
1937     rc = spec->generate (spec->algo, nbits, use_e, list, r_key);
1938   else
1939     rc = GPG_ERR_NOT_IMPLEMENTED;
1940
1941  leave:
1942   gcry_sexp_release (list); list = NULL;
1943   gcry_free (name);
1944   gcry_sexp_release (l3);
1945   gcry_sexp_release (l2);
1946   gcry_sexp_release (list);
1947
1948   return gcry_error (rc);
1949 }
1950
1951
1952 /*
1953    Get the number of nbits from the public key.
1954
1955    Hmmm: Should we have really this function or is it better to have a
1956    more general function to retrieve different properties of the key?  */
1957 unsigned int
1958 gcry_pk_get_nbits (gcry_sexp_t key)
1959 {
1960   gcry_pk_spec_t *spec;
1961   gcry_mpi_t *keyarr = NULL;
1962   unsigned int nbits = 0;
1963   gcry_err_code_t rc;
1964
1965   /* FIXME: Parsing KEY is often too much overhead.  For example for
1966      ECC we would only need to look at P and stop parsing right
1967      away.  */
1968
1969   rc = sexp_to_key (key, 0, 0, NULL, &keyarr, &spec, NULL);
1970   if (rc == GPG_ERR_INV_OBJ)
1971     rc = sexp_to_key (key, 1, 0, NULL, &keyarr, &spec, NULL);
1972   if (rc)
1973     return 0; /* Error - 0 is a suitable indication for that. */
1974
1975   nbits = spec->get_nbits (spec->algo, keyarr);
1976
1977   release_mpi_array (keyarr);
1978   gcry_free (keyarr);
1979
1980   return nbits;
1981 }
1982
1983
1984 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
1985    key parameters expressed in a way depending on the algorithm.
1986
1987    ARRAY must either be 20 bytes long or NULL; in the latter case a
1988    newly allocated array of that size is returned, otherwise ARRAY or
1989    NULL is returned to indicate an error which is most likely an
1990    unknown algorithm.  The function accepts public or secret keys. */
1991 unsigned char *
1992 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
1993 {
1994   gcry_sexp_t list = NULL;
1995   gcry_sexp_t l2 = NULL;
1996   gcry_pk_spec_t *spec = NULL;
1997   const char *s;
1998   char *name = NULL;
1999   int idx;
2000   const char *elems;
2001   gcry_md_hd_t md = NULL;
2002   int okay = 0;
2003
2004   /* Check that the first element is valid. */
2005   list = gcry_sexp_find_token (key, "public-key", 0);
2006   if (! list)
2007     list = gcry_sexp_find_token (key, "private-key", 0);
2008   if (! list)
2009     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2010   if (! list)
2011     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
2012   if (! list)
2013     return NULL; /* No public- or private-key object. */
2014
2015   l2 = gcry_sexp_cadr (list);
2016   gcry_sexp_release (list);
2017   list = l2;
2018   l2 = NULL;
2019
2020   name = _gcry_sexp_nth_string (list, 0);
2021   if (!name)
2022     goto fail; /* Invalid structure of object. */
2023
2024   spec = spec_from_name (name);
2025   if (!spec)
2026     goto fail; /* Unknown algorithm.  */
2027
2028   elems = spec->elements_grip;
2029   if (!elems)
2030     goto fail; /* No grip parameter.  */
2031
2032   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2033     goto fail;
2034
2035   if (spec->comp_keygrip)
2036     {
2037       /* Module specific method to compute a keygrip.  */
2038       if (spec->comp_keygrip (md, list))
2039         goto fail;
2040     }
2041   else
2042     {
2043       /* Generic method to compute a keygrip.  */
2044       for (idx = 0, s = elems; *s; s++, idx++)
2045         {
2046           const char *data;
2047           size_t datalen;
2048           char buf[30];
2049
2050           l2 = gcry_sexp_find_token (list, s, 1);
2051           if (! l2)
2052             goto fail;
2053           data = gcry_sexp_nth_data (l2, 1, &datalen);
2054           if (! data)
2055             goto fail;
2056
2057           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
2058           gcry_md_write (md, buf, strlen (buf));
2059           gcry_md_write (md, data, datalen);
2060           gcry_sexp_release (l2);
2061           l2 = NULL;
2062           gcry_md_write (md, ")", 1);
2063         }
2064     }
2065
2066   if (!array)
2067     {
2068       array = gcry_malloc (20);
2069       if (! array)
2070         goto fail;
2071     }
2072
2073   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2074   okay = 1;
2075
2076  fail:
2077   gcry_free (name);
2078   gcry_sexp_release (l2);
2079   gcry_md_close (md);
2080   gcry_sexp_release (list);
2081   return okay? array : NULL;
2082 }
2083
2084
2085 \f
2086 const char *
2087 gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
2088 {
2089   gcry_mpi_t *pkey = NULL;
2090   gcry_sexp_t list = NULL;
2091   gcry_sexp_t l2;
2092   char *name = NULL;
2093   const char *result = NULL;
2094   int want_private = 1;
2095   gcry_pk_spec_t *spec = NULL;
2096
2097   if (r_nbits)
2098     *r_nbits = 0;
2099
2100   if (key)
2101     {
2102       iterator = 0;
2103
2104       /* Check that the first element is valid. */
2105       list = gcry_sexp_find_token (key, "public-key", 0);
2106       if (list)
2107         want_private = 0;
2108       if (!list)
2109         list = gcry_sexp_find_token (key, "private-key", 0);
2110       if (!list)
2111         return NULL; /* No public- or private-key object. */
2112
2113       l2 = gcry_sexp_cadr (list);
2114       gcry_sexp_release (list);
2115       list = l2;
2116       l2 = NULL;
2117
2118       name = _gcry_sexp_nth_string (list, 0);
2119       if (!name)
2120         goto leave; /* Invalid structure of object. */
2121
2122       /* Get the key.  We pass the names of the parameters for
2123          override_elems; this allows to call this function without the
2124          actual public key parameter.  */
2125       if (sexp_to_key (key, want_private, 0, "pabgn", &pkey, &spec, NULL))
2126         goto leave;
2127     }
2128   else
2129     {
2130       spec = spec_from_name ("ecc");
2131       if (!spec)
2132         goto leave;
2133     }
2134
2135   if (!spec || !spec->get_curve)
2136     goto leave;
2137
2138   result = spec->get_curve (pkey, iterator, r_nbits);
2139
2140  leave:
2141   if (pkey)
2142     {
2143       release_mpi_array (pkey);
2144       gcry_free (pkey);
2145     }
2146   gcry_free (name);
2147   gcry_sexp_release (list);
2148   return result;
2149 }
2150
2151
2152 \f
2153 gcry_sexp_t
2154 gcry_pk_get_param (int algo, const char *name)
2155 {
2156   gcry_sexp_t result = NULL;
2157   gcry_pk_spec_t *spec = NULL;
2158
2159   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
2160     return NULL;
2161
2162   spec = spec_from_name ("ecc");
2163   if (spec)
2164     {
2165       if (spec && spec->get_curve_param)
2166         result = spec->get_curve_param (name);
2167     }
2168   return result;
2169 }
2170
2171
2172 \f
2173 gcry_error_t
2174 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
2175 {
2176   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2177
2178   switch (cmd)
2179     {
2180     case GCRYCTL_DISABLE_ALGO:
2181       /* This one expects a buffer pointing to an integer with the
2182          algo number.  */
2183       if ((! buffer) || (buflen != sizeof (int)))
2184         err = GPG_ERR_INV_ARG;
2185       else
2186         disable_pubkey_algo (*((int *) buffer));
2187       break;
2188
2189     default:
2190       err = GPG_ERR_INV_OP;
2191     }
2192
2193   return gcry_error (err);
2194 }
2195
2196
2197 /* Return information about the given algorithm
2198
2199    WHAT selects the kind of information returned:
2200
2201     GCRYCTL_TEST_ALGO:
2202         Returns 0 when the specified algorithm is available for use.
2203         Buffer must be NULL, nbytes  may have the address of a variable
2204         with the required usage of the algorithm. It may be 0 for don't
2205         care or a combination of the GCRY_PK_USAGE_xxx flags;
2206
2207     GCRYCTL_GET_ALGO_USAGE:
2208         Return the usage flags for the given algo.  An invalid algo
2209         returns 0.  Disabled algos are ignored here because we
2210         only want to know whether the algo is at all capable of
2211         the usage.
2212
2213    Note: Because this function is in most cases used to return an
2214    integer value, we can make it easier for the caller to just look at
2215    the return value.  The caller will in all cases consult the value
2216    and thereby detecting whether a error occurred or not (i.e. while
2217    checking the block size) */
2218 gcry_error_t
2219 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
2220 {
2221   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2222
2223   switch (what)
2224     {
2225     case GCRYCTL_TEST_ALGO:
2226       {
2227         int use = nbytes ? *nbytes : 0;
2228         if (buffer)
2229           err = GPG_ERR_INV_ARG;
2230         else if (check_pubkey_algo (algorithm, use))
2231           err = GPG_ERR_PUBKEY_ALGO;
2232         break;
2233       }
2234
2235     case GCRYCTL_GET_ALGO_USAGE:
2236       {
2237         gcry_pk_spec_t *spec;
2238
2239         spec = spec_from_algo (algorithm);
2240         *nbytes = spec? spec->use : 0;
2241         break;
2242       }
2243
2244     case GCRYCTL_GET_ALGO_NPKEY:
2245       {
2246         /* FIXME?  */
2247         int npkey = pubkey_get_npkey (algorithm);
2248         *nbytes = npkey;
2249         break;
2250       }
2251     case GCRYCTL_GET_ALGO_NSKEY:
2252       {
2253         /* FIXME?  */
2254         int nskey = pubkey_get_nskey (algorithm);
2255         *nbytes = nskey;
2256         break;
2257       }
2258     case GCRYCTL_GET_ALGO_NSIGN:
2259       {
2260         /* FIXME?  */
2261         int nsign = pubkey_get_nsig (algorithm);
2262         *nbytes = nsign;
2263         break;
2264       }
2265     case GCRYCTL_GET_ALGO_NENCR:
2266       {
2267         /* FIXME?  */
2268         int nencr = pubkey_get_nenc (algorithm);
2269         *nbytes = nencr;
2270         break;
2271       }
2272
2273     default:
2274       err = GPG_ERR_INV_OP;
2275     }
2276
2277   return gcry_error (err);
2278 }
2279
2280
2281 /* Return an S-expression representing the context CTX.  Depending on
2282    the state of that context, the S-expression may either be a public
2283    key, a private key or any other object used with public key
2284    operations.  On success a new S-expression is stored at R_SEXP and
2285    0 is returned, on error NULL is store there and an error code is
2286    returned.  MODE is either 0 or one of the GCRY_PK_GET_xxx values.
2287
2288    As of now it only support certain ECC operations because a context
2289    object is right now only defined for ECC.  Over time this function
2290    will be extended to cover more algorithms.  Note also that the name
2291    of the function is gcry_pubkey_xxx and not gcry_pk_xxx.  The idea
2292    is that we will eventually provide variants of the existing
2293    gcry_pk_xxx functions which will take a context parameter.   */
2294 gcry_err_code_t
2295 _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
2296 {
2297   mpi_ec_t ec;
2298
2299   if (!r_sexp)
2300     return GPG_ERR_INV_VALUE;
2301   *r_sexp = NULL;
2302   switch (mode)
2303     {
2304     case 0:
2305     case GCRY_PK_GET_PUBKEY:
2306     case GCRY_PK_GET_SECKEY:
2307       break;
2308     default:
2309       return GPG_ERR_INV_VALUE;
2310     }
2311   if (!ctx)
2312     return GPG_ERR_NO_CRYPT_CTX;
2313
2314   ec = _gcry_ctx_find_pointer (ctx, CONTEXT_TYPE_EC);
2315   if (ec)
2316     return _gcry_pk_ecc_get_sexp (r_sexp, mode, ec);
2317
2318   return GPG_ERR_WRONG_CRYPT_CTX;
2319 }
2320
2321
2322 \f
2323 /* Explicitly initialize this module.  */
2324 gcry_err_code_t
2325 _gcry_pk_init (void)
2326 {
2327   return 0;
2328 }
2329
2330
2331 /* Run the selftests for pubkey algorithm ALGO with optional reporting
2332    function REPORT.  */
2333 gpg_error_t
2334 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
2335 {
2336   gcry_err_code_t ec;
2337   gcry_pk_spec_t *spec = spec_from_algo (algo);
2338
2339   if (spec && spec->selftest)
2340     ec = spec->selftest (algo, extended, report);
2341   else
2342     {
2343       ec = GPG_ERR_PUBKEY_ALGO;
2344       if (report)
2345         report ("pubkey", algo, "module",
2346                 spec && !spec->flags.disabled?
2347                 "no selftest available" :
2348                 spec? "algorithm disabled" :
2349                 "algorithm not found");
2350     }
2351
2352   return gpg_error (ec);
2353 }