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