GCM: Add support for split data buffers and online operation
[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 #endif
52     NULL
53   };
54
55
56 static int
57 map_algo (int algo)
58 {
59  switch (algo)
60    {
61    case GCRY_PK_ECDSA:
62    case GCRY_PK_ECDH:
63      return GCRY_PK_ECC;
64    case GCRY_PK_ELG_E:
65      return GCRY_PK_ELG;
66    default:
67      return algo;
68    }
69 }
70
71
72
73 /* Return the spec structure for the public key algorithm ALGO.  For
74    an unknown algorithm NULL is returned.  */
75 static gcry_pk_spec_t *
76 spec_from_algo (int algo)
77 {
78   int idx;
79   gcry_pk_spec_t *spec;
80
81   algo = map_algo (algo);
82
83   for (idx = 0; (spec = pubkey_list[idx]); idx++)
84     if (algo == spec->algo)
85       return spec;
86   return NULL;
87 }
88
89
90 /* Return the spec structure for the public key algorithm with NAME.
91    For an unknown name NULL is returned.  */
92 static gcry_pk_spec_t *
93 spec_from_name (const char *name)
94 {
95   gcry_pk_spec_t *spec;
96   int idx;
97   const char **aliases;
98
99   for (idx=0; (spec = pubkey_list[idx]); idx++)
100     {
101       if (!stricmp (name, spec->name))
102         return spec;
103       for (aliases = spec->aliases; *aliases; aliases++)
104         if (!stricmp (name, *aliases))
105           return spec;
106     }
107
108   return NULL;
109 }
110
111
112
113 /* Given the s-expression SEXP with the first element be either
114  * "private-key" or "public-key" return the spec structure for it.  We
115  * look through the list to find a list beginning with "private-key"
116  * or "public-key" - the first one found is used.  If WANT_PRIVATE is
117  * set the function will only succeed if a private key has been given.
118  * On success the spec is stored at R_SPEC.  On error NULL is stored
119  * at R_SPEC and an error code returned.  If R_PARMS is not NULL and
120  * the fucntion returns success, the parameter list below
121  * "private-key" or "public-key" is stored there and the caller must
122  * call gcry_sexp_release on it.
123  */
124 static gcry_err_code_t
125 spec_from_sexp (gcry_sexp_t sexp, int want_private,
126                 gcry_pk_spec_t **r_spec, gcry_sexp_t *r_parms)
127 {
128   gcry_sexp_t list, l2;
129   char *name;
130   gcry_pk_spec_t *spec;
131
132   *r_spec = NULL;
133   if (r_parms)
134     *r_parms = NULL;
135
136   /* Check that the first element is valid.  If we are looking for a
137      public key but a private key was supplied, we allow the use of
138      the private key anyway.  The rationale for this is that the
139      private key is a superset of the public key.  */
140   list = gcry_sexp_find_token (sexp,
141                                want_private? "private-key":"public-key", 0);
142   if (!list && !want_private)
143     list = gcry_sexp_find_token (sexp, "private-key", 0);
144   if (!list)
145     return GPG_ERR_INV_OBJ; /* Does not contain a key object.  */
146
147   l2 = gcry_sexp_cadr (list);
148   gcry_sexp_release (list);
149   list = l2;
150   name = _gcry_sexp_nth_string (list, 0);
151   if (!name)
152     {
153       gcry_sexp_release ( list );
154       return GPG_ERR_INV_OBJ;      /* Invalid structure of object. */
155     }
156   spec = spec_from_name (name);
157   gcry_free (name);
158   if (!spec)
159     {
160       gcry_sexp_release (list);
161       return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
162     }
163   *r_spec = spec;
164   if (r_parms)
165     *r_parms = list;
166   else
167     gcry_sexp_release (list);
168   return 0;
169 }
170
171
172
173 /* Disable the use of the algorithm ALGO.  This is not thread safe and
174    should thus be called early.  */
175 static void
176 disable_pubkey_algo (int algo)
177 {
178   gcry_pk_spec_t *spec = spec_from_algo (algo);
179
180   if (spec)
181     spec->flags.disabled = 1;
182 }
183
184
185 \f
186 /*
187  * Map a string to the pubkey algo
188  */
189 int
190 gcry_pk_map_name (const char *string)
191 {
192   gcry_pk_spec_t *spec;
193
194   if (!string)
195     return 0;
196   spec = spec_from_name (string);
197   if (!spec)
198     return 0;
199   if (spec->flags.disabled)
200     return 0;
201   return spec->algo;
202 }
203
204
205 /* Map the public key algorithm whose ID is contained in ALGORITHM to
206    a string representation of the algorithm name.  For unknown
207    algorithm IDs this functions returns "?". */
208 const char *
209 gcry_pk_algo_name (int algo)
210 {
211   gcry_pk_spec_t *spec;
212
213   spec = spec_from_algo (algo);
214   if (spec)
215     return spec->name;
216   return "?";
217 }
218
219
220 /****************
221  * A USE of 0 means: don't care.
222  */
223 static gcry_err_code_t
224 check_pubkey_algo (int algo, unsigned use)
225 {
226   gcry_err_code_t err = 0;
227   gcry_pk_spec_t *spec;
228
229   spec = spec_from_algo (algo);
230   if (spec)
231     {
232       if (((use & GCRY_PK_USAGE_SIGN)
233            && (! (spec->use & GCRY_PK_USAGE_SIGN)))
234           || ((use & GCRY_PK_USAGE_ENCR)
235               && (! (spec->use & GCRY_PK_USAGE_ENCR))))
236         err = GPG_ERR_WRONG_PUBKEY_ALGO;
237     }
238   else
239     err = GPG_ERR_PUBKEY_ALGO;
240
241   return err;
242 }
243
244
245 /****************
246  * Return the number of public key material numbers
247  */
248 static int
249 pubkey_get_npkey (int algo)
250 {
251   gcry_pk_spec_t *spec = spec_from_algo (algo);
252
253   return spec? strlen (spec->elements_pkey) : 0;
254 }
255
256
257 /****************
258  * Return the number of secret key material numbers
259  */
260 static int
261 pubkey_get_nskey (int algo)
262 {
263   gcry_pk_spec_t *spec = spec_from_algo (algo);
264
265   return spec? strlen (spec->elements_skey) : 0;
266 }
267
268
269 /****************
270  * Return the number of signature material numbers
271  */
272 static int
273 pubkey_get_nsig (int algo)
274 {
275   gcry_pk_spec_t *spec = spec_from_algo (algo);
276
277   return spec? strlen (spec->elements_sig) : 0;
278 }
279
280 /****************
281  * Return the number of encryption material numbers
282  */
283 static int
284 pubkey_get_nenc (int algo)
285 {
286   gcry_pk_spec_t *spec = spec_from_algo (algo);
287
288   return spec? strlen (spec->elements_enc) : 0;
289 }
290
291
292 \f
293 /*
294    Do a PK encrypt operation
295
296    Caller has to provide a public key as the SEXP pkey and data as a
297    SEXP with just one MPI in it. Alternatively S_DATA might be a
298    complex S-Expression, similar to the one used for signature
299    verification.  This provides a flag which allows to handle PKCS#1
300    block type 2 padding.  The function returns a sexp which may be
301    passed to to pk_decrypt.
302
303    Returns: 0 or an errorcode.
304
305    s_data = See comment for _gcry_pk_util_data_to_mpi
306    s_pkey = <key-as-defined-in-sexp_to_key>
307    r_ciph = (enc-val
308                (<algo>
309                  (<param_name1> <mpi>)
310                  ...
311                  (<param_namen> <mpi>)
312                ))
313
314 */
315 gcry_error_t
316 gcry_pk_encrypt (gcry_sexp_t *r_ciph, gcry_sexp_t s_data, gcry_sexp_t s_pkey)
317 {
318   gcry_err_code_t rc;
319   gcry_pk_spec_t *spec;
320   gcry_sexp_t keyparms;
321
322   *r_ciph = NULL;
323
324   rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
325   if (rc)
326     goto leave;
327
328   if (spec->encrypt)
329     rc = spec->encrypt (r_ciph, s_data, keyparms);
330   else
331     rc = GPG_ERR_NOT_IMPLEMENTED;
332
333  leave:
334   gcry_sexp_release (keyparms);
335   return gcry_error (rc);
336 }
337
338
339 /*
340    Do a PK decrypt operation
341
342    Caller has to provide a secret key as the SEXP skey and data in a
343    format as created by gcry_pk_encrypt.  For historic reasons the
344    function returns simply an MPI as an S-expression part; this is
345    deprecated and the new method should be used which returns a real
346    S-expressionl this is selected by adding at least an empty flags
347    list to S_DATA.
348
349    Returns: 0 or an errorcode.
350
351    s_data = (enc-val
352               [(flags [raw, pkcs1, oaep])]
353               (<algo>
354                 (<param_name1> <mpi>)
355                 ...
356                 (<param_namen> <mpi>)
357               ))
358    s_skey = <key-as-defined-in-sexp_to_key>
359    r_plain= Either an incomplete S-expression without the parentheses
360             or if the flags list is used (even if empty) a real S-expression:
361             (value PLAIN).  In raw mode (or no flags given) the returned value
362             is to be interpreted as a signed MPI, thus it may have an extra
363             leading zero octet even if not included in the original data.
364             With pkcs1 or oaep decoding enabled the returned value is a
365             verbatim octet string.
366  */
367 gcry_error_t
368 gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
369 {
370   gcry_err_code_t rc;
371   gcry_pk_spec_t *spec;
372   gcry_sexp_t keyparms;
373
374   *r_plain = NULL;
375
376   rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
377   if (rc)
378     goto leave;
379
380   if (spec->decrypt)
381     rc = spec->decrypt (r_plain, s_data, keyparms);
382   else
383     rc = GPG_ERR_NOT_IMPLEMENTED;
384
385  leave:
386   gcry_sexp_release (keyparms);
387   return gcry_error (rc);
388 }
389
390
391
392 /*
393    Create a signature.
394
395    Caller has to provide a secret key as the SEXP skey and data
396    expressed as a SEXP list hash with only one element which should
397    instantly be available as a MPI. Alternatively the structure given
398    below may be used for S_HASH, it provides the abiliy to pass flags
399    to the operation; the flags defined by now are "pkcs1" which does
400    PKCS#1 block type 1 style padding and "pss" for PSS encoding.
401
402    Returns: 0 or an errorcode.
403             In case of 0 the function returns a new SEXP with the
404             signature value; the structure of this signature depends on the
405             other arguments but is always suitable to be passed to
406             gcry_pk_verify
407
408    s_hash = See comment for _gcry-pk_util_data_to_mpi
409
410    s_skey = <key-as-defined-in-sexp_to_key>
411    r_sig  = (sig-val
412               (<algo>
413                 (<param_name1> <mpi>)
414                 ...
415                 (<param_namen> <mpi>))
416              [(hash algo)])
417
418   Note that (hash algo) in R_SIG is not used.
419 */
420 gcry_error_t
421 gcry_pk_sign (gcry_sexp_t *r_sig, gcry_sexp_t s_hash, gcry_sexp_t s_skey)
422 {
423   gcry_err_code_t rc;
424   gcry_pk_spec_t *spec;
425   gcry_sexp_t keyparms;
426
427   *r_sig = NULL;
428
429   rc = spec_from_sexp (s_skey, 1, &spec, &keyparms);
430   if (rc)
431     goto leave;
432
433   if (spec->sign)
434     rc = spec->sign (r_sig, s_hash, keyparms);
435   else
436     rc = GPG_ERR_NOT_IMPLEMENTED;
437
438  leave:
439   gcry_sexp_release (keyparms);
440   return gcry_error (rc);
441 }
442
443
444 /*
445    Verify a signature.
446
447    Caller has to supply the public key pkey, the signature sig and his
448    hashvalue data.  Public key has to be a standard public key given
449    as an S-Exp, sig is a S-Exp as returned from gcry_pk_sign and data
450    must be an S-Exp like the one in sign too.  */
451 gcry_error_t
452 gcry_pk_verify (gcry_sexp_t s_sig, gcry_sexp_t s_hash, gcry_sexp_t s_pkey)
453 {
454   gcry_err_code_t rc;
455   gcry_pk_spec_t *spec;
456   gcry_sexp_t keyparms;
457
458   rc = spec_from_sexp (s_pkey, 0, &spec, &keyparms);
459   if (rc)
460     goto leave;
461
462   if (spec->verify)
463     rc = spec->verify (s_sig, s_hash, keyparms);
464   else
465     rc = GPG_ERR_NOT_IMPLEMENTED;
466
467  leave:
468   gcry_sexp_release (keyparms);
469   return gcry_error (rc);
470 }
471
472
473 /*
474    Test a key.
475
476    This may be used either for a public or a secret key to see whether
477    the internal structure is okay.
478
479    Returns: 0 or an errorcode.
480
481    NOTE: We currently support only secret key checking. */
482 gcry_error_t
483 gcry_pk_testkey (gcry_sexp_t s_key)
484 {
485   gcry_err_code_t rc;
486   gcry_pk_spec_t *spec;
487   gcry_sexp_t keyparms;
488
489   rc = spec_from_sexp (s_key, 1, &spec, &keyparms);
490   if (rc)
491     goto leave;
492
493   if (spec->check_secret_key)
494     rc = spec->check_secret_key (keyparms);
495   else
496     rc = GPG_ERR_NOT_IMPLEMENTED;
497
498  leave:
499   gcry_sexp_release (keyparms);
500   return gcry_error (rc);
501 }
502
503
504 /*
505   Create a public key pair and return it in r_key.
506   How the key is created depends on s_parms:
507   (genkey
508    (algo
509      (parameter_name_1 ....)
510       ....
511      (parameter_name_n ....)
512   ))
513   The key is returned in a format depending on the
514   algorithm. Both, private and secret keys are returned
515   and optionally some additional informatin.
516   For elgamal we return this structure:
517   (key-data
518    (public-key
519      (elg
520         (p <mpi>)
521         (g <mpi>)
522         (y <mpi>)
523      )
524    )
525    (private-key
526      (elg
527         (p <mpi>)
528         (g <mpi>)
529         (y <mpi>)
530         (x <mpi>)
531      )
532    )
533    (misc-key-info
534       (pm1-factors n1 n2 ... nn)
535    ))
536  */
537 gcry_error_t
538 gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms)
539 {
540   gcry_pk_spec_t *spec = NULL;
541   gcry_sexp_t list = NULL;
542   gcry_sexp_t l2 = NULL;
543   char *name = NULL;
544   gcry_err_code_t rc;
545
546   *r_key = NULL;
547
548   list = gcry_sexp_find_token (s_parms, "genkey", 0);
549   if (!list)
550     {
551       rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */
552       goto leave;
553     }
554
555   l2 = gcry_sexp_cadr (list);
556   gcry_sexp_release (list);
557   list = l2;
558   l2 = NULL;
559   if (! list)
560     {
561       rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */
562       goto leave;
563     }
564
565   name = _gcry_sexp_nth_string (list, 0);
566   if (!name)
567     {
568       rc = GPG_ERR_INV_OBJ; /* Algo string missing.  */
569       goto leave;
570     }
571
572   spec = spec_from_name (name);
573   gcry_free (name);
574   name = NULL;
575   if (!spec)
576     {
577       rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm.  */
578       goto leave;
579     }
580
581   if (spec->generate)
582     rc = spec->generate (list, r_key);
583   else
584     rc = GPG_ERR_NOT_IMPLEMENTED;
585
586  leave:
587   gcry_sexp_release (list);
588   gcry_free (name);
589   gcry_sexp_release (l2);
590
591   return gcry_error (rc);
592 }
593
594
595 /*
596    Get the number of nbits from the public key.
597
598    Hmmm: Should we have really this function or is it better to have a
599    more general function to retrieve different properties of the key?  */
600 unsigned int
601 gcry_pk_get_nbits (gcry_sexp_t key)
602 {
603   gcry_pk_spec_t *spec;
604   gcry_sexp_t parms;
605   unsigned int nbits;
606
607   /* Parsing KEY might be considered too much overhead.  For example
608      for RSA we would only need to look at P and stop parsing right
609      away.  However, with ECC things are more complicate in that only
610      a curve name might be specified.  Thus we need to tear the sexp
611      apart. */
612
613   if (spec_from_sexp (key, 0, &spec, &parms))
614     return 0; /* Error - 0 is a suitable indication for that.  */
615
616   nbits = spec->get_nbits (parms);
617   gcry_sexp_release (parms);
618   return nbits;
619 }
620
621
622 /* Return the so called KEYGRIP which is the SHA-1 hash of the public
623    key parameters expressed in a way depending on the algorithm.
624
625    ARRAY must either be 20 bytes long or NULL; in the latter case a
626    newly allocated array of that size is returned, otherwise ARRAY or
627    NULL is returned to indicate an error which is most likely an
628    unknown algorithm.  The function accepts public or secret keys. */
629 unsigned char *
630 gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array)
631 {
632   gcry_sexp_t list = NULL;
633   gcry_sexp_t l2 = NULL;
634   gcry_pk_spec_t *spec = NULL;
635   const char *s;
636   char *name = NULL;
637   int idx;
638   const char *elems;
639   gcry_md_hd_t md = NULL;
640   int okay = 0;
641
642   /* Check that the first element is valid. */
643   list = gcry_sexp_find_token (key, "public-key", 0);
644   if (! list)
645     list = gcry_sexp_find_token (key, "private-key", 0);
646   if (! list)
647     list = gcry_sexp_find_token (key, "protected-private-key", 0);
648   if (! list)
649     list = gcry_sexp_find_token (key, "shadowed-private-key", 0);
650   if (! list)
651     return NULL; /* No public- or private-key object. */
652
653   l2 = gcry_sexp_cadr (list);
654   gcry_sexp_release (list);
655   list = l2;
656   l2 = NULL;
657
658   name = _gcry_sexp_nth_string (list, 0);
659   if (!name)
660     goto fail; /* Invalid structure of object. */
661
662   spec = spec_from_name (name);
663   if (!spec)
664     goto fail; /* Unknown algorithm.  */
665
666   elems = spec->elements_grip;
667   if (!elems)
668     goto fail; /* No grip parameter.  */
669
670   if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
671     goto fail;
672
673   if (spec->comp_keygrip)
674     {
675       /* Module specific method to compute a keygrip.  */
676       if (spec->comp_keygrip (md, list))
677         goto fail;
678     }
679   else
680     {
681       /* Generic method to compute a keygrip.  */
682       for (idx = 0, s = elems; *s; s++, idx++)
683         {
684           const char *data;
685           size_t datalen;
686           char buf[30];
687
688           l2 = gcry_sexp_find_token (list, s, 1);
689           if (! l2)
690             goto fail;
691           data = gcry_sexp_nth_data (l2, 1, &datalen);
692           if (! data)
693             goto fail;
694
695           snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
696           gcry_md_write (md, buf, strlen (buf));
697           gcry_md_write (md, data, datalen);
698           gcry_sexp_release (l2);
699           l2 = NULL;
700           gcry_md_write (md, ")", 1);
701         }
702     }
703
704   if (!array)
705     {
706       array = gcry_malloc (20);
707       if (! array)
708         goto fail;
709     }
710
711   memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
712   okay = 1;
713
714  fail:
715   gcry_free (name);
716   gcry_sexp_release (l2);
717   gcry_md_close (md);
718   gcry_sexp_release (list);
719   return okay? array : NULL;
720 }
721
722
723 \f
724 const char *
725 gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
726 {
727   const char *result = NULL;
728   gcry_pk_spec_t *spec;
729   gcry_sexp_t keyparms = NULL;
730
731   if (r_nbits)
732     *r_nbits = 0;
733
734   if (key)
735     {
736       iterator = 0;
737
738       if (spec_from_sexp (key, 0, &spec, &keyparms))
739         return NULL;
740     }
741   else
742     {
743       spec = spec_from_name ("ecc");
744       if (!spec)
745         return NULL;
746     }
747
748   if (spec->get_curve)
749     result = spec->get_curve (keyparms, iterator, r_nbits);
750
751    gcry_sexp_release (keyparms);
752   return result;
753 }
754
755
756 \f
757 gcry_sexp_t
758 gcry_pk_get_param (int algo, const char *name)
759 {
760   gcry_sexp_t result = NULL;
761   gcry_pk_spec_t *spec = NULL;
762
763   algo = map_algo (algo);
764
765   if (algo != GCRY_PK_ECC)
766     return NULL;
767
768   spec = spec_from_name ("ecc");
769   if (spec)
770     {
771       if (spec && spec->get_curve_param)
772         result = spec->get_curve_param (name);
773     }
774   return result;
775 }
776
777
778 \f
779 gcry_error_t
780 gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
781 {
782   gcry_err_code_t err = GPG_ERR_NO_ERROR;
783
784   switch (cmd)
785     {
786     case GCRYCTL_DISABLE_ALGO:
787       /* This one expects a buffer pointing to an integer with the
788          algo number.  */
789       if ((! buffer) || (buflen != sizeof (int)))
790         err = GPG_ERR_INV_ARG;
791       else
792         disable_pubkey_algo (*((int *) buffer));
793       break;
794
795     default:
796       err = GPG_ERR_INV_OP;
797     }
798
799   return gcry_error (err);
800 }
801
802
803 /* Return information about the given algorithm
804
805    WHAT selects the kind of information returned:
806
807     GCRYCTL_TEST_ALGO:
808         Returns 0 when the specified algorithm is available for use.
809         Buffer must be NULL, nbytes  may have the address of a variable
810         with the required usage of the algorithm. It may be 0 for don't
811         care or a combination of the GCRY_PK_USAGE_xxx flags;
812
813     GCRYCTL_GET_ALGO_USAGE:
814         Return the usage flags for the given algo.  An invalid algo
815         returns 0.  Disabled algos are ignored here because we
816         only want to know whether the algo is at all capable of
817         the usage.
818
819    Note: Because this function is in most cases used to return an
820    integer value, we can make it easier for the caller to just look at
821    the return value.  The caller will in all cases consult the value
822    and thereby detecting whether a error occurred or not (i.e. while
823    checking the block size) */
824 gcry_error_t
825 gcry_pk_algo_info (int algorithm, int what, void *buffer, size_t *nbytes)
826 {
827   gcry_err_code_t err = GPG_ERR_NO_ERROR;
828
829   switch (what)
830     {
831     case GCRYCTL_TEST_ALGO:
832       {
833         int use = nbytes ? *nbytes : 0;
834         if (buffer)
835           err = GPG_ERR_INV_ARG;
836         else if (check_pubkey_algo (algorithm, use))
837           err = GPG_ERR_PUBKEY_ALGO;
838         break;
839       }
840
841     case GCRYCTL_GET_ALGO_USAGE:
842       {
843         gcry_pk_spec_t *spec;
844
845         spec = spec_from_algo (algorithm);
846         *nbytes = spec? spec->use : 0;
847         break;
848       }
849
850     case GCRYCTL_GET_ALGO_NPKEY:
851       {
852         /* FIXME?  */
853         int npkey = pubkey_get_npkey (algorithm);
854         *nbytes = npkey;
855         break;
856       }
857     case GCRYCTL_GET_ALGO_NSKEY:
858       {
859         /* FIXME?  */
860         int nskey = pubkey_get_nskey (algorithm);
861         *nbytes = nskey;
862         break;
863       }
864     case GCRYCTL_GET_ALGO_NSIGN:
865       {
866         /* FIXME?  */
867         int nsign = pubkey_get_nsig (algorithm);
868         *nbytes = nsign;
869         break;
870       }
871     case GCRYCTL_GET_ALGO_NENCR:
872       {
873         /* FIXME?  */
874         int nencr = pubkey_get_nenc (algorithm);
875         *nbytes = nencr;
876         break;
877       }
878
879     default:
880       err = GPG_ERR_INV_OP;
881     }
882
883   return gcry_error (err);
884 }
885
886
887 /* Return an S-expression representing the context CTX.  Depending on
888    the state of that context, the S-expression may either be a public
889    key, a private key or any other object used with public key
890    operations.  On success a new S-expression is stored at R_SEXP and
891    0 is returned, on error NULL is store there and an error code is
892    returned.  MODE is either 0 or one of the GCRY_PK_GET_xxx values.
893
894    As of now it only support certain ECC operations because a context
895    object is right now only defined for ECC.  Over time this function
896    will be extended to cover more algorithms.  Note also that the name
897    of the function is gcry_pubkey_xxx and not gcry_pk_xxx.  The idea
898    is that we will eventually provide variants of the existing
899    gcry_pk_xxx functions which will take a context parameter.   */
900 gcry_err_code_t
901 _gcry_pubkey_get_sexp (gcry_sexp_t *r_sexp, int mode, gcry_ctx_t ctx)
902 {
903   mpi_ec_t ec;
904
905   if (!r_sexp)
906     return GPG_ERR_INV_VALUE;
907   *r_sexp = NULL;
908   switch (mode)
909     {
910     case 0:
911     case GCRY_PK_GET_PUBKEY:
912     case GCRY_PK_GET_SECKEY:
913       break;
914     default:
915       return GPG_ERR_INV_VALUE;
916     }
917   if (!ctx)
918     return GPG_ERR_NO_CRYPT_CTX;
919
920   ec = _gcry_ctx_find_pointer (ctx, CONTEXT_TYPE_EC);
921   if (ec)
922     return _gcry_pk_ecc_get_sexp (r_sexp, mode, ec);
923
924   return GPG_ERR_WRONG_CRYPT_CTX;
925 }
926
927
928 \f
929 /* Explicitly initialize this module.  */
930 gcry_err_code_t
931 _gcry_pk_init (void)
932 {
933   return 0;
934 }
935
936
937 /* Run the selftests for pubkey algorithm ALGO with optional reporting
938    function REPORT.  */
939 gpg_error_t
940 _gcry_pk_selftest (int algo, int extended, selftest_report_func_t report)
941 {
942   gcry_err_code_t ec;
943   gcry_pk_spec_t *spec;
944
945   algo = map_algo (algo);
946   spec = spec_from_algo (algo);
947   if (spec && !spec->flags.disabled && spec->selftest)
948     ec = spec->selftest (algo, extended, report);
949   else
950     {
951       ec = GPG_ERR_PUBKEY_ALGO;
952       /* Fixme: We need to change the report fucntion to allow passing
953          of an encryption mode (e.g. pkcs1, ecdsa, or ecdh).  */
954       if (report)
955         report ("pubkey", algo, "module",
956                 spec && !spec->flags.disabled?
957                 "no selftest available" :
958                 spec? "algorithm disabled" :
959                 "algorithm not found");
960     }
961
962   return gpg_error (ec);
963 }