mpi: Extend the internal mpi_get_buffer.
[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  * Copyright (C) 2013, 2014 g10 Code GmbH
5  *
6  * This file is part of Libgcrypt.
7  *
8  * Libgcrypt is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as
10  * published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * Libgcrypt is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <config.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <stdlib.h>
26
27 #include "mpi-internal.h"
28 #include "g10lib.h"
29
30 #define MAX_EXTERN_MPI_BITS 16384
31
32 /* Helper used to scan PGP style MPIs.  Returns NULL on failure. */
33 static gcry_mpi_t
34 mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
35                       int secure)
36 {
37   int i, j;
38   unsigned int nbits, nbytes, nlimbs, nread=0;
39   mpi_limb_t a;
40   gcry_mpi_t val = MPI_NULL;
41
42   if ( *ret_nread < 2 )
43     goto leave;
44   nbits = buffer[0] << 8 | buffer[1];
45   if ( nbits > MAX_EXTERN_MPI_BITS )
46     {
47 /*       log_debug ("mpi too large (%u bits)\n", nbits); */
48       goto leave;
49     }
50   buffer += 2;
51   nread = 2;
52
53   nbytes = (nbits+7) / 8;
54   nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
55   val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
56   i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
57   i %= BYTES_PER_MPI_LIMB;
58   j= val->nlimbs = nlimbs;
59   val->sign = 0;
60   for ( ; j > 0; j-- )
61     {
62       a = 0;
63       for (; i < BYTES_PER_MPI_LIMB; i++ )
64         {
65           if ( ++nread > *ret_nread )
66             {
67 /*               log_debug ("mpi larger than buffer"); */
68               mpi_free (val);
69               val = NULL;
70               goto leave;
71             }
72           a <<= 8;
73           a |= *buffer++;
74         }
75       i = 0;
76       val->d[j-1] = a;
77     }
78
79  leave:
80   *ret_nread = nread;
81   return val;
82 }
83
84
85 /****************
86  * Fill the mpi VAL from the hex string in STR.
87  */
88 static int
89 mpi_fromstr (gcry_mpi_t val, const char *str)
90 {
91   int sign = 0;
92   int prepend_zero = 0;
93   int i, j, c, c1, c2;
94   unsigned int nbits, nbytes, nlimbs;
95   mpi_limb_t a;
96
97   if ( *str == '-' )
98     {
99       sign = 1;
100       str++;
101     }
102
103   /* Skip optional hex prefix.  */
104   if ( *str == '0' && str[1] == 'x' )
105     str += 2;
106
107   nbits = 4 * strlen (str);
108   if ((nbits % 8))
109     prepend_zero = 1;
110
111   nbytes = (nbits+7) / 8;
112   nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
113
114   if ( val->alloced < nlimbs )
115     mpi_resize (val, nlimbs);
116
117   i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
118   i %= BYTES_PER_MPI_LIMB;
119   j = val->nlimbs = nlimbs;
120   val->sign = sign;
121   for (; j > 0; j--)
122     {
123       a = 0;
124       for (; i < BYTES_PER_MPI_LIMB; i++)
125         {
126           if (prepend_zero)
127             {
128               c1 = '0';
129               prepend_zero = 0;
130             }
131           else
132             c1 = *str++;
133
134           if (!c1)
135             {
136               mpi_clear (val);
137               return 1;  /* Error.  */
138             }
139           c2 = *str++;
140           if (!c2)
141             {
142               mpi_clear (val);
143               return 1;  /* Error.  */
144             }
145           if ( c1 >= '0' && c1 <= '9' )
146             c = c1 - '0';
147           else if ( c1 >= 'a' && c1 <= 'f' )
148             c = c1 - 'a' + 10;
149           else if ( c1 >= 'A' && c1 <= 'F' )
150             c = c1 - 'A' + 10;
151           else
152             {
153               mpi_clear (val);
154               return 1;  /* Error.  */
155             }
156           c <<= 4;
157           if ( c2 >= '0' && c2 <= '9' )
158             c |= c2 - '0';
159           else if( c2 >= 'a' && c2 <= 'f' )
160             c |= c2 - 'a' + 10;
161           else if( c2 >= 'A' && c2 <= 'F' )
162             c |= c2 - 'A' + 10;
163           else
164             {
165               mpi_clear(val);
166               return 1;  /* Error. */
167             }
168           a <<= 8;
169           a |= c;
170         }
171       i = 0;
172       val->d[j-1] = a;
173     }
174
175   return 0;  /* Okay.  */
176 }
177
178
179 /* Return an allocated buffer with the MPI (msb first).  NBYTES
180    receives the length of this buffer.  If FILL_LE is not 0, the
181    returned value is stored as little endian and right padded with
182    zeroes so that the returned buffer has at least FILL_LE bytes.
183
184    If EXTRAALLOC > 0 the returned buffer has these number of bytes
185    extra allocated at the end; if EXTRAALLOC < 0 the returned buffer
186    has the absolute value of EXTRAALLOC allocated at the begin of the
187    buffer (the are not initialized) and the MPI is stored right after
188    this.  This feature is useful to allow the caller to prefix the
189    returned value.  EXTRAALLOC is _not_ included in the value stored
190    at NBYTES.
191
192    Caller must free the return string.  This function returns an
193    allocated buffer with NBYTES set to zero if the value of A is zero.
194    If sign is not NULL, it will be set to the sign of the A.  On error
195    NULL is returned and ERRNO set appropriately.  */
196 static unsigned char *
197 do_get_buffer (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
198                unsigned int *nbytes, int *sign, int force_secure)
199 {
200   unsigned char *p, *buffer, *retbuffer;
201   unsigned int length, tmp;
202   mpi_limb_t alimb;
203   int i;
204   size_t n, n2;
205
206   if (sign)
207     *sign = a->sign;
208
209   *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
210   n = *nbytes? *nbytes:1; /* Allocate at least one byte.  */
211   if (n < fill_le)
212     n = fill_le;
213   if (extraalloc < 0)
214     n2 = n + -extraalloc;
215   else
216     n2 = n + extraalloc;
217
218   retbuffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n2)
219                                                 : xtrymalloc (n2);
220   if (!retbuffer)
221     return NULL;
222   if (extraalloc < 0)
223     buffer = retbuffer + -extraalloc;
224   else
225     buffer = retbuffer;
226   p = buffer;
227
228   for (i=a->nlimbs-1; i >= 0; i--)
229     {
230       alimb = a->d[i];
231 #if BYTES_PER_MPI_LIMB == 4
232       *p++ = alimb >> 24;
233       *p++ = alimb >> 16;
234       *p++ = alimb >>  8;
235       *p++ = alimb        ;
236 #elif BYTES_PER_MPI_LIMB == 8
237       *p++ = alimb >> 56;
238       *p++ = alimb >> 48;
239       *p++ = alimb >> 40;
240       *p++ = alimb >> 32;
241       *p++ = alimb >> 24;
242       *p++ = alimb >> 16;
243       *p++ = alimb >>  8;
244       *p++ = alimb        ;
245 #else
246 #     error please implement for this limb size.
247 #endif
248     }
249
250   if (fill_le)
251     {
252       length = *nbytes;
253       /* Reverse buffer and pad with zeroes.  */
254       for (i=0; i < length/2; i++)
255         {
256           tmp = buffer[i];
257           buffer[i] = buffer[length-1-i];
258           buffer[length-1-i] = tmp;
259         }
260       /* Pad with zeroes.  */
261       for (p = buffer + length; length < fill_le; length++)
262         *p++ = 0;
263       *nbytes = length;
264
265       return retbuffer;
266     }
267
268   /* This is sub-optimal but we need to do the shift operation because
269      the caller has to free the returned buffer.  */
270   for (p=buffer; *nbytes && !*p; p++, --*nbytes)
271     ;
272   if (p != buffer)
273     memmove (buffer, p, *nbytes);
274   return retbuffer;
275 }
276
277
278 byte *
279 _gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
280                       unsigned int *r_nbytes, int *sign)
281 {
282   return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 0);
283 }
284
285 byte *
286 _gcry_mpi_get_buffer_extra (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
287                             unsigned int *r_nbytes, int *sign)
288 {
289   return do_get_buffer (a, fill_le, extraalloc, r_nbytes, sign, 0);
290 }
291
292 byte *
293 _gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
294                              unsigned int *r_nbytes, int *sign)
295 {
296   return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 1);
297 }
298
299
300 /*
301  * Use the NBYTES at BUFFER_ARG to update A.  Set the sign of a to
302  * SIGN.
303  */
304 void
305 _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
306                       unsigned int nbytes, int sign)
307 {
308   const unsigned char *buffer = (const unsigned char*)buffer_arg;
309   const unsigned char *p;
310   mpi_limb_t alimb;
311   int nlimbs;
312   int i;
313
314   if (mpi_is_immutable (a))
315     {
316       mpi_immutable_failed ();
317       return;
318     }
319
320   nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
321   RESIZE_IF_NEEDED(a, nlimbs);
322   a->sign = sign;
323
324   for (i=0, p = buffer+nbytes-1; p >= buffer+BYTES_PER_MPI_LIMB; )
325     {
326 #if BYTES_PER_MPI_LIMB == 4
327       alimb  = *p--         ;
328       alimb |= *p-- <<  8 ;
329       alimb |= *p-- << 16 ;
330       alimb |= *p-- << 24 ;
331 #elif BYTES_PER_MPI_LIMB == 8
332       alimb  = (mpi_limb_t)*p-- ;
333       alimb |= (mpi_limb_t)*p-- <<  8 ;
334       alimb |= (mpi_limb_t)*p-- << 16 ;
335       alimb |= (mpi_limb_t)*p-- << 24 ;
336       alimb |= (mpi_limb_t)*p-- << 32 ;
337       alimb |= (mpi_limb_t)*p-- << 40 ;
338       alimb |= (mpi_limb_t)*p-- << 48 ;
339       alimb |= (mpi_limb_t)*p-- << 56 ;
340 #else
341 #       error please implement for this limb size.
342 #endif
343       a->d[i++] = alimb;
344     }
345   if ( p >= buffer )
346     {
347 #if BYTES_PER_MPI_LIMB == 4
348       alimb  = *p--;
349       if (p >= buffer)
350         alimb |= *p-- <<  8;
351       if (p >= buffer)
352         alimb |= *p-- << 16;
353       if (p >= buffer)
354         alimb |= *p-- << 24;
355 #elif BYTES_PER_MPI_LIMB == 8
356       alimb  = (mpi_limb_t)*p--;
357       if (p >= buffer)
358         alimb |= (mpi_limb_t)*p-- << 8;
359       if (p >= buffer)
360         alimb |= (mpi_limb_t)*p-- << 16;
361       if (p >= buffer)
362         alimb |= (mpi_limb_t)*p-- << 24;
363       if (p >= buffer)
364         alimb |= (mpi_limb_t)*p-- << 32;
365       if (p >= buffer)
366         alimb |= (mpi_limb_t)*p-- << 40;
367       if (p >= buffer)
368         alimb |= (mpi_limb_t)*p-- << 48;
369       if (p >= buffer)
370         alimb |= (mpi_limb_t)*p-- << 56;
371 #else
372 #     error please implement for this limb size.
373 #endif
374       a->d[i++] = alimb;
375     }
376   a->nlimbs = i;
377   gcry_assert (i == nlimbs);
378 }
379
380
381 static void
382 onecompl (gcry_mpi_t a)
383 {
384   mpi_ptr_t ap;
385   mpi_size_t n;
386   unsigned int i;
387   unsigned int nbits = mpi_get_nbits (a);
388
389   if (mpi_is_immutable (a))
390     {
391       mpi_immutable_failed ();
392       return;
393     }
394
395   mpi_normalize (a);
396   ap = a->d;
397   n = a->nlimbs;
398
399   for( i = 0; i < n; i++ )
400     ap[i] ^= (mpi_limb_t)(-1);
401
402   a->sign = 0;
403   mpi_clear_highbit (a, nbits-1);
404 }
405
406
407 /* Perform a two's complement operation on buffer P of size N bytes.  */
408 static void
409 twocompl (unsigned char *p, unsigned int n)
410 {
411   int i;
412
413   for (i=n-1; i >= 0 && !p[i]; i--)
414     ;
415   if (i >= 0)
416     {
417       if ((p[i] & 0x01))
418         p[i] = (((p[i] ^ 0xfe) | 0x01) & 0xff);
419       else if ((p[i] & 0x02))
420         p[i] = (((p[i] ^ 0xfc) | 0x02) & 0xfe);
421       else if ((p[i] & 0x04))
422         p[i] = (((p[i] ^ 0xf8) | 0x04) & 0xfc);
423       else if ((p[i] & 0x08))
424         p[i] = (((p[i] ^ 0xf0) | 0x08) & 0xf8);
425       else if ((p[i] & 0x10))
426         p[i] = (((p[i] ^ 0xe0) | 0x10) & 0xf0);
427       else if ((p[i] & 0x20))
428         p[i] = (((p[i] ^ 0xc0) | 0x20) & 0xe0);
429       else if ((p[i] & 0x40))
430         p[i] = (((p[i] ^ 0x80) | 0x40) & 0xc0);
431       else
432         p[i] = 0x80;
433
434       for (i--; i >= 0; i--)
435         p[i] ^= 0xff;
436     }
437 }
438
439
440 /* Convert the external representation of an integer stored in BUFFER
441    with a length of BUFLEN into a newly create MPI returned in
442    RET_MPI.  If NBYTES is not NULL, it will receive the number of
443    bytes actually scanned after a successful operation.  */
444 gcry_err_code_t
445 _gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
446                 const void *buffer_arg, size_t buflen, size_t *nscanned)
447 {
448   const unsigned char *buffer = (const unsigned char*)buffer_arg;
449   struct gcry_mpi *a = NULL;
450   unsigned int len;
451   int secure = (buffer && _gcry_is_secure (buffer));
452
453   if (format == GCRYMPI_FMT_SSH)
454     len = 0;
455   else
456     len = buflen;
457
458   if (format == GCRYMPI_FMT_STD)
459     {
460       const unsigned char *s = buffer;
461
462       a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
463                                     /BYTES_PER_MPI_LIMB)
464                 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
465       if (len)
466         {
467           _gcry_mpi_set_buffer (a, s, len, 0);
468           a->sign = !!(*s & 0x80);
469           if (a->sign)
470             {
471               onecompl (a);
472               mpi_add_ui (a, a, 1);
473               a->sign = 1;
474             }
475         }
476       if (ret_mpi)
477         {
478           mpi_normalize ( a );
479           *ret_mpi = a;
480         }
481       else
482         mpi_free(a);
483       if (nscanned)
484         *nscanned = len;
485       return 0;
486     }
487   else if (format == GCRYMPI_FMT_USG)
488     {
489       a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
490                                     /BYTES_PER_MPI_LIMB)
491                 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
492
493       if (len)
494         _gcry_mpi_set_buffer (a, buffer, len, 0);
495       if (ret_mpi)
496         {
497           mpi_normalize ( a );
498           *ret_mpi = a;
499         }
500       else
501         mpi_free(a);
502       if (nscanned)
503         *nscanned = len;
504       return 0;
505     }
506   else if (format == GCRYMPI_FMT_PGP)
507     {
508       a = mpi_read_from_buffer (buffer, &len, secure);
509       if (nscanned)
510         *nscanned = len;
511       if (ret_mpi && a)
512         {
513           mpi_normalize (a);
514           *ret_mpi = a;
515         }
516       else if (a)
517         {
518           mpi_free(a);
519           a = NULL;
520         }
521       return a? 0 : GPG_ERR_INV_OBJ;
522     }
523   else if (format == GCRYMPI_FMT_SSH)
524     {
525       const unsigned char *s = buffer;
526       size_t n;
527
528       /* This test is not strictly necessary and an assert (!len)
529          would be sufficient.  We keep this test in case we later
530          allow the BUFLEN argument to act as a sanitiy check.  Same
531          below. */
532       if (len && len < 4)
533         return GPG_ERR_TOO_SHORT;
534
535       n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
536       s += 4;
537       if (len)
538         len -= 4;
539       if (len && n > len)
540         return GPG_ERR_TOO_LARGE;
541
542       a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
543                                     /BYTES_PER_MPI_LIMB)
544                 : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
545       if (n)
546         {
547           _gcry_mpi_set_buffer( a, s, n, 0 );
548           a->sign = !!(*s & 0x80);
549           if (a->sign)
550             {
551               onecompl (a);
552               mpi_add_ui (a, a, 1);
553               a->sign = 1;
554             }
555         }
556       if (nscanned)
557         *nscanned = n+4;
558       if (ret_mpi)
559         {
560           mpi_normalize ( a );
561           *ret_mpi = a;
562         }
563       else
564         mpi_free(a);
565       return 0;
566     }
567   else if (format == GCRYMPI_FMT_HEX)
568     {
569       /* We can only handle C strings for now.  */
570       if (buflen)
571         return GPG_ERR_INV_ARG;
572
573       a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
574       if (mpi_fromstr (a, (const char *)buffer))
575         {
576           mpi_free (a);
577           return GPG_ERR_INV_OBJ;
578         }
579       if (ret_mpi)
580         {
581           mpi_normalize ( a );
582           *ret_mpi = a;
583         }
584       else
585         mpi_free(a);
586       if (nscanned)
587         *nscanned = strlen ((const char*)buffer);
588       return 0;
589     }
590   else
591     return GPG_ERR_INV_ARG;
592 }
593
594
595 /* Convert the big integer A into the external representation
596    described by FORMAT and store it in the provided BUFFER which has
597    been allocated by the user with a size of BUFLEN bytes.  NWRITTEN
598    receives the actual length of the external representation unless it
599    has been passed as NULL.  BUFFER may be NULL to query the required
600    length.  */
601 gcry_err_code_t
602 _gcry_mpi_print (enum gcry_mpi_format format,
603                  unsigned char *buffer, size_t buflen,
604                  size_t *nwritten, struct gcry_mpi *a)
605 {
606   unsigned int nbits = mpi_get_nbits (a);
607   size_t len;
608   size_t dummy_nwritten;
609   int negative;
610
611   if (!nwritten)
612     nwritten = &dummy_nwritten;
613
614   /* Libgcrypt does no always care to set clear the sign if the value
615      is 0.  For printing this is a bit of a surprise, in particular
616      because if some of the formats don't support negative numbers but
617      should be able to print a zero.  Thus we need this extra test
618      for a negative number.  */
619   if (a->sign && _gcry_mpi_cmp_ui (a, 0))
620     negative = 1;
621   else
622     negative = 0;
623
624   len = buflen;
625   *nwritten = 0;
626   if (format == GCRYMPI_FMT_STD)
627     {
628       unsigned char *tmp;
629       int extra = 0;
630       unsigned int n;
631
632       tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
633       if (!tmp)
634         return gpg_err_code_from_syserror ();
635
636       if (negative)
637         {
638           twocompl (tmp, n);
639           if (!(*tmp & 0x80))
640             {
641               /* Need to extend the sign.  */
642               n++;
643               extra = 2;
644             }
645         }
646       else if (n && (*tmp & 0x80))
647         {
648           /* Positive but the high bit of the returned buffer is set.
649              Thus we need to print an extra leading 0x00 so that the
650              output is interpreted as a positive number.  */
651           n++;
652           extra = 1;
653         }
654
655       if (buffer && n > len)
656         {
657           /* The provided buffer is too short. */
658           xfree (tmp);
659           return GPG_ERR_TOO_SHORT;
660         }
661       if (buffer)
662         {
663           unsigned char *s = buffer;
664
665           if (extra == 1)
666             *s++ = 0;
667           else if (extra)
668             *s++ = 0xff;
669           memcpy (s, tmp, n-!!extra);
670         }
671       xfree (tmp);
672       *nwritten = n;
673       return 0;
674     }
675   else if (format == GCRYMPI_FMT_USG)
676     {
677       unsigned int n = (nbits + 7)/8;
678
679       /* Note:  We ignore the sign for this format.  */
680       /* FIXME: for performance reasons we should put this into
681          mpi_aprint because we can then use the buffer directly.  */
682
683       if (buffer && n > len)
684         return GPG_ERR_TOO_SHORT;
685       if (buffer)
686         {
687           unsigned char *tmp;
688
689           tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
690           if (!tmp)
691             return gpg_err_code_from_syserror ();
692           memcpy (buffer, tmp, n);
693           xfree (tmp);
694         }
695       *nwritten = n;
696       return 0;
697     }
698   else if (format == GCRYMPI_FMT_PGP)
699     {
700       unsigned int n = (nbits + 7)/8;
701
702       /* The PGP format can only handle unsigned integers.  */
703       if (negative)
704         return GPG_ERR_INV_ARG;
705
706       if (buffer && n+2 > len)
707         return GPG_ERR_TOO_SHORT;
708
709       if (buffer)
710         {
711           unsigned char *tmp;
712           unsigned char *s = buffer;
713
714           s[0] = nbits >> 8;
715           s[1] = nbits;
716
717           tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
718           if (!tmp)
719             return gpg_err_code_from_syserror ();
720           memcpy (s+2, tmp, n);
721           xfree (tmp);
722         }
723       *nwritten = n+2;
724       return 0;
725     }
726   else if (format == GCRYMPI_FMT_SSH)
727     {
728       unsigned char *tmp;
729       int extra = 0;
730       unsigned int n;
731
732       tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
733       if (!tmp)
734         return gpg_err_code_from_syserror ();
735
736       if (negative)
737         {
738           twocompl (tmp, n);
739           if (!(*tmp & 0x80))
740             {
741               /* Need to extend the sign.  */
742               n++;
743               extra = 2;
744             }
745         }
746       else if (n && (*tmp & 0x80))
747         {
748           n++;
749           extra=1;
750         }
751
752       if (buffer && n+4 > len)
753         {
754           xfree(tmp);
755           return GPG_ERR_TOO_SHORT;
756         }
757
758       if (buffer)
759         {
760           unsigned char *s = buffer;
761
762           *s++ = n >> 24;
763           *s++ = n >> 16;
764           *s++ = n >> 8;
765           *s++ = n;
766           if (extra == 1)
767             *s++ = 0;
768           else if (extra)
769             *s++ = 0xff;
770           memcpy (s, tmp, n-!!extra);
771         }
772       xfree (tmp);
773       *nwritten = 4+n;
774       return 0;
775     }
776   else if (format == GCRYMPI_FMT_HEX)
777     {
778       unsigned char *tmp;
779       int i;
780       int extra = 0;
781       unsigned int n = 0;
782
783       tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
784       if (!tmp)
785         return gpg_err_code_from_syserror ();
786       if (!n || (*tmp & 0x80))
787         extra = 2;
788
789       if (buffer && 2*n + extra + negative + 1 > len)
790         {
791           xfree(tmp);
792           return GPG_ERR_TOO_SHORT;
793         }
794       if (buffer)
795         {
796           unsigned char *s = buffer;
797
798           if (negative)
799             *s++ = '-';
800           if (extra)
801             {
802               *s++ = '0';
803               *s++ = '0';
804             }
805
806           for (i=0; i < n; i++)
807             {
808               unsigned int c = tmp[i];
809
810               *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
811               c &= 15;
812               *s++ = c < 10? '0'+c : 'A'+c-10 ;
813             }
814           *s++ = 0;
815           *nwritten = s - buffer;
816         }
817       else
818         {
819           *nwritten = 2*n + extra + negative + 1;
820         }
821       xfree (tmp);
822       return 0;
823     }
824   else
825     return GPG_ERR_INV_ARG;
826 }
827
828
829 /*
830  * Like gcry_mpi_print but this function allocates the buffer itself.
831  * The caller has to supply the address of a pointer.  NWRITTEN may be
832  * NULL.
833  */
834 gcry_err_code_t
835 _gcry_mpi_aprint (enum gcry_mpi_format format,
836                   unsigned char **buffer, size_t *nwritten,
837                   struct gcry_mpi *a)
838 {
839   size_t n;
840   gcry_err_code_t rc;
841
842   *buffer = NULL;
843   rc = _gcry_mpi_print (format, NULL, 0, &n, a);
844   if (rc)
845     return rc;
846
847   *buffer = mpi_is_secure(a) ? xtrymalloc_secure (n?n:1) : xtrymalloc (n?n:1);
848   if (!*buffer)
849     return gpg_err_code_from_syserror ();
850   /* If the returned buffer will have a length of 0, we nevertheless
851      allocated 1 byte (malloc needs it anyway) and store a 0.  */
852   if (!n)
853     **buffer = 0;
854   rc = _gcry_mpi_print( format, *buffer, n, &n, a );
855   if (rc)
856     {
857       xfree (*buffer);
858       *buffer = NULL;
859     }
860   else if (nwritten)
861     *nwritten = n;
862   return rc;
863 }
864
865
866 /* Turn VALUE into an octet string and store it in an allocated buffer
867    at R_FRAME or - if R_RAME is NULL - copy it into the caller
868    provided buffer SPACE; either SPACE or R_FRAME may be used.  If
869    SPACE if not NULL, the caller must provide a buffer of at least
870    NBYTES.  If the resulting octet string is shorter than NBYTES pad
871    it to the left with zeroes.  If VALUE does not fit into NBYTES
872    return an error code.  */
873 gpg_err_code_t
874 _gcry_mpi_to_octet_string (unsigned char **r_frame, void *space,
875                            gcry_mpi_t value, size_t nbytes)
876 {
877   gpg_err_code_t rc;
878   size_t nframe, noff, n;
879   unsigned char *frame;
880
881   if (!r_frame == !space)
882     return GPG_ERR_INV_ARG;  /* Only one may be used.  */
883
884   if (r_frame)
885     *r_frame = NULL;
886
887   rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
888   if (rc)
889     return rc;
890   if (nframe > nbytes)
891     return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES.  */
892
893   noff = (nframe < nbytes)? nbytes - nframe : 0;
894   n = nframe + noff;
895   if (space)
896     frame = space;
897   else
898     {
899       frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
900       if (!frame)
901         {
902           rc = gpg_err_code_from_syserror ();
903           return rc;
904         }
905     }
906   if (noff)
907     memset (frame, 0, noff);
908   nframe += noff;
909   rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
910   if (rc)
911     {
912       xfree (frame);
913       return rc;
914     }
915
916   if (r_frame)
917     *r_frame = frame;
918   return 0;
919 }