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