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