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