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