pk: Remove unused function.
[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 *ret_modern, 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   *ret_modern = 0;
730
731   /* Check that the first element is valid.  */
732   list = gcry_sexp_find_token (sexp, "enc-val" , 0);
733   if (!list)
734     {
735       err = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
736       goto leave;
737     }
738
739   l2 = gcry_sexp_nth (list, 1);
740   if (!l2)
741     {
742       err = GPG_ERR_NO_OBJ; /* No cdr for the data object.  */
743       goto leave;
744     }
745
746   /* Extract identifier of sublist.  */
747   name = _gcry_sexp_nth_string (l2, 0);
748   if (!name)
749     {
750       err = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
751       goto leave;
752     }
753
754   if (!strcmp (name, "flags"))
755     {
756       /* There is a flags element - process it.  */
757       const char *s;
758       int i;
759
760       *ret_modern = 1;
761       for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
762         {
763           s = gcry_sexp_nth_data (l2, i, &n);
764           if (! s)
765             ; /* Not a data element - ignore.  */
766           else if (n == 3 && !memcmp (s, "raw", 3)
767                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
768             ctx->encoding = PUBKEY_ENC_RAW;
769           else if (n == 5 && !memcmp (s, "pkcs1", 5)
770                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
771             ctx->encoding = PUBKEY_ENC_PKCS1;
772           else if (n == 4 && !memcmp (s, "oaep", 4)
773                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
774             ctx->encoding = PUBKEY_ENC_OAEP;
775           else if (n == 3 && !memcmp (s, "pss", 3)
776                    && ctx->encoding == PUBKEY_ENC_UNKNOWN)
777             {
778               err = GPG_ERR_CONFLICT;
779               goto leave;
780             }
781           else if (n == 11 && ! memcmp (s, "no-blinding", 11))
782             parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
783           else
784             {
785               err = GPG_ERR_INV_FLAG;
786               goto leave;
787             }
788         }
789       gcry_sexp_release (l2);
790
791       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
792       if (ctx->encoding == PUBKEY_ENC_OAEP)
793         {
794           /* Get HASH-ALGO. */
795           l2 = gcry_sexp_find_token (list, "hash-algo", 0);
796           if (l2)
797             {
798               s = gcry_sexp_nth_data (l2, 1, &n);
799               if (!s)
800                 err = GPG_ERR_NO_OBJ;
801               else
802                 {
803                   ctx->hash_algo = get_hash_algo (s, n);
804                   if (!ctx->hash_algo)
805                     err = GPG_ERR_DIGEST_ALGO;
806                 }
807               gcry_sexp_release (l2);
808               if (err)
809                 goto leave;
810             }
811
812           /* Get LABEL. */
813           l2 = gcry_sexp_find_token (list, "label", 0);
814           if (l2)
815             {
816               s = gcry_sexp_nth_data (l2, 1, &n);
817               if (!s)
818                 err = GPG_ERR_NO_OBJ;
819               else if (n > 0)
820                 {
821                   ctx->label = gcry_malloc (n);
822                   if (!ctx->label)
823                     err = gpg_err_code_from_syserror ();
824                   else
825                     {
826                       memcpy (ctx->label, s, n);
827                       ctx->labellen = n;
828                     }
829                 }
830               gcry_sexp_release (l2);
831               if (err)
832                 goto leave;
833             }
834         }
835
836       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
837       for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
838         {
839           s = gcry_sexp_nth_data (l2, 0, &n);
840           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
841               && !(n == 5 && !memcmp (s, "label", 5))
842               && !(n == 15 && !memcmp (s, "random-override", 15)))
843             break;
844           gcry_sexp_release (l2);
845         }
846
847       if (!l2)
848         {
849           err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
850           goto leave;
851         }
852
853       /* Extract sublist identifier.  */
854       gcry_free (name);
855       name = _gcry_sexp_nth_string (l2, 0);
856       if (!name)
857         {
858           err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
859           goto leave;
860         }
861
862       gcry_sexp_release (list);
863       list = l2;
864       l2 = NULL;
865     }
866
867   spec = spec_from_name (name);
868   if (!spec)
869     {
870       err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
871       goto leave;
872     }
873
874   elems = spec->elements_enc;
875   array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
876   if (!array)
877     {
878       err = gpg_err_code_from_syserror ();
879       goto leave;
880     }
881
882   err = sexp_elements_extract (list, elems, array, NULL, 0);
883
884  leave:
885   gcry_sexp_release (list);
886   gcry_sexp_release (l2);
887   gcry_free (name);
888
889   if (err)
890     {
891       gcry_free (array);
892       gcry_free (ctx->label);
893       ctx->label = NULL;
894     }
895   else
896     {
897       *retarray = array;
898       *r_spec = spec;
899       *flags = parsed_flags;
900     }
901
902   return err;
903 }
904
905
906 /* Callback for the pubkey algorithm code to verify PSS signatures.
907    OPAQUE is the data provided by the actual caller.  The meaning of
908    TMP depends on the actual algorithm (but there is only RSA); now
909    for RSA it is the output of running the public key function on the
910    input.  */
911 static int
912 pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
913 {
914   struct pk_encoding_ctx *ctx = opaque;
915   gcry_mpi_t hash = ctx->verify_arg;
916
917   return _gcry_rsa_pss_verify (hash, tmp, ctx->nbits - 1,
918                                ctx->hash_algo, ctx->saltlen);
919 }
920
921
922 /* Take the hash value and convert into an MPI, suitable for
923    passing to the low level functions.  We currently support the
924    old style way of passing just a MPI and the modern interface which
925    allows to pass flags so that we can choose between raw and pkcs1
926    padding - may be more padding options later.
927
928    (<mpi>)
929    or
930    (data
931     [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
932     [(hash <algo> <value>)]
933     [(value <text>)]
934     [(hash-algo <algo>)]
935     [(label <label>)]
936     [(salt-length <length>)]
937     [(random-override <data>)]
938    )
939
940    Either the VALUE or the HASH element must be present for use
941    with signatures.  VALUE is used for encryption.
942
943    HASH-ALGO is specific to OAEP and EDDSA.
944
945    LABEL is specific to OAEP.
946
947    SALT-LENGTH is for PSS.
948
949    RANDOM-OVERRIDE is used to replace random nonces for regression
950    testing.  */
951 static gcry_err_code_t
952 sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
953                   struct pk_encoding_ctx *ctx)
954 {
955   gcry_err_code_t rc = 0;
956   gcry_sexp_t ldata, lhash, lvalue;
957   int i;
958   size_t n;
959   const char *s;
960   int unknown_flag = 0;
961   int parsed_flags = 0;
962   int explicit_raw = 0;
963
964   *ret_mpi = NULL;
965   ldata = gcry_sexp_find_token (input, "data", 0);
966   if (!ldata)
967     { /* assume old style */
968       *ret_mpi = gcry_sexp_nth_mpi (input, 0, 0);
969       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
970     }
971
972   /* see whether there is a flags object */
973   {
974     gcry_sexp_t lflags = gcry_sexp_find_token (ldata, "flags", 0);
975     if (lflags)
976       { /* parse the flags list. */
977         for (i=gcry_sexp_length (lflags)-1; i > 0; i--)
978           {
979             s = gcry_sexp_nth_data (lflags, i, &n);
980             if (!s)
981               ; /* not a data element*/
982             else if (n == 7 && !memcmp (s, "rfc6979", 7))
983               parsed_flags |= PUBKEY_FLAG_RFC6979;
984             else if (n == 5 && !memcmp (s, "eddsa", 5))
985               {
986                 ctx->encoding = PUBKEY_ENC_RAW;
987                 parsed_flags |= PUBKEY_FLAG_EDDSA;
988               }
989             else if ( n == 3 && !memcmp (s, "raw", 3)
990                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
991               {
992                 ctx->encoding = PUBKEY_ENC_RAW;
993                 explicit_raw = 1;
994               }
995             else if ( n == 5 && !memcmp (s, "pkcs1", 5)
996                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
997               {
998                 ctx->encoding = PUBKEY_ENC_PKCS1;
999                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
1000               }
1001             else if ( n == 4 && !memcmp (s, "oaep", 4)
1002                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1003               {
1004                 ctx->encoding = PUBKEY_ENC_OAEP;
1005                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
1006               }
1007             else if ( n == 3 && !memcmp (s, "pss", 3)
1008                       && ctx->encoding == PUBKEY_ENC_UNKNOWN)
1009               {
1010                 ctx->encoding = PUBKEY_ENC_PSS;
1011                 parsed_flags |= PUBKEY_FLAG_FIXEDLEN;
1012               }
1013             else if (n == 11 && ! memcmp (s, "no-blinding", 11))
1014               parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
1015             else
1016               unknown_flag = 1;
1017           }
1018         gcry_sexp_release (lflags);
1019       }
1020   }
1021
1022   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
1023     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
1024
1025   /* Get HASH or MPI */
1026   lhash = gcry_sexp_find_token (ldata, "hash", 0);
1027   lvalue = lhash? NULL : gcry_sexp_find_token (ldata, "value", 0);
1028
1029   if (!(!lhash ^ !lvalue))
1030     rc = GPG_ERR_INV_OBJ; /* none or both given */
1031   else if (unknown_flag)
1032     rc = GPG_ERR_INV_FLAG;
1033   else if (ctx->encoding == PUBKEY_ENC_RAW
1034            && (parsed_flags & PUBKEY_FLAG_EDDSA))
1035     {
1036       /* Prepare for EdDSA.  */
1037       gcry_sexp_t list;
1038       void *value;
1039       size_t valuelen;
1040
1041       if (!lvalue)
1042         {
1043           rc = GPG_ERR_INV_OBJ;
1044           goto leave;
1045         }
1046       /* Get HASH-ALGO. */
1047       list = gcry_sexp_find_token (ldata, "hash-algo", 0);
1048       if (list)
1049         {
1050           s = gcry_sexp_nth_data (list, 1, &n);
1051           if (!s)
1052             rc = GPG_ERR_NO_OBJ;
1053           else
1054             {
1055               ctx->hash_algo = get_hash_algo (s, n);
1056               if (!ctx->hash_algo)
1057                 rc = GPG_ERR_DIGEST_ALGO;
1058             }
1059           gcry_sexp_release (list);
1060         }
1061       else
1062         rc = GPG_ERR_INV_OBJ;
1063       if (rc)
1064         goto leave;
1065
1066       /* Get VALUE.  */
1067       value = gcry_sexp_nth_buffer (lvalue, 1, &valuelen);
1068       if (!value)
1069         {
1070           /* We assume that a zero length message is meant by
1071              "(value)".  This is commonly used by test vectors.  Note
1072              that S-expression do not allow zero length items. */
1073           valuelen = 0;
1074           value = gcry_malloc (1);
1075           if (!value)
1076             rc = gpg_err_code_from_syserror ();
1077         }
1078       else if ((valuelen * 8) < valuelen)
1079         {
1080           gcry_free (value);
1081           rc = GPG_ERR_TOO_LARGE;
1082         }
1083       if (rc)
1084         goto leave;
1085
1086       /* Note that mpi_set_opaque takes ownership of VALUE.  */
1087       *ret_mpi = gcry_mpi_set_opaque (NULL, value, valuelen*8);
1088     }
1089   else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
1090            && (explicit_raw || (parsed_flags & PUBKEY_FLAG_RFC6979)))
1091     {
1092       /* Raw encoding along with a hash element.  This is commonly
1093          used for DSA.  For better backward error compatibility we
1094          allow this only if either the rfc6979 flag has been given or
1095          the raw flags was explicitly given.  */
1096       if (gcry_sexp_length (lhash) != 3)
1097         rc = GPG_ERR_INV_OBJ;
1098       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1099         rc = GPG_ERR_INV_OBJ;
1100       else
1101         {
1102           void *value;
1103           size_t valuelen;
1104
1105           ctx->hash_algo = get_hash_algo (s, n);
1106           if (!ctx->hash_algo)
1107             rc = GPG_ERR_DIGEST_ALGO;
1108           else if (!(value=gcry_sexp_nth_buffer (lhash, 2, &valuelen)))
1109             rc = GPG_ERR_INV_OBJ;
1110           else if ((valuelen * 8) < valuelen)
1111             {
1112               gcry_free (value);
1113               rc = GPG_ERR_TOO_LARGE;
1114             }
1115           else
1116             *ret_mpi = gcry_mpi_set_opaque (NULL, value, valuelen*8);
1117         }
1118     }
1119   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
1120     {
1121       /* RFC6969 may only be used with the a hash value and not the
1122          MPI based value.  */
1123       if (parsed_flags & PUBKEY_FLAG_RFC6979)
1124         {
1125           rc = GPG_ERR_CONFLICT;
1126           goto leave;
1127         }
1128
1129       /* Get the value */
1130       *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
1131       if (!*ret_mpi)
1132         rc = GPG_ERR_INV_OBJ;
1133     }
1134   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
1135            && ctx->op == PUBKEY_OP_ENCRYPT)
1136     {
1137       const void * value;
1138       size_t valuelen;
1139       gcry_sexp_t list;
1140       void *random_override = NULL;
1141       size_t random_override_len = 0;
1142
1143       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1144         rc = GPG_ERR_INV_OBJ;
1145       else
1146         {
1147           /* Get optional RANDOM-OVERRIDE.  */
1148           list = gcry_sexp_find_token (ldata, "random-override", 0);
1149           if (list)
1150             {
1151               s = gcry_sexp_nth_data (list, 1, &n);
1152               if (!s)
1153                 rc = GPG_ERR_NO_OBJ;
1154               else if (n > 0)
1155                 {
1156                   random_override = gcry_malloc (n);
1157                   if (!random_override)
1158                     rc = gpg_err_code_from_syserror ();
1159                   else
1160                     {
1161                       memcpy (random_override, s, n);
1162                       random_override_len = n;
1163                     }
1164                 }
1165               gcry_sexp_release (list);
1166               if (rc)
1167                 goto leave;
1168             }
1169
1170           rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
1171                                                value, valuelen,
1172                                                random_override,
1173                                                random_override_len);
1174           gcry_free (random_override);
1175         }
1176     }
1177   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
1178            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
1179     {
1180       if (gcry_sexp_length (lhash) != 3)
1181         rc = GPG_ERR_INV_OBJ;
1182       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1183         rc = GPG_ERR_INV_OBJ;
1184       else
1185         {
1186           const void * value;
1187           size_t valuelen;
1188
1189           ctx->hash_algo = get_hash_algo (s, n);
1190
1191           if (!ctx->hash_algo)
1192             rc = GPG_ERR_DIGEST_ALGO;
1193           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1194                     || !valuelen )
1195             rc = GPG_ERR_INV_OBJ;
1196           else
1197             rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
1198                                                  value, valuelen,
1199                                                  ctx->hash_algo);
1200         }
1201     }
1202   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
1203            && ctx->op == PUBKEY_OP_ENCRYPT)
1204     {
1205       const void * value;
1206       size_t valuelen;
1207
1208       if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
1209         rc = GPG_ERR_INV_OBJ;
1210       else
1211         {
1212           gcry_sexp_t list;
1213           void *random_override = NULL;
1214           size_t random_override_len = 0;
1215
1216           /* Get HASH-ALGO. */
1217           list = gcry_sexp_find_token (ldata, "hash-algo", 0);
1218           if (list)
1219             {
1220               s = gcry_sexp_nth_data (list, 1, &n);
1221               if (!s)
1222                 rc = GPG_ERR_NO_OBJ;
1223               else
1224                 {
1225                   ctx->hash_algo = get_hash_algo (s, n);
1226                   if (!ctx->hash_algo)
1227                     rc = GPG_ERR_DIGEST_ALGO;
1228                 }
1229               gcry_sexp_release (list);
1230               if (rc)
1231                 goto leave;
1232             }
1233
1234           /* Get LABEL. */
1235           list = gcry_sexp_find_token (ldata, "label", 0);
1236           if (list)
1237             {
1238               s = gcry_sexp_nth_data (list, 1, &n);
1239               if (!s)
1240                 rc = GPG_ERR_NO_OBJ;
1241               else if (n > 0)
1242                 {
1243                   ctx->label = gcry_malloc (n);
1244                   if (!ctx->label)
1245                     rc = gpg_err_code_from_syserror ();
1246                   else
1247                     {
1248                       memcpy (ctx->label, s, n);
1249                       ctx->labellen = n;
1250                     }
1251                 }
1252               gcry_sexp_release (list);
1253               if (rc)
1254                 goto leave;
1255             }
1256           /* Get optional RANDOM-OVERRIDE.  */
1257           list = gcry_sexp_find_token (ldata, "random-override", 0);
1258           if (list)
1259             {
1260               s = gcry_sexp_nth_data (list, 1, &n);
1261               if (!s)
1262                 rc = GPG_ERR_NO_OBJ;
1263               else if (n > 0)
1264                 {
1265                   random_override = gcry_malloc (n);
1266                   if (!random_override)
1267                     rc = gpg_err_code_from_syserror ();
1268                   else
1269                     {
1270                       memcpy (random_override, s, n);
1271                       random_override_len = n;
1272                     }
1273                 }
1274               gcry_sexp_release (list);
1275               if (rc)
1276                 goto leave;
1277             }
1278
1279           rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
1280                                       value, valuelen,
1281                                       ctx->label, ctx->labellen,
1282                                       random_override, random_override_len);
1283
1284           gcry_free (random_override);
1285         }
1286     }
1287   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1288            && ctx->op == PUBKEY_OP_SIGN)
1289     {
1290       if (gcry_sexp_length (lhash) != 3)
1291         rc = GPG_ERR_INV_OBJ;
1292       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1293         rc = GPG_ERR_INV_OBJ;
1294       else
1295         {
1296           const void * value;
1297           size_t valuelen;
1298           void *random_override = NULL;
1299           size_t random_override_len = 0;
1300
1301           ctx->hash_algo = get_hash_algo (s, n);
1302
1303           if (!ctx->hash_algo)
1304             rc = GPG_ERR_DIGEST_ALGO;
1305           else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
1306                     || !valuelen )
1307             rc = GPG_ERR_INV_OBJ;
1308           else
1309             {
1310               gcry_sexp_t list;
1311
1312               /* Get SALT-LENGTH. */
1313               list = gcry_sexp_find_token (ldata, "salt-length", 0);
1314               if (list)
1315                 {
1316                   s = gcry_sexp_nth_data (list, 1, &n);
1317                   if (!s)
1318                     {
1319                       rc = GPG_ERR_NO_OBJ;
1320                       goto leave;
1321                     }
1322                   ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
1323                   gcry_sexp_release (list);
1324                 }
1325
1326               /* Get optional RANDOM-OVERRIDE.  */
1327               list = gcry_sexp_find_token (ldata, "random-override", 0);
1328               if (list)
1329                 {
1330                   s = gcry_sexp_nth_data (list, 1, &n);
1331                   if (!s)
1332                     rc = GPG_ERR_NO_OBJ;
1333                   else if (n > 0)
1334                     {
1335                       random_override = gcry_malloc (n);
1336                       if (!random_override)
1337                         rc = gpg_err_code_from_syserror ();
1338                       else
1339                         {
1340                           memcpy (random_override, s, n);
1341                           random_override_len = n;
1342                         }
1343                     }
1344                   gcry_sexp_release (list);
1345                   if (rc)
1346                     goto leave;
1347                 }
1348
1349               /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
1350               rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
1351                                          ctx->hash_algo,
1352                                          value, valuelen, ctx->saltlen,
1353                                          random_override, random_override_len);
1354
1355               gcry_free (random_override);
1356             }
1357         }
1358     }
1359   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1360            && ctx->op == PUBKEY_OP_VERIFY)
1361     {
1362       if (gcry_sexp_length (lhash) != 3)
1363         rc = GPG_ERR_INV_OBJ;
1364       else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
1365         rc = GPG_ERR_INV_OBJ;
1366       else
1367         {
1368           ctx->hash_algo = get_hash_algo (s, n);
1369
1370           if (!ctx->hash_algo)
1371             rc = GPG_ERR_DIGEST_ALGO;
1372           else
1373             {
1374               *ret_mpi = gcry_sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
1375               if (!*ret_mpi)
1376                 rc = GPG_ERR_INV_OBJ;
1377               ctx->verify_cmp = pss_verify_cmp;
1378               ctx->verify_arg = *ret_mpi;
1379             }
1380         }
1381     }
1382   else
1383     rc = GPG_ERR_CONFLICT;
1384
1385  leave:
1386   gcry_sexp_release (ldata);
1387   gcry_sexp_release (lhash);
1388   gcry_sexp_release (lvalue);
1389
1390   if (!rc)
1391     ctx->flags = parsed_flags;
1392   else
1393     {
1394       gcry_free (ctx->label);
1395       ctx->label = NULL;
1396     }
1397
1398   return rc;
1399 }
1400
1401 static void
1402 init_encoding_ctx (struct pk_encoding_ctx *ctx, enum pk_operation op,
1403                    unsigned int nbits)
1404 {
1405   ctx->op = op;
1406   ctx->nbits = nbits;
1407   ctx->encoding = PUBKEY_ENC_UNKNOWN;
1408   ctx->flags = 0;
1409   ctx->hash_algo = GCRY_MD_SHA1;
1410   ctx->label = NULL;
1411   ctx->labellen = 0;
1412   ctx->saltlen = 20;
1413   ctx->verify_cmp = NULL;
1414   ctx->verify_arg = NULL;
1415 }
1416
1417
1418 /*
1419    Do a PK encrypt operation
1420
1421    Caller has to provide a public key as the SEXP pkey and data as a
1422    SEXP with just one MPI in it. Alternatively S_DATA might be a
1423    complex S-Expression, similar to the one used for signature
1424    verification.  This provides a flag which allows to handle PKCS#1
1425    block type 2 padding.  The function returns a sexp which may be
1426    passed to to pk_decrypt.
1427
1428    Returns: 0 or an errorcode.
1429
1430    s_data = See comment for sexp_data_to_mpi
1431    s_pkey = <key-as-defined-in-sexp_to_key>
1432    r_ciph = (enc-val
1433                (<algo>
1434                  (<param_name1> <mpi>)
1435                  ...
1436                  (<param_namen> <mpi>)
1437                ))
1438
1439 */
1440 gcry_error_t
1441 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
1442 {
1443   gcry_err_code_t rc;
1444   gcry_mpi_t *pkey = NULL;
1445   gcry_mpi_t data = NULL;
1446   struct pk_encoding_ctx ctx;
1447   gcry_pk_spec_t *spec = NULL;
1448   int i;
1449
1450   *r_ciph = NULL;
1451
1452   /* Get the key. */
1453   rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_ENCR, NULL, &pkey, &spec, NULL);
1454   if (rc)
1455     goto leave;
1456
1457   gcry_assert (spec);
1458
1459   /* Get the stuff we want to encrypt. */
1460   init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
1461   rc = sexp_data_to_mpi (s_data, &data, &ctx);
1462   if (rc)
1463     goto leave;
1464
1465   /* In fips mode DBG_CIPHER will never evaluate to true but as an
1466      extra failsafe protection we explicitly test for fips mode
1467      here. */
1468   if (DBG_CIPHER && !fips_mode ())
1469     {
1470       log_debug ("pubkey_encrypt: algo=%d\n", spec->algo);
1471       for(i = 0; i < pubkey_get_npkey (spec->algo); i++)
1472         log_mpidump ("  pkey", pkey[i]);
1473       log_mpidump ("  data", data);
1474     }
1475
1476   if (spec->encrypt)
1477     rc = spec->encrypt (spec->algo, r_ciph, data, pkey, ctx.flags);
1478   else
1479     rc = GPG_ERR_NOT_IMPLEMENTED;
1480
1481
1482   /* if (DBG_CIPHER && !fips_mode ()) */
1483   /*   { */
1484   /*     for (i = 0; i < pubkey_get_nenc (spec->algo); i++) */
1485   /*       log_mpidump ("  encr", ciph[i]); */
1486   /*   } */
1487
1488  leave:
1489   mpi_free (data);
1490   if (pkey)
1491     {
1492       release_mpi_array (pkey);
1493       gcry_free (pkey);
1494     }
1495
1496   gcry_free (ctx.label);
1497
1498   return gcry_error (rc);
1499 }
1500
1501
1502 /*
1503    Do a PK decrypt operation
1504
1505    Caller has to provide a secret key as the SEXP skey and data in a
1506    format as created by gcry_pk_encrypt.  For historic reasons the
1507    function returns simply an MPI as an S-expression part; this is
1508    deprecated and the new method should be used which returns a real
1509    S-expressionl this is selected by adding at least an empty flags
1510    list to S_DATA.
1511
1512    Returns: 0 or an errorcode.
1513
1514    s_data = (enc-val
1515               [(flags [raw, pkcs1, oaep])]
1516               (<algo>
1517                 (<param_name1> <mpi>)
1518                 ...
1519                 (<param_namen> <mpi>)
1520               ))
1521    s_skey = <key-as-defined-in-sexp_to_key>
1522    r_plain= Either an incomplete S-expression without the parentheses
1523             or if the flags list is used (even if empty) a real S-expression:
1524             (value PLAIN).  In raw mode (or no flags given) the returned value
1525             is to be interpreted as a signed MPI, thus it may have an extra
1526             leading zero octet even if not included in the original data.
1527             With pkcs1 or oaep decoding enabled the returned value is a
1528             verbatim octet string.
1529  */
1530 gcry_error_t
1531 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
1532 {
1533   gcry_err_code_t rc;
1534   gcry_mpi_t *skey = NULL;
1535   gcry_mpi_t *data = NULL;
1536   gcry_mpi_t plain = NULL;
1537   unsigned char *unpad = NULL;
1538   size_t unpadlen = 0;
1539   int i;
1540   int modern, flags;
1541   struct pk_encoding_ctx ctx;
1542   gcry_pk_spec_t *spec = NULL;
1543   gcry_pk_spec_t *spec_enc = NULL;
1544
1545   *r_plain = NULL;
1546   ctx.label = NULL;
1547
1548   rc = sexp_to_key (s_skey, 1, GCRY_PK_USAGE_ENCR, NULL,
1549                     &skey, &spec, NULL);
1550   if (rc)
1551     goto leave;
1552
1553   init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, gcry_pk_get_nbits (s_skey));
1554   rc = sexp_to_enc (s_data, &data, &spec_enc, &modern, &flags, &ctx);
1555   if (rc)
1556     goto leave;
1557
1558   if (spec->algo != spec_enc->algo)
1559     {
1560       rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
1561       goto leave;
1562     }
1563
1564   if (DBG_CIPHER && !fips_mode ())
1565     {
1566       log_debug ("gcry_pk_decrypt: algo=%d\n", spec->algo);
1567       for(i = 0; i < pubkey_get_nskey (spec->algo); i++)
1568         log_mpidump ("  skey", skey[i]);
1569       for(i = 0; i < pubkey_get_nenc (spec->algo); i++)
1570         log_mpidump ("  data", data[i]);
1571     }
1572
1573   if (spec->decrypt)
1574     rc = spec->decrypt (spec->algo, &plain, data, skey, flags);
1575   else
1576     rc = GPG_ERR_NOT_IMPLEMENTED;
1577   if (rc)
1578     goto leave;
1579
1580   if (DBG_CIPHER && !fips_mode ())
1581     log_mpidump (" plain", plain);
1582
1583   /* Do un-padding if necessary. */
1584   switch (ctx.encoding)
1585     {
1586     case PUBKEY_ENC_PKCS1:
1587       rc = _gcry_rsa_pkcs1_decode_for_enc (&unpad, &unpadlen,
1588                                            gcry_pk_get_nbits (s_skey),
1589                                            plain);
1590       mpi_free (plain);
1591       plain = NULL;
1592       if (!rc)
1593         rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
1594                                              (int)unpadlen, unpad));
1595       break;
1596
1597     case PUBKEY_ENC_OAEP:
1598       rc = _gcry_rsa_oaep_decode (&unpad, &unpadlen,
1599                                   gcry_pk_get_nbits (s_skey), ctx.hash_algo,
1600                                   plain, ctx.label, ctx.labellen);
1601       mpi_free (plain);
1602       plain = NULL;
1603       if (!rc)
1604         rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
1605                                              (int)unpadlen, unpad));
1606       break;
1607
1608     default:
1609       /* Raw format.  For backward compatibility we need to assume a
1610          signed mpi by using the sexp format string "%m".  */
1611       rc = gcry_err_code (gcry_sexp_build
1612                           (r_plain, NULL, modern? "(value %m)" : "%m", plain));
1613       break;
1614     }
1615
1616  leave:
1617   gcry_free (unpad);
1618
1619   if (skey)
1620     {
1621       release_mpi_array (skey);
1622       gcry_free (skey);
1623     }
1624
1625   mpi_free (plain);
1626
1627   if (data)
1628     {
1629       release_mpi_array (data);
1630       gcry_free (data);
1631     }
1632
1633   gcry_free (ctx.label);
1634
1635   return gcry_error (rc);
1636 }
1637
1638
1639
1640 /*
1641    Create a signature.
1642
1643    Caller has to provide a secret key as the SEXP skey and data
1644    expressed as a SEXP list hash with only one element which should
1645    instantly be available as a MPI. Alternatively the structure given
1646    below may be used for S_HASH, it provides the abiliy to pass flags
1647    to the operation; the flags defined by now are "pkcs1" which does
1648    PKCS#1 block type 1 style padding and "pss" for PSS encoding.
1649
1650    Returns: 0 or an errorcode.
1651             In case of 0 the function returns a new SEXP with the
1652             signature value; the structure of this signature depends on the
1653             other arguments but is always suitable to be passed to
1654             gcry_pk_verify
1655
1656    s_hash = See comment for sexp_data_to_mpi
1657
1658    s_skey = <key-as-defined-in-sexp_to_key>
1659    r_sig  = (sig-val
1660               (<algo>
1661                 (<param_name1> <mpi>)
1662                 ...
1663                 (<param_namen> <mpi>))
1664              [(hash algo)])
1665
1666   Note that (hash algo) in R_SIG is not used.
1667 */
1668 gcry_error_t
1669 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
1670 {
1671   gcry_mpi_t *skey = NULL;
1672   gcry_mpi_t hash = NULL;
1673   gcry_pk_spec_t *spec = NULL;
1674   struct pk_encoding_ctx ctx;
1675   int i;
1676   int is_ecc;
1677   gcry_err_code_t rc;
1678
1679   *r_sig = NULL;
1680
1681   rc = sexp_to_key (s_skey, 1, GCRY_PK_USAGE_SIGN, NULL,
1682                     &skey, &spec, &is_ecc);
1683   if (rc)
1684     goto leave;
1685
1686   gcry_assert (spec);
1687
1688   /* Get the stuff we want to sign.  Note that pk_get_nbits does also
1689      work on a private key.  We don't need the number of bits for ECC
1690      here, thus set it to 0 so that we don't need to parse it.  */
1691   init_encoding_ctx (&ctx, PUBKEY_OP_SIGN,
1692                      is_ecc? 0 : gcry_pk_get_nbits (s_skey));
1693   rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
1694   if (rc)
1695     goto leave;
1696
1697   if (DBG_CIPHER && !fips_mode ())
1698     {
1699       log_debug ("gcry_pk_sign: algo=%d\n", spec->algo);
1700       for(i = 0; i < pubkey_get_nskey (spec->algo); i++)
1701         log_mpidump ("  skey", skey[i]);
1702       log_mpidump("  data", hash);
1703     }
1704
1705   if (spec->sign)
1706     rc = spec->sign (spec->algo, r_sig, hash, skey, ctx.flags, ctx.hash_algo);
1707   else
1708     rc = GPG_ERR_NOT_IMPLEMENTED;
1709
1710   if (rc)
1711     goto leave;
1712
1713   /* Fixme: To print the result we need to print an sexp.  */
1714   /* if (!rc && DBG_CIPHER && !fips_mode ()) */
1715   /*   for (i = 0; i < pubkey_get_nsig (algo); i++) */
1716   /*     log_mpidump ("   sig", resarr[i]); */
1717
1718  leave:
1719   if (skey)
1720     {
1721       if (is_ecc)
1722         /* Q is optional and may be NULL, while there is D after Q.  */
1723         for (i = 0; i < 7; i++)
1724           {
1725             if (skey[i])
1726               mpi_free (skey[i]);
1727             skey[i] = NULL;
1728           }
1729       else
1730         release_mpi_array (skey);
1731       gcry_free (skey);
1732     }
1733
1734   mpi_free (hash);
1735
1736   return gcry_error (rc);
1737 }
1738
1739
1740 /*
1741    Verify a signature.
1742
1743    Caller has to supply the public key pkey, the signature sig and his
1744    hashvalue data.  Public key has to be a standard public key given
1745    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
1746    must be an S-Exp like the one in sign too.  */
1747 gcry_error_t
1748 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
1749 {
1750   gcry_err_code_t rc;
1751   gcry_pk_spec_t *spec = NULL;
1752   gcry_pk_spec_t *spec_sig = NULL;
1753   gcry_mpi_t *pkey = NULL;
1754   gcry_mpi_t hash = NULL;
1755   gcry_mpi_t *sig = NULL;
1756   struct pk_encoding_ctx ctx;
1757   int i;
1758
1759   rc = sexp_to_key (s_pkey, 0, GCRY_PK_USAGE_SIGN, NULL,
1760                     &pkey, &spec, NULL);
1761   if (rc)
1762     goto leave;
1763
1764   /* Get the stuff we want to verify. */
1765   init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, gcry_pk_get_nbits (s_pkey));
1766   rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
1767   if (rc)
1768     goto leave;
1769
1770   /* Get the signature.  */
1771   rc = sexp_to_sig (s_sig, &sig, &spec_sig,
1772                     !!(ctx.flags & PUBKEY_FLAG_EDDSA));
1773   if (rc)
1774     goto leave;
1775   /* Fixme: Check that the algorithm of S_SIG is compatible to the one
1776      of S_PKEY.  */
1777
1778   if (spec->algo != spec_sig->algo)
1779     {
1780       rc = GPG_ERR_CONFLICT;
1781       goto leave;
1782     }
1783
1784   if (DBG_CIPHER && !fips_mode ())
1785     {
1786       log_debug ("gcry_pk_verify: algo=%d\n", spec->algo);
1787       for (i = 0; i < pubkey_get_npkey (spec->algo); i++)
1788         log_mpidump ("  pkey", pkey[i]);
1789       for (i = 0; i < pubkey_get_nsig (spec->algo); i++)
1790         log_mpidump ("   sig", sig[i]);
1791       log_mpidump ("  hash", hash);
1792       }
1793
1794   if (spec->verify)
1795     rc = spec->verify (spec->algo, hash, sig, pkey,
1796                        ctx.verify_cmp, &ctx, ctx.flags, ctx.hash_algo);
1797   else
1798     rc = GPG_ERR_NOT_IMPLEMENTED;
1799
1800
1801  leave:
1802   if (pkey)
1803     {
1804       release_mpi_array (pkey);
1805       gcry_free (pkey);
1806     }
1807   if (sig)
1808     {
1809       release_mpi_array (sig);
1810       gcry_free (sig);
1811     }
1812   if (hash)
1813     mpi_free (hash);
1814
1815   return gcry_error (rc);
1816 }
1817
1818
1819 /*
1820    Test a key.
1821
1822    This may be used either for a public or a secret key to see whether
1823    the internal structure is okay.
1824
1825    Returns: 0 or an errorcode.
1826
1827    s_key = <key-as-defined-in-sexp_to_key> */
1828 gcry_error_t
1829 gcry_pk_testkey (gcry_sexp_t s_key)
1830 {
1831   gcry_pk_spec_t *spec = NULL;
1832   gcry_mpi_t *key = NULL;
1833   gcry_err_code_t rc;
1834
1835   /* Note we currently support only secret key checking. */
1836   rc = sexp_to_key (s_key, 1, 0, NULL, &key, &spec, NULL);
1837   if (!rc)
1838     {
1839       rc = pubkey_check_secret_key (spec->algo, key);
1840       release_mpi_array (key);
1841       gcry_free (key);
1842     }
1843   return gcry_error (rc);
1844 }
1845
1846
1847 /*
1848   Create a public key pair and return it in r_key.
1849   How the key is created depends on s_parms:
1850   (genkey
1851    (algo
1852      (parameter_name_1 ....)
1853       ....
1854      (parameter_name_n ....)
1855   ))
1856   The key is returned in a format depending on the
1857   algorithm. Both, private and secret keys are returned
1858   and optionally some additional informatin.
1859   For elgamal we return this structure:
1860   (key-data
1861    (public-key
1862      (elg
1863         (p <mpi>)
1864         (g <mpi>)
1865         (y <mpi>)
1866      )
1867    )
1868    (private-key
1869      (elg
1870         (p <mpi>)
1871         (g <mpi>)
1872         (y <mpi>)
1873         (x <mpi>)
1874      )
1875    )
1876    (misc-key-info
1877       (pm1-factors n1 n2 ... nn)
1878    ))
1879  */
1880 gcry_error_t
1881 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
1882 {
1883   gcry_pk_spec_t *spec = NULL;
1884   gcry_sexp_t list = NULL;
1885   gcry_sexp_t l2 = NULL;
1886   gcry_sexp_t l3 = NULL;
1887   char *name = NULL;
1888   size_t n;
1889   gcry_err_code_t rc = GPG_ERR_NO_ERROR;
1890   unsigned int nbits = 0;
1891   unsigned long use_e = 0;
1892
1893   *r_key = NULL;
1894
1895   list = gcry_sexp_find_token (s_parms, "genkey", 0);
1896   if (!list)
1897     {
1898       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
1899       goto leave;
1900     }
1901
1902   l2 = gcry_sexp_cadr (list);
1903   gcry_sexp_release (list);
1904   list = l2;
1905   l2 = NULL;
1906   if (! list)
1907     {
1908       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
1909       goto leave;
1910     }
1911
1912   name = _gcry_sexp_nth_string (list, 0);
1913   if (!name)
1914     {
1915       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
1916       goto leave;
1917     }
1918
1919   spec = spec_from_name (name);
1920   gcry_free (name);
1921   name = NULL;
1922   if (!spec)
1923     {
1924       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
1925       goto leave;
1926     }
1927
1928   /* Handle the optional rsa-use-e element.  Actually this belong into
1929      the algorithm module but we have this parameter in the public
1930      module API, so we need to parse it right here.  */
1931   l2 = gcry_sexp_find_token (list, "rsa-use-e", 0);
1932   if (l2)
1933     {
1934       char buf[50];
1935       const char *s;
1936
1937       s = gcry_sexp_nth_data (l2, 1, &n);
1938       if ( !s || n >= DIM (buf) - 1 )
1939         {
1940           rc = GPG_ERR_INV_OBJ; /* No value or value too large.  */
1941           goto leave;
1942         }
1943       memcpy (buf, s, n);
1944       buf[n] = 0;
1945       use_e = strtoul (buf, NULL, 0);
1946       gcry_sexp_release (l2);
1947       l2 = NULL;
1948     }
1949   else
1950     use_e = 65537; /* Not given, use the value generated by old versions. */
1951
1952
1953   /* Get the "nbits" parameter.  */
1954   l2 = gcry_sexp_find_token (list, "nbits", 0);
1955   if (l2)
1956     {
1957       char buf[50];
1958       const char *s;
1959
1960       s = gcry_sexp_nth_data (l2, 1, &n);
1961       if (!s || n >= DIM (buf) - 1 )
1962         {
1963           rc = GPG_ERR_INV_OBJ; /* NBITS given without a cdr.  */
1964           goto leave;
1965         }
1966       memcpy (buf, s, n);
1967       buf[n] = 0;
1968       nbits = (unsigned int)strtoul (buf, NULL, 0);
1969       gcry_sexp_release (l2); l2 = NULL;
1970     }
1971   else
1972     nbits = 0;
1973
1974   if (spec->generate)
1975     rc = spec->generate (spec->algo, nbits, use_e, list, r_key);
1976   else
1977     rc = GPG_ERR_NOT_IMPLEMENTED;
1978
1979  leave:
1980   gcry_sexp_release (list); list = NULL;
1981   gcry_free (name);
1982   gcry_sexp_release (l3);
1983   gcry_sexp_release (l2);
1984   gcry_sexp_release (list);
1985
1986   return gcry_error (rc);
1987 }
1988
1989
1990 /*
1991    Get the number of nbits from the public key.
1992
1993    Hmmm: Should we have really this function or is it better to have a
1994    more general function to retrieve different properties of the key?  */
1995 unsigned int
1996 gcry_pk_get_nbits (gcry_sexp_t key)
1997 {
1998   gcry_pk_spec_t *spec;
1999   gcry_mpi_t *keyarr = NULL;
2000   unsigned int nbits = 0;
2001   gcry_err_code_t rc;
2002
2003   /* FIXME: Parsing KEY is often too much overhead.  For example for
2004      ECC we would only need to look at P and stop parsing right
2005      away.  */
2006
2007   rc = sexp_to_key (key, 0, 0, NULL, &keyarr, &spec, NULL);
2008   if (rc == GPG_ERR_INV_OBJ)
2009     rc = sexp_to_key (key, 1, 0, NULL, &keyarr, &spec, NULL);
2010   if (rc)
2011     return 0; /* Error - 0 is a suitable indication for that. */
2012
2013   nbits = spec->get_nbits (spec->algo, keyarr);
2014
2015   release_mpi_array (keyarr);
2016   gcry_free (keyarr);
2017
2018   return nbits;
2019 }
2020
2021
2022 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
2023    key parameters expressed in a way depending on the algorithm.
2024
2025    ARRAY must either be 20 bytes long or NULL; in the latter case a
2026    newly allocated array of that size is returned, otherwise ARRAY or
2027    NULL is returned to indicate an error which is most likely an
2028    unknown algorithm.  The function accepts public or secret keys. */
2029 unsigned char *
2030 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
2031 {
2032   gcry_sexp_t list = NULL;
2033   gcry_sexp_t l2 = NULL;
2034   gcry_pk_spec_t *spec = NULL;
2035   const char *s;
2036   char *name = NULL;
2037   int idx;
2038   const char *elems;
2039   gcry_md_hd_t md = NULL;
2040   int okay = 0;
2041
2042   /* Check that the first element is valid. */
2043   list = gcry_sexp_find_token (key, "public-key", 0);
2044   if (! list)
2045     list = gcry_sexp_find_token (key, "private-key", 0);
2046   if (! list)
2047     list = gcry_sexp_find_token (key, "protected-private-key", 0);
2048   if (! list)
2049     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
2050   if (! list)
2051     return NULL; /* No public- or private-key object. */
2052
2053   l2 = gcry_sexp_cadr (list);
2054   gcry_sexp_release (list);
2055   list = l2;
2056   l2 = NULL;
2057
2058   name = _gcry_sexp_nth_string (list, 0);
2059   if (!name)
2060     goto fail; /* Invalid structure of object. */
2061
2062   spec = spec_from_name (name);
2063   if (!spec)
2064     goto fail; /* Unknown algorithm.  */
2065
2066   elems = spec->elements_grip;
2067   if (!elems)
2068     goto fail; /* No grip parameter.  */
2069
2070   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
2071     goto fail;
2072
2073   if (spec->comp_keygrip)
2074     {
2075       /* Module specific method to compute a keygrip.  */
2076       if (spec->comp_keygrip (md, list))
2077         goto fail;
2078     }
2079   else
2080     {
2081       /* Generic method to compute a keygrip.  */
2082       for (idx = 0, s = elems; *s; s++, idx++)
2083         {
2084           const char *data;
2085           size_t datalen;
2086           char buf[30];
2087
2088           l2 = gcry_sexp_find_token (list, s, 1);
2089           if (! l2)
2090             goto fail;
2091           data = gcry_sexp_nth_data (l2, 1, &datalen);
2092           if (! data)
2093             goto fail;
2094
2095           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
2096           gcry_md_write (md, buf, strlen (buf));
2097           gcry_md_write (md, data, datalen);
2098           gcry_sexp_release (l2);
2099           l2 = NULL;
2100           gcry_md_write (md, ")", 1);
2101         }
2102     }
2103
2104   if (!array)
2105     {
2106       array = gcry_malloc (20);
2107       if (! array)
2108         goto fail;
2109     }
2110
2111   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
2112   okay = 1;
2113
2114  fail:
2115   gcry_free (name);
2116   gcry_sexp_release (l2);
2117   gcry_md_close (md);
2118   gcry_sexp_release (list);
2119   return okay? array : NULL;
2120 }
2121
2122
2123 \f
2124 const char *
2125 gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
2126 {
2127   gcry_mpi_t *pkey = NULL;
2128   gcry_sexp_t list = NULL;
2129   gcry_sexp_t l2;
2130   char *name = NULL;
2131   const char *result = NULL;
2132   int want_private = 1;
2133   gcry_pk_spec_t *spec = NULL;
2134
2135   if (r_nbits)
2136     *r_nbits = 0;
2137
2138   if (key)
2139     {
2140       iterator = 0;
2141
2142       /* Check that the first element is valid. */
2143       list = gcry_sexp_find_token (key, "public-key", 0);
2144       if (list)
2145         want_private = 0;
2146       if (!list)
2147         list = gcry_sexp_find_token (key, "private-key", 0);
2148       if (!list)
2149         return NULL; /* No public- or private-key object. */
2150
2151       l2 = gcry_sexp_cadr (list);
2152       gcry_sexp_release (list);
2153       list = l2;
2154       l2 = NULL;
2155
2156       name = _gcry_sexp_nth_string (list, 0);
2157       if (!name)
2158         goto leave; /* Invalid structure of object. */
2159
2160       /* Get the key.  We pass the names of the parameters for
2161          override_elems; this allows to call this function without the
2162          actual public key parameter.  */
2163       if (sexp_to_key (key, want_private, 0, "pabgn", &pkey, &spec, NULL))
2164         goto leave;
2165     }
2166   else
2167     {
2168       spec = spec_from_name ("ecc");
2169       if (!spec)
2170         goto leave;
2171     }
2172
2173   if (!spec || !spec->get_curve)
2174     goto leave;
2175
2176   result = spec->get_curve (pkey, iterator, r_nbits);
2177
2178  leave:
2179   if (pkey)
2180     {
2181       release_mpi_array (pkey);
2182       gcry_free (pkey);
2183     }
2184   gcry_free (name);
2185   gcry_sexp_release (list);
2186   return result;
2187 }
2188
2189
2190 \f
2191 gcry_sexp_t
2192 gcry_pk_get_param (int algo, const char *name)
2193 {
2194   gcry_sexp_t result = NULL;
2195   gcry_pk_spec_t *spec = NULL;
2196
2197   if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
2198     return NULL;
2199
2200   spec = spec_from_name ("ecc");
2201   if (spec)
2202     {
2203       if (spec && spec->get_curve_param)
2204         result = spec->get_curve_param (name);
2205     }
2206   return result;
2207 }
2208
2209
2210 \f
2211 gcry_error_t
2212 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
2213 {
2214   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2215
2216   switch (cmd)
2217     {
2218     case GCRYCTL_DISABLE_ALGO:
2219       /* This one expects a buffer pointing to an integer with the
2220          algo number.  */
2221       if ((! buffer) || (buflen != sizeof (int)))
2222         err = GPG_ERR_INV_ARG;
2223       else
2224         disable_pubkey_algo (*((int *) buffer));
2225       break;
2226
2227     default:
2228       err = GPG_ERR_INV_OP;
2229     }
2230
2231   return gcry_error (err);
2232 }
2233
2234
2235 /* Return information about the given algorithm
2236
2237    WHAT selects the kind of information returned:
2238
2239     GCRYCTL_TEST_ALGO:
2240         Returns 0 when the specified algorithm is available for use.
2241         Buffer must be NULL, nbytes  may have the address of a variable
2242         with the required usage of the algorithm. It may be 0 for don't
2243         care or a combination of the GCRY_PK_USAGE_xxx flags;
2244
2245     GCRYCTL_GET_ALGO_USAGE:
2246         Return the usage flags for the given algo.  An invalid algo
2247         returns 0.  Disabled algos are ignored here because we
2248         only want to know whether the algo is at all capable of
2249         the usage.
2250
2251    Note: Because this function is in most cases used to return an
2252    integer value, we can make it easier for the caller to just look at
2253    the return value.  The caller will in all cases consult the value
2254    and thereby detecting whether a error occurred or not (i.e. while
2255    checking the block size) */
2256 gcry_error_t
2257 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
2258 {
2259   gcry_err_code_t err = GPG_ERR_NO_ERROR;
2260
2261   switch (what)
2262     {
2263     case GCRYCTL_TEST_ALGO:
2264       {
2265         int use = nbytes ? *nbytes : 0;
2266         if (buffer)
2267           err = GPG_ERR_INV_ARG;
2268         else if (check_pubkey_algo (algorithm, use))
2269           err = GPG_ERR_PUBKEY_ALGO;
2270         break;
2271       }
2272
2273     case GCRYCTL_GET_ALGO_USAGE:
2274       {
2275         gcry_pk_spec_t *spec;
2276
2277         spec = spec_from_algo (algorithm);
2278         *nbytes = spec? spec->use : 0;
2279         break;
2280       }
2281
2282     case GCRYCTL_GET_ALGO_NPKEY:
2283       {
2284         /* FIXME?  */
2285         int npkey = pubkey_get_npkey (algorithm);
2286         *nbytes = npkey;
2287         break;
2288       }
2289     case GCRYCTL_GET_ALGO_NSKEY:
2290       {
2291         /* FIXME?  */
2292         int nskey = pubkey_get_nskey (algorithm);
2293         *nbytes = nskey;
2294         break;
2295       }
2296     case GCRYCTL_GET_ALGO_NSIGN:
2297       {
2298         /* FIXME?  */
2299         int nsign = pubkey_get_nsig (algorithm);
2300         *nbytes = nsign;
2301         break;
2302       }
2303     case GCRYCTL_GET_ALGO_NENCR:
2304       {
2305         /* FIXME?  */
2306         int nencr = pubkey_get_nenc (algorithm);
2307         *nbytes = nencr;
2308         break;
2309       }
2310
2311     default:
2312       err = GPG_ERR_INV_OP;
2313     }
2314
2315   return gcry_error (err);
2316 }
2317
2318
2319 /* Return an S-expression representing the context CTX.  Depending on
2320    the state of that context, the S-expression may either be a public
2321    key, a private key or any other object used with public key
2322    operations.  On success a new S-expression is stored at R_SEXP and
2323    0 is returned, on error NULL is store there and an error code is
2324    returned.  MODE is either 0 or one of the GCRY_PK_GET_xxx values.
2325
2326    As of now it only support certain ECC operations because a context
2327    object is right now only defined for ECC.  Over time this function
2328    will be extended to cover more algorithms.  Note also that the name
2329    of the function is gcry_pubkey_xxx and not gcry_pk_xxx.  The idea
2330    is that we will eventually provide variants of the existing
2331    gcry_pk_xxx functions which will take a context parameter.   */
2332 gcry_err_code_t
2333 _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
2334 {
2335   mpi_ec_t ec;
2336
2337   if (!r_sexp)
2338     return GPG_ERR_INV_VALUE;
2339   *r_sexp = NULL;
2340   switch (mode)
2341     {
2342     case 0:
2343     case GCRY_PK_GET_PUBKEY:
2344     case GCRY_PK_GET_SECKEY:
2345       break;
2346     default:
2347       return GPG_ERR_INV_VALUE;
2348     }
2349   if (!ctx)
2350     return GPG_ERR_NO_CRYPT_CTX;
2351
2352   ec = _gcry_ctx_find_pointer (ctx, CONTEXT_TYPE_EC);
2353   if (ec)
2354     return _gcry_pk_ecc_get_sexp (r_sexp, mode, ec);
2355
2356   return GPG_ERR_WRONG_CRYPT_CTX;
2357 }
2358
2359
2360 \f
2361 /* Explicitly initialize this module.  */
2362 gcry_err_code_t
2363 _gcry_pk_init (void)
2364 {
2365   return 0;
2366 }
2367
2368
2369 /* Run the selftests for pubkey algorithm ALGO with optional reporting
2370    function REPORT.  */
2371 gpg_error_t
2372 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
2373 {
2374   gcry_err_code_t ec;
2375   gcry_pk_spec_t *spec = spec_from_algo (algo);
2376
2377   if (spec && spec->selftest)
2378     ec = spec->selftest (algo, extended, report);
2379   else
2380     {
2381       ec = GPG_ERR_PUBKEY_ALGO;
2382       if (report)
2383         report ("pubkey", algo, "module",
2384                 spec && !spec->flags.disabled?
2385                 "no selftest available" :
2386                 spec? "algorithm disabled" :
2387                 "algorithm not found");
2388     }
2389
2390   return gpg_error (ec);
2391 }