f5e946a2d8fe6d15438d5b2669b6a297d5dde3ef
[libgcrypt.git] / cipher / ac.c
1 /* ac.c - Alternative interface for asymmetric cryptography.
2    Copyright (C) 2003, 2004, 2005, 2006
3                  2007, 2008  Free Software Foundation, Inc.
4
5    This file is part of Libgcrypt.
6
7    Libgcrypt is free software; you can redistribute it and/or modify
8    it under the terms of the GNU Lesser general Public License as
9    published by the Free Software Foundation; either version 2.1 of
10    the License, or (at your option) any later version.
11
12    Libgcrypt is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU Lesser General Public License for more details.
16
17    You should have received a copy of the GNU Lesser General Public
18    License along with this program; if not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <config.h>
22 #include <errno.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
26 #include <stddef.h>
27
28 #include "g10lib.h"
29 #include "cipher.h"
30 #include "mpi.h"
31
32 \f
33
34 /* At the moment the ac interface is a wrapper around the pk
35    interface, but this might change somewhen in the future, depending
36    on how many people prefer the ac interface.  */
37
38 /* Mapping of flag numbers to the according strings as it is expected
39    for S-expressions.  */
40 static struct number_string
41 {
42   int number;
43   const char *string;
44 } ac_flags[] =
45   {
46     { GCRY_AC_FLAG_NO_BLINDING, "no-blinding" },
47   };
48
49 /* The positions in this list correspond to the values contained in
50    the gcry_ac_key_type_t enumeration list.  */
51 static const char *ac_key_identifiers[] =
52   {
53     "private-key",
54     "public-key"
55   };
56
57 /* These specifications are needed for key-pair generation; the caller
58    is allowed to pass additional, algorithm-specific `specs' to
59    gcry_ac_key_pair_generate.  This list is used for decoding the
60    provided values according to the selected algorithm.  */
61 struct gcry_ac_key_generate_spec
62 {
63   int algorithm;                /* Algorithm for which this flag is
64                                    relevant.  */
65   const char *name;             /* Name of this flag.  */
66   size_t offset;                /* Offset in the cipher-specific spec
67                                    structure at which the MPI value
68                                    associated with this flag is to be
69                                    found.  */
70 } ac_key_generate_specs[] =
71   {
72     { GCRY_AC_RSA, "rsa-use-e", offsetof (gcry_ac_key_spec_rsa_t, e) },
73     { 0 }
74   };
75
76 /* Handle structure.  */
77 struct gcry_ac_handle
78 {
79   int algorithm;                /* Algorithm ID associated with this
80                                    handle.  */
81   const char *algorithm_name;   /* Name of the algorithm.  */
82   unsigned int flags;           /* Flags, not used yet.  */
83   gcry_module_t module;         /* Reference to the algorithm
84                                    module.  */
85 };
86
87 /* A named MPI value.  */
88 typedef struct gcry_ac_mpi
89 {
90   char *name;                   /* Self-maintained copy of name.  */
91   gcry_mpi_t mpi;               /* MPI value.         */
92   unsigned int flags;           /* Flags.             */
93 } gcry_ac_mpi_t;
94
95 /* A data set, that is simply a list of named MPI values.  */
96 struct gcry_ac_data
97 {
98   gcry_ac_mpi_t *data;          /* List of named values.      */
99   unsigned int data_n;          /* Number of values in DATA.  */
100 };
101
102 /* A single key.  */
103 struct gcry_ac_key
104 {
105   gcry_ac_data_t data;          /* Data in native ac structure.  */
106   gcry_ac_key_type_t type;      /* Type of the key.              */
107 };
108
109 /* A key pair.  */
110 struct gcry_ac_key_pair
111 {
112   gcry_ac_key_t public;
113   gcry_ac_key_t secret;
114 };
115
116 \f
117
118 /*
119  * Functions for working with data sets.
120  */
121
122 /* Creates a new, empty data set and store it in DATA.  */
123 gcry_error_t
124 _gcry_ac_data_new (gcry_ac_data_t *data)
125 {
126   gcry_ac_data_t data_new;
127   gcry_error_t err;
128
129   if (fips_mode ())
130     return gpg_error (GPG_ERR_NOT_SUPPORTED);
131
132   data_new = gcry_malloc (sizeof (*data_new));
133   if (! data_new)
134     {
135       err = gcry_error_from_errno (errno);
136       goto out;
137     }
138
139   data_new->data = NULL;
140   data_new->data_n = 0;
141   *data = data_new;
142   err = 0;
143
144  out:
145
146   return err;
147 }
148
149 /* Destroys all the entries in DATA, but not DATA itself.  */
150 static void
151 ac_data_values_destroy (gcry_ac_data_t data)
152 {
153   unsigned int i;
154
155   for (i = 0; i < data->data_n; i++)
156     if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
157       {
158         gcry_mpi_release (data->data[i].mpi);
159         gcry_free (data->data[i].name);
160       }
161 }
162
163 /* Destroys the data set DATA.  */
164 void
165 _gcry_ac_data_destroy (gcry_ac_data_t data)
166 {
167   if (data)
168     {
169       ac_data_values_destroy (data);
170       gcry_free (data->data);
171       gcry_free (data);
172     }
173 }
174
175 /* This function creates a copy of the array of named MPIs DATA_MPIS,
176    which is of length DATA_MPIS_N; the copy is stored in
177    DATA_MPIS_CP.  */
178 static gcry_error_t
179 ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n,
180                   gcry_ac_mpi_t **data_mpis_cp)
181 {
182   gcry_ac_mpi_t *data_mpis_new;
183   gcry_error_t err;
184   unsigned int i;
185   gcry_mpi_t mpi;
186   char *label;
187
188   data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n);
189   if (! data_mpis_new)
190     {
191       err = gcry_error_from_errno (errno);
192       goto out;
193     }
194   memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n);
195
196   err = 0;
197   for (i = 0; i < data_mpis_n; i++)
198     {
199       /* Copy values.  */
200
201       label = gcry_strdup (data_mpis[i].name);
202       mpi = gcry_mpi_copy (data_mpis[i].mpi);
203       if (! (label && mpi))
204         {
205           err = gcry_error_from_errno (errno);
206           gcry_mpi_release (mpi);
207           gcry_free (label);
208           break;
209         }
210
211       data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC;
212       data_mpis_new[i].name = label;
213       data_mpis_new[i].mpi = mpi;
214     }
215   if (err)
216     goto out;
217
218   *data_mpis_cp = data_mpis_new;
219   err = 0;
220
221  out:
222
223   if (err)
224     if (data_mpis_new)
225       {
226         for (i = 0; i < data_mpis_n; i++)
227           {
228             gcry_mpi_release (data_mpis_new[i].mpi);
229             gcry_free (data_mpis_new[i].name);
230           }
231         gcry_free (data_mpis_new);
232       }
233
234   return err;
235 }
236
237 /* Create a copy of the data set DATA and store it in DATA_CP.  */
238 gcry_error_t
239 _gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
240 {
241   gcry_ac_mpi_t *data_mpis = NULL;
242   gcry_ac_data_t data_new;
243   gcry_error_t err;
244
245   if (fips_mode ())
246     return gpg_error (GPG_ERR_NOT_SUPPORTED);
247
248   /* Allocate data set.  */
249   data_new = gcry_malloc (sizeof (*data_new));
250   if (! data_new)
251     {
252       err = gcry_error_from_errno (errno);
253       goto out;
254     }
255
256   err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
257   if (err)
258     goto out;
259
260   data_new->data_n = data->data_n;
261   data_new->data = data_mpis;
262   *data_cp = data_new;
263
264  out:
265
266   if (err)
267     gcry_free (data_new);
268
269   return err;
270 }
271
272 /* Returns the number of named MPI values inside of the data set
273    DATA.  */
274 unsigned int
275 _gcry_ac_data_length (gcry_ac_data_t data)
276 {
277   return data->data_n;
278 }
279
280
281 /* Add the value MPI to DATA with the label NAME.  If FLAGS contains
282    GCRY_AC_FLAG_COPY, the data set will contain copies of NAME
283    and MPI.  If FLAGS contains GCRY_AC_FLAG_DEALLOC or
284    GCRY_AC_FLAG_COPY, the values contained in the data set will
285    be deallocated when they are to be removed from the data set.  */
286 gcry_error_t
287 _gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
288                    const char *name, gcry_mpi_t mpi)
289 {
290   gcry_error_t err;
291   gcry_mpi_t mpi_cp;
292   char *name_cp;
293   unsigned int i;
294
295   name_cp = NULL;
296   mpi_cp = NULL;
297
298   if (fips_mode ())
299     return gpg_error (GPG_ERR_NOT_SUPPORTED);
300
301   if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY))
302     {
303       err = gcry_error (GPG_ERR_INV_ARG);
304       goto out;
305     }
306
307   if (flags & GCRY_AC_FLAG_COPY)
308     {
309       /* Create copies.  */
310
311       flags |= GCRY_AC_FLAG_DEALLOC;
312       name_cp = gcry_strdup (name);
313       mpi_cp = gcry_mpi_copy (mpi);
314       if (! (name_cp && mpi_cp))
315         {
316           err = gcry_error_from_errno (errno);
317           goto out;
318         }
319     }
320
321   /* Search for existing entry.  */
322   for (i = 0; i < data->data_n; i++)
323     if (! strcmp (name, data->data[i].name))
324       break;
325   if (i < data->data_n)
326     {
327       /* An entry for NAME does already exist.  */
328       if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
329         {
330           gcry_mpi_release (data->data[i].mpi);
331           gcry_free (data->data[i].name);
332         }
333     }
334   else
335     {
336       /* Create a new entry.  */
337
338       gcry_ac_mpi_t *ac_mpis;
339
340       ac_mpis = gcry_realloc (data->data,
341                               sizeof (*data->data) * (data->data_n + 1));
342       if (! ac_mpis)
343         {
344           err = gcry_error_from_errno (errno);
345           goto out;
346         }
347
348       if (data->data != ac_mpis)
349         data->data = ac_mpis;
350       data->data_n++;
351     }
352
353   data->data[i].name = name_cp ? name_cp : ((char *) name);
354   data->data[i].mpi = mpi_cp ? mpi_cp : mpi;
355   data->data[i].flags = flags;
356   err = 0;
357
358  out:
359
360   if (err)
361     {
362       gcry_mpi_release (mpi_cp);
363       gcry_free (name_cp);
364     }
365
366   return err;
367 }
368
369 /* Stores the value labelled with NAME found in the data set DATA in
370    MPI.  The returned MPI value will be released in case
371    gcry_ac_data_set is used to associate the label NAME with a
372    different MPI value.  */
373 gcry_error_t
374 _gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
375                         const char *name, gcry_mpi_t *mpi)
376 {
377   gcry_mpi_t mpi_return;
378   gcry_error_t err;
379   unsigned int i;
380
381   if (fips_mode ())
382     return gpg_error (GPG_ERR_NOT_SUPPORTED);
383
384   if (flags & ~(GCRY_AC_FLAG_COPY))
385     {
386       err = gcry_error (GPG_ERR_INV_ARG);
387       goto out;
388     }
389
390   for (i = 0; i < data->data_n; i++)
391     if (! strcmp (name, data->data[i].name))
392       break;
393   if (i == data->data_n)
394     {
395       err = gcry_error (GPG_ERR_NOT_FOUND);
396       goto out;
397     }
398
399   if (flags & GCRY_AC_FLAG_COPY)
400     {
401       mpi_return = gcry_mpi_copy (data->data[i].mpi);
402       if (! mpi_return)
403         {
404           err = gcry_error_from_errno (errno); /* FIXME? */
405           goto out;
406         }
407     }
408   else
409     mpi_return = data->data[i].mpi;
410
411   *mpi = mpi_return;
412   err = 0;
413
414  out:
415
416   return err;
417 }
418
419 /* Stores in NAME and MPI the named MPI value contained in the data
420    set DATA with the index IDX.  NAME or MPI may be NULL.  The
421    returned MPI value will be released in case gcry_ac_data_set is
422    used to associate the label NAME with a different MPI value.  */
423 gcry_error_t
424 _gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
425                          unsigned int idx,
426                          const char **name, gcry_mpi_t *mpi)
427 {
428   gcry_error_t err;
429   gcry_mpi_t mpi_cp;
430   char *name_cp;
431
432   name_cp = NULL;
433   mpi_cp = NULL;
434
435   if (fips_mode ())
436     return gpg_error (GPG_ERR_NOT_SUPPORTED);
437
438   if (flags & ~(GCRY_AC_FLAG_COPY))
439     {
440       err = gcry_error (GPG_ERR_INV_ARG);
441       goto out;
442     }
443
444   if (idx >= data->data_n)
445     {
446       err = gcry_error (GPG_ERR_INV_ARG);
447       goto out;
448     }
449
450   if (flags & GCRY_AC_FLAG_COPY)
451     {
452       /* Return copies to the user.  */
453       if (name)
454         {
455           name_cp = gcry_strdup (data->data[idx].name);
456           if (! name_cp)
457             {
458               err = gcry_error_from_errno (errno);
459               goto out;
460             }
461         }
462       if (mpi)
463         {
464           mpi_cp = gcry_mpi_copy (data->data[idx].mpi);
465           if (! mpi_cp)
466             {
467               err = gcry_error_from_errno (errno);
468               goto out;
469             }
470         }
471     }
472
473   if (name)
474     *name = name_cp ? name_cp : data->data[idx].name;
475   if (mpi)
476     *mpi = mpi_cp ? mpi_cp : data->data[idx].mpi;
477   err = 0;
478
479  out:
480
481   if (err)
482     {
483       gcry_mpi_release (mpi_cp);
484       gcry_free (name_cp);
485     }
486
487   return err;
488 }
489
490 /* Convert the data set DATA into a new S-Expression, which is to be
491    stored in SEXP, according to the identifiers contained in
492    IDENTIFIERS.  */
493 gcry_error_t
494 _gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
495                        const char **identifiers)
496 {
497   gcry_sexp_t sexp_new;
498   gcry_error_t err;
499   char *sexp_buffer;
500   size_t sexp_buffer_n;
501   size_t identifiers_n;
502   const char *label;
503   gcry_mpi_t mpi;
504   void **arg_list;
505   size_t data_n;
506   unsigned int i;
507
508   sexp_buffer_n = 1;
509   sexp_buffer = NULL;
510   arg_list = NULL;
511   err = 0;
512
513   if (fips_mode ())
514     return gpg_error (GPG_ERR_NOT_SUPPORTED);
515
516   /* Calculate size of S-expression representation.  */
517
518   i = 0;
519   if (identifiers)
520     while (identifiers[i])
521       {
522         /* For each identifier, we add "(<IDENTIFIER>)".  */
523         sexp_buffer_n += 1 + strlen (identifiers[i]) + 1;
524         i++;
525       }
526   identifiers_n = i;
527
528   if (! identifiers_n)
529     /* If there are NO identifiers, we still add surrounding braces so
530        that we have a list of named MPI value lists.  Otherwise it
531        wouldn't be too much fun to process these lists.  */
532     sexp_buffer_n += 2;
533
534   data_n = _gcry_ac_data_length (data);
535   for (i = 0; i < data_n; i++)
536     {
537       err = gcry_ac_data_get_index (data, 0, i, &label, NULL);
538       if (err)
539         break;
540       /* For each MPI we add "(<LABEL> %m)".  */
541       sexp_buffer_n += 1 + strlen (label) + 4;
542     }
543   if (err)
544     goto out;
545
546   /* Allocate buffer.  */
547
548   sexp_buffer = gcry_malloc (sexp_buffer_n);
549   if (! sexp_buffer)
550     {
551       err = gcry_error_from_errno (errno);
552       goto out;
553     }
554
555   /* Fill buffer.  */
556
557   *sexp_buffer = 0;
558   sexp_buffer_n = 0;
559
560   /* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)).  */
561   if (identifiers_n)
562     {
563       /* Add nested identifier lists as usual.  */
564       for (i = 0; i < identifiers_n; i++)
565         sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(%s",
566                                   identifiers[i]);
567     }
568   else
569     {
570       /* Add special list.  */
571       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(");
572     }
573
574   /* Add MPI list.  */
575   arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1));
576   if (! arg_list)
577     {
578       err = gcry_error_from_errno (errno);
579       goto out;
580     }
581   for (i = 0; i < data_n; i++)
582     {
583       err = gcry_ac_data_get_index (data, 0, i, &label, &mpi);
584       if (err)
585         break;
586       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n,
587                                 "(%s %%m)", label);
588       arg_list[i] = &data->data[i].mpi;
589     }
590   if (err)
591     goto out;
592
593   if (identifiers_n)
594     {
595       /* Add closing braces for identifier lists as usual.  */
596       for (i = 0; i < identifiers_n; i++)
597         sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
598     }
599   else
600     {
601       /* Add closing braces for special list.  */
602       sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")");
603     }
604
605   /* Construct.  */
606   err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list);
607   if (err)
608     goto out;
609
610   *sexp = sexp_new;
611
612  out:
613
614   gcry_free (sexp_buffer);
615   gcry_free (arg_list);
616
617   return err;
618 }
619
620 /* Create a new data set, which is to be stored in DATA_SET, from the
621    S-Expression SEXP, according to the identifiers contained in
622    IDENTIFIERS.  */
623 gcry_error_t
624 _gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp,
625                          const char **identifiers)
626 {
627   gcry_ac_data_t data_set_new;
628   gcry_error_t err;
629   gcry_sexp_t sexp_cur;
630   gcry_sexp_t sexp_tmp;
631   gcry_mpi_t mpi;
632   char *string;
633   const char *data;
634   size_t data_n;
635   size_t sexp_n;
636   unsigned int i;
637   int skip_name;
638
639   data_set_new = NULL;
640   sexp_cur = sexp;
641   sexp_tmp = NULL;
642   string = NULL;
643   mpi = NULL;
644   err = 0;
645
646   if (fips_mode ())
647     return gpg_error (GPG_ERR_NOT_SUPPORTED);
648
649   /* Process S-expression/identifiers.  */
650
651   if (identifiers)
652     {
653       for (i = 0; identifiers[i]; i++)
654         {
655           /* Next identifier.  Extract first data item from
656              SEXP_CUR.  */
657           data = gcry_sexp_nth_data (sexp_cur, 0, &data_n);
658
659           if (! ((data_n == strlen (identifiers[i]))
660                  && (! strncmp (data, identifiers[i], data_n))))
661             {
662               /* Identifier mismatch -> error.  */
663               err = gcry_error (GPG_ERR_INV_SEXP);
664               break;
665             }
666
667           /* Identifier matches.  Now we have to distinguish two
668              cases:
669
670              (i)  we are at the last identifier:
671              leave loop
672
673              (ii) we are not at the last identifier:
674              extract next element, which is supposed to be a
675              sublist.  */
676
677           if (! identifiers[i + 1])
678             /* Last identifier.  */
679             break;
680           else
681             {
682               /* Not the last identifier, extract next sublist.  */
683
684               sexp_tmp = gcry_sexp_nth (sexp_cur, 1);
685               if (! sexp_tmp)
686                 {
687                   /* Missing sublist.  */
688                   err = gcry_error (GPG_ERR_INV_SEXP);
689                   break;
690                 }
691
692               /* Release old SEXP_CUR, in case it is not equal to the
693                  original SEXP.  */
694               if (sexp_cur != sexp)
695                 gcry_sexp_release (sexp_cur);
696
697               /* Make SEXP_CUR point to the new current sublist.  */
698               sexp_cur = sexp_tmp;
699               sexp_tmp = NULL;
700             }
701         }
702       if (err)
703         goto out;
704
705       if (i)
706         {
707           /* We have at least one identifier in the list, this means
708              the the list of named MPI values is prefixed, this means
709              that we need to skip the first item (the list name), when
710              processing the MPI values.  */
711           skip_name = 1;
712         }
713       else
714         {
715           /* Since there is no identifiers list, the list of named MPI
716              values is not prefixed with a list name, therefore the
717              offset to use is zero.  */
718           skip_name = 0;
719         }
720     }
721   else
722     /* Since there is no identifiers list, the list of named MPI
723        values is not prefixed with a list name, therefore the offset
724        to use is zero.  */
725     skip_name = 0;
726
727   /* Create data set from S-expression data.  */
728
729   err = gcry_ac_data_new (&data_set_new);
730   if (err)
731     goto out;
732
733   /* Figure out amount of named MPIs in SEXP_CUR.  */
734   if (sexp_cur)
735     sexp_n = gcry_sexp_length (sexp_cur) - skip_name;
736   else
737     sexp_n = 0;
738
739   /* Extracte the named MPIs sequentially.  */
740   for (i = 0; i < sexp_n; i++)
741     {
742       /* Store next S-Expression pair, which is supposed to consist of
743          a name and an MPI value, in SEXP_TMP.  */
744
745       sexp_tmp = gcry_sexp_nth (sexp_cur, i + skip_name);
746       if (! sexp_tmp)
747         {
748           err = gcry_error (GPG_ERR_INV_SEXP);
749           break;
750         }
751
752       /* Extract name from current S-Expression pair.  */
753       data = gcry_sexp_nth_data (sexp_tmp, 0, &data_n);
754       string = gcry_malloc (data_n + 1);
755       if (! string)
756         {
757           err = gcry_error_from_errno (errno);
758           break;
759         }
760       memcpy (string, data, data_n);
761       string[data_n] = 0;
762
763       /* Extract MPI value.  */
764       mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0);
765       if (! mpi)
766         {
767           err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */
768           break;
769         }
770
771       /* Store named MPI in data_set_new.  */
772       err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi);
773       if (err)
774         break;
775
776 /*       gcry_free (string); */
777       string = NULL;
778 /*       gcry_mpi_release (mpi); */
779       mpi = NULL;
780
781       gcry_sexp_release (sexp_tmp);
782       sexp_tmp = NULL;
783     }
784   if (err)
785     goto out;
786
787   *data_set = data_set_new;
788
789  out:
790
791   if (sexp_cur != sexp)
792     gcry_sexp_release (sexp_cur);
793   gcry_sexp_release (sexp_tmp);
794   gcry_mpi_release (mpi);
795   gcry_free (string);
796
797   if (err)
798     gcry_ac_data_destroy (data_set_new);
799
800   return err;
801 }
802
803
804 static void
805 _gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
806 {
807   unsigned char *mpi_buffer;
808   size_t mpi_buffer_n;
809   unsigned int data_n;
810   gcry_error_t err;
811   const char *name;
812   gcry_mpi_t mpi;
813   unsigned int i;
814
815   if (! data)
816     return;
817
818   if (fips_mode ())
819     return;
820
821   mpi_buffer = NULL;
822
823   data_n = _gcry_ac_data_length (data);
824   for (i = 0; i < data_n; i++)
825     {
826       err = gcry_ac_data_get_index (data, 0, i, &name, &mpi);
827       if (err)
828         {
829           log_error ("failed to dump data set");
830           break;
831         }
832
833       err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &mpi_buffer, &mpi_buffer_n, mpi);
834       if (err)
835         {
836           log_error ("failed to dump data set");
837           break;
838         }
839
840       log_printf ("%s%s%s: %s\n",
841                   prefix ? prefix : "",
842                   prefix ? ": " : ""
843                   , name, mpi_buffer);
844
845       gcry_free (mpi_buffer);
846       mpi_buffer = NULL;
847     }
848
849   gcry_free (mpi_buffer);
850 }
851
852 /* Dump the named MPI values contained in the data set DATA to
853    Libgcrypt's logging stream.  */
854 void
855 gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data)
856 {
857   _gcry_ac_data_dump (prefix, data);
858 }
859
860 /* Destroys any values contained in the data set DATA.  */
861 void
862 _gcry_ac_data_clear (gcry_ac_data_t data)
863 {
864   ac_data_values_destroy (data);
865   gcry_free (data->data);
866   data->data = NULL;
867   data->data_n = 0;
868 }
869
870 \f
871
872 /*
873  * Implementation of `ac io' objects.
874  */
875
876 /* Initialize AC_IO according to MODE, TYPE and the variable list of
877    arguments AP.  The list of variable arguments to specify depends on
878    the given TYPE.  */
879 void
880 _gcry_ac_io_init_va (gcry_ac_io_t *ac_io,
881                      gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap)
882 {
883   memset (ac_io, 0, sizeof (*ac_io));
884
885   if (fips_mode ())
886     return;
887
888   gcry_assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE));
889   gcry_assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING));
890
891   ac_io->mode = mode;
892   ac_io->type = type;
893
894   switch (mode)
895     {
896     case GCRY_AC_IO_READABLE:
897       switch (type)
898         {
899         case GCRY_AC_IO_STRING:
900           ac_io->io.readable.string.data = va_arg (ap, unsigned char *);
901           ac_io->io.readable.string.data_n = va_arg (ap, size_t);
902           break;
903
904         case GCRY_AC_IO_CALLBACK:
905           ac_io->io.readable.callback.cb = va_arg (ap, gcry_ac_data_read_cb_t);
906           ac_io->io.readable.callback.opaque = va_arg (ap, void *);
907           break;
908         }
909       break;
910     case GCRY_AC_IO_WRITABLE:
911       switch (type)
912         {
913         case GCRY_AC_IO_STRING:
914           ac_io->io.writable.string.data = va_arg (ap, unsigned char **);
915           ac_io->io.writable.string.data_n = va_arg (ap, size_t *);
916           break;
917
918         case GCRY_AC_IO_CALLBACK:
919           ac_io->io.writable.callback.cb = va_arg (ap, gcry_ac_data_write_cb_t);
920           ac_io->io.writable.callback.opaque = va_arg (ap, void *);
921           break;
922         }
923       break;
924     }
925 }
926
927 /* Initialize AC_IO according to MODE, TYPE and the variable list of
928    arguments.  The list of variable arguments to specify depends on
929    the given TYPE. */
930 void
931 _gcry_ac_io_init (gcry_ac_io_t *ac_io,
932                   gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...)
933 {
934   va_list ap;
935
936   va_start (ap, type);
937   _gcry_ac_io_init_va (ac_io, mode, type, ap);
938   va_end (ap);
939 }
940
941
942 /* Write to the IO object AC_IO BUFFER_N bytes from BUFFER.  Return
943    zero on success or error code.  */
944 static gcry_error_t
945 _gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n)
946 {
947   gcry_error_t err;
948
949   gcry_assert (ac_io->mode == GCRY_AC_IO_WRITABLE);
950   err = 0;
951
952   switch (ac_io->type)
953     {
954     case GCRY_AC_IO_STRING:
955       {
956         unsigned char *p;
957
958         if (*ac_io->io.writable.string.data)
959           {
960             p = gcry_realloc (*ac_io->io.writable.string.data,
961                               *ac_io->io.writable.string.data_n + buffer_n);
962             if (! p)
963               err = gcry_error_from_errno (errno);
964             else
965               {
966                 if (*ac_io->io.writable.string.data != p)
967                   *ac_io->io.writable.string.data = p;
968                 memcpy (p + *ac_io->io.writable.string.data_n, buffer, buffer_n);
969                 *ac_io->io.writable.string.data_n += buffer_n;
970               }
971           }
972         else
973           {
974             if (gcry_is_secure (buffer))
975               p = gcry_malloc_secure (buffer_n);
976             else
977               p = gcry_malloc (buffer_n);
978             if (! p)
979               err = gcry_error_from_errno (errno);
980             else
981               {
982                 memcpy (p, buffer, buffer_n);
983                 *ac_io->io.writable.string.data = p;
984                 *ac_io->io.writable.string.data_n = buffer_n;
985               }
986           }
987       }
988       break;
989
990     case GCRY_AC_IO_CALLBACK:
991       err = (*ac_io->io.writable.callback.cb) (ac_io->io.writable.callback.opaque,
992                                                buffer, buffer_n);
993       break;
994     }
995
996   return err;
997 }
998
999 /* Read *BUFFER_N bytes from the IO object AC_IO into BUFFER; NREAD
1000    bytes have already been read from the object; on success, store the
1001    amount of bytes read in *BUFFER_N; zero bytes read means EOF.
1002    Return zero on success or error code.  */
1003 static gcry_error_t
1004 _gcry_ac_io_read (gcry_ac_io_t *ac_io,
1005                   unsigned int nread, unsigned char *buffer, size_t *buffer_n)
1006 {
1007   gcry_error_t err;
1008
1009   gcry_assert (ac_io->mode == GCRY_AC_IO_READABLE);
1010   err = 0;
1011
1012   switch (ac_io->type)
1013     {
1014     case GCRY_AC_IO_STRING:
1015       {
1016         size_t bytes_available;
1017         size_t bytes_to_read;
1018         size_t bytes_wanted;
1019
1020         bytes_available = ac_io->io.readable.string.data_n - nread;
1021         bytes_wanted = *buffer_n;
1022
1023         if (bytes_wanted > bytes_available)
1024           bytes_to_read = bytes_available;
1025         else
1026           bytes_to_read = bytes_wanted;
1027
1028         memcpy (buffer, ac_io->io.readable.string.data + nread, bytes_to_read);
1029         *buffer_n = bytes_to_read;
1030         err = 0;
1031         break;
1032       }
1033
1034     case GCRY_AC_IO_CALLBACK:
1035       err = (*ac_io->io.readable.callback.cb)
1036         (ac_io->io.readable.callback.opaque, buffer, buffer_n);
1037       break;
1038     }
1039
1040   return err;
1041 }
1042
1043 /* Read all data available from the IO object AC_IO into newly
1044    allocated memory, storing an appropriate pointer in *BUFFER and the
1045    amount of bytes read in *BUFFER_N.  Return zero on success or error
1046    code.  */
1047 static gcry_error_t
1048 _gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n)
1049 {
1050   unsigned char *buffer_new;
1051   size_t buffer_new_n;
1052   unsigned char buf[BUFSIZ];
1053   size_t buf_n;
1054   unsigned char *p;
1055   gcry_error_t err;
1056
1057   buffer_new = NULL;
1058   buffer_new_n = 0;
1059
1060   while (1)
1061     {
1062       buf_n = sizeof (buf);
1063       err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n);
1064       if (err)
1065         break;
1066
1067       if (buf_n)
1068         {
1069           p = gcry_realloc (buffer_new, buffer_new_n + buf_n);
1070           if (! p)
1071             {
1072               err = gcry_error_from_errno (errno);
1073               break;
1074             }
1075
1076           if (buffer_new != p)
1077             buffer_new = p;
1078
1079           memcpy (buffer_new + buffer_new_n, buf, buf_n);
1080           buffer_new_n += buf_n;
1081         }
1082       else
1083         break;
1084     }
1085   if (err)
1086     goto out;
1087
1088   *buffer_n = buffer_new_n;
1089   *buffer = buffer_new;
1090
1091  out:
1092
1093   if (err)
1094     gcry_free (buffer_new);
1095
1096   return err;
1097 }
1098
1099 /* Read data chunks from the IO object AC_IO until EOF, feeding them
1100    to the callback function CB.  Return zero on success or error
1101    code.  */
1102 static gcry_error_t
1103 _gcry_ac_io_process (gcry_ac_io_t *ac_io,
1104                      gcry_ac_data_write_cb_t cb, void *opaque)
1105 {
1106   unsigned char buffer[BUFSIZ];
1107   unsigned int nread;
1108   size_t buffer_n;
1109   gcry_error_t err;
1110
1111   nread = 0;
1112
1113   while (1)
1114     {
1115       buffer_n = sizeof (buffer);
1116       err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n);
1117       if (err)
1118         break;
1119       if (buffer_n)
1120         {
1121           err = (*cb) (opaque, buffer, buffer_n);
1122           if (err)
1123             break;
1124           nread += buffer_n;
1125         }
1126       else
1127         break;
1128     }
1129
1130   return err;
1131 }
1132
1133 \f
1134
1135 /*
1136  * Functions for converting data between the native ac and the
1137  * S-expression structure used by the pk interface.
1138  */
1139
1140 /* Extract the S-Expression DATA_SEXP into DATA under the control of
1141    TYPE and NAME.  This function assumes that S-Expressions are of the
1142    following structure:
1143
1144    (IDENTIFIER [...]
1145    (ALGORITHM <list of named MPI values>)) */
1146 static gcry_error_t
1147 ac_data_extract (const char *identifier, const char *algorithm,
1148                  gcry_sexp_t sexp, gcry_ac_data_t *data)
1149 {
1150   gcry_error_t err;
1151   gcry_sexp_t value_sexp;
1152   gcry_sexp_t data_sexp;
1153   size_t data_sexp_n;
1154   gcry_mpi_t value_mpi;
1155   char *value_name;
1156   const char *data_raw;
1157   size_t data_raw_n;
1158   gcry_ac_data_t data_new;
1159   unsigned int i;
1160
1161   value_sexp = NULL;
1162   data_sexp = NULL;
1163   value_name = NULL;
1164   value_mpi = NULL;
1165   data_new = NULL;
1166
1167   /* Verify that the S-expression contains the correct identifier.  */
1168   data_raw = gcry_sexp_nth_data (sexp, 0, &data_raw_n);
1169   if ((! data_raw) || strncmp (identifier, data_raw, data_raw_n))
1170     {
1171       err = gcry_error (GPG_ERR_INV_SEXP);
1172       goto out;
1173     }
1174
1175   /* Extract inner S-expression.  */
1176   data_sexp = gcry_sexp_find_token (sexp, algorithm, 0);
1177   if (! data_sexp)
1178     {
1179       err = gcry_error (GPG_ERR_INV_SEXP);
1180       goto out;
1181     }
1182
1183   /* Count data elements.  */
1184   data_sexp_n = gcry_sexp_length (data_sexp);
1185   data_sexp_n--;
1186
1187   /* Allocate new data set.  */
1188   err = _gcry_ac_data_new (&data_new);
1189   if (err)
1190     goto out;
1191
1192   /* Iterate through list of data elements and add them to the data
1193      set.  */
1194   for (i = 0; i < data_sexp_n; i++)
1195     {
1196       /* Get the S-expression of the named MPI, that contains the name
1197          and the MPI value.  */
1198       value_sexp = gcry_sexp_nth (data_sexp, i + 1);
1199       if (! value_sexp)
1200         {
1201           err = gcry_error (GPG_ERR_INV_SEXP);
1202           break;
1203         }
1204
1205       /* Extract the name.  */
1206       data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n);
1207       if (! data_raw)
1208         {
1209           err = gcry_error (GPG_ERR_INV_SEXP);
1210           break;
1211         }
1212
1213       /* Extract the MPI value.  */
1214       value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG);
1215       if (! value_mpi)
1216         {
1217           err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */
1218           break;
1219         }
1220
1221       /* Duplicate the name.  */
1222       value_name = gcry_malloc (data_raw_n + 1);
1223       if (! value_name)
1224         {
1225           err = gcry_error_from_errno (errno);
1226           break;
1227         }
1228       strncpy (value_name, data_raw, data_raw_n);
1229       value_name[data_raw_n] = 0;
1230
1231       err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi);
1232       if (err)
1233         break;
1234
1235       gcry_sexp_release (value_sexp);
1236       value_sexp = NULL;
1237       value_name = NULL;
1238       value_mpi = NULL;
1239     }
1240   if (err)
1241     goto out;
1242
1243   /* Copy out.  */
1244   *data = data_new;
1245
1246  out:
1247
1248   /* Deallocate resources.  */
1249   if (err)
1250     {
1251       _gcry_ac_data_destroy (data_new);
1252       gcry_mpi_release (value_mpi);
1253       gcry_free (value_name);
1254       gcry_sexp_release (value_sexp);
1255     }
1256   gcry_sexp_release (data_sexp);
1257
1258   return err;
1259 }
1260
1261 /* Construct an S-expression from the DATA and store it in
1262    DATA_SEXP. The S-expression will be of the following structure:
1263
1264    (IDENTIFIER [(flags [...])]
1265    (ALGORITHM <list of named MPI values>))  */
1266 static gcry_error_t
1267 ac_data_construct (const char *identifier, int include_flags,
1268                    unsigned int flags, const char *algorithm,
1269                    gcry_ac_data_t data, gcry_sexp_t *sexp)
1270 {
1271   unsigned int data_length;
1272   gcry_sexp_t sexp_new;
1273   gcry_error_t err;
1274   size_t sexp_format_n;
1275   char *sexp_format;
1276   void **arg_list;
1277   unsigned int i;
1278
1279   arg_list = NULL;
1280   sexp_new = NULL;
1281   sexp_format = NULL;
1282
1283   /* We build a list of arguments to pass to
1284      gcry_sexp_build_array().  */
1285   data_length = _gcry_ac_data_length (data);
1286   arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2));
1287   if (! arg_list)
1288     {
1289       err = gcry_error_from_errno (errno);
1290       goto out;
1291     }
1292
1293   /* Fill list with MPIs.  */
1294   for (i = 0; i < data_length; i++)
1295     {
1296       char **nameaddr  = &data->data[i].name;
1297
1298       arg_list[(i * 2) + 0] = nameaddr;
1299       arg_list[(i * 2) + 1] = &data->data[i].mpi;
1300     }
1301
1302   /* Calculate size of format string.  */
1303   sexp_format_n = (3
1304                    + (include_flags ? 7 : 0)
1305                    + (algorithm ? (2 + strlen (algorithm)) : 0)
1306                    + strlen (identifier));
1307
1308   for (i = 0; i < data_length; i++)
1309     /* Per-element sizes.  */
1310     sexp_format_n += 6;
1311
1312   if (include_flags)
1313     /* Add flags.  */
1314     for (i = 0; i < DIM (ac_flags); i++)
1315       if (flags & ac_flags[i].number)
1316         sexp_format_n += strlen (ac_flags[i].string) + 1;
1317
1318   /* Done.  */
1319   sexp_format = gcry_malloc (sexp_format_n);
1320   if (! sexp_format)
1321     {
1322       err = gcry_error_from_errno (errno);
1323       goto out;
1324     }
1325
1326   /* Construct the format string.  */
1327
1328   *sexp_format = 0;
1329   strcat (sexp_format, "(");
1330   strcat (sexp_format, identifier);
1331   if (include_flags)
1332     {
1333       strcat (sexp_format, "(flags");
1334       for (i = 0; i < DIM (ac_flags); i++)
1335         if (flags & ac_flags[i].number)
1336           {
1337             strcat (sexp_format, " ");
1338             strcat (sexp_format, ac_flags[i].string);
1339           }
1340       strcat (sexp_format, ")");
1341     }
1342   if (algorithm)
1343     {
1344       strcat (sexp_format, "(");
1345       strcat (sexp_format, algorithm);
1346     }
1347   for (i = 0; i < data_length; i++)
1348     strcat (sexp_format, "(%s%m)");
1349   if (algorithm)
1350     strcat (sexp_format, ")");
1351   strcat (sexp_format, ")");
1352
1353   /* Create final S-expression.  */
1354   err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list);
1355   if (err)
1356     goto out;
1357
1358   *sexp = sexp_new;
1359
1360  out:
1361
1362   /* Deallocate resources.  */
1363   gcry_free (sexp_format);
1364   gcry_free (arg_list);
1365   if (err)
1366     gcry_sexp_release (sexp_new);
1367
1368   return err;
1369 }
1370
1371 \f
1372
1373 /*
1374  * Handle management.
1375  */
1376
1377 /* Creates a new handle for the algorithm ALGORITHM and stores it in
1378    HANDLE.  FLAGS is not used yet.  */
1379 gcry_error_t
1380 _gcry_ac_open (gcry_ac_handle_t *handle,
1381                gcry_ac_id_t algorithm, unsigned int flags)
1382 {
1383   gcry_ac_handle_t handle_new;
1384   const char *algorithm_name;
1385   gcry_module_t module;
1386   gcry_error_t err;
1387
1388   *handle = NULL;
1389   module = NULL;
1390
1391   if (fips_mode ())
1392     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1393
1394   /* Get name.  */
1395   algorithm_name = _gcry_pk_aliased_algo_name (algorithm);
1396   if (! algorithm_name)
1397     {
1398       err = gcry_error (GPG_ERR_PUBKEY_ALGO);
1399       goto out;
1400     }
1401
1402   /* Acquire reference to the pubkey module.  */
1403   err = _gcry_pk_module_lookup (algorithm, &module);
1404   if (err)
1405     goto out;
1406
1407   /* Allocate.  */
1408   handle_new = gcry_malloc (sizeof (*handle_new));
1409   if (! handle_new)
1410     {
1411       err = gcry_error_from_errno (errno);
1412       goto out;
1413     }
1414
1415   /* Done.  */
1416   handle_new->algorithm = algorithm;
1417   handle_new->algorithm_name = algorithm_name;
1418   handle_new->flags = flags;
1419   handle_new->module = module;
1420   *handle = handle_new;
1421
1422  out:
1423
1424   /* Deallocate resources.  */
1425   if (err)
1426     _gcry_pk_module_release (module);
1427
1428   return err;
1429 }
1430
1431
1432 /* Destroys the handle HANDLE.  */
1433 void
1434 _gcry_ac_close (gcry_ac_handle_t handle)
1435 {
1436   /* Release reference to pubkey module.  */
1437   if (handle)
1438     {
1439       _gcry_pk_module_release (handle->module);
1440       gcry_free (handle);
1441     }
1442 }
1443
1444
1445 \f
1446 /*
1447  * Key management.
1448  */
1449
1450 /* Initialize a key from a given data set.  */
1451 /* FIXME/Damn: the argument HANDLE is not only unnecessary, it is
1452    completely WRONG here.  */
1453 gcry_error_t
1454 _gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
1455                    gcry_ac_key_type_t type, gcry_ac_data_t data)
1456 {
1457   gcry_ac_data_t data_new;
1458   gcry_ac_key_t key_new;
1459   gcry_error_t err;
1460
1461   (void)handle;
1462
1463   if (fips_mode ())
1464     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1465
1466   /* Allocate.  */
1467   key_new = gcry_malloc (sizeof (*key_new));
1468   if (! key_new)
1469     {
1470       err = gcry_error_from_errno (errno);
1471       goto out;
1472     }
1473
1474   /* Copy data set.  */
1475   err = _gcry_ac_data_copy (&data_new, data);
1476   if (err)
1477     goto out;
1478
1479   /* Done.  */
1480   key_new->data = data_new;
1481   key_new->type = type;
1482   *key = key_new;
1483
1484  out:
1485
1486   if (err)
1487     /* Deallocate resources.  */
1488     gcry_free (key_new);
1489
1490   return err;
1491 }
1492
1493
1494 /* Generates a new key pair via the handle HANDLE of NBITS bits and
1495    stores it in KEY_PAIR.  In case non-standard settings are wanted, a
1496    pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
1497    matching the selected algorithm, can be given as KEY_SPEC.
1498    MISC_DATA is not used yet.  */
1499 gcry_error_t
1500 _gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits,
1501                             void *key_spec,
1502                             gcry_ac_key_pair_t *key_pair,
1503                             gcry_mpi_t **misc_data)
1504 {
1505   gcry_sexp_t genkey_sexp_request;
1506   gcry_sexp_t genkey_sexp_reply;
1507   gcry_ac_data_t key_data_secret;
1508   gcry_ac_data_t key_data_public;
1509   gcry_ac_key_pair_t key_pair_new;
1510   gcry_ac_key_t key_secret;
1511   gcry_ac_key_t key_public;
1512   gcry_sexp_t key_sexp;
1513   gcry_error_t err;
1514   char *genkey_format;
1515   size_t genkey_format_n;
1516   void **arg_list;
1517   size_t arg_list_n;
1518   unsigned int i;
1519   unsigned int j;
1520
1521   (void)misc_data;
1522
1523   if (fips_mode ())
1524     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1525
1526   key_data_secret = NULL;
1527   key_data_public = NULL;
1528   key_secret = NULL;
1529   key_public = NULL;
1530   genkey_format = NULL;
1531   arg_list = NULL;
1532   genkey_sexp_request = NULL;
1533   genkey_sexp_reply = NULL;
1534   key_sexp = NULL;
1535
1536   /* Allocate key pair.  */
1537   key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair));
1538   if (! key_pair_new)
1539     {
1540       err = gcry_error_from_errno (errno);
1541       goto out;
1542     }
1543
1544   /* Allocate keys.  */
1545   key_secret = gcry_malloc (sizeof (*key_secret));
1546   if (! key_secret)
1547     {
1548       err = gcry_error_from_errno (errno);
1549       goto out;
1550     }
1551   key_public = gcry_malloc (sizeof (*key_public));
1552   if (! key_public)
1553     {
1554       err = gcry_error_from_errno (errno);
1555       goto out;
1556     }
1557
1558   /* Calculate size of the format string, that is used for creating
1559      the request S-expression.  */
1560   genkey_format_n = 22;
1561
1562   /* Respect any relevant algorithm specific commands.  */
1563   if (key_spec)
1564     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1565       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1566         genkey_format_n += 6;
1567
1568   /* Create format string.  */
1569   genkey_format = gcry_malloc (genkey_format_n);
1570   if (! genkey_format)
1571     {
1572       err = gcry_error_from_errno (errno);
1573       goto out;
1574     }
1575
1576   /* Fill format string.  */
1577   *genkey_format = 0;
1578   strcat (genkey_format, "(genkey(%s(nbits%d)");
1579   if (key_spec)
1580     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1581       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1582         strcat (genkey_format, "(%s%m)");
1583   strcat (genkey_format, "))");
1584
1585   /* Build list of argument pointers, the algorithm name and the nbits
1586      are always needed.  */
1587   arg_list_n = 2;
1588
1589   /* Now the algorithm specific arguments.  */
1590   if (key_spec)
1591     for (i = 0; i < DIM (ac_key_generate_specs); i++)
1592       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1593         arg_list_n += 2;
1594
1595   /* Allocate list.  */
1596   arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n);
1597   if (! arg_list)
1598     {
1599       err = gcry_error_from_errno (errno);
1600       goto out;
1601     }
1602
1603   arg_list[0] = (void *) &handle->algorithm_name;
1604   arg_list[1] = (void *) &nbits;
1605   if (key_spec)
1606     for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++)
1607       if (handle->algorithm == ac_key_generate_specs[i].algorithm)
1608         {
1609           /* Add name of this specification flag and the
1610              according member of the spec strucuture.  */
1611           arg_list[j++] = (void *)(&ac_key_generate_specs[i].name);
1612           arg_list[j++] = (void *)
1613             (((char *) key_spec)
1614              + ac_key_generate_specs[i].offset);
1615           /* FIXME: above seems to suck.  */
1616         }
1617
1618   /* Construct final request S-expression.  */
1619   err = gcry_sexp_build_array (&genkey_sexp_request,
1620                                NULL, genkey_format, arg_list);
1621   if (err)
1622     goto out;
1623
1624   /* Perform genkey operation.  */
1625   err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request);
1626   if (err)
1627     goto out;
1628
1629   key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0);
1630   if (! key_sexp)
1631     {
1632       err = gcry_error (GPG_ERR_INTERNAL);
1633       goto out;
1634     }
1635   err = ac_data_extract ("private-key", handle->algorithm_name,
1636                          key_sexp, &key_data_secret);
1637   if (err)
1638     goto out;
1639
1640   gcry_sexp_release (key_sexp);
1641   key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0);
1642   if (! key_sexp)
1643     {
1644       err = gcry_error (GPG_ERR_INTERNAL);
1645       goto out;
1646     }
1647   err = ac_data_extract ("public-key", handle->algorithm_name,
1648                          key_sexp, &key_data_public);
1649   if (err)
1650     goto out;
1651
1652   /* Done.  */
1653
1654   key_secret->type = GCRY_AC_KEY_SECRET;
1655   key_secret->data = key_data_secret;
1656   key_public->type = GCRY_AC_KEY_PUBLIC;
1657   key_public->data = key_data_public;
1658   key_pair_new->secret = key_secret;
1659   key_pair_new->public = key_public;
1660   *key_pair = key_pair_new;
1661
1662  out:
1663
1664   /* Deallocate resources.  */
1665
1666   gcry_free (genkey_format);
1667   gcry_free (arg_list);
1668   gcry_sexp_release (genkey_sexp_request);
1669   gcry_sexp_release (genkey_sexp_reply);
1670   gcry_sexp_release (key_sexp);
1671   if (err)
1672     {
1673       _gcry_ac_data_destroy (key_data_secret);
1674       _gcry_ac_data_destroy (key_data_public);
1675       gcry_free (key_secret);
1676       gcry_free (key_public);
1677       gcry_free (key_pair_new);
1678     }
1679
1680   return err;
1681 }
1682
1683 /* Returns the key of type WHICH out of the key pair KEY_PAIR.  */
1684 gcry_ac_key_t
1685 _gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
1686                            gcry_ac_key_type_t which)
1687 {
1688   gcry_ac_key_t key;
1689
1690   if (fips_mode ())
1691     return NULL;
1692
1693   switch (which)
1694     {
1695     case GCRY_AC_KEY_SECRET:
1696       key = key_pair->secret;
1697       break;
1698
1699     case GCRY_AC_KEY_PUBLIC:
1700       key = key_pair->public;
1701       break;
1702
1703     default:
1704       key = NULL;
1705       break;
1706     }
1707
1708   return key;
1709 }
1710
1711 /* Destroys the key KEY.  */
1712 void
1713 _gcry_ac_key_destroy (gcry_ac_key_t key)
1714 {
1715   unsigned int i;
1716
1717   if (key)
1718     {
1719       if (key->data)
1720         {
1721           for (i = 0; i < key->data->data_n; i++)
1722             {
1723               if (key->data->data[i].mpi)
1724                 gcry_mpi_release (key->data->data[i].mpi);
1725               if (key->data->data[i].name)
1726                 gcry_free (key->data->data[i].name);
1727             }
1728           gcry_free (key->data->data);
1729           gcry_free (key->data);
1730         }
1731       gcry_free (key);
1732     }
1733 }
1734
1735 /* Destroys the key pair KEY_PAIR.  */
1736 void
1737 _gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
1738 {
1739   if (key_pair)
1740     {
1741       gcry_ac_key_destroy (key_pair->secret);
1742       gcry_ac_key_destroy (key_pair->public);
1743       gcry_free (key_pair);
1744     }
1745 }
1746
1747 /* Returns the data set contained in the key KEY.  */
1748 gcry_ac_data_t
1749 _gcry_ac_key_data_get (gcry_ac_key_t key)
1750 {
1751   if (fips_mode ())
1752     return NULL;
1753   return key->data;
1754 }
1755
1756 /* Verifies that the key KEY is sane via HANDLE.  */
1757 gcry_error_t
1758 _gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
1759 {
1760   gcry_sexp_t key_sexp;
1761   gcry_error_t err;
1762
1763   if (fips_mode ())
1764     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1765
1766   key_sexp = NULL;
1767   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1768                            handle->algorithm_name, key->data, &key_sexp);
1769   if (err)
1770     goto out;
1771
1772   err = gcry_pk_testkey (key_sexp);
1773
1774  out:
1775
1776   gcry_sexp_release (key_sexp);
1777
1778   return gcry_error (err);
1779 }
1780
1781 /* Stores the number of bits of the key KEY in NBITS via HANDLE.  */
1782 gcry_error_t
1783 _gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
1784                         gcry_ac_key_t key, unsigned int *nbits)
1785 {
1786   gcry_sexp_t key_sexp;
1787   gcry_error_t err;
1788   unsigned int n;
1789
1790   if (fips_mode ())
1791     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1792
1793   key_sexp = NULL;
1794
1795   err = ac_data_construct (ac_key_identifiers[key->type],
1796                            0, 0, handle->algorithm_name, key->data, &key_sexp);
1797   if (err)
1798     goto out;
1799
1800   n = gcry_pk_get_nbits (key_sexp);
1801   if (! n)
1802     {
1803       err = gcry_error (GPG_ERR_PUBKEY_ALGO);
1804       goto out;
1805     }
1806
1807   *nbits = n;
1808
1809  out:
1810
1811   gcry_sexp_release (key_sexp);
1812
1813   return err;
1814 }
1815
1816 /* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
1817    HANDLE.  */
1818 gcry_error_t
1819 _gcry_ac_key_get_grip (gcry_ac_handle_t handle,
1820                        gcry_ac_key_t key, unsigned char *key_grip)
1821 {
1822   gcry_sexp_t key_sexp;
1823   gcry_error_t err;
1824   unsigned char *ret;
1825
1826   if (fips_mode ())
1827     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1828
1829   key_sexp = NULL;
1830   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1831                            handle->algorithm_name, key->data, &key_sexp);
1832   if (err)
1833     goto out;
1834
1835   ret = gcry_pk_get_keygrip (key_sexp, key_grip);
1836   if (! ret)
1837     {
1838       err = gcry_error (GPG_ERR_INV_OBJ);
1839       goto out;
1840     }
1841
1842   err = 0;
1843
1844  out:
1845
1846   gcry_sexp_release (key_sexp);
1847
1848   return err;
1849 }
1850
1851
1852 \f
1853
1854 /*
1855  * Functions performing cryptographic operations.
1856  */
1857
1858 /* Encrypts the plain text MPI value DATA_PLAIN with the key public
1859    KEY under the control of the flags FLAGS and stores the resulting
1860    data set into DATA_ENCRYPTED.  */
1861 gcry_error_t
1862 _gcry_ac_data_encrypt (gcry_ac_handle_t handle,
1863                        unsigned int flags,
1864                        gcry_ac_key_t key,
1865                        gcry_mpi_t data_plain,
1866                        gcry_ac_data_t *data_encrypted)
1867 {
1868   gcry_ac_data_t data_encrypted_new;
1869   gcry_ac_data_t data_value;
1870   gcry_sexp_t sexp_request;
1871   gcry_sexp_t sexp_reply;
1872   gcry_sexp_t sexp_key;
1873   gcry_error_t err;
1874
1875   if (fips_mode ())
1876     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1877
1878   data_encrypted_new = NULL;
1879   sexp_request = NULL;
1880   sexp_reply = NULL;
1881   data_value = NULL;
1882   sexp_key = NULL;
1883
1884   if (key->type != GCRY_AC_KEY_PUBLIC)
1885     {
1886       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
1887       goto out;
1888     }
1889
1890   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1891                            handle->algorithm_name, key->data, &sexp_key);
1892   if (err)
1893     goto out;
1894
1895   err = _gcry_ac_data_new (&data_value);
1896   if (err)
1897     goto out;
1898
1899   err = _gcry_ac_data_set (data_value, 0, "value", data_plain);
1900   if (err)
1901     goto out;
1902
1903   err = ac_data_construct ("data", 1, flags, handle->algorithm_name,
1904                            data_value, &sexp_request);
1905   if (err)
1906     goto out;
1907
1908   /* FIXME: error vs. errcode? */
1909
1910   err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key);
1911   if (err)
1912     goto out;
1913
1914   /* Extract data.  */
1915   err = ac_data_extract ("enc-val", handle->algorithm_name,
1916                          sexp_reply, &data_encrypted_new);
1917   if (err)
1918     goto out;
1919
1920   *data_encrypted = data_encrypted_new;
1921
1922  out:
1923
1924   /* Deallocate resources.  */
1925
1926   gcry_sexp_release (sexp_request);
1927   gcry_sexp_release (sexp_reply);
1928   gcry_sexp_release (sexp_key);
1929   _gcry_ac_data_destroy (data_value);
1930
1931   return err;
1932 }
1933
1934 /* Decrypts the encrypted data contained in the data set
1935    DATA_ENCRYPTED with the secret key KEY under the control of the
1936    flags FLAGS and stores the resulting plain text MPI value in
1937    DATA_PLAIN.  */
1938 gcry_error_t
1939 _gcry_ac_data_decrypt (gcry_ac_handle_t handle,
1940                        unsigned int flags,
1941                        gcry_ac_key_t key,
1942                        gcry_mpi_t *data_plain,
1943                        gcry_ac_data_t data_encrypted)
1944 {
1945   gcry_mpi_t data_decrypted;
1946   gcry_sexp_t sexp_request;
1947   gcry_sexp_t sexp_reply;
1948   gcry_sexp_t sexp_value;
1949   gcry_sexp_t sexp_key;
1950   gcry_error_t err;
1951
1952   if (fips_mode ())
1953     return gpg_error (GPG_ERR_NOT_SUPPORTED);
1954
1955   sexp_request = NULL;
1956   sexp_reply = NULL;
1957   sexp_value = NULL;
1958   sexp_key = NULL;
1959
1960   if (key->type != GCRY_AC_KEY_SECRET)
1961     {
1962       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
1963       goto out;
1964     }
1965
1966   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
1967                            handle->algorithm_name, key->data, &sexp_key);
1968   if (err)
1969     goto out;
1970
1971   /* Create S-expression from data.  */
1972   err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name,
1973                            data_encrypted, &sexp_request);
1974   if (err)
1975     goto out;
1976
1977   /* Decrypt.  */
1978   err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key);
1979   if (err)
1980     goto out;
1981
1982   /* Extract plain text. */
1983   sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0);
1984   if (! sexp_value)
1985     {
1986       /* FIXME?  */
1987       err = gcry_error (GPG_ERR_GENERAL);
1988       goto out;
1989     }
1990
1991   data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG);
1992   if (! data_decrypted)
1993     {
1994       err = gcry_error (GPG_ERR_GENERAL);
1995       goto out;
1996     }
1997
1998   *data_plain = data_decrypted;
1999
2000  out:
2001
2002   /* Deallocate resources.  */
2003   gcry_sexp_release (sexp_request);
2004   gcry_sexp_release (sexp_reply);
2005   gcry_sexp_release (sexp_value);
2006   gcry_sexp_release (sexp_key);
2007
2008   return gcry_error (err);
2009
2010 }
2011
2012 /* Signs the data contained in DATA with the secret key KEY and stores
2013    the resulting signature data set in DATA_SIGNATURE.  */
2014 gcry_error_t
2015 _gcry_ac_data_sign (gcry_ac_handle_t handle,
2016                     gcry_ac_key_t key,
2017                     gcry_mpi_t data,
2018                     gcry_ac_data_t *data_signature)
2019 {
2020   gcry_ac_data_t data_signed;
2021   gcry_ac_data_t data_value;
2022   gcry_sexp_t sexp_request;
2023   gcry_sexp_t sexp_reply;
2024   gcry_sexp_t sexp_key;
2025   gcry_error_t err;
2026
2027   if (fips_mode ())
2028     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2029
2030   data_signed = NULL;
2031   data_value = NULL;
2032   sexp_request = NULL;
2033   sexp_reply = NULL;
2034   sexp_key = NULL;
2035
2036   if (key->type != GCRY_AC_KEY_SECRET)
2037     {
2038       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2039       goto out;
2040     }
2041
2042   err = ac_data_construct (ac_key_identifiers[key->type], 0, 0,
2043                            handle->algorithm_name, key->data, &sexp_key);
2044   if (err)
2045     goto out;
2046
2047   err = _gcry_ac_data_new (&data_value);
2048   if (err)
2049     goto out;
2050
2051   err = _gcry_ac_data_set (data_value, 0, "value", data);
2052   if (err)
2053     goto out;
2054
2055   /* Create S-expression holding the data.  */
2056   err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request);
2057   if (err)
2058     goto out;
2059
2060   /* Sign.  */
2061   err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key);
2062   if (err)
2063     goto out;
2064
2065   /* Extract data.  */
2066   err = ac_data_extract ("sig-val", handle->algorithm_name,
2067                          sexp_reply, &data_signed);
2068   if (err)
2069     goto out;
2070
2071   /* Done.  */
2072   *data_signature = data_signed;
2073
2074  out:
2075
2076   gcry_sexp_release (sexp_request);
2077   gcry_sexp_release (sexp_reply);
2078   gcry_sexp_release (sexp_key);
2079   _gcry_ac_data_destroy (data_value);
2080
2081   return gcry_error (err);
2082 }
2083
2084
2085 /* Verifies that the signature contained in the data set
2086    DATA_SIGNATURE is indeed the result of signing the data contained
2087    in DATA with the secret key belonging to the public key KEY.  */
2088 gcry_error_t
2089 _gcry_ac_data_verify (gcry_ac_handle_t handle,
2090                       gcry_ac_key_t key,
2091                       gcry_mpi_t data,
2092                       gcry_ac_data_t data_signature)
2093 {
2094   gcry_sexp_t sexp_signature;
2095   gcry_ac_data_t data_value;
2096   gcry_sexp_t sexp_data;
2097   gcry_sexp_t sexp_key;
2098   gcry_error_t err;
2099
2100   if (fips_mode ())
2101     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2102
2103   sexp_signature = NULL;
2104   data_value = NULL;
2105   sexp_data = NULL;
2106   sexp_key = NULL;
2107
2108   err = ac_data_construct ("public-key", 0, 0,
2109                            handle->algorithm_name, key->data, &sexp_key);
2110   if (err)
2111     goto out;
2112
2113   if (key->type != GCRY_AC_KEY_PUBLIC)
2114     {
2115       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2116       goto out;
2117     }
2118
2119   /* Construct S-expression holding the signature data.  */
2120   err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name,
2121                            data_signature, &sexp_signature);
2122   if (err)
2123     goto out;
2124
2125   err = _gcry_ac_data_new (&data_value);
2126   if (err)
2127     goto out;
2128
2129   err = _gcry_ac_data_set (data_value, 0, "value", data);
2130   if (err)
2131     goto out;
2132
2133   /* Construct S-expression holding the data.  */
2134   err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data);
2135   if (err)
2136     goto out;
2137
2138   /* Verify signature.  */
2139   err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key);
2140
2141  out:
2142
2143   gcry_sexp_release (sexp_signature);
2144   gcry_sexp_release (sexp_data);
2145   gcry_sexp_release (sexp_key);
2146   _gcry_ac_data_destroy (data_value);
2147
2148   return gcry_error (err);
2149 }
2150
2151
2152
2153 \f
2154 /*
2155  * Implementation of encoding methods (em).
2156  */
2157
2158 /* Type for functions that encode or decode (hence the name) a
2159    message.  */
2160 typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags,
2161                                                  void *options,
2162                                                  gcry_ac_io_t *ac_io_read,
2163                                                  gcry_ac_io_t *ac_io_write);
2164
2165 /* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero
2166    random bytes of random level LEVEL.  */
2167 static void
2168 em_randomize_nonzero (unsigned char *buffer, size_t buffer_n,
2169                       gcry_random_level_t level)
2170 {
2171   unsigned char *buffer_rand;
2172   unsigned int buffer_rand_n;
2173   unsigned int zeros;
2174   unsigned int i;
2175   unsigned int j;
2176
2177   for (i = 0; i < buffer_n; i++)
2178     buffer[i] = 0;
2179
2180   do
2181     {
2182       /* Count zeros.  */
2183       for (i = zeros = 0; i < buffer_n; i++)
2184         if (! buffer[i])
2185           zeros++;
2186
2187       if (zeros)
2188         {
2189           /* Get random bytes.  */
2190           buffer_rand_n = zeros + (zeros / 128);
2191           buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level);
2192
2193           /* Substitute zeros with non-zero random bytes.  */
2194           for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++)
2195             if (! buffer[i])
2196               {
2197                 while ((j < buffer_rand_n) && (! buffer_rand[j]))
2198                   j++;
2199                 if (j < buffer_rand_n)
2200                   {
2201                     buffer[i] = buffer_rand[j++];
2202                     zeros--;
2203                   }
2204                 else
2205                   break;
2206               }
2207           gcry_free (buffer_rand);
2208         }
2209     }
2210   while (zeros);
2211 }
2212
2213 /* Encode a message according to the Encoding Method for Encryption
2214    `PKCS-V1_5' (EME-PKCS-V1_5).  */
2215 static gcry_error_t
2216 eme_pkcs_v1_5_encode (unsigned int flags, void *opts,
2217                       gcry_ac_io_t *ac_io_read,
2218                       gcry_ac_io_t *ac_io_write)
2219 {
2220   gcry_ac_eme_pkcs_v1_5_t *options;
2221   gcry_error_t err;
2222   unsigned char *buffer;
2223   unsigned char *ps;
2224   unsigned char *m;
2225   size_t m_n;
2226   unsigned int ps_n;
2227   unsigned int k;
2228
2229   (void)flags;
2230
2231   options = opts;
2232   buffer = NULL;
2233   m = NULL;
2234
2235   err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n);
2236   if (err)
2237     goto out;
2238
2239   /* Figure out key length in bytes.  */
2240   k = options->key_size / 8;
2241
2242   if (m_n > k - 11)
2243     {
2244       /* Key is too short for message.  */
2245       err = gcry_error (GPG_ERR_TOO_SHORT);
2246       goto out;
2247     }
2248
2249   /* According to this encoding method, the first byte of the encoded
2250      message is zero.  This byte will be lost anyway, when the encoded
2251      message is to be converted into an MPI, that's why we skip
2252      it.  */
2253
2254   /* Allocate buffer.  */
2255   buffer = gcry_malloc (k - 1);
2256   if (! buffer)
2257     {
2258       err = gcry_error_from_errno (errno);
2259       goto out;
2260     }
2261
2262   /* Generate an octet string PS of length k - mLen - 3 consisting
2263      of pseudorandomly generated nonzero octets.  The length of PS
2264      will be at least eight octets.  */
2265   ps_n = k - m_n - 3;
2266   ps = buffer + 1;
2267   em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM);
2268
2269   /* Concatenate PS, the message M, and other padding to form an
2270      encoded message EM of length k octets as:
2271
2272      EM = 0x00 || 0x02 || PS || 0x00 || M.  */
2273
2274   buffer[0] = 0x02;
2275   buffer[ps_n + 1] = 0x00;
2276   memcpy (buffer + ps_n + 2, m, m_n);
2277
2278   err = _gcry_ac_io_write (ac_io_write, buffer, k - 1);
2279
2280  out:
2281
2282   gcry_free (buffer);
2283   gcry_free (m);
2284
2285   return err;
2286 }
2287
2288 /* Decode a message according to the Encoding Method for Encryption
2289    `PKCS-V1_5' (EME-PKCS-V1_5).  */
2290 static gcry_error_t
2291 eme_pkcs_v1_5_decode (unsigned int flags, void *opts,
2292                       gcry_ac_io_t *ac_io_read,
2293                       gcry_ac_io_t *ac_io_write)
2294 {
2295   gcry_ac_eme_pkcs_v1_5_t *options;
2296   unsigned char *buffer;
2297   unsigned char *em;
2298   size_t em_n;
2299   gcry_error_t err;
2300   unsigned int i;
2301   unsigned int k;
2302
2303   (void)flags;
2304
2305   options = opts;
2306   buffer = NULL;
2307   em = NULL;
2308
2309   err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n);
2310   if (err)
2311     goto out;
2312
2313   /* Figure out key size.  */
2314   k = options->key_size / 8;
2315
2316   /* Search for zero byte.  */
2317   for (i = 0; (i < em_n) && em[i]; i++);
2318
2319   /* According to this encoding method, the first byte of the encoded
2320      message should be zero.  This byte is lost.  */
2321
2322   if (! ((em_n >= 10)
2323          && (em_n == (k - 1))
2324          && (em[0] == 0x02)
2325          && (i < em_n)
2326          && ((i - 1) >= 8)))
2327     {
2328       err = gcry_error (GPG_ERR_DECRYPT_FAILED);
2329       goto out;
2330     }
2331
2332   i++;
2333   buffer = gcry_malloc (em_n - i);
2334   if (! buffer)
2335     {
2336       err = gcry_error_from_errno (errno);
2337       goto out;
2338     }
2339
2340   memcpy (buffer, em + i, em_n - i);
2341   err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i);
2342
2343  out:
2344
2345   gcry_free (buffer);
2346   gcry_free (em);
2347
2348   return err;
2349 }
2350
2351 static gcry_error_t
2352 emsa_pkcs_v1_5_encode_data_cb (void *opaque,
2353                                unsigned char *buffer, size_t buffer_n)
2354 {
2355   gcry_md_hd_t md_handle;
2356
2357   md_handle = opaque;
2358   gcry_md_write (md_handle, buffer, buffer_n);
2359
2360   return 0;
2361 }
2362
2363
2364 /* Encode a message according to the Encoding Method for Signatures
2365    with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5).  */
2366 static gcry_error_t
2367 emsa_pkcs_v1_5_encode (unsigned int flags, void *opts,
2368                        gcry_ac_io_t *ac_io_read,
2369                        gcry_ac_io_t *ac_io_write)
2370 {
2371   gcry_ac_emsa_pkcs_v1_5_t *options;
2372   gcry_error_t err;
2373   gcry_md_hd_t md;
2374   unsigned char *t;
2375   size_t t_n;
2376   unsigned char *h;
2377   size_t h_n;
2378   unsigned char *ps;
2379   size_t ps_n;
2380   unsigned char *buffer;
2381   size_t buffer_n;
2382   unsigned char asn[100];       /* FIXME, always enough?  */
2383   size_t asn_n;
2384   unsigned int i;
2385
2386   (void)flags;
2387
2388   options = opts;
2389   buffer = NULL;
2390   md = NULL;
2391   ps = NULL;
2392   t = NULL;
2393
2394   /* Create hashing handle and get the necessary information.  */
2395   err = gcry_md_open (&md, options->md, 0);
2396   if (err)
2397     goto out;
2398
2399   asn_n = DIM (asn);
2400   err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n);
2401   if (err)
2402     goto out;
2403
2404   h_n = gcry_md_get_algo_dlen (options->md);
2405
2406   err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md);
2407   if (err)
2408     goto out;
2409
2410   h = gcry_md_read (md, 0);
2411
2412   /* Encode the algorithm ID for the hash function and the hash value
2413      into an ASN.1 value of type DigestInfo with the Distinguished
2414      Encoding Rules (DER), where the type DigestInfo has the syntax:
2415
2416      DigestInfo ::== SEQUENCE {
2417      digestAlgorithm AlgorithmIdentifier,
2418      digest OCTET STRING
2419      }
2420
2421      The first field identifies the hash function and the second
2422      contains the hash value.  Let T be the DER encoding of the
2423      DigestInfo value and let tLen be the length in octets of T.  */
2424
2425   t_n = asn_n + h_n;
2426   t = gcry_malloc (t_n);
2427   if (! t)
2428     {
2429       err = gcry_error_from_errno (errno);
2430       goto out;
2431     }
2432
2433   for (i = 0; i < asn_n; i++)
2434     t[i] = asn[i];
2435   for (i = 0; i < h_n; i++)
2436     t[asn_n + i] = h[i];
2437
2438   /* If emLen < tLen + 11, output "intended encoded message length
2439      too short" and stop.  */
2440   if (options->em_n < t_n + 11)
2441     {
2442       err = gcry_error (GPG_ERR_TOO_SHORT);
2443       goto out;
2444     }
2445
2446   /* Generate an octet string PS consisting of emLen - tLen - 3 octets
2447      with hexadecimal value 0xFF.  The length of PS will be at least 8
2448      octets.  */
2449   ps_n = options->em_n - t_n - 3;
2450   ps = gcry_malloc (ps_n);
2451   if (! ps)
2452     {
2453       err = gcry_error_from_errno (errno);
2454       goto out;
2455     }
2456   for (i = 0; i < ps_n; i++)
2457     ps[i] = 0xFF;
2458
2459   /* Concatenate PS, the DER encoding T, and other padding to form the
2460      encoded message EM as:
2461
2462      EM = 0x00 || 0x01 || PS || 0x00 || T.  */
2463
2464   buffer_n = ps_n + t_n + 3;
2465   buffer = gcry_malloc (buffer_n);
2466   if (! buffer)
2467     {
2468       err = gcry_error_from_errno (errno);
2469       goto out;
2470     }
2471
2472   buffer[0] = 0x00;
2473   buffer[1] = 0x01;
2474   for (i = 0; i < ps_n; i++)
2475     buffer[2 + i] = ps[i];
2476   buffer[2 + ps_n] = 0x00;
2477   for (i = 0; i < t_n; i++)
2478     buffer[3 + ps_n + i] = t[i];
2479
2480   err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n);
2481
2482  out:
2483
2484   gcry_md_close (md);
2485
2486   gcry_free (buffer);
2487   gcry_free (ps);
2488   gcry_free (t);
2489
2490   return err;
2491 }
2492
2493 /* `Actions' for data_dencode().  */
2494 typedef enum dencode_action
2495   {
2496     DATA_ENCODE,
2497     DATA_DECODE,
2498   }
2499 dencode_action_t;
2500
2501 /* Encode or decode a message according to the the encoding method
2502    METHOD; ACTION specifies whether the message that is contained in
2503    BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded.
2504    The resulting message will be stored in a newly allocated buffer in
2505    BUFFER_OUT and BUFFER_OUT_N.  */
2506 static gcry_error_t
2507 ac_data_dencode (gcry_ac_em_t method, dencode_action_t action,
2508                  unsigned int flags, void *options,
2509                  gcry_ac_io_t *ac_io_read,
2510                  gcry_ac_io_t *ac_io_write)
2511 {
2512   struct
2513   {
2514     gcry_ac_em_t method;
2515     gcry_ac_em_dencode_t encode;
2516     gcry_ac_em_dencode_t decode;
2517   } methods[] =
2518     {
2519       { GCRY_AC_EME_PKCS_V1_5,
2520         eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode },
2521       { GCRY_AC_EMSA_PKCS_V1_5,
2522         emsa_pkcs_v1_5_encode, NULL },
2523     };
2524   size_t methods_n;
2525   gcry_error_t err;
2526   unsigned int i;
2527
2528   methods_n = sizeof (methods) / sizeof (*methods);
2529
2530   for (i = 0; i < methods_n; i++)
2531     if (methods[i].method == method)
2532       break;
2533   if (i == methods_n)
2534     {
2535       err = gcry_error (GPG_ERR_NOT_FOUND);     /* FIXME? */
2536       goto out;
2537     }
2538
2539   err = 0;
2540   switch (action)
2541     {
2542     case DATA_ENCODE:
2543       if (methods[i].encode)
2544         /* FIXME? */
2545         err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write);
2546       break;
2547
2548     case DATA_DECODE:
2549       if (methods[i].decode)
2550         /* FIXME? */
2551         err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write);
2552       break;
2553
2554     default:
2555       err = gcry_error (GPG_ERR_INV_ARG);
2556       break;
2557     }
2558
2559  out:
2560
2561   return err;
2562 }
2563
2564 /* Encode a message according to the encoding method METHOD.  OPTIONS
2565    must be a pointer to a method-specific structure
2566    (gcry_ac_em*_t).  */
2567 gcry_error_t
2568 _gcry_ac_data_encode (gcry_ac_em_t method,
2569                       unsigned int flags, void *options,
2570                       gcry_ac_io_t *ac_io_read,
2571                       gcry_ac_io_t *ac_io_write)
2572 {
2573   if (fips_mode ())
2574     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2575
2576   return ac_data_dencode (method, DATA_ENCODE, flags, options,
2577                           ac_io_read, ac_io_write);
2578 }
2579
2580 /* Dencode a message according to the encoding method METHOD.  OPTIONS
2581    must be a pointer to a method-specific structure
2582    (gcry_ac_em*_t).  */
2583 gcry_error_t
2584 _gcry_ac_data_decode (gcry_ac_em_t method,
2585                       unsigned int flags, void *options,
2586                       gcry_ac_io_t *ac_io_read,
2587                       gcry_ac_io_t *ac_io_write)
2588 {
2589   if (fips_mode ())
2590     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2591
2592   return ac_data_dencode (method, DATA_DECODE, flags, options,
2593                           ac_io_read, ac_io_write);
2594 }
2595
2596 /* Convert an MPI into an octet string.  */
2597 void
2598 _gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2599 {
2600   unsigned long digit;
2601   gcry_mpi_t base;
2602   unsigned int i;
2603   unsigned int n;
2604   gcry_mpi_t m;
2605   gcry_mpi_t d;
2606
2607   if (fips_mode ())
2608     return;
2609
2610   base = gcry_mpi_new (0);
2611   gcry_mpi_set_ui (base, 256);
2612
2613   n = 0;
2614   m = gcry_mpi_copy (mpi);
2615   while (gcry_mpi_cmp_ui (m, 0))
2616     {
2617       n++;
2618       gcry_mpi_div (m, NULL, m, base, 0);
2619     }
2620
2621   gcry_mpi_set (m, mpi);
2622   d = gcry_mpi_new (0);
2623   for (i = 0; (i < n) && (i < os_n); i++)
2624     {
2625       gcry_mpi_mod (d, m, base);
2626       _gcry_mpi_get_ui (d, &digit);
2627       gcry_mpi_div (m, NULL, m, base, 0);
2628       os[os_n - i - 1] = (digit & 0xFF);
2629     }
2630
2631   for (; i < os_n; i++)
2632     os[os_n - i - 1] = 0;
2633
2634   gcry_mpi_release (base);
2635   gcry_mpi_release (d);
2636   gcry_mpi_release (m);
2637 }
2638
2639 /* Convert an MPI into an newly allocated octet string.  */
2640 gcry_error_t
2641 _gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n)
2642 {
2643   unsigned char *buffer;
2644   size_t buffer_n;
2645   gcry_error_t err;
2646   unsigned int nbits;
2647
2648   if (fips_mode ())
2649     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2650
2651   nbits = gcry_mpi_get_nbits (mpi);
2652   buffer_n = (nbits + 7) / 8;
2653   buffer = gcry_malloc (buffer_n);
2654   if (! buffer)
2655     {
2656       err = gcry_error_from_errno (errno);
2657       goto out;
2658     }
2659
2660   _gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
2661   *os = buffer;
2662   *os_n = buffer_n;
2663   err = 0;
2664
2665  out:
2666
2667   return err;
2668 }
2669
2670
2671 /* Convert an octet string into an MPI.  */
2672 void
2673 _gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n)
2674 {
2675   unsigned int i;
2676   gcry_mpi_t xi;
2677   gcry_mpi_t x;
2678   gcry_mpi_t a;
2679
2680   if (fips_mode ())
2681     return;
2682
2683   a = gcry_mpi_new (0);
2684   gcry_mpi_set_ui (a, 1);
2685   x = gcry_mpi_new (0);
2686   gcry_mpi_set_ui (x, 0);
2687   xi = gcry_mpi_new (0);
2688
2689   for (i = 0; i < os_n; i++)
2690     {
2691       gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]);
2692       gcry_mpi_add (x, x, xi);
2693       gcry_mpi_mul_ui (a, a, 256);
2694     }
2695
2696   gcry_mpi_release (xi);
2697   gcry_mpi_release (a);
2698
2699   gcry_mpi_set (mpi, x);
2700   gcry_mpi_release (x);         /* FIXME: correct? */
2701 }
2702
2703
2704 \f
2705 /*
2706  * Implementation of Encryption Schemes (ES) and Signature Schemes
2707  * with Appendix (SSA).
2708  */
2709
2710 /* Schemes consist of two things: encoding methods and cryptographic
2711    primitives.
2712
2713    Since encoding methods are accessible through a common API with
2714    method-specific options passed as an anonymous struct, schemes have
2715    to provide functions that construct this method-specific structure;
2716    this is what the functions of type `gcry_ac_dencode_prepare_t' are
2717    there for.  */
2718
2719 typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle,
2720                                                    gcry_ac_key_t key,
2721                                                    void *opts,
2722                                                    void *opts_em);
2723
2724 /* The `dencode_prepare' function for ES-PKCS-V1_5.  */
2725 static gcry_error_t
2726 ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
2727                                  void *opts, void *opts_em)
2728 {
2729   gcry_ac_eme_pkcs_v1_5_t *options_em;
2730   unsigned int nbits;
2731   gcry_error_t err;
2732
2733   (void)opts;
2734
2735   err = _gcry_ac_key_get_nbits (handle, key, &nbits);
2736   if (err)
2737     goto out;
2738
2739   options_em = opts_em;
2740   options_em->key_size = nbits;
2741
2742  out:
2743
2744   return err;
2745 }
2746
2747 /* The `dencode_prepare' function for SSA-PKCS-V1_5.  */
2748 static gcry_error_t
2749 ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key,
2750                                   void *opts, void *opts_em)
2751 {
2752   gcry_ac_emsa_pkcs_v1_5_t *options_em;
2753   gcry_ac_ssa_pkcs_v1_5_t *options;
2754   gcry_error_t err;
2755   unsigned int k;
2756
2757   options_em = opts_em;
2758   options = opts;
2759
2760   err = _gcry_ac_key_get_nbits (handle, key, &k);
2761   if (err)
2762     goto out;
2763
2764   k = (k + 7) / 8;
2765   options_em->md = options->md;
2766   options_em->em_n = k;
2767
2768  out:
2769
2770   return err;
2771 }
2772
2773 /* Type holding the information about each supported
2774    Encryption/Signature Scheme.  */
2775 typedef struct ac_scheme
2776 {
2777   gcry_ac_scheme_t scheme;
2778   gcry_ac_em_t scheme_encoding;
2779   gcry_ac_dencode_prepare_t dencode_prepare;
2780   size_t options_em_n;
2781 } ac_scheme_t;
2782
2783 /* List of supported Schemes.  */
2784 static ac_scheme_t ac_schemes[] =
2785   {
2786     { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5,
2787       ac_es_dencode_prepare_pkcs_v1_5,
2788       sizeof (gcry_ac_eme_pkcs_v1_5_t) },
2789     { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5,
2790       ac_ssa_dencode_prepare_pkcs_v1_5,
2791       sizeof (gcry_ac_emsa_pkcs_v1_5_t) }
2792   };
2793
2794 /* Lookup a scheme by it's ID.  */
2795 static ac_scheme_t *
2796 ac_scheme_get (gcry_ac_scheme_t scheme)
2797 {
2798   ac_scheme_t *ac_scheme;
2799   unsigned int i;
2800
2801   for (i = 0; i < DIM (ac_schemes); i++)
2802     if (scheme == ac_schemes[i].scheme)
2803       break;
2804   if (i == DIM (ac_schemes))
2805     ac_scheme = NULL;
2806   else
2807     ac_scheme = ac_schemes + i;
2808
2809   return ac_scheme;
2810 }
2811
2812 /* Prepares the encoding/decoding by creating an according option
2813    structure.  */
2814 static gcry_error_t
2815 ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts,
2816                     ac_scheme_t scheme, void **opts_em)
2817 {
2818   gcry_error_t err;
2819   void *options_em;
2820
2821   options_em = gcry_malloc (scheme.options_em_n);
2822   if (! options_em)
2823     {
2824       err = gcry_error_from_errno (errno);
2825       goto out;
2826     }
2827
2828   err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
2829   if (err)
2830     goto out;
2831
2832   *opts_em = options_em;
2833
2834  out:
2835
2836   if (err)
2837     free (options_em);
2838
2839   return err;
2840 }
2841
2842 /* Convert a data set into a single MPI; currently, this is only
2843    supported for data sets containing a single MPI.  */
2844 static gcry_error_t
2845 ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi)
2846 {
2847   gcry_error_t err;
2848   gcry_mpi_t mpi_new;
2849   unsigned int elems;
2850
2851   elems = _gcry_ac_data_length (data);
2852
2853   if (elems != 1)
2854     {
2855       /* FIXME: I guess, we should be more flexible in this respect by
2856          allowing the actual encryption/signature schemes to implement
2857          this conversion mechanism.  */
2858       err = gcry_error (GPG_ERR_CONFLICT);
2859       goto out;
2860     }
2861
2862   err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new);
2863   if (err)
2864     goto out;
2865
2866   *mpi = mpi_new;
2867
2868  out:
2869
2870   return err;
2871 }
2872
2873 /* Encrypts the plain text message contained in M, which is of size
2874    M_N, with the public key KEY_PUBLIC according to the Encryption
2875    Scheme SCHEME_ID.  HANDLE is used for accessing the low-level
2876    cryptographic primitives.  If OPTS is not NULL, it has to be an
2877    anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
2878    The encrypted message will be stored in C and C_N.  */
2879 gcry_error_t
2880 _gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
2881                               gcry_ac_scheme_t scheme_id,
2882                               unsigned int flags, void *opts,
2883                               gcry_ac_key_t key,
2884                               gcry_ac_io_t *io_message,
2885                               gcry_ac_io_t *io_cipher)
2886 {
2887   gcry_error_t err;
2888   gcry_ac_io_t io_em;
2889   unsigned char *em;
2890   size_t em_n;
2891   gcry_mpi_t mpi_plain;
2892   gcry_ac_data_t data_encrypted;
2893   gcry_mpi_t mpi_encrypted;
2894   unsigned char *buffer;
2895   size_t buffer_n;
2896   void *opts_em;
2897   ac_scheme_t *scheme;
2898
2899   (void)flags;
2900
2901   if (fips_mode ())
2902     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2903
2904   data_encrypted = NULL;
2905   mpi_encrypted = NULL;
2906   mpi_plain = NULL;
2907   opts_em = NULL;
2908   buffer = NULL;
2909   em = NULL;
2910
2911   scheme = ac_scheme_get (scheme_id);
2912   if (! scheme)
2913     {
2914       err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
2915       goto out;
2916     }
2917
2918   if (key->type != GCRY_AC_KEY_PUBLIC)
2919     {
2920       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
2921       goto out;
2922     }
2923
2924   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
2925   if (err)
2926     goto out;
2927
2928   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
2929                     GCRY_AC_IO_STRING, &em, &em_n);
2930
2931   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
2932                               io_message, &io_em);
2933   if (err)
2934     goto out;
2935
2936   mpi_plain = gcry_mpi_snew (0);
2937   gcry_ac_os_to_mpi (mpi_plain, em, em_n);
2938
2939   err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted);
2940   if (err)
2941     goto out;
2942
2943   err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted);
2944   if (err)
2945     goto out;
2946
2947   err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n);
2948   if (err)
2949     goto out;
2950
2951   err = _gcry_ac_io_write (io_cipher, buffer, buffer_n);
2952
2953  out:
2954
2955   gcry_ac_data_destroy (data_encrypted);
2956   gcry_mpi_release (mpi_encrypted);
2957   gcry_mpi_release (mpi_plain);
2958   gcry_free (opts_em);
2959   gcry_free (buffer);
2960   gcry_free (em);
2961
2962   return err;
2963 }
2964
2965 /* Decryptes the cipher message contained in C, which is of size C_N,
2966    with the secret key KEY_SECRET according to the Encryption Scheme
2967    SCHEME_ID.  Handle is used for accessing the low-level
2968    cryptographic primitives.  If OPTS is not NULL, it has to be an
2969    anonymous structure specific to the chosen scheme (gcry_ac_es_*_t).
2970    The decrypted message will be stored in M and M_N.  */
2971 gcry_error_t
2972 _gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
2973                               gcry_ac_scheme_t scheme_id,
2974                               unsigned int flags, void *opts,
2975                               gcry_ac_key_t key,
2976                               gcry_ac_io_t *io_cipher,
2977                               gcry_ac_io_t *io_message)
2978 {
2979   gcry_ac_io_t io_em;
2980   gcry_error_t err;
2981   gcry_ac_data_t data_encrypted;
2982   unsigned char *em;
2983   size_t em_n;
2984   gcry_mpi_t mpi_encrypted;
2985   gcry_mpi_t mpi_decrypted;
2986   void *opts_em;
2987   ac_scheme_t *scheme;
2988   char *elements_enc;
2989   size_t elements_enc_n;
2990   unsigned char *c;
2991   size_t c_n;
2992
2993   (void)flags;
2994
2995   if (fips_mode ())
2996     return gpg_error (GPG_ERR_NOT_SUPPORTED);
2997
2998   data_encrypted = NULL;
2999   mpi_encrypted = NULL;
3000   mpi_decrypted = NULL;
3001   elements_enc = NULL;
3002   opts_em = NULL;
3003   em = NULL;
3004   c = NULL;
3005
3006   scheme = ac_scheme_get (scheme_id);
3007   if (! scheme)
3008     {
3009       err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME);
3010       goto out;
3011     }
3012
3013   if (key->type != GCRY_AC_KEY_SECRET)
3014     {
3015       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3016       goto out;
3017     }
3018
3019   err = _gcry_ac_io_read_all (io_cipher, &c, &c_n);
3020   if (err)
3021     goto out;
3022
3023   mpi_encrypted = gcry_mpi_snew (0);
3024   gcry_ac_os_to_mpi (mpi_encrypted, c, c_n);
3025
3026   err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL);
3027   if (err)
3028     goto out;
3029
3030   elements_enc_n = strlen (elements_enc);
3031   if (elements_enc_n != 1)
3032     {
3033       /* FIXME? */
3034       err = gcry_error (GPG_ERR_CONFLICT);
3035       goto out;
3036     }
3037
3038   err = _gcry_ac_data_new (&data_encrypted);
3039   if (err)
3040     goto out;
3041
3042   err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
3043                            elements_enc, mpi_encrypted);
3044   if (err)
3045     goto out;
3046
3047   err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted);
3048   if (err)
3049     goto out;
3050
3051   err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n);
3052   if (err)
3053     goto out;
3054
3055   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3056   if (err)
3057     goto out;
3058
3059   _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE,
3060                     GCRY_AC_IO_STRING, em, em_n);
3061
3062   err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em,
3063                               &io_em, io_message);
3064   if (err)
3065     goto out;
3066
3067  out:
3068
3069   _gcry_ac_data_destroy (data_encrypted);
3070   gcry_mpi_release (mpi_encrypted);
3071   gcry_mpi_release (mpi_decrypted);
3072   free (elements_enc);
3073   gcry_free (opts_em);
3074   gcry_free (em);
3075   gcry_free (c);
3076
3077   return err;
3078 }
3079
3080
3081 /* Signs the message contained in M, which is of size M_N, with the
3082    secret key KEY according to the Signature Scheme SCHEME_ID.  Handle
3083    is used for accessing the low-level cryptographic primitives.  If
3084    OPTS is not NULL, it has to be an anonymous structure specific to
3085    the chosen scheme (gcry_ac_ssa_*_t).  The signed message will be
3086    stored in S and S_N.  */
3087 gcry_error_t
3088 _gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
3089                            gcry_ac_scheme_t scheme_id,
3090                            unsigned int flags, void *opts,
3091                            gcry_ac_key_t key,
3092                            gcry_ac_io_t *io_message,
3093                            gcry_ac_io_t *io_signature)
3094 {
3095   gcry_ac_io_t io_em;
3096   gcry_error_t err;
3097   gcry_ac_data_t data_signed;
3098   unsigned char *em;
3099   size_t em_n;
3100   gcry_mpi_t mpi;
3101   void *opts_em;
3102   unsigned char *buffer;
3103   size_t buffer_n;
3104   gcry_mpi_t mpi_signed;
3105   ac_scheme_t *scheme;
3106
3107   (void)flags;
3108
3109   if (fips_mode ())
3110     return gpg_error (GPG_ERR_NOT_SUPPORTED);
3111
3112   data_signed = NULL;
3113   mpi_signed = NULL;
3114   opts_em = NULL;
3115   buffer = NULL;
3116   mpi = NULL;
3117   em = NULL;
3118
3119   if (key->type != GCRY_AC_KEY_SECRET)
3120     {
3121       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3122       goto out;
3123     }
3124
3125   scheme = ac_scheme_get (scheme_id);
3126   if (! scheme)
3127     {
3128       /* FIXME: adjust api of scheme_get in respect to err codes.  */
3129       err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
3130       goto out;
3131     }
3132
3133   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3134   if (err)
3135     goto out;
3136
3137   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3138                     GCRY_AC_IO_STRING, &em, &em_n);
3139
3140   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3141                               io_message, &io_em);
3142   if (err)
3143     goto out;
3144
3145   mpi = gcry_mpi_new (0);
3146   _gcry_ac_os_to_mpi (mpi, em, em_n);
3147
3148   err = _gcry_ac_data_sign (handle, key, mpi, &data_signed);
3149   if (err)
3150     goto out;
3151
3152   err = ac_data_set_to_mpi (data_signed, &mpi_signed);
3153   if (err)
3154     goto out;
3155
3156   err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n);
3157   if (err)
3158     goto out;
3159
3160   err = _gcry_ac_io_write (io_signature, buffer, buffer_n);
3161
3162  out:
3163
3164   _gcry_ac_data_destroy (data_signed);
3165   gcry_mpi_release (mpi_signed);
3166   gcry_mpi_release (mpi);
3167   gcry_free (opts_em);
3168   gcry_free (buffer);
3169   gcry_free (em);
3170
3171   return err;
3172 }
3173
3174 /* Verifies that the signature contained in S, which is of length S_N,
3175    is indeed the result of signing the message contained in M, which
3176    is of size M_N, with the secret key belonging to the public key
3177    KEY_PUBLIC.  If OPTS is not NULL, it has to be an anonymous
3178    structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose
3179    ID is contained in SCHEME_ID.  */
3180 gcry_error_t
3181 _gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
3182                              gcry_ac_scheme_t scheme_id,
3183                              unsigned int flags, void *opts,
3184                              gcry_ac_key_t key,
3185                              gcry_ac_io_t *io_message,
3186                              gcry_ac_io_t *io_signature)
3187 {
3188   gcry_ac_io_t io_em;
3189   gcry_error_t err;
3190   gcry_ac_data_t data_signed;
3191   unsigned char *em;
3192   size_t em_n;
3193   void *opts_em;
3194   gcry_mpi_t mpi_signature;
3195   gcry_mpi_t mpi_data;
3196   ac_scheme_t *scheme;
3197   char *elements_sig;
3198   size_t elements_sig_n;
3199   unsigned char *s;
3200   size_t s_n;
3201
3202   (void)flags;
3203
3204   if (fips_mode ())
3205     return gpg_error (GPG_ERR_NOT_SUPPORTED);
3206
3207   mpi_signature = NULL;
3208   elements_sig = NULL;
3209   data_signed = NULL;
3210   mpi_data = NULL;
3211   opts_em = NULL;
3212   em = NULL;
3213   s = NULL;
3214
3215   if (key->type != GCRY_AC_KEY_PUBLIC)
3216     {
3217       err = gcry_error (GPG_ERR_WRONG_KEY_USAGE);
3218       goto out;
3219     }
3220
3221   scheme = ac_scheme_get (scheme_id);
3222   if (! scheme)
3223     {
3224       err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME);
3225       goto out;
3226     }
3227
3228   err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em);
3229   if (err)
3230     goto out;
3231
3232   _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE,
3233                     GCRY_AC_IO_STRING, &em, &em_n);
3234
3235   err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em,
3236                               io_message, &io_em);
3237   if (err)
3238     goto out;
3239
3240   mpi_data = gcry_mpi_new (0);
3241   _gcry_ac_os_to_mpi (mpi_data, em, em_n);
3242
3243   err = _gcry_ac_io_read_all (io_signature, &s, &s_n);
3244   if (err)
3245     goto out;
3246
3247   mpi_signature = gcry_mpi_new (0);
3248   _gcry_ac_os_to_mpi (mpi_signature, s, s_n);
3249
3250   err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig);
3251   if (err)
3252     goto out;
3253
3254   elements_sig_n = strlen (elements_sig);
3255   if (elements_sig_n != 1)
3256     {
3257       /* FIXME? */
3258       err = gcry_error (GPG_ERR_CONFLICT);
3259       goto out;
3260     }
3261
3262   err = _gcry_ac_data_new (&data_signed);
3263   if (err)
3264     goto out;
3265
3266   err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC,
3267                            elements_sig, mpi_signature);
3268   if (err)
3269     goto out;
3270
3271   gcry_mpi_release (mpi_signature);
3272   mpi_signature = NULL;
3273
3274   err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
3275
3276  out:
3277
3278   _gcry_ac_data_destroy (data_signed);
3279   gcry_mpi_release (mpi_signature);
3280   gcry_mpi_release (mpi_data);
3281   free (elements_sig);
3282   gcry_free (opts_em);
3283   gcry_free (em);
3284   gcry_free (s);
3285
3286   return err;
3287 }
3288
3289
3290 /*
3291  * General functions.
3292  */
3293
3294 gcry_err_code_t
3295 _gcry_ac_init (void)
3296 {
3297   if (fips_mode ())
3298     return GPG_ERR_NOT_SUPPORTED;
3299
3300   return 0;
3301 }