doc: Fix typo.
[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     { NULL, 0 }
225   };
226   int algo;
227   int i;
228
229   for (i=0; hashnames[i].name; i++)
230     {
231       if ( strlen (hashnames[i].name) == n
232            && !memcmp (hashnames[i].name, s, n))
233         break;
234     }
235   if (hashnames[i].name)
236     algo = hashnames[i].algo;
237   else
238     {
239       /* In case of not listed or dynamically allocated hash
240          algorithm we fall back to this somewhat slower
241          method.  Further, it also allows to use OIDs as
242          algorithm names. */
243       char *tmpname;
244
245       tmpname = xtrymalloc (n+1);
246       if (!tmpname)
247         algo = 0;  /* Out of core - silently give up.  */
248       else
249         {
250           memcpy (tmpname, s, n);
251           tmpname[n] = 0;
252           algo = _gcry_md_map_name (tmpname);
253           xfree (tmpname);
254         }
255     }
256   return algo;
257 }
258
259
260 /* Get the "nbits" parameter from an s-expression of the format:
261  *
262  *   (algo
263  *     (parameter_name_1 ....)
264  *      ....
265  *     (parameter_name_n ....))
266  *
267  * Example:
268  *
269  *   (rsa
270  *     (nbits 4:2048))
271  *
272  * On success the value for nbits is stored at R_NBITS.  If no nbits
273  * parameter is found, the function returns success and stores 0 at
274  * R_NBITS.  For parsing errors the function returns an error code and
275  * stores 0 at R_NBITS.
276  */
277 gpg_err_code_t
278 _gcry_pk_util_get_nbits (gcry_sexp_t list, unsigned int *r_nbits)
279 {
280   char buf[50];
281   const char *s;
282   size_t n;
283
284   *r_nbits = 0;
285
286   list = sexp_find_token (list, "nbits", 0);
287   if (!list)
288     return 0; /* No NBITS found.  */
289
290   s = sexp_nth_data (list, 1, &n);
291   if (!s || n >= DIM (buf) - 1 )
292     {
293       /* NBITS given without a cdr.  */
294       sexp_release (list);
295       return GPG_ERR_INV_OBJ;
296     }
297   memcpy (buf, s, n);
298   buf[n] = 0;
299   *r_nbits = (unsigned int)strtoul (buf, NULL, 0);
300   sexp_release (list);
301   return 0;
302 }
303
304
305 /* Get the optional "rsa-use-e" parameter from an s-expression of the
306  * format:
307  *
308  *   (algo
309  *     (parameter_name_1 ....)
310  *      ....
311  *     (parameter_name_n ....))
312  *
313  * Example:
314  *
315  *   (rsa
316  *     (nbits 4:2048)
317  *     (rsa-use-e 2:41))
318  *
319  * On success the value for nbits is stored at R_E.  If no rsa-use-e
320  * parameter is found, the function returns success and stores 65537 at
321  * R_E.  For parsing errors the function returns an error code and
322  * stores 0 at R_E.
323  */
324 gpg_err_code_t
325 _gcry_pk_util_get_rsa_use_e (gcry_sexp_t list, unsigned long *r_e)
326 {
327   char buf[50];
328   const char *s;
329   size_t n;
330
331   *r_e = 0;
332
333   list = sexp_find_token (list, "rsa-use-e", 0);
334   if (!list)
335     {
336       *r_e = 65537; /* Not given, use the value generated by old versions. */
337       return 0;
338     }
339
340   s = sexp_nth_data (list, 1, &n);
341   if (!s || n >= DIM (buf) - 1 )
342     {
343       /* No value or value too large.  */
344       sexp_release (list);
345       return GPG_ERR_INV_OBJ;
346     }
347   memcpy (buf, s, n);
348   buf[n] = 0;
349   *r_e = strtoul (buf, NULL, 0);
350   sexp_release (list);
351   return 0;
352 }
353
354
355 /* Parse a "sig-val" s-expression and store the inner parameter list at
356    R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
357    "sig-val" is valid.  Returns 0 on success and stores a new list at
358    R_PARMS which must be freed by the caller.  On error R_PARMS is set
359    to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
360    values are set into it; as of now they are only used with ecc
361    algorithms.  */
362 gpg_err_code_t
363 _gcry_pk_util_preparse_sigval (gcry_sexp_t s_sig, const char **algo_names,
364                                gcry_sexp_t *r_parms, int *r_eccflags)
365 {
366   gpg_err_code_t rc;
367   gcry_sexp_t l1 = NULL;
368   gcry_sexp_t l2 = NULL;
369   char *name = NULL;
370   int i;
371
372   *r_parms = NULL;
373   if (r_eccflags)
374     *r_eccflags = 0;
375
376   /* Extract the signature value.  */
377   l1 = sexp_find_token (s_sig, "sig-val", 0);
378   if (!l1)
379     {
380       rc = GPG_ERR_INV_OBJ; /* Does not contain a signature value object.  */
381       goto leave;
382     }
383
384   l2 = sexp_nth (l1, 1);
385   if (!l2)
386     {
387       rc = GPG_ERR_NO_OBJ;   /* No cadr for the sig object.  */
388       goto leave;
389     }
390   name = sexp_nth_string (l2, 0);
391   if (!name)
392     {
393       rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
394       goto leave;
395     }
396   else if (!strcmp (name, "flags"))
397     {
398       /* Skip a "flags" parameter and look again for the algorithm
399          name.  This is not used but here just for the sake of
400          consistent S-expressions we need to handle it. */
401       sexp_release (l2);
402       l2 = sexp_nth (l1, 2);
403       if (!l2)
404         {
405           rc = GPG_ERR_INV_OBJ;
406           goto leave;
407         }
408       xfree (name);
409       name = sexp_nth_string (l2, 0);
410       if (!name)
411         {
412           rc = GPG_ERR_INV_OBJ;  /* Invalid structure of object.  */
413           goto leave;
414         }
415     }
416
417   for (i=0; algo_names[i]; i++)
418     if (!stricmp (name, algo_names[i]))
419       break;
420   if (!algo_names[i])
421     {
422       rc = GPG_ERR_CONFLICT; /* "sig-val" uses an unexpected algo. */
423       goto leave;
424     }
425   if (r_eccflags)
426     {
427       if (!strcmp (name, "eddsa"))
428         *r_eccflags = PUBKEY_FLAG_EDDSA;
429       if (!strcmp (name, "gost"))
430         *r_eccflags = PUBKEY_FLAG_GOST;
431     }
432
433   *r_parms = l2;
434   l2 = NULL;
435   rc = 0;
436
437  leave:
438   xfree (name);
439   sexp_release (l2);
440   sexp_release (l1);
441   return rc;
442 }
443
444
445 /* Parse a "enc-val" s-expression and store the inner parameter list
446    at R_PARMS.  ALGO_NAMES is used to verify that the algorithm in
447    "enc-val" is valid.  Returns 0 on success and stores a new list at
448    R_PARMS which must be freed by the caller.  On error R_PARMS is set
449    to NULL and an error code returned.  If R_ECCFLAGS is not NULL flag
450    values are set into it; as of now they are only used with ecc
451    algorithms.
452
453      (enc-val
454        [(flags [raw, pkcs1, oaep, no-blinding])]
455        [(hash-algo <algo>)]
456        [(label <label>)]
457         (<algo>
458           (<param_name1> <mpi>)
459           ...
460           (<param_namen> <mpi>)))
461
462    HASH-ALGO and LABEL are specific to OAEP.  CTX will be updated with
463    encoding information.  */
464 gpg_err_code_t
465 _gcry_pk_util_preparse_encval (gcry_sexp_t sexp, const char **algo_names,
466                                gcry_sexp_t *r_parms,
467                                struct pk_encoding_ctx *ctx)
468 {
469   gcry_err_code_t rc = 0;
470   gcry_sexp_t l1 = NULL;
471   gcry_sexp_t l2 = NULL;
472   char *name = NULL;
473   size_t n;
474   int parsed_flags = 0;
475   int i;
476
477   *r_parms = NULL;
478
479   /* Check that the first element is valid.  */
480   l1 = sexp_find_token (sexp, "enc-val" , 0);
481   if (!l1)
482     {
483       rc = GPG_ERR_INV_OBJ; /* Does not contain an encrypted value object.  */
484       goto leave;
485     }
486
487   l2 = sexp_nth (l1, 1);
488   if (!l2)
489     {
490       rc = GPG_ERR_NO_OBJ;  /* No cadr for the data object.  */
491       goto leave;
492     }
493
494   /* Extract identifier of sublist.  */
495   name = sexp_nth_string (l2, 0);
496   if (!name)
497     {
498       rc = GPG_ERR_INV_OBJ; /* Invalid structure of object.  */
499       goto leave;
500     }
501
502   if (!strcmp (name, "flags"))
503     {
504       const char *s;
505
506       /* There is a flags element - process it.  */
507       rc = _gcry_pk_util_parse_flaglist (l2, &parsed_flags, &ctx->encoding);
508       if (rc)
509         goto leave;
510       if (ctx->encoding == PUBKEY_ENC_PSS)
511         {
512           rc = GPG_ERR_CONFLICT;
513           goto leave;
514         }
515
516       /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
517       if (ctx->encoding == PUBKEY_ENC_OAEP)
518         {
519           /* Get HASH-ALGO. */
520           sexp_release (l2);
521           l2 = sexp_find_token (l1, "hash-algo", 0);
522           if (l2)
523             {
524               s = sexp_nth_data (l2, 1, &n);
525               if (!s)
526                 rc = GPG_ERR_NO_OBJ;
527               else
528                 {
529                   ctx->hash_algo = get_hash_algo (s, n);
530                   if (!ctx->hash_algo)
531                     rc = GPG_ERR_DIGEST_ALGO;
532                 }
533               if (rc)
534                 goto leave;
535             }
536
537           /* Get LABEL. */
538           sexp_release (l2);
539           l2 = sexp_find_token (l1, "label", 0);
540           if (l2)
541             {
542               s = sexp_nth_data (l2, 1, &n);
543               if (!s)
544                 rc = GPG_ERR_NO_OBJ;
545               else if (n > 0)
546                 {
547                   ctx->label = xtrymalloc (n);
548                   if (!ctx->label)
549                     rc = gpg_err_code_from_syserror ();
550                   else
551                     {
552                       memcpy (ctx->label, s, n);
553                       ctx->labellen = n;
554                     }
555                 }
556               if (rc)
557                 goto leave;
558             }
559         }
560
561       /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
562       for (i = 2; (sexp_release (l2), l2 = sexp_nth (l1, i)); i++)
563         {
564           s = sexp_nth_data (l2, 0, &n);
565           if (!(n == 9 && !memcmp (s, "hash-algo", 9))
566               && !(n == 5 && !memcmp (s, "label", 5))
567               && !(n == 15 && !memcmp (s, "random-override", 15)))
568             break;
569         }
570       if (!l2)
571         {
572           rc = GPG_ERR_NO_OBJ; /* No cadr for the data object. */
573           goto leave;
574         }
575
576       /* Extract sublist identifier.  */
577       xfree (name);
578       name = sexp_nth_string (l2, 0);
579       if (!name)
580         {
581           rc = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
582           goto leave;
583         }
584     }
585   else /* No flags - flag as legacy structure.  */
586     parsed_flags |= PUBKEY_FLAG_LEGACYRESULT;
587
588   for (i=0; algo_names[i]; i++)
589     if (!stricmp (name, algo_names[i]))
590       break;
591   if (!algo_names[i])
592     {
593       rc = GPG_ERR_CONFLICT; /* "enc-val" uses an unexpected algo. */
594       goto leave;
595     }
596
597   *r_parms = l2;
598   l2 = NULL;
599   ctx->flags |= parsed_flags;
600   rc = 0;
601
602  leave:
603   xfree (name);
604   sexp_release (l2);
605   sexp_release (l1);
606   return rc;
607 }
608
609
610 /* Initialize an encoding context.  */
611 void
612 _gcry_pk_util_init_encoding_ctx (struct pk_encoding_ctx *ctx,
613                                  enum pk_operation op,
614                                  unsigned int nbits)
615 {
616   ctx->op = op;
617   ctx->nbits = nbits;
618   ctx->encoding = PUBKEY_ENC_UNKNOWN;
619   ctx->flags = 0;
620   ctx->hash_algo = GCRY_MD_SHA1;
621   ctx->label = NULL;
622   ctx->labellen = 0;
623   ctx->saltlen = 20;
624   ctx->verify_cmp = NULL;
625   ctx->verify_arg = NULL;
626 }
627
628 /* Free a context initialzied by _gcry_pk_util_init_encoding_ctx.  */
629 void
630 _gcry_pk_util_free_encoding_ctx (struct pk_encoding_ctx *ctx)
631 {
632   xfree (ctx->label);
633 }
634
635
636 /* Take the hash value and convert into an MPI, suitable for
637    passing to the low level functions.  We currently support the
638    old style way of passing just a MPI and the modern interface which
639    allows to pass flags so that we can choose between raw and pkcs1
640    padding - may be more padding options later.
641
642    (<mpi>)
643    or
644    (data
645     [(flags [raw, direct, pkcs1, oaep, pss, no-blinding, rfc6979, eddsa])]
646     [(hash <algo> <value>)]
647     [(value <text>)]
648     [(hash-algo <algo>)]
649     [(label <label>)]
650     [(salt-length <length>)]
651     [(random-override <data>)]
652    )
653
654    Either the VALUE or the HASH element must be present for use
655    with signatures.  VALUE is used for encryption.
656
657    HASH-ALGO is specific to OAEP and EDDSA.
658
659    LABEL is specific to OAEP.
660
661    SALT-LENGTH is for PSS.
662
663    RANDOM-OVERRIDE is used to replace random nonces for regression
664    testing.  */
665 gcry_err_code_t
666 _gcry_pk_util_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
667                            struct pk_encoding_ctx *ctx)
668 {
669   gcry_err_code_t rc = 0;
670   gcry_sexp_t ldata, lhash, lvalue;
671   size_t n;
672   const char *s;
673   int unknown_flag = 0;
674   int parsed_flags = 0;
675
676   *ret_mpi = NULL;
677   ldata = sexp_find_token (input, "data", 0);
678   if (!ldata)
679     { /* assume old style */
680       *ret_mpi = sexp_nth_mpi (input, 0, 0);
681       return *ret_mpi ? GPG_ERR_NO_ERROR : GPG_ERR_INV_OBJ;
682     }
683
684   /* See whether there is a flags list.  */
685   {
686     gcry_sexp_t lflags = sexp_find_token (ldata, "flags", 0);
687     if (lflags)
688       {
689         if (_gcry_pk_util_parse_flaglist (lflags,
690                                           &parsed_flags, &ctx->encoding))
691           unknown_flag = 1;
692         sexp_release (lflags);
693       }
694   }
695
696   if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
697     ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
698
699   /* Get HASH or MPI */
700   lhash = sexp_find_token (ldata, "hash", 0);
701   lvalue = lhash? NULL : sexp_find_token (ldata, "value", 0);
702
703   if (!(!lhash ^ !lvalue))
704     rc = GPG_ERR_INV_OBJ; /* none or both given */
705   else if (unknown_flag)
706     rc = GPG_ERR_INV_FLAG;
707   else if (ctx->encoding == PUBKEY_ENC_RAW
708            && (parsed_flags & PUBKEY_FLAG_EDDSA))
709     {
710       /* Prepare for EdDSA.  */
711       gcry_sexp_t list;
712       void *value;
713       size_t valuelen;
714
715       if (!lvalue)
716         {
717           rc = GPG_ERR_INV_OBJ;
718           goto leave;
719         }
720       /* Get HASH-ALGO. */
721       list = sexp_find_token (ldata, "hash-algo", 0);
722       if (list)
723         {
724           s = sexp_nth_data (list, 1, &n);
725           if (!s)
726             rc = GPG_ERR_NO_OBJ;
727           else
728             {
729               ctx->hash_algo = get_hash_algo (s, n);
730               if (!ctx->hash_algo)
731                 rc = GPG_ERR_DIGEST_ALGO;
732             }
733           sexp_release (list);
734         }
735       else
736         rc = GPG_ERR_INV_OBJ;
737       if (rc)
738         goto leave;
739
740       /* Get VALUE.  */
741       value = sexp_nth_buffer (lvalue, 1, &valuelen);
742       if (!value)
743         {
744           /* We assume that a zero length message is meant by
745              "(value)".  This is commonly used by test vectors.  Note
746              that S-expression do not allow zero length items. */
747           valuelen = 0;
748           value = xtrymalloc (1);
749           if (!value)
750             rc = gpg_err_code_from_syserror ();
751         }
752       else if ((valuelen * 8) < valuelen)
753         {
754           xfree (value);
755           rc = GPG_ERR_TOO_LARGE;
756         }
757       if (rc)
758         goto leave;
759
760       /* Note that mpi_set_opaque takes ownership of VALUE.  */
761       *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
762     }
763   else if (ctx->encoding == PUBKEY_ENC_RAW && lhash
764            && ((parsed_flags & PUBKEY_FLAG_RAW_FLAG)
765                || (parsed_flags & PUBKEY_FLAG_RFC6979)))
766     {
767       /* Raw encoding along with a hash element.  This is commonly
768          used for DSA.  For better backward error compatibility we
769          allow this only if either the rfc6979 flag has been given or
770          the raw flags was explicitly given.  */
771       if (sexp_length (lhash) != 3)
772         rc = GPG_ERR_INV_OBJ;
773       else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
774         rc = GPG_ERR_INV_OBJ;
775       else
776         {
777           void *value;
778           size_t valuelen;
779
780           ctx->hash_algo = get_hash_algo (s, n);
781           if (!ctx->hash_algo)
782             rc = GPG_ERR_DIGEST_ALGO;
783           else if (!(value=sexp_nth_buffer (lhash, 2, &valuelen)))
784             rc = GPG_ERR_INV_OBJ;
785           else if ((valuelen * 8) < valuelen)
786             {
787               xfree (value);
788               rc = GPG_ERR_TOO_LARGE;
789             }
790           else
791             *ret_mpi = mpi_set_opaque (NULL, value, valuelen*8);
792         }
793     }
794   else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
795     {
796       /* RFC6969 may only be used with the a hash value and not the
797          MPI based value.  */
798       if (parsed_flags & PUBKEY_FLAG_RFC6979)
799         {
800           rc = GPG_ERR_CONFLICT;
801           goto leave;
802         }
803
804       /* Get the value */
805       *ret_mpi = sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
806       if (!*ret_mpi)
807         rc = GPG_ERR_INV_OBJ;
808     }
809   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
810            && ctx->op == PUBKEY_OP_ENCRYPT)
811     {
812       const void * value;
813       size_t valuelen;
814       gcry_sexp_t list;
815       void *random_override = NULL;
816       size_t random_override_len = 0;
817
818       if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
819         rc = GPG_ERR_INV_OBJ;
820       else
821         {
822           /* Get optional RANDOM-OVERRIDE.  */
823           list = sexp_find_token (ldata, "random-override", 0);
824           if (list)
825             {
826               s = sexp_nth_data (list, 1, &n);
827               if (!s)
828                 rc = GPG_ERR_NO_OBJ;
829               else if (n > 0)
830                 {
831                   random_override = xtrymalloc (n);
832                   if (!random_override)
833                     rc = gpg_err_code_from_syserror ();
834                   else
835                     {
836                       memcpy (random_override, s, n);
837                       random_override_len = n;
838                     }
839                 }
840               sexp_release (list);
841               if (rc)
842                 goto leave;
843             }
844
845           rc = _gcry_rsa_pkcs1_encode_for_enc (ret_mpi, ctx->nbits,
846                                                value, valuelen,
847                                                random_override,
848                                                random_override_len);
849           xfree (random_override);
850         }
851     }
852   else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
853            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
854     {
855       if (sexp_length (lhash) != 3)
856         rc = GPG_ERR_INV_OBJ;
857       else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
858         rc = GPG_ERR_INV_OBJ;
859       else
860         {
861           const void * value;
862           size_t valuelen;
863
864           ctx->hash_algo = get_hash_algo (s, n);
865
866           if (!ctx->hash_algo)
867             rc = GPG_ERR_DIGEST_ALGO;
868           else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
869                     || !valuelen )
870             rc = GPG_ERR_INV_OBJ;
871           else
872             rc = _gcry_rsa_pkcs1_encode_for_sig (ret_mpi, ctx->nbits,
873                                                  value, valuelen,
874                                                  ctx->hash_algo);
875         }
876     }
877   else if (ctx->encoding == PUBKEY_ENC_PKCS1_RAW && lvalue
878            && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
879     {
880       const void * value;
881       size_t valuelen;
882
883       if (sexp_length (lvalue) != 2)
884         rc = GPG_ERR_INV_OBJ;
885       else if ( !(value=sexp_nth_data (lvalue, 1, &valuelen))
886                 || !valuelen )
887         rc = GPG_ERR_INV_OBJ;
888       else
889         rc = _gcry_rsa_pkcs1_encode_raw_for_sig (ret_mpi, ctx->nbits,
890                                                  value, valuelen);
891     }
892   else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
893            && ctx->op == PUBKEY_OP_ENCRYPT)
894     {
895       const void * value;
896       size_t valuelen;
897
898       if ( !(value=sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
899         rc = GPG_ERR_INV_OBJ;
900       else
901         {
902           gcry_sexp_t list;
903           void *random_override = NULL;
904           size_t random_override_len = 0;
905
906           /* Get HASH-ALGO. */
907           list = sexp_find_token (ldata, "hash-algo", 0);
908           if (list)
909             {
910               s = sexp_nth_data (list, 1, &n);
911               if (!s)
912                 rc = GPG_ERR_NO_OBJ;
913               else
914                 {
915                   ctx->hash_algo = get_hash_algo (s, n);
916                   if (!ctx->hash_algo)
917                     rc = GPG_ERR_DIGEST_ALGO;
918                 }
919               sexp_release (list);
920               if (rc)
921                 goto leave;
922             }
923
924           /* Get LABEL. */
925           list = sexp_find_token (ldata, "label", 0);
926           if (list)
927             {
928               s = sexp_nth_data (list, 1, &n);
929               if (!s)
930                 rc = GPG_ERR_NO_OBJ;
931               else if (n > 0)
932                 {
933                   ctx->label = xtrymalloc (n);
934                   if (!ctx->label)
935                     rc = gpg_err_code_from_syserror ();
936                   else
937                     {
938                       memcpy (ctx->label, s, n);
939                       ctx->labellen = n;
940                     }
941                 }
942               sexp_release (list);
943               if (rc)
944                 goto leave;
945             }
946           /* Get optional RANDOM-OVERRIDE.  */
947           list = sexp_find_token (ldata, "random-override", 0);
948           if (list)
949             {
950               s = sexp_nth_data (list, 1, &n);
951               if (!s)
952                 rc = GPG_ERR_NO_OBJ;
953               else if (n > 0)
954                 {
955                   random_override = xtrymalloc (n);
956                   if (!random_override)
957                     rc = gpg_err_code_from_syserror ();
958                   else
959                     {
960                       memcpy (random_override, s, n);
961                       random_override_len = n;
962                     }
963                 }
964               sexp_release (list);
965               if (rc)
966                 goto leave;
967             }
968
969           rc = _gcry_rsa_oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
970                                       value, valuelen,
971                                       ctx->label, ctx->labellen,
972                                       random_override, random_override_len);
973
974           xfree (random_override);
975         }
976     }
977   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
978            && ctx->op == PUBKEY_OP_SIGN)
979     {
980       if (sexp_length (lhash) != 3)
981         rc = GPG_ERR_INV_OBJ;
982       else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
983         rc = GPG_ERR_INV_OBJ;
984       else
985         {
986           const void * value;
987           size_t valuelen;
988           void *random_override = NULL;
989           size_t random_override_len = 0;
990
991           ctx->hash_algo = get_hash_algo (s, n);
992
993           if (!ctx->hash_algo)
994             rc = GPG_ERR_DIGEST_ALGO;
995           else if ( !(value=sexp_nth_data (lhash, 2, &valuelen))
996                     || !valuelen )
997             rc = GPG_ERR_INV_OBJ;
998           else
999             {
1000               gcry_sexp_t list;
1001
1002               /* Get SALT-LENGTH. */
1003               list = sexp_find_token (ldata, "salt-length", 0);
1004               if (list)
1005                 {
1006                   s = sexp_nth_data (list, 1, &n);
1007                   if (!s)
1008                     {
1009                       rc = GPG_ERR_NO_OBJ;
1010                       goto leave;
1011                     }
1012                   ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
1013                   sexp_release (list);
1014                 }
1015
1016               /* Get optional RANDOM-OVERRIDE.  */
1017               list = sexp_find_token (ldata, "random-override", 0);
1018               if (list)
1019                 {
1020                   s = sexp_nth_data (list, 1, &n);
1021                   if (!s)
1022                     rc = GPG_ERR_NO_OBJ;
1023                   else if (n > 0)
1024                     {
1025                       random_override = xtrymalloc (n);
1026                       if (!random_override)
1027                         rc = gpg_err_code_from_syserror ();
1028                       else
1029                         {
1030                           memcpy (random_override, s, n);
1031                           random_override_len = n;
1032                         }
1033                     }
1034                   sexp_release (list);
1035                   if (rc)
1036                     goto leave;
1037                 }
1038
1039               /* Encode the data.  (NBITS-1 is due to 8.1.1, step 1.) */
1040               rc = _gcry_rsa_pss_encode (ret_mpi, ctx->nbits - 1,
1041                                          ctx->hash_algo,
1042                                          value, valuelen, ctx->saltlen,
1043                                          random_override, random_override_len);
1044
1045               xfree (random_override);
1046             }
1047         }
1048     }
1049   else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
1050            && ctx->op == PUBKEY_OP_VERIFY)
1051     {
1052       if (sexp_length (lhash) != 3)
1053         rc = GPG_ERR_INV_OBJ;
1054       else if ( !(s=sexp_nth_data (lhash, 1, &n)) || !n )
1055         rc = GPG_ERR_INV_OBJ;
1056       else
1057         {
1058           ctx->hash_algo = get_hash_algo (s, n);
1059
1060           if (!ctx->hash_algo)
1061             rc = GPG_ERR_DIGEST_ALGO;
1062           else
1063             {
1064               *ret_mpi = sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
1065               if (!*ret_mpi)
1066                 rc = GPG_ERR_INV_OBJ;
1067               ctx->verify_cmp = pss_verify_cmp;
1068               ctx->verify_arg = *ret_mpi;
1069             }
1070         }
1071     }
1072   else
1073     rc = GPG_ERR_CONFLICT;
1074
1075  leave:
1076   sexp_release (ldata);
1077   sexp_release (lhash);
1078   sexp_release (lvalue);
1079
1080   if (!rc)
1081     ctx->flags = parsed_flags;
1082   else
1083     {
1084       xfree (ctx->label);
1085       ctx->label = NULL;
1086     }
1087
1088   return rc;
1089 }