Allow gcry_mpi_dump to print opaque MPIs.
[libgcrypt.git] / mpi / mpicoder.c
1 /* mpicoder.c  -  Coder for the external representation of MPIs
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
3  *               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 <stdio.h>
23 #include <string.h>
24 #include <stdlib.h>
25
26 #include "mpi-internal.h"
27 #include "g10lib.h"
28
29 #define MAX_EXTERN_MPI_BITS 16384
30
31 /* Helper used to scan PGP style MPIs.  Returns NULL on failure. */
32 static gcry_mpi_t
33 mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
34                       int secure)
35 {
36   int i, j;
37   unsigned int nbits, nbytes, nlimbs, nread=0;
38   mpi_limb_t a;
39   gcry_mpi_t val = MPI_NULL;
40
41   if ( *ret_nread < 2 )
42     goto leave;
43   nbits = buffer[0] << 8 | buffer[1];
44   if ( nbits > MAX_EXTERN_MPI_BITS )
45     {
46 /*       log_debug ("mpi too large (%u bits)\n", nbits); */
47       goto leave;
48     }
49   buffer += 2;
50   nread = 2;
51
52   nbytes = (nbits+7) / 8;
53   nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
54   val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
55   i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
56   i %= BYTES_PER_MPI_LIMB;
57   j= val->nlimbs = nlimbs;
58   val->sign = 0;
59   for ( ; j > 0; j-- )
60     {
61       a = 0;
62       for (; i < BYTES_PER_MPI_LIMB; i++ )
63         {
64           if ( ++nread > *ret_nread )
65             {
66 /*               log_debug ("mpi larger than buffer"); */
67               mpi_free (val);
68               val = NULL;
69               goto leave;
70             }
71           a <<= 8;
72           a |= *buffer++;
73         }
74       i = 0;
75       val->d[j-1] = a;
76     }
77
78  leave:
79   *ret_nread = nread;
80   return val;
81 }
82
83
84 /****************
85  * Fill the mpi VAL from the hex string in STR.
86  */
87 static int
88 mpi_fromstr (gcry_mpi_t val, const char *str)
89 {
90   int sign = 0;
91   int prepend_zero = 0;
92   int i, j, c, c1, c2;
93   unsigned int nbits, nbytes, nlimbs;
94   mpi_limb_t a;
95
96   if ( *str == '-' )
97     {
98       sign = 1;
99       str++;
100     }
101
102   /* Skip optional hex prefix.  */
103   if ( *str == '0' && str[1] == 'x' )
104     str += 2;
105
106   nbits = 4 * strlen (str);
107   if ((nbits % 8))
108     prepend_zero = 1;
109
110   nbytes = (nbits+7) / 8;
111   nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
112
113   if ( val->alloced < nlimbs )
114     mpi_resize (val, nlimbs);
115
116   i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
117   i %= BYTES_PER_MPI_LIMB;
118   j = val->nlimbs = nlimbs;
119   val->sign = sign;
120   for (; j > 0; j--)
121     {
122       a = 0;
123       for (; i < BYTES_PER_MPI_LIMB; i++)
124         {
125           if (prepend_zero)
126             {
127               c1 = '0';
128               prepend_zero = 0;
129             }
130           else
131             c1 = *str++;
132
133           if (!c1)
134             {
135               mpi_clear (val);
136               return 1;  /* Error.  */
137             }
138           c2 = *str++;
139           if (!c2)
140             {
141               mpi_clear (val);
142               return 1;  /* Error.  */
143             }
144           if ( c1 >= '0' && c1 <= '9' )
145             c = c1 - '0';
146           else if ( c1 >= 'a' && c1 <= 'f' )
147             c = c1 - 'a' + 10;
148           else if ( c1 >= 'A' && c1 <= 'F' )
149             c = c1 - 'A' + 10;
150           else
151             {
152               mpi_clear (val);
153               return 1;  /* Error.  */
154             }
155           c <<= 4;
156           if ( c2 >= '0' && c2 <= '9' )
157             c |= c2 - '0';
158           else if( c2 >= 'a' && c2 <= 'f' )
159             c |= c2 - 'a' + 10;
160           else if( c2 >= 'A' && c2 <= 'F' )
161             c |= c2 - 'A' + 10;
162           else
163             {
164               mpi_clear(val);
165               return 1;  /* Error. */
166             }
167           a <<= 8;
168           a |= c;
169         }
170       i = 0;
171       val->d[j-1] = a;
172     }
173
174   return 0;  /* Okay.  */
175 }
176
177
178 /* Dump the value of A in a format suitable for debugging to
179    Libgcrypt's logging stream.  Note that one leading space but no
180    trailing space or linefeed will be printed.  It is okay to pass
181    NULL for A. */
182 void
183 gcry_mpi_dump (const gcry_mpi_t a)
184 {
185   int i;
186
187   log_printf (" ");
188   if (!a)
189     log_printf ("[MPI_NULL]");
190   else if (mpi_is_opaque (a))
191     {
192       unsigned int nbits;
193       const unsigned char *p;
194
195       p = gcry_mpi_get_opaque (a, &nbits);
196       log_printf ("[%u bit: ", nbits);
197       for (i=0; i < (nbits + 7)/8; i++)
198         log_printf ("%02x", p[i]);
199       log_printf ("]");
200     }
201   else
202     {
203       if (a->sign)
204         log_printf ( "-");
205 #if BYTES_PER_MPI_LIMB == 2
206 # define X "4"
207 #elif BYTES_PER_MPI_LIMB == 4
208 # define X "8"
209 #elif BYTES_PER_MPI_LIMB == 8
210 # define X "16"
211 #elif BYTES_PER_MPI_LIMB == 16
212 # define X "32"
213 #else
214 # error please define the format here
215 #endif
216       for (i=a->nlimbs; i > 0 ; i-- )
217         {
218           log_printf (i != a->nlimbs? "%0" X "lX":"%lX", (ulong)a->d[i-1]);
219         }
220 #undef X
221       if (!a->nlimbs)
222         log_printf ("0");
223     }
224 }
225
226 /* Convience function used internally. */
227 void
228 _gcry_log_mpidump (const char *text, gcry_mpi_t a)
229 {
230   log_printf ("%s:", text);
231   gcry_mpi_dump (a);
232   log_printf ("\n");
233 }
234
235
236 /* Return an allocated buffer with the MPI (msb first).  NBYTES
237    receives the length of this buffer.  Caller must free the return
238    string.  This function returns an allocated buffer with NBYTES set
239    to zero if the value of A is zero.  If sign is not NULL, it will be
240    set to the sign of the A.  On error NULL is returned and ERRNO set
241    appropriately.  */
242 static unsigned char *
243 do_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign, int force_secure)
244 {
245   unsigned char *p, *buffer;
246   mpi_limb_t alimb;
247   int i;
248   size_t n;
249
250   if (sign)
251     *sign = a->sign;
252
253   *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
254   n = *nbytes? *nbytes:1; /* Allocate at least one byte.  */
255   p = buffer = (force_secure || mpi_is_secure(a))? gcry_malloc_secure (n)
256                                                  : gcry_malloc (n);
257   if (!buffer)
258     return NULL;
259
260   for (i=a->nlimbs-1; i >= 0; i--)
261     {
262       alimb = a->d[i];
263 #if BYTES_PER_MPI_LIMB == 4
264       *p++ = alimb >> 24;
265       *p++ = alimb >> 16;
266       *p++ = alimb >>  8;
267       *p++ = alimb        ;
268 #elif BYTES_PER_MPI_LIMB == 8
269       *p++ = alimb >> 56;
270       *p++ = alimb >> 48;
271       *p++ = alimb >> 40;
272       *p++ = alimb >> 32;
273       *p++ = alimb >> 24;
274       *p++ = alimb >> 16;
275       *p++ = alimb >>  8;
276       *p++ = alimb        ;
277 #else
278 #     error please implement for this limb size.
279 #endif
280     }
281
282   /* This is sub-optimal but we need to do the shift operation because
283      the caller has to free the returned buffer.  */
284   for (p=buffer; *nbytes && !*p; p++, --*nbytes)
285     ;
286   if (p != buffer)
287     memmove (buffer,p, *nbytes);
288   return buffer;
289 }
290
291
292 byte *
293 _gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int *nbytes, int *sign)
294 {
295   return do_get_buffer (a, nbytes, sign, 0);
296 }
297
298 byte *
299 _gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned *nbytes, int *sign)
300 {
301   return do_get_buffer (a, nbytes, sign, 1);
302 }
303
304
305 /*
306  * Use the NBYTES at BUFFER_ARG to update A.  Set the sign of a to
307  * SIGN.
308  */
309 void
310 _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
311                       unsigned int nbytes, int sign)
312 {
313   const unsigned char *buffer = (const unsigned char*)buffer_arg;
314   const unsigned char *p;
315   mpi_limb_t alimb;
316   int nlimbs;
317   int i;
318
319   if (mpi_is_immutable (a))
320     {
321       mpi_immutable_failed ();
322       return;
323     }
324
325   nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
326   RESIZE_IF_NEEDED(a, nlimbs);
327   a->sign = sign;
328
329   for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
330     {
331 #if BYTES_PER_MPI_LIMB == 4
332       alimb  = *p--         ;
333       alimb |= *p-- <<  8 ;
334       alimb |= *p-- << 16 ;
335       alimb |= *p-- << 24 ;
336 #elif BYTES_PER_MPI_LIMB == 8
337       alimb  = (mpi_limb_t)*p-- ;
338       alimb |= (mpi_limb_t)*p-- <<  8 ;
339       alimb |= (mpi_limb_t)*p-- << 16 ;
340       alimb |= (mpi_limb_t)*p-- << 24 ;
341       alimb |= (mpi_limb_t)*p-- << 32 ;
342       alimb |= (mpi_limb_t)*p-- << 40 ;
343       alimb |= (mpi_limb_t)*p-- << 48 ;
344       alimb |= (mpi_limb_t)*p-- << 56 ;
345 #else
346 #       error please implement for this limb size.
347 #endif
348       a->d[i++] = alimb;
349     }
350   if ( p >= buffer )
351     {
352 #if BYTES_PER_MPI_LIMB == 4
353       alimb  = *p--;
354       if (p >= buffer)
355         alimb |= *p-- <<  8;
356       if (p >= buffer)
357         alimb |= *p-- << 16;
358       if (p >= buffer)
359         alimb |= *p-- << 24;
360 #elif BYTES_PER_MPI_LIMB == 8
361       alimb  = (mpi_limb_t)*p--;
362       if (p >= buffer)
363         alimb |= (mpi_limb_t)*p-- << 8;
364       if (p >= buffer)
365         alimb |= (mpi_limb_t)*p-- << 16;
366       if (p >= buffer)
367         alimb |= (mpi_limb_t)*p-- << 24;
368       if (p >= buffer)
369         alimb |= (mpi_limb_t)*p-- << 32;
370       if (p >= buffer)
371         alimb |= (mpi_limb_t)*p-- << 40;
372       if (p >= buffer)
373         alimb |= (mpi_limb_t)*p-- << 48;
374       if (p >= buffer)
375         alimb |= (mpi_limb_t)*p-- << 56;
376 #else
377 #     error please implement for this limb size.
378 #endif
379       a->d[i++] = alimb;
380     }
381   a->nlimbs = i;
382   gcry_assert (i == nlimbs);
383 }
384
385
386 /* Convert the external representation of an integer stored in BUFFER
387    with a length of BUFLEN into a newly create MPI returned in
388    RET_MPI.  If NBYTES is not NULL, it will receive the number of
389    bytes actually scanned after a successful operation.  */
390 gcry_error_t
391 gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
392                const void *buffer_arg, size_t buflen, size_t *nscanned)
393 {
394   const unsigned char *buffer = (const unsigned char*)buffer_arg;
395   struct gcry_mpi *a = NULL;
396   unsigned int len;
397   int secure = (buffer && gcry_is_secure (buffer));
398
399   if (format == GCRYMPI_FMT_SSH)
400     len = 0;
401   else
402     len = buflen;
403
404   if (format == GCRYMPI_FMT_STD)
405     {
406       const unsigned char *s = buffer;
407
408       a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
409                                     /BYTES_PER_MPI_LIMB)
410                 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
411       if (len)
412         {
413           a->sign = !!(*s & 0x80);
414           if (a->sign)
415             {
416               /* FIXME: we have to convert from 2compl to magnitude format */
417               mpi_free (a);
418               return gcry_error (GPG_ERR_INTERNAL);
419             }
420           else
421             _gcry_mpi_set_buffer (a, s, len, 0);
422         }
423       if (ret_mpi)
424         {
425           mpi_normalize ( a );
426           *ret_mpi = a;
427         }
428       else
429         mpi_free(a);
430       return 0;
431     }
432   else if (format == GCRYMPI_FMT_USG)
433     {
434       a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
435                                     /BYTES_PER_MPI_LIMB)
436                 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
437
438       if (len)
439         _gcry_mpi_set_buffer (a, buffer, len, 0);
440       if (ret_mpi)
441         {
442           mpi_normalize ( a );
443           *ret_mpi = a;
444         }
445       else
446         mpi_free(a);
447       return 0;
448     }
449   else if (format == GCRYMPI_FMT_PGP)
450     {
451       a = mpi_read_from_buffer (buffer, &len, secure);
452       if (nscanned)
453         *nscanned = len;
454       if (ret_mpi && a)
455         {
456           mpi_normalize (a);
457           *ret_mpi = a;
458         }
459       else if (a)
460         {
461           mpi_free(a);
462           a = NULL;
463         }
464       return a? 0 : gcry_error (GPG_ERR_INV_OBJ);
465     }
466   else if (format == GCRYMPI_FMT_SSH)
467     {
468       const unsigned char *s = buffer;
469       size_t n;
470
471       /* This test is not strictly necessary and an assert (!len)
472          would be sufficient.  We keep this test in case we later
473          allow the BUFLEN argument to act as a sanitiy check.  Same
474          below. */
475       if (len && len < 4)
476         return gcry_error (GPG_ERR_TOO_SHORT);
477
478       n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
479       s += 4;
480       if (len)
481         len -= 4;
482       if (len && n > len)
483         return gcry_error (GPG_ERR_TOO_LARGE);
484
485       a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
486                                     /BYTES_PER_MPI_LIMB)
487                 : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
488       if (n)
489         {
490           a->sign = !!(*s & 0x80);
491           if (a->sign)
492             {
493               /* FIXME: we have to convert from 2compl to magnitude format */
494               mpi_free(a);
495               return gcry_error (GPG_ERR_INTERNAL);
496             }
497           else
498             _gcry_mpi_set_buffer( a, s, n, 0 );
499         }
500       if (nscanned)
501         *nscanned = n+4;
502       if (ret_mpi)
503         {
504           mpi_normalize ( a );
505           *ret_mpi = a;
506         }
507       else
508         mpi_free(a);
509       return 0;
510     }
511   else if (format == GCRYMPI_FMT_HEX)
512     {
513       /* We can only handle C strings for now.  */
514       if (buflen)
515         return gcry_error (GPG_ERR_INV_ARG);
516
517       a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
518       if (mpi_fromstr (a, (const char *)buffer))
519         {
520           mpi_free (a);
521           return gcry_error (GPG_ERR_INV_OBJ);
522         }
523       if (ret_mpi)
524         {
525           mpi_normalize ( a );
526           *ret_mpi = a;
527         }
528       else
529         mpi_free(a);
530       return 0;
531     }
532   else
533     return gcry_error (GPG_ERR_INV_ARG);
534 }
535
536
537 /* Convert the big integer A into the external representation
538    described by FORMAT and store it in the provided BUFFER which has
539    been allocated by the user with a size of BUFLEN bytes.  NWRITTEN
540    receives the actual length of the external representation unless it
541    has been passed as NULL.  BUFFER may be NULL to query the required
542    length.  */
543 gcry_error_t
544 gcry_mpi_print (enum gcry_mpi_format format,
545                 unsigned char *buffer, size_t buflen,
546                 size_t *nwritten, struct gcry_mpi *a)
547 {
548   unsigned int nbits = mpi_get_nbits (a);
549   size_t len;
550   size_t dummy_nwritten;
551
552   if (!nwritten)
553     nwritten = &dummy_nwritten;
554
555   len = buflen;
556   *nwritten = 0;
557   if (format == GCRYMPI_FMT_STD)
558     {
559       unsigned char *tmp;
560       int extra = 0;
561       unsigned int n;
562
563       if (a->sign)
564         return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet. */
565
566       tmp = _gcry_mpi_get_buffer (a, &n, NULL);
567       if (!tmp)
568         return gpg_error_from_syserror ();
569       if (n && (*tmp & 0x80))
570         {
571           n++;
572           extra=1;
573         }
574
575       if (buffer && n > len)
576         {
577           /* The provided buffer is too short. */
578           gcry_free (tmp);
579           return gcry_error (GPG_ERR_TOO_SHORT);
580         }
581       if (buffer)
582         {
583           unsigned char *s = buffer;
584
585           if (extra)
586             *s++ = 0;
587           memcpy (s, tmp, n-extra);
588         }
589       gcry_free(tmp);
590       *nwritten = n;
591       return 0;
592     }
593   else if (format == GCRYMPI_FMT_USG)
594     {
595       unsigned int n = (nbits + 7)/8;
596
597       /* Note:  We ignore the sign for this format.  */
598       /* FIXME: for performance reasons we should put this into
599          mpi_aprint because we can then use the buffer directly.  */
600       if (buffer && n > len)
601         return gcry_error (GPG_ERR_TOO_SHORT);
602       if (buffer)
603         {
604           unsigned char *tmp;
605
606           tmp = _gcry_mpi_get_buffer (a, &n, NULL);
607           if (!tmp)
608             return gpg_error_from_syserror ();
609           memcpy (buffer, tmp, n);
610           gcry_free (tmp);
611         }
612       *nwritten = n;
613       return 0;
614     }
615   else if (format == GCRYMPI_FMT_PGP)
616     {
617       unsigned int n = (nbits + 7)/8;
618
619       /* The PGP format can only handle unsigned integers.  */
620       if( a->sign )
621         return gcry_error (GPG_ERR_INV_ARG);
622
623       if (buffer && n+2 > len)
624         return gcry_error (GPG_ERR_TOO_SHORT);
625
626       if (buffer)
627         {
628           unsigned char *tmp;
629           unsigned char *s = buffer;
630
631           s[0] = nbits >> 8;
632           s[1] = nbits;
633
634           tmp = _gcry_mpi_get_buffer (a, &n, NULL);
635           if (!tmp)
636             return gpg_error_from_syserror ();
637           memcpy (s+2, tmp, n);
638           gcry_free (tmp);
639         }
640       *nwritten = n+2;
641       return 0;
642     }
643   else if (format == GCRYMPI_FMT_SSH)
644     {
645       unsigned char *tmp;
646       int extra = 0;
647       unsigned int n;
648
649       if (a->sign)
650         return gcry_error (GPG_ERR_INTERNAL); /* Can't handle it yet.  */
651
652       tmp = _gcry_mpi_get_buffer (a, &n, NULL);
653       if (!tmp)
654         return gpg_error_from_syserror ();
655       if (n && (*tmp & 0x80))
656         {
657           n++;
658           extra=1;
659         }
660
661       if (buffer && n+4 > len)
662         {
663           gcry_free(tmp);
664           return gcry_error (GPG_ERR_TOO_SHORT);
665         }
666
667       if (buffer)
668         {
669           unsigned char *s = buffer;
670
671           *s++ = n >> 24;
672           *s++ = n >> 16;
673           *s++ = n >> 8;
674           *s++ = n;
675           if (extra)
676             *s++ = 0;
677
678           memcpy (s, tmp, n-extra);
679         }
680       gcry_free (tmp);
681       *nwritten = 4+n;
682       return 0;
683     }
684   else if (format == GCRYMPI_FMT_HEX)
685     {
686       unsigned char *tmp;
687       int i;
688       int extra = 0;
689       unsigned int n = 0;
690
691       tmp = _gcry_mpi_get_buffer (a, &n, NULL);
692       if (!tmp)
693         return gpg_error_from_syserror ();
694       if (!n || (*tmp & 0x80))
695         extra = 2;
696
697       if (buffer && 2*n + extra + !!a->sign + 1 > len)
698         {
699           gcry_free(tmp);
700           return gcry_error (GPG_ERR_TOO_SHORT);
701         }
702       if (buffer)
703         {
704           unsigned char *s = buffer;
705
706           if (a->sign)
707             *s++ = '-';
708           if (extra)
709             {
710               *s++ = '0';
711               *s++ = '0';
712             }
713
714           for (i=0; i < n; i++)
715             {
716               unsigned int c = tmp[i];
717
718               *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
719               c &= 15;
720               *s++ = c < 10? '0'+c : 'A'+c-10 ;
721             }
722           *s++ = 0;
723           *nwritten = s - buffer;
724         }
725       else
726         {
727           *nwritten = 2*n + extra + !!a->sign + 1;
728         }
729       gcry_free (tmp);
730       return 0;
731     }
732   else
733     return gcry_error (GPG_ERR_INV_ARG);
734 }
735
736
737 /*
738  * Like gcry_mpi_print but this function allocates the buffer itself.
739  * The caller has to supply the address of a pointer.  NWRITTEN may be
740  * NULL.
741  */
742 gcry_error_t
743 gcry_mpi_aprint (enum gcry_mpi_format format,
744                  unsigned char **buffer, size_t *nwritten,
745                  struct gcry_mpi *a)
746 {
747   size_t n;
748   gcry_error_t rc;
749
750   *buffer = NULL;
751   rc = gcry_mpi_print (format, NULL, 0, &n, a);
752   if (rc)
753     return rc;
754
755   *buffer = mpi_is_secure(a) ? gcry_malloc_secure (n) : gcry_malloc (n);
756   if (!*buffer)
757     return gpg_error_from_syserror ();
758   rc = gcry_mpi_print( format, *buffer, n, &n, a );
759   if (rc)
760     {
761       gcry_free(*buffer);
762       *buffer = NULL;
763     }
764   else if (nwritten)
765     *nwritten = n;
766   return rc;
767 }