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