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