build: Fix build with !HAVE_PTHREAD
[libgcrypt.git] / cipher / pubkey-util.c
1 /* pubkey-util.c - Supporting functions for all pubkey modules.
2  * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
3  *               2007, 2008, 2011 Free Software Foundation, Inc.
4  * Copyright (C) 2013, 2015 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
27 #include "g10lib.h"
28 #include "mpi.h"
29 #include "cipher.h"
30 #include "pubkey-internal.h"
31
32
33 /* Callback for the pubkey algorithm code to verify PSS signatures.
34    OPAQUE is the data provided by the actual caller.  The meaning of
35    TMP depends on the actual algorithm (but there is only RSA); now
36    for RSA it is the output of running the public key function on the
37    input.  */
38 static int
39 pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
40 {
41   struct pk_encoding_ctx *ctx = opaque;
42   gcry_mpi_t hash = ctx->verify_arg;
43
44   return _gcry_rsa_pss_verify (hash, tmp, ctx->nbits - 1,
45                                ctx->hash_algo, ctx->saltlen);
46 }
47
48
49 /* Parser for a flag list.  On return the encoding is stored at
50    R_ENCODING and the flags are stored at R_FLAGS.  If any of them is
51    not needed, NULL may be passed.  The function returns 0 on success
52    or an error code. */
53 gpg_err_code_t
54 _gcry_pk_util_parse_flaglist (gcry_sexp_t list,
55                               int *r_flags, enum pk_encoding *r_encoding)
56 {
57   gpg_err_code_t rc = 0;
58   const char *s;
59   size_t n;
60   int i;
61   int encoding = PUBKEY_ENC_UNKNOWN;
62   int flags = 0;
63   int igninvflag = 0;
64
65   for (i = list ? sexp_length (list)-1 : 0; i > 0; i--)
66     {
67       s = sexp_nth_data (list, i, &n);
68       if (!s)
69         continue; /* Not a data element. */
70
71       switch (n)
72         {
73         case 3:
74           if (!memcmp (s, "pss", 3) && encoding == PUBKEY_ENC_UNKNOWN)
75             {
76               encoding = PUBKEY_ENC_PSS;
77               flags |= PUBKEY_FLAG_FIXEDLEN;
78             }
79           else if (!memcmp (s, "raw", 3) && encoding == PUBKEY_ENC_UNKNOWN)
80             {
81               encoding = PUBKEY_ENC_RAW;
82               flags |= PUBKEY_FLAG_RAW_FLAG; /* Explicitly given.  */
83             }
84           else if (!igninvflag)
85             rc = GPG_ERR_INV_FLAG;
86           break;
87
88         case 4:
89           if (!memcmp (s, "comp", 4))
90             flags |= PUBKEY_FLAG_COMP;
91           else if (!memcmp (s, "oaep", 4) && encoding == PUBKEY_ENC_UNKNOWN)
92             {
93               encoding = PUBKEY_ENC_OAEP;
94               flags |= PUBKEY_FLAG_FIXEDLEN;
95             }
96           else if (!memcmp (s, "gost", 4))
97             {
98               encoding = PUBKEY_ENC_RAW;
99               flags |= PUBKEY_FLAG_GOST;
100             }
101           else if (!igninvflag)
102             rc = GPG_ERR_INV_FLAG;
103           break;
104
105         case 5:
106           if (!memcmp (s, "eddsa", 5))
107             {
108               encoding = PUBKEY_ENC_RAW;
109               flags |= PUBKEY_FLAG_EDDSA;
110               flags |= PUBKEY_FLAG_DJB_TWEAK;
111             }
112           else if (!memcmp (s, "pkcs1", 5) && encoding == PUBKEY_ENC_UNKNOWN)
113             {
114               encoding = PUBKEY_ENC_PKCS1;
115               flags |= PUBKEY_FLAG_FIXEDLEN;
116             }
117           else if (!memcmp (s, "param", 5))
118             flags |= PUBKEY_FLAG_PARAM;
119           else if (!igninvflag)
120             rc = GPG_ERR_INV_FLAG;
121           break;
122
123         case 6:
124           if (!memcmp (s, "nocomp", 6))
125             flags |= PUBKEY_FLAG_NOCOMP;
126           else if (!igninvflag)
127             rc = GPG_ERR_INV_FLAG;
128           break;
129
130         case 7:
131           if (!memcmp (s, "rfc6979", 7))
132             flags |= PUBKEY_FLAG_RFC6979;
133           else if (!memcmp (s, "noparam", 7))
134             ; /* Ignore - it is the default.  */
135           else if (!igninvflag)
136             rc = GPG_ERR_INV_FLAG;
137           break;
138
139         case 8:
140           if (!memcmp (s, "use-x931", 8))
141             flags |= PUBKEY_FLAG_USE_X931;
142           else if (!igninvflag)
143             rc = GPG_ERR_INV_FLAG;
144           break;
145
146         case 9:
147           if (!memcmp (s, "pkcs1-raw", 9) && encoding == PUBKEY_ENC_UNKNOWN)
148             {
149               encoding = PUBKEY_ENC_PKCS1_RAW;
150               flags |= PUBKEY_FLAG_FIXEDLEN;
151             }
152           else if (!memcmp (s, "djb-tweak", 9))
153             {
154               encoding = PUBKEY_ENC_RAW;
155               flags |= PUBKEY_FLAG_DJB_TWEAK;
156             }
157           else if (!igninvflag)
158             rc = GPG_ERR_INV_FLAG;
159           break;
160
161         case 10:
162           if (!memcmp (s, "igninvflag", 10))
163             igninvflag = 1;
164           else if (!memcmp (s, "no-keytest", 10))
165             flags |= PUBKEY_FLAG_NO_KEYTEST;
166           else if (!igninvflag)
167             rc = GPG_ERR_INV_FLAG;
168           break;
169
170         case 11:
171           if (!memcmp (s, "no-blinding", 11))
172             flags |= PUBKEY_FLAG_NO_BLINDING;
173           else if (!memcmp (s, "use-fips186", 11))
174             flags |= PUBKEY_FLAG_USE_FIPS186;
175           else if (!igninvflag)
176             rc = GPG_ERR_INV_FLAG;
177           break;
178
179         case 13:
180           if (!memcmp (s, "use-fips186-2", 13))
181             flags |= PUBKEY_FLAG_USE_FIPS186_2;
182           else if (!memcmp (s, "transient-key", 13))
183             flags |= PUBKEY_FLAG_TRANSIENT_KEY;
184           else if (!igninvflag)
185             rc = GPG_ERR_INV_FLAG;
186           break;
187
188         default:
189           if (!igninvflag)
190             rc = GPG_ERR_INV_FLAG;
191           break;
192         }
193     }
194
195   if (r_flags)
196     *r_flags = flags;
197   if (r_encoding)
198     *r_encoding = encoding;
199
200   return rc;
201 }
202
203
204 static int
205 get_hash_algo (const char *s, size_t n)
206 {
207   static const struct { const char *name; int algo; } hashnames[] = {
208     { "sha1",   GCRY_MD_SHA1 },
209     { "md5",    GCRY_MD_MD5 },
210     { "sha256", GCRY_MD_SHA256 },
211     { "ripemd160", GCRY_MD_RMD160 },
212     { "rmd160", GCRY_MD_RMD160 },
213     { "sha384", GCRY_MD_SHA384 },
214     { "sha512", GCRY_MD_SHA512 },
215     { "sha224", GCRY_MD_SHA224 },
216     { "md2",    GCRY_MD_MD2 },
217     { "md4",    GCRY_MD_MD4 },
218     { "tiger",  GCRY_MD_TIGER },
219     { "haval",  GCRY_MD_HAVAL },
220     { "sha3-224", GCRY_MD_SHA3_224 },
221     { "sha3-256", GCRY_MD_SHA3_256 },
222     { "sha3-384", GCRY_MD_SHA3_384 },
223     { "sha3-512", GCRY_MD_SHA3_512 },
224     { "sm3", GCRY_MD_SM3 },
225     { NULL, 0 }
226   };
227   int algo;
228   int i;
229
230   for (i=0; hashnames[i].name; i++)
231     {
232       if ( strlen (hashnames[i].name) == n
233            && !memcmp (hashnames[i].name, s, n))
234         break;
235     }
236   if (hashnames[i].name)
237     algo = hashnames[i].algo;
238   else
239     {
240       /* In case of not listed or dynamically allocated hash
241          algorithm we fall back to this somewhat slower
242          method.  Further, it also allows to use OIDs as
243          algorithm names. */
244       char *tmpname;
245
246       tmpname = xtrymalloc (n+1);
247       if (!tmpname)
248         algo = 0;  /* Out of core - silently give up.  */
249       else
250         {
251           memcpy (tmpname, s, n);
252           tmpname[n] = 0;
253           algo = _gcry_md_map_name (tmpname);
254           xfree (tmpname);
255         }
256     }
257   return algo;
258 }
259
260
261 /* Get the "nbits" parameter from an s-expression of the format:
262  *
263  *   (algo
264  *     (parameter_name_1 ....)
265  *      ....
266  *     (parameter_name_n ....))
267  *
268  * Example:
269  *
270  *   (rsa
271  *     (nbits 4:2048))
272  *
273  * On success the value for nbits is stored at R_NBITS.  If no nbits
274  * parameter is found, the function returns success and stores 0 at
275  * R_NBITS.  For parsing errors the function returns an error code and
276  * stores 0 at R_NBITS.
277  */
278 gpg_err_code_t
279 _gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
280 {
281   char buf[50];
282   const char *s;
283   size_t n;
284
285   *r_nbits = 0;
286
287   list = sexp_find_token (list, "nbits", 0);
288   if (!list)
289     return 0; /* No NBITS found.  */
290
291   s = sexp_nth_data (list, 1, &n);
292   if (!s || n >= DIM (buf) - 1 )
293     {
294       /* NBITS given without a cdr.  */
295       sexp_release (list);
296       return GPG_ERR_INV_OBJ;
297     }
298   memcpy (buf, s, n);
299   buf[n] = 0;
300   *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
301   sexp_release (list);
302   return 0;
303 }
304
305
306 /* Get the optional "rsa-use-e" parameter from an s-expression of the
307  * format:
308  *
309  *   (algo
310  *     (parameter_name_1 ....)
311  *      ....
312  *     (parameter_name_n ....))
313  *
314  * Example:
315  *
316  *   (rsa
317  *     (nbits 4:2048)
318  *     (rsa-use-e 2:41))
319  *
320  * On success the value for nbits is stored at R_E.  If no rsa-use-e
321  * parameter is found, the function returns success and stores 65537 at
322  * R_E.  For parsing errors the function returns an error code and
323  * stores 0 at R_E.
324  */
325 gpg_err_code_t
326 _gcry_pk_util_get_rsa_use_e (gcry_sexp_t list, unsigned long *r_e)
327 {
328   char buf[50];
329   const char *s;
330   size_t n;
331
332   *r_e = 0;
333
334   list = sexp_find_token (list, "rsa-use-e", 0);
335   if (!list)
336     {
337       *r_e = 65537; /* Not given, use the value generated by old versions. */
338       return 0;
339     }
340
341   s = sexp_nth_data (list, 1, &n);
342   if (!s || n >= DIM (buf) - 1 )
343     {
344       /* No value or value too large.  */
345       sexp_release (list);
346       return GPG_ERR_INV_OBJ;
347     }
348   memcpy (buf, s, n);
349   buf[n] = 0;
350   *r_e = strtoul (buf, NULL, 0);
351   sexp_release (list);
352   return 0;
353 }
354
355
356 /* Parse a "sig-val" s-expression and store the inner parameter list at
357    R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
358    "sig-val" is valid.  Returns 0 on success and stores a new list at
359    R_PARMS which must be freed by the caller.  On error R_PARMS is set
360    to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
361    values are set into it; as of now they are only used with ecc
362    algorithms.  */
363 gpg_err_code_t
364 _gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig, const char **algo_names,
365                                gcry_sexp_t *r_parms, int *r_eccflags)
366 {
367   gpg_err_code_t rc;
368   gcry_sexp_t l1 = NULL;
369   gcry_sexp_t l2 = NULL;
370   char *name = NULL;
371   int i;
372
373   *r_parms = NULL;
374   if (r_eccflags)
375     *r_eccflags = 0;
376
377   /* Extract the signature value.  */
378   l1 = sexp_find_token (s_sig, "sig-val", 0);
379   if (!l1)
380     {
381       rc = GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
382       goto leave;
383     }
384
385   l2 = sexp_nth (l1, 1);
386   if (!l2)
387     {
388       rc = GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
389       goto leave;
390     }
391   name = sexp_nth_string (l2, 0);
392   if (!name)
393     {
394       rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
395       goto leave;
396     }
397   else if (!strcmp (name, "flags"))
398     {
399       /* Skip a "flags" parameter and look again for the algorithm
400          name.  This is not used but here just for the sake of
401          consistent S-expressions we need to handle it. */
402       sexp_release (l2);
403       l2 = sexp_nth (l1, 2);
404       if (!l2)
405         {
406           rc = GPG_ERR_INV_OBJ;
407           goto leave;
408         }
409       xfree (name);
410       name = sexp_nth_string (l2, 0);
411       if (!name)
412         {
413           rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
414           goto leave;
415         }
416     }
417
418   for (i=0; algo_names[i]; i++)
419     if (!stricmp (name, algo_names[i]))
420       break;
421   if (!algo_names[i])
422     {
423       rc = GPG_ERR_CONFLICT; /* "sig-val" uses an unexpected algo. */
424       goto leave;
425     }
426   if (r_eccflags)
427     {
428       if (!strcmp (name, "eddsa"))
429         *r_eccflags = PUBKEY_FLAG_EDDSA;
430       if (!strcmp (name, "gost"))
431         *r_eccflags = PUBKEY_FLAG_GOST;
432     }
433
434   *r_parms = l2;
435   l2 = NULL;
436   rc = 0;
437
438  leave:
439   xfree (name);
440   sexp_release (l2);
441   sexp_release (l1);
442   return rc;
443 }
444
445
446 /* Parse a "enc-val" s-expression and store the inner parameter list
447    at R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
448    "enc-val" is valid.  Returns 0 on success and stores a new list at
449    R_PARMS which must be freed by the caller.  On error R_PARMS is set
450    to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
451    values are set into it; as of now they are only used with ecc
452    algorithms.
453
454      (enc-val
455        [(flags [raw, pkcs1, oaep, no-blinding])]
456        [(hash-algo <algo>)]
457        [(label <label>)]
458         (<algo>
459           (<param_name1> <mpi>)
460           ...
461           (<param_namen> <mpi>)))
462
463    HASH-ALGO and LABEL are specific to OAEP.  CTX will be updated with
464    encoding information.  */
465 gpg_err_code_t
466 _gcry_pk_util_preparse_encval (gcry_sexp_t sexp, const char **algo_names,
467                                gcry_sexp_t *r_parms,
468                                struct pk_encoding_ctx *ctx)
469 {
470   gcry_err_code_t rc = 0;
471   gcry_sexp_t l1 = NULL;
472   gcry_sexp_t l2 = NULL;
473   char *name = NULL;
474   size_t n;
475   int parsed_flags = 0;
476   int i;
477
478   *r_parms = NULL;
479
480   /* Check that the first element is valid.  */
481   l1 = sexp_find_token (sexp, "enc-val" , 0);
482   if (!l1)
483     {
484       rc = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
485       goto leave;
486     }
487
488   l2 = sexp_nth (l1, 1);
489   if (!l2)
490     {
491       rc = GPG_ERR_NO_OBJ;  /* No cadr for the data object.  */
492       goto leave;
493     }
494
495   /* Extract identifier of sublist.  */
496   name = sexp_nth_string (l2, 0);
497   if (!name)
498     {
499       rc = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
500       goto leave;
501     }
502
503   if (!strcmp (name, "flags"))
504     {
505       const char *s;
506
507       /* There is a flags element - process it.  */
508       rc = _gcry_pk_util_parse_flaglist (l2, &parsed_flags, &ctx->encoding);
509       if (rc)
510         goto leave;
511       if (ctx->encoding == PUBKEY_ENC_PSS)
512         {
513           rc = GPG_ERR_CONFLICT;
514           goto leave;
515         }
516
517       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
518       if (ctx->encoding == PUBKEY_ENC_OAEP)
519         {
520           /* Get HASH-ALGO. */
521           sexp_release (l2);
522           l2 = sexp_find_token (l1, "hash-algo", 0);
523           if (l2)
524             {
525               s = sexp_nth_data (l2, 1, &n);
526               if (!s)
527                 rc = GPG_ERR_NO_OBJ;
528               else
529                 {
530                   ctx->hash_algo = get_hash_algo (s, n);
531                   if (!ctx->hash_algo)
532                     rc = GPG_ERR_DIGEST_ALGO;
533                 }
534               if (rc)
535                 goto leave;
536             }
537
538           /* Get LABEL. */
539           sexp_release (l2);
540           l2 = sexp_find_token (l1, "label", 0);
541           if (l2)
542             {
543               s = sexp_nth_data (l2, 1, &n);
544               if (!s)
545                 rc = GPG_ERR_NO_OBJ;
546               else if (n > 0)
547                 {
548                   ctx->label = xtrymalloc (n);
549                   if (!ctx->label)
550                     rc = gpg_err_code_from_syserror ();
551                   else
552                     {
553                       memcpy (ctx->label, s, n);
554                       ctx->labellen = n;
555                     }
556                 }
557               if (rc)
558                 goto leave;
559             }
560         }
561
562       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
563       for (i = 2; (sexp_release (l2), l2 = sexp_nth (l1, i)); i++)
564         {
565           s = sexp_nth_data (l2, 0, &n);
566           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
567               && !(n == 5 && !memcmp (s, "label", 5))
568               && !(n == 15 && !memcmp (s, "random-override", 15)))
569             break;
570         }
571       if (!l2)
572         {
573           rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
574           goto leave;
575         }
576
577       /* Extract sublist identifier.  */
578       xfree (name);
579       name = sexp_nth_string (l2, 0);
580       if (!name)
581         {
582           rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
583           goto leave;
584         }
585     }
586   else /* No flags - flag as legacy structure.  */
587     parsed_flags |= PUBKEY_FLAG_LEGACYRESULT;
588
589   for (i=0; algo_names[i]; i++)
590     if (!stricmp (name, algo_names[i]))
591       break;
592   if (!algo_names[i])
593     {
594       rc = GPG_ERR_CONFLICT; /* "enc-val" uses an unexpected algo. */
595       goto leave;
596     }
597
598   *r_parms = l2;
599   l2 = NULL;
600   ctx->flags |= parsed_flags;
601   rc = 0;
602
603  leave:
604   xfree (name);
605   sexp_release (l2);
606   sexp_release (l1);
607   return rc;
608 }
609
610
611 /* Initialize an encoding context.  */
612 void
613 _gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
614                                  enum pk_operation op,
615                                  unsigned int nbits)
616 {
617   ctx->op = op;
618   ctx->nbits = nbits;
619   ctx->encoding = PUBKEY_ENC_UNKNOWN;
620   ctx->flags = 0;
621   if (fips_mode ())
622     {
623       ctx->hash_algo = GCRY_MD_SHA256;
624     }
625   else
626     {
627       ctx->hash_algo = GCRY_MD_SHA1;
628     }
629   ctx->label = NULL;
630   ctx->labellen = 0;
631   ctx->saltlen = 20;
632   ctx->verify_cmp = NULL;
633   ctx->verify_arg = NULL;
634 }
635
636 /* Free a context initialzied by _gcry_pk_util_init_encoding_ctx.  */
637 void
638 _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
639 {
640   xfree (ctx->label);
641 }
642
643
644 /* Take the hash value and convert into an MPI, suitable for
645    passing to the low level functions.  We currently support the
646    old style way of passing just a MPI and the modern interface which
647    allows to pass flags so that we can choose between raw and pkcs1
648    padding - may be more padding options later.
649
650    (<mpi>)
651    or
652    (data
653     [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
654     [(hash <algo> <value>)]
655     [(value <text>)]
656     [(hash-algo <algo>)]
657     [(label <label>)]
658     [(salt-length <length>)]
659     [(random-override <data>)]
660    )
661
662    Either the VALUE or the HASH element must be present for use
663    with signatures.  VALUE is used for encryption.
664
665    HASH-ALGO is specific to OAEP and EDDSA.
666
667    LABEL is specific to OAEP.
668
669    SALT-LENGTH is for PSS it is limited to 16384 bytes.
670
671    RANDOM-OVERRIDE is used to replace random nonces for regression
672    testing.  */
673 gcry_err_code_t
674 _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
675                            struct pk_encoding_ctx *ctx)
676 {
677   gcry_err_code_t rc = 0;
678   gcry_sexp_t ldata, lhash, lvalue;
679   size_t n;
680   const char *s;
681   int unknown_flag = 0;
682   int parsed_flags = 0;
683
684   *ret_mpi = NULL;
685   ldata = sexp_find_token (input, "data", 0);
686   if (!ldata)
687     { /* assume old style */
688       *ret_mpi = sexp_nth_mpi (input, 0, 0);
689       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
690     }
691
692   /* See whether there is a flags list.  */
693   {
694     gcry_sexp_t lflags = sexp_find_token (ldata, "flags", 0);
695     if (lflags)
696       {
697         if (_gcry_pk_util_parse_flaglist (lflags,
698                                           &parsed_flags, &ctx->encoding))
699           unknown_flag = 1;
700         sexp_release (lflags);
701       }
702   }
703
704   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
705     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
706
707   /* Get HASH or MPI */
708   lhash = sexp_find_token (ldata, "hash", 0);
709   lvalue = lhash? NULL : sexp_find_token (ldata, "value", 0);
710
711   if (!(!lhash ^ !lvalue))
712     rc = GPG_ERR_INV_OBJ; /* none or both given */
713   else if (unknown_flag)
714     rc = GPG_ERR_INV_FLAG;
715   else if (ctx->encoding == PUBKEY_ENC_RAW
716            && (parsed_flags & PUBKEY_FLAG_EDDSA))
717     {
718       /* Prepare for EdDSA.  */
719       gcry_sexp_t list;
720       void *value;
721       size_t valuelen;
722
723       if (!lvalue)
724         {
725           rc = GPG_ERR_INV_OBJ;
726           goto leave;
727         }
728       /* Get HASH-ALGO. */
729       list = sexp_find_token (ldata, "hash-algo", 0);
730       if (list)
731         {
732           s = sexp_nth_data (list, 1, &n);
733           if (!s)
734             rc = GPG_ERR_NO_OBJ;
735           else
736             {
737               ctx->hash_algo = get_hash_algo (s, n);
738               if (!ctx->hash_algo)
739                 rc = GPG_ERR_DIGEST_ALGO;
740             }
741           sexp_release (list);
742         }
743       else
744         rc = GPG_ERR_INV_OBJ;
745       if (rc)
746         goto leave;
747
748       /* Get VALUE.  */
749       value = sexp_nth_buffer (lvalue, 1, &valuelen);
750       if (!value)
751         {
752           /* We assume that a zero length message is meant by
753              "(value)".  This is commonly used by test vectors.  Note
754              that S-expression do not allow zero length items. */
755           valuelen = 0;
756           value = xtrymalloc (1);
757           if (!value)
758             rc = gpg_err_code_from_syserror ();
759         }
760       else if ((valuelen * 8) < valuelen)
761         {
762           xfree (value);
763           rc = GPG_ERR_TOO_LARGE;
764         }
765       if (rc)
766         goto leave;
767
768       /* Note that mpi_set_opaque takes ownership of VALUE.  */
769       *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
770     }
771   else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
772            && ((parsed_flags & PUBKEY_FLAG_RAW_FLAG)
773                || (parsed_flags & PUBKEY_FLAG_RFC6979)))
774     {
775       /* Raw encoding along with a hash element.  This is commonly
776          used for DSA.  For better backward error compatibility we
777          allow this only if either the rfc6979 flag has been given or
778          the raw flags was explicitly given.  */
779       if (sexp_length (lhash) != 3)
780         rc = GPG_ERR_INV_OBJ;
781       else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
782         rc = GPG_ERR_INV_OBJ;
783       else
784         {
785           void *value;
786           size_t valuelen;
787
788           ctx->hash_algo = get_hash_algo (s, n);
789           if (!ctx->hash_algo)
790             rc = GPG_ERR_DIGEST_ALGO;
791           else if (!(value=sexp_nth_buffer (lhash, 2, &valuelen)))
792             rc = GPG_ERR_INV_OBJ;
793           else if ((valuelen * 8) < valuelen)
794             {
795               xfree (value);
796               rc = GPG_ERR_TOO_LARGE;
797             }
798           else
799             *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
800         }
801     }
802   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
803     {
804       /* RFC6969 may only be used with the a hash value and not the
805          MPI based value.  */
806       if (parsed_flags & PUBKEY_FLAG_RFC6979)
807         {
808           rc = GPG_ERR_CONFLICT;
809           goto leave;
810         }
811
812       /* Get the value */
813       *ret_mpi = sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
814       if (!*ret_mpi)
815         rc = GPG_ERR_INV_OBJ;
816     }
817   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
818            && ctx->op == PUBKEY_OP_ENCRYPT)
819     {
820       const void * value;
821       size_t valuelen;
822       gcry_sexp_t list;
823       void *random_override = NULL;
824       size_t random_override_len = 0;
825
826       if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
827         rc = GPG_ERR_INV_OBJ;
828       else
829         {
830           /* Get optional RANDOM-OVERRIDE.  */
831           list = sexp_find_token (ldata, "random-override", 0);
832           if (list)
833             {
834               s = sexp_nth_data (list, 1, &n);
835               if (!s)
836                 rc = GPG_ERR_NO_OBJ;
837               else if (n > 0)
838                 {
839                   random_override = xtrymalloc (n);
840                   if (!random_override)
841                     rc = gpg_err_code_from_syserror ();
842                   else
843                     {
844                       memcpy (random_override, s, n);
845                       random_override_len = n;
846                     }
847                 }
848               sexp_release (list);
849               if (rc)
850                 goto leave;
851             }
852
853           rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
854                                                value, valuelen,
855                                                random_override,
856                                                random_override_len);
857           xfree (random_override);
858         }
859     }
860   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
861            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
862     {
863       if (sexp_length (lhash) != 3)
864         rc = GPG_ERR_INV_OBJ;
865       else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
866         rc = GPG_ERR_INV_OBJ;
867       else
868         {
869           const void * value;
870           size_t valuelen;
871
872           ctx->hash_algo = get_hash_algo (s, n);
873
874           if (!ctx->hash_algo)
875             rc = GPG_ERR_DIGEST_ALGO;
876           else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
877                     || !valuelen )
878             rc = GPG_ERR_INV_OBJ;
879           else
880             rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
881                                                  value, valuelen,
882                                                  ctx->hash_algo);
883         }
884     }
885   else if (ctx->encoding == PUBKEY_ENC_PKCS1_RAW && lvalue
886            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
887     {
888       const void * value;
889       size_t valuelen;
890
891       if (sexp_length (lvalue) != 2)
892         rc = GPG_ERR_INV_OBJ;
893       else if ( !(value=sexp_nth_data (lvalue, 1, &valuelen))
894                 || !valuelen )
895         rc = GPG_ERR_INV_OBJ;
896       else
897         rc = _gcry_rsa_pkcs1_encode_raw_for_sig (ret_mpi, ctx->nbits,
898                                                  value, valuelen);
899     }
900   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
901            && ctx->op == PUBKEY_OP_ENCRYPT)
902     {
903       const void * value;
904       size_t valuelen;
905
906       if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
907         rc = GPG_ERR_INV_OBJ;
908       else
909         {
910           gcry_sexp_t list;
911           void *random_override = NULL;
912           size_t random_override_len = 0;
913
914           /* Get HASH-ALGO. */
915           list = sexp_find_token (ldata, "hash-algo", 0);
916           if (list)
917             {
918               s = sexp_nth_data (list, 1, &n);
919               if (!s)
920                 rc = GPG_ERR_NO_OBJ;
921               else
922                 {
923                   ctx->hash_algo = get_hash_algo (s, n);
924                   if (!ctx->hash_algo)
925                     rc = GPG_ERR_DIGEST_ALGO;
926                 }
927               sexp_release (list);
928               if (rc)
929                 goto leave;
930             }
931
932           /* Get LABEL. */
933           list = sexp_find_token (ldata, "label", 0);
934           if (list)
935             {
936               s = sexp_nth_data (list, 1, &n);
937               if (!s)
938                 rc = GPG_ERR_NO_OBJ;
939               else if (n > 0)
940                 {
941                   ctx->label = xtrymalloc (n);
942                   if (!ctx->label)
943                     rc = gpg_err_code_from_syserror ();
944                   else
945                     {
946                       memcpy (ctx->label, s, n);
947                       ctx->labellen = n;
948                     }
949                 }
950               sexp_release (list);
951               if (rc)
952                 goto leave;
953             }
954           /* Get optional RANDOM-OVERRIDE.  */
955           list = sexp_find_token (ldata, "random-override", 0);
956           if (list)
957             {
958               s = sexp_nth_data (list, 1, &n);
959               if (!s)
960                 rc = GPG_ERR_NO_OBJ;
961               else if (n > 0)
962                 {
963                   random_override = xtrymalloc (n);
964                   if (!random_override)
965                     rc = gpg_err_code_from_syserror ();
966                   else
967                     {
968                       memcpy (random_override, s, n);
969                       random_override_len = n;
970                     }
971                 }
972               sexp_release (list);
973               if (rc)
974                 goto leave;
975             }
976
977           rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
978                                       value, valuelen,
979                                       ctx->label, ctx->labellen,
980                                       random_override, random_override_len);
981
982           xfree (random_override);
983         }
984     }
985   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
986            && ctx->op == PUBKEY_OP_SIGN)
987     {
988       if (sexp_length (lhash) != 3)
989         rc = GPG_ERR_INV_OBJ;
990       else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
991         rc = GPG_ERR_INV_OBJ;
992       else
993         {
994           const void * value;
995           size_t valuelen;
996           void *random_override = NULL;
997           size_t random_override_len = 0;
998
999           ctx->hash_algo = get_hash_algo (s, n);
1000
1001           if (!ctx->hash_algo)
1002             rc = GPG_ERR_DIGEST_ALGO;
1003           else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
1004                     || !valuelen )
1005             rc = GPG_ERR_INV_OBJ;
1006           else
1007             {
1008               gcry_sexp_t list;
1009
1010               /* Get SALT-LENGTH. */
1011               list = sexp_find_token (ldata, "salt-length", 0);
1012               if (list)
1013                 {
1014                   s = sexp_nth_data (list, 1, &n);
1015                   if (!s)
1016                     {
1017                       rc = GPG_ERR_NO_OBJ;
1018                       goto leave;
1019                     }
1020                   ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
1021                   sexp_release (list);
1022                 }
1023
1024               /* Get optional RANDOM-OVERRIDE.  */
1025               list = sexp_find_token (ldata, "random-override", 0);
1026               if (list)
1027                 {
1028                   s = sexp_nth_data (list, 1, &n);
1029                   if (!s)
1030                     rc = GPG_ERR_NO_OBJ;
1031                   else if (n > 0)
1032                     {
1033                       random_override = xtrymalloc (n);
1034                       if (!random_override)
1035                         rc = gpg_err_code_from_syserror ();
1036                       else
1037                         {
1038                           memcpy (random_override, s, n);
1039                           random_override_len = n;
1040                         }
1041                     }
1042                   sexp_release (list);
1043                   if (rc)
1044                     goto leave;
1045                 }
1046
1047               /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
1048               rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
1049                                          ctx->hash_algo,
1050                                          value, valuelen, ctx->saltlen,
1051                                          random_override, random_override_len);
1052
1053               xfree (random_override);
1054             }
1055         }
1056     }
1057   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1058            && ctx->op == PUBKEY_OP_VERIFY)
1059     {
1060       if (sexp_length (lhash) != 3)
1061         rc = GPG_ERR_INV_OBJ;
1062       else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
1063         rc = GPG_ERR_INV_OBJ;
1064       else
1065         {
1066           ctx->hash_algo = get_hash_algo (s, n);
1067
1068           if (!ctx->hash_algo)
1069             rc = GPG_ERR_DIGEST_ALGO;
1070           else
1071             {
1072               gcry_sexp_t list;
1073               /* Get SALT-LENGTH. */
1074               list = sexp_find_token (ldata, "salt-length", 0);
1075               if (list)
1076                 {
1077                   unsigned long ul;
1078
1079                   s = sexp_nth_data (list, 1, &n);
1080                   if (!s)
1081                     {
1082                       rc = GPG_ERR_NO_OBJ;
1083                       sexp_release (list);
1084                       goto leave;
1085                     }
1086                   ul = strtoul (s, NULL, 10);
1087                   if (ul > 16384)
1088                     {
1089                       rc = GPG_ERR_TOO_LARGE;
1090                       sexp_release (list);
1091                       goto leave;
1092                     }
1093                   ctx->saltlen = ul;
1094                   sexp_release (list);
1095                 }
1096
1097               *ret_mpi = sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
1098               if (!*ret_mpi)
1099                 rc = GPG_ERR_INV_OBJ;
1100               ctx->verify_cmp = pss_verify_cmp;
1101               ctx->verify_arg = *ret_mpi;
1102             }
1103         }
1104     }
1105   else
1106     rc = GPG_ERR_CONFLICT;
1107
1108  leave:
1109   sexp_release (ldata);
1110   sexp_release (lhash);
1111   sexp_release (lvalue);
1112
1113   if (!rc)
1114     ctx->flags = parsed_flags;
1115   else
1116     {
1117       xfree (ctx->label);
1118       ctx->label = NULL;
1119     }
1120
1121   return rc;
1122 }