LCOV - code coverage report
Current view: top level - mpi - mpicoder.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 392 459 85.4 %
Date: 2015-11-05 17:08:00 Functions: 12 13 92.3 %

          Line data    Source code
       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          12 : mpi_read_from_buffer (const unsigned char *buffer, unsigned *ret_nread,
      35             :                       int secure)
      36             : {
      37             :   int i, j;
      38          12 :   unsigned int nbits, nbytes, nlimbs, nread=0;
      39             :   mpi_limb_t a;
      40          12 :   gcry_mpi_t val = MPI_NULL;
      41             : 
      42          12 :   if ( *ret_nread < 2 )
      43           0 :     goto leave;
      44          12 :   nbits = buffer[0] << 8 | buffer[1];
      45          12 :   if ( nbits > MAX_EXTERN_MPI_BITS )
      46             :     {
      47             : /*       log_debug ("mpi too large (%u bits)\n", nbits); */
      48           0 :       goto leave;
      49             :     }
      50          12 :   buffer += 2;
      51          12 :   nread = 2;
      52             : 
      53          12 :   nbytes = (nbits+7) / 8;
      54          12 :   nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
      55          12 :   val = secure? mpi_alloc_secure (nlimbs) : mpi_alloc (nlimbs);
      56          12 :   i = BYTES_PER_MPI_LIMB - nbytes % BYTES_PER_MPI_LIMB;
      57          12 :   i %= BYTES_PER_MPI_LIMB;
      58          12 :   j= val->nlimbs = nlimbs;
      59          12 :   val->sign = 0;
      60          23 :   for ( ; j > 0; j-- )
      61             :     {
      62          11 :       a = 0;
      63          29 :       for (; i < BYTES_PER_MPI_LIMB; i++ )
      64             :         {
      65          18 :           if ( ++nread > *ret_nread )
      66             :             {
      67             : /*               log_debug ("mpi larger than buffer"); */
      68           0 :               mpi_free (val);
      69           0 :               val = NULL;
      70           0 :               goto leave;
      71             :             }
      72          18 :           a <<= 8;
      73          18 :           a |= *buffer++;
      74             :         }
      75          11 :       i = 0;
      76          11 :       val->d[j-1] = a;
      77             :     }
      78             : 
      79             :  leave:
      80          12 :   *ret_nread = nread;
      81          12 :   return val;
      82             : }
      83             : 
      84             : 
      85             : /****************
      86             :  * Fill the mpi VAL from the hex string in STR.
      87             :  */
      88             : static int
      89       17184 : mpi_fromstr (gcry_mpi_t val, const char *str)
      90             : {
      91       17184 :   int sign = 0;
      92       17184 :   int prepend_zero = 0;
      93             :   int i, j, c, c1, c2;
      94             :   unsigned int nbits, nbytes, nlimbs;
      95             :   mpi_limb_t a;
      96             : 
      97       17184 :   if ( *str == '-' )
      98             :     {
      99        4216 :       sign = 1;
     100        4216 :       str++;
     101             :     }
     102             : 
     103             :   /* Skip optional hex prefix.  */
     104       17184 :   if ( *str == '0' && str[1] == 'x' )
     105       17001 :     str += 2;
     106             : 
     107       17184 :   nbits = 4 * strlen (str);
     108       17184 :   if ((nbits % 8))
     109          99 :     prepend_zero = 1;
     110             : 
     111       17184 :   nbytes = (nbits+7) / 8;
     112       17184 :   nlimbs = (nbytes+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB;
     113             : 
     114       17184 :   if ( val->alloced < nlimbs )
     115       17184 :     mpi_resize (val, nlimbs);
     116             : 
     117       17184 :   i = BYTES_PER_MPI_LIMB - (nbytes % BYTES_PER_MPI_LIMB);
     118       17184 :   i %= BYTES_PER_MPI_LIMB;
     119       17184 :   j = val->nlimbs = nlimbs;
     120       17184 :   val->sign = sign;
     121       74851 :   for (; j > 0; j--)
     122             :     {
     123       57667 :       a = 0;
     124      483798 :       for (; i < BYTES_PER_MPI_LIMB; i++)
     125             :         {
     126      426131 :           if (prepend_zero)
     127             :             {
     128          99 :               c1 = '0';
     129          99 :               prepend_zero = 0;
     130             :             }
     131             :           else
     132      426032 :             c1 = *str++;
     133             : 
     134      426131 :           if (!c1)
     135             :             {
     136           0 :               mpi_clear (val);
     137           0 :               return 1;  /* Error.  */
     138             :             }
     139      426131 :           c2 = *str++;
     140      426131 :           if (!c2)
     141             :             {
     142           0 :               mpi_clear (val);
     143           0 :               return 1;  /* Error.  */
     144             :             }
     145      426131 :           if ( c1 >= '0' && c1 <= '9' )
     146      247001 :             c = c1 - '0';
     147      179130 :           else if ( c1 >= 'a' && c1 <= 'f' )
     148       39444 :             c = c1 - 'a' + 10;
     149      139686 :           else if ( c1 >= 'A' && c1 <= 'F' )
     150      139686 :             c = c1 - 'A' + 10;
     151             :           else
     152             :             {
     153           0 :               mpi_clear (val);
     154           0 :               return 1;  /* Error.  */
     155             :             }
     156      426131 :           c <<= 4;
     157      426131 :           if ( c2 >= '0' && c2 <= '9' )
     158      260055 :             c |= c2 - '0';
     159      166076 :           else if( c2 >= 'a' && c2 <= 'f' )
     160       39052 :             c |= c2 - 'a' + 10;
     161      127024 :           else if( c2 >= 'A' && c2 <= 'F' )
     162      127024 :             c |= c2 - 'A' + 10;
     163             :           else
     164             :             {
     165           0 :               mpi_clear(val);
     166           0 :               return 1;  /* Error. */
     167             :             }
     168      426131 :           a <<= 8;
     169      426131 :           a |= c;
     170             :         }
     171       57667 :       i = 0;
     172       57667 :       val->d[j-1] = a;
     173             :     }
     174             : 
     175       17184 :   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        9704 : 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        9704 :   if (sign)
     207           0 :     *sign = a->sign;
     208             : 
     209        9704 :   *nbytes = a->nlimbs * BYTES_PER_MPI_LIMB;
     210        9704 :   n = *nbytes? *nbytes:1; /* Allocate at least one byte.  */
     211        9704 :   if (n < fill_le)
     212           0 :     n = fill_le;
     213        9704 :   if (extraalloc < 0)
     214           0 :     n2 = n + -extraalloc;
     215             :   else
     216        9704 :     n2 = n + extraalloc;
     217             : 
     218        9704 :   retbuffer = (force_secure || mpi_is_secure(a))? xtrymalloc_secure (n2)
     219             :                                                 : xtrymalloc (n2);
     220        9704 :   if (!retbuffer)
     221           0 :     return NULL;
     222        9704 :   if (extraalloc < 0)
     223           0 :     buffer = retbuffer + -extraalloc;
     224             :   else
     225        9704 :     buffer = retbuffer;
     226        9704 :   p = buffer;
     227             : 
     228       85597 :   for (i=a->nlimbs-1; i >= 0; i--)
     229             :     {
     230       75893 :       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       75893 :       *p++ = alimb >> 56;
     238       75893 :       *p++ = alimb >> 48;
     239       75893 :       *p++ = alimb >> 40;
     240       75893 :       *p++ = alimb >> 32;
     241       75893 :       *p++ = alimb >> 24;
     242       75893 :       *p++ = alimb >> 16;
     243       75893 :       *p++ = alimb >>  8;
     244       75893 :       *p++ = alimb        ;
     245             : #else
     246             : #     error please implement for this limb size.
     247             : #endif
     248             :     }
     249             : 
     250        9704 :   if (fill_le)
     251             :     {
     252        4144 :       length = *nbytes;
     253             :       /* Reverse buffer and pad with zeroes.  */
     254       70448 :       for (i=0; i < length/2; i++)
     255             :         {
     256       66304 :           tmp = buffer[i];
     257       66304 :           buffer[i] = buffer[length-1-i];
     258       66304 :           buffer[length-1-i] = tmp;
     259             :         }
     260             :       /* Pad with zeroes.  */
     261        4144 :       for (p = buffer + length; length < fill_le; length++)
     262           0 :         *p++ = 0;
     263        4144 :       *nbytes = length;
     264             : 
     265        4144 :       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        5560 :   for (p=buffer; *nbytes && !*p; p++, --*nbytes)
     271             :     ;
     272        5560 :   if (p != buffer)
     273        2065 :     memmove (buffer, p, *nbytes);
     274        5560 :   return retbuffer;
     275             : }
     276             : 
     277             : 
     278             : byte *
     279        6596 : _gcry_mpi_get_buffer (gcry_mpi_t a, unsigned int fill_le,
     280             :                       unsigned int *r_nbytes, int *sign)
     281             : {
     282        6596 :   return do_get_buffer (a, fill_le, 0, r_nbytes, sign, 0);
     283             : }
     284             : 
     285             : byte *
     286        3108 : _gcry_mpi_get_buffer_extra (gcry_mpi_t a, unsigned int fill_le, int extraalloc,
     287             :                             unsigned int *r_nbytes, int *sign)
     288             : {
     289        3108 :   return do_get_buffer (a, fill_le, extraalloc, r_nbytes, sign, 0);
     290             : }
     291             : 
     292             : byte *
     293           0 : _gcry_mpi_get_secure_buffer (gcry_mpi_t a, unsigned int fill_le,
     294             :                              unsigned int *r_nbytes, int *sign)
     295             : {
     296           0 :   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       54852 : _gcry_mpi_set_buffer (gcry_mpi_t a, const void *buffer_arg,
     306             :                       unsigned int nbytes, int sign)
     307             : {
     308       54852 :   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       54852 :   if (mpi_is_immutable (a))
     315             :     {
     316           0 :       mpi_immutable_failed ();
     317           0 :       return;
     318             :     }
     319             : 
     320       54852 :   nlimbs = (nbytes + BYTES_PER_MPI_LIMB - 1) / BYTES_PER_MPI_LIMB;
     321       54852 :   RESIZE_IF_NEEDED(a, nlimbs);
     322       54852 :   a->sign = sign;
     323             : 
     324      417909 :   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      308205 :       alimb  = (mpi_limb_t)*p-- ;
     333      308205 :       alimb |= (mpi_limb_t)*p-- <<  8 ;
     334      308205 :       alimb |= (mpi_limb_t)*p-- << 16 ;
     335      308205 :       alimb |= (mpi_limb_t)*p-- << 24 ;
     336      308205 :       alimb |= (mpi_limb_t)*p-- << 32 ;
     337      308205 :       alimb |= (mpi_limb_t)*p-- << 40 ;
     338      308205 :       alimb |= (mpi_limb_t)*p-- << 48 ;
     339      308205 :       alimb |= (mpi_limb_t)*p-- << 56 ;
     340             : #else
     341             : #       error please implement for this limb size.
     342             : #endif
     343      308205 :       a->d[i++] = alimb;
     344             :     }
     345       54852 :   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       54852 :       alimb  = (mpi_limb_t)*p--;
     357       54852 :       if (p >= buffer)
     358       48960 :         alimb |= (mpi_limb_t)*p-- << 8;
     359       54852 :       if (p >= buffer)
     360       48642 :         alimb |= (mpi_limb_t)*p-- << 16;
     361       54852 :       if (p >= buffer)
     362       46356 :         alimb |= (mpi_limb_t)*p-- << 24;
     363       54852 :       if (p >= buffer)
     364       18431 :         alimb |= (mpi_limb_t)*p-- << 32;
     365       54852 :       if (p >= buffer)
     366       16456 :         alimb |= (mpi_limb_t)*p-- << 40;
     367       54852 :       if (p >= buffer)
     368       15566 :         alimb |= (mpi_limb_t)*p-- << 48;
     369       54852 :       if (p >= buffer)
     370       15396 :         alimb |= (mpi_limb_t)*p-- << 56;
     371             : #else
     372             : #     error please implement for this limb size.
     373             : #endif
     374       54852 :       a->d[i++] = alimb;
     375             :     }
     376       54852 :   a->nlimbs = i;
     377       54852 :   gcry_assert (i == nlimbs);
     378             : }
     379             : 
     380             : 
     381             : static void
     382          27 : onecompl (gcry_mpi_t a)
     383             : {
     384             :   mpi_ptr_t ap;
     385             :   mpi_size_t n;
     386             :   unsigned int i;
     387          27 :   unsigned int nbits = mpi_get_nbits (a);
     388             : 
     389          27 :   if (mpi_is_immutable (a))
     390             :     {
     391           0 :       mpi_immutable_failed ();
     392          27 :       return;
     393             :     }
     394             : 
     395          27 :   mpi_normalize (a);
     396          27 :   ap = a->d;
     397          27 :   n = a->nlimbs;
     398             : 
     399          60 :   for( i = 0; i < n; i++ )
     400          33 :     ap[i] ^= (mpi_limb_t)(-1);
     401             : 
     402          27 :   a->sign = 0;
     403          27 :   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          60 : twocompl (unsigned char *p, unsigned int n)
     410             : {
     411             :   int i;
     412             : 
     413          60 :   for (i=n-1; i >= 0 && !p[i]; i--)
     414             :     ;
     415          60 :   if (i >= 0)
     416             :     {
     417          60 :       if ((p[i] & 0x01))
     418          44 :         p[i] = (((p[i] ^ 0xfe) | 0x01) & 0xff);
     419          16 :       else if ((p[i] & 0x02))
     420          12 :         p[i] = (((p[i] ^ 0xfc) | 0x02) & 0xfe);
     421           4 :       else if ((p[i] & 0x04))
     422           0 :         p[i] = (((p[i] ^ 0xf8) | 0x04) & 0xfc);
     423           4 :       else if ((p[i] & 0x08))
     424           0 :         p[i] = (((p[i] ^ 0xf0) | 0x08) & 0xf8);
     425           4 :       else if ((p[i] & 0x10))
     426           0 :         p[i] = (((p[i] ^ 0xe0) | 0x10) & 0xf0);
     427           4 :       else if ((p[i] & 0x20))
     428           0 :         p[i] = (((p[i] ^ 0xc0) | 0x20) & 0xe0);
     429           4 :       else if ((p[i] & 0x40))
     430           0 :         p[i] = (((p[i] ^ 0x80) | 0x40) & 0xc0);
     431             :       else
     432           4 :         p[i] = 0x80;
     433             : 
     434         324 :       for (i--; i >= 0; i--)
     435         264 :         p[i] ^= 0xff;
     436             :     }
     437          60 : }
     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       58709 : _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       58709 :   const unsigned char *buffer = (const unsigned char*)buffer_arg;
     449       58709 :   struct gcry_mpi *a = NULL;
     450             :   unsigned int len;
     451       58709 :   int secure = (buffer && _gcry_is_secure (buffer));
     452             : 
     453       58709 :   if (format == GCRYMPI_FMT_SSH)
     454          23 :     len = 0;
     455             :   else
     456       58686 :     len = buflen;
     457             : 
     458       58709 :   if (format == GCRYMPI_FMT_STD)
     459             :     {
     460         118 :       const unsigned char *s = buffer;
     461             : 
     462         118 :       a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
     463             :                                     /BYTES_PER_MPI_LIMB)
     464         118 :                 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
     465         118 :       if (len)
     466             :         {
     467         117 :           _gcry_mpi_set_buffer (a, s, len, 0);
     468         117 :           a->sign = !!(*s & 0x80);
     469         117 :           if (a->sign)
     470             :             {
     471          16 :               onecompl (a);
     472          16 :               mpi_add_ui (a, a, 1);
     473          16 :               a->sign = 1;
     474             :             }
     475             :         }
     476         118 :       if (ret_mpi)
     477             :         {
     478         118 :           mpi_normalize ( a );
     479         118 :           *ret_mpi = a;
     480             :         }
     481             :       else
     482           0 :         mpi_free(a);
     483         118 :       if (nscanned)
     484          23 :         *nscanned = len;
     485         118 :       return 0;
     486             :     }
     487       58591 :   else if (format == GCRYMPI_FMT_USG)
     488             :     {
     489       41372 :       a = secure? mpi_alloc_secure ((len+BYTES_PER_MPI_LIMB-1)
     490             :                                     /BYTES_PER_MPI_LIMB)
     491       41372 :                 : mpi_alloc ((len+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
     492             : 
     493       41372 :       if (len)
     494       41370 :         _gcry_mpi_set_buffer (a, buffer, len, 0);
     495       41372 :       if (ret_mpi)
     496             :         {
     497       41372 :           mpi_normalize ( a );
     498       41372 :           *ret_mpi = a;
     499             :         }
     500             :       else
     501           0 :         mpi_free(a);
     502       41372 :       if (nscanned)
     503        1124 :         *nscanned = len;
     504       41372 :       return 0;
     505             :     }
     506       17219 :   else if (format == GCRYMPI_FMT_PGP)
     507             :     {
     508          12 :       a = mpi_read_from_buffer (buffer, &len, secure);
     509          12 :       if (nscanned)
     510          12 :         *nscanned = len;
     511          12 :       if (ret_mpi && a)
     512             :         {
     513          12 :           mpi_normalize (a);
     514          12 :           *ret_mpi = a;
     515             :         }
     516           0 :       else if (a)
     517             :         {
     518           0 :           mpi_free(a);
     519           0 :           a = NULL;
     520             :         }
     521          12 :       return a? 0 : GPG_ERR_INV_OBJ;
     522             :     }
     523       17207 :   else if (format == GCRYMPI_FMT_SSH)
     524             :     {
     525          23 :       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          23 :       if (len && len < 4)
     533           0 :         return GPG_ERR_TOO_SHORT;
     534             : 
     535          23 :       n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
     536          23 :       s += 4;
     537          23 :       if (len)
     538           0 :         len -= 4;
     539          23 :       if (len && n > len)
     540           0 :         return GPG_ERR_TOO_LARGE;
     541             : 
     542          23 :       a = secure? mpi_alloc_secure ((n+BYTES_PER_MPI_LIMB-1)
     543             :                                     /BYTES_PER_MPI_LIMB)
     544          23 :                 : mpi_alloc ((n+BYTES_PER_MPI_LIMB-1)/BYTES_PER_MPI_LIMB);
     545          23 :       if (n)
     546             :         {
     547          22 :           _gcry_mpi_set_buffer( a, s, n, 0 );
     548          22 :           a->sign = !!(*s & 0x80);
     549          22 :           if (a->sign)
     550             :             {
     551          11 :               onecompl (a);
     552          11 :               mpi_add_ui (a, a, 1);
     553          11 :               a->sign = 1;
     554             :             }
     555             :         }
     556          23 :       if (nscanned)
     557          23 :         *nscanned = n+4;
     558          23 :       if (ret_mpi)
     559             :         {
     560          23 :           mpi_normalize ( a );
     561          23 :           *ret_mpi = a;
     562             :         }
     563             :       else
     564           0 :         mpi_free(a);
     565          23 :       return 0;
     566             :     }
     567       17184 :   else if (format == GCRYMPI_FMT_HEX)
     568             :     {
     569             :       /* We can only handle C strings for now.  */
     570       17184 :       if (buflen)
     571           0 :         return GPG_ERR_INV_ARG;
     572             : 
     573       17184 :       a = secure? mpi_alloc_secure (0) : mpi_alloc(0);
     574       17184 :       if (mpi_fromstr (a, (const char *)buffer))
     575             :         {
     576           0 :           mpi_free (a);
     577           0 :           return GPG_ERR_INV_OBJ;
     578             :         }
     579       17184 :       if (ret_mpi)
     580             :         {
     581       17184 :           mpi_normalize ( a );
     582       17184 :           *ret_mpi = a;
     583             :         }
     584             :       else
     585           0 :         mpi_free(a);
     586       17184 :       if (nscanned)
     587          23 :         *nscanned = strlen ((const char*)buffer);
     588       17184 :       return 0;
     589             :     }
     590             :   else
     591           0 :     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        6288 : _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        6288 :   unsigned int nbits = mpi_get_nbits (a);
     607             :   size_t len;
     608             :   size_t dummy_nwritten;
     609             :   int negative;
     610             : 
     611        6288 :   if (!nwritten)
     612        1298 :     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        6288 :   if (a->sign && _gcry_mpi_cmp_ui (a, 0))
     620         115 :     negative = 1;
     621             :   else
     622        6173 :     negative = 0;
     623             : 
     624        6288 :   len = buflen;
     625        6288 :   *nwritten = 0;
     626        6288 :   if (format == GCRYMPI_FMT_STD)
     627             :     {
     628             :       unsigned char *tmp;
     629        2120 :       int extra = 0;
     630             :       unsigned int n;
     631             : 
     632        2120 :       tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
     633        2120 :       if (!tmp)
     634           0 :         return gpg_err_code_from_syserror ();
     635             : 
     636        2120 :       if (negative)
     637             :         {
     638          38 :           twocompl (tmp, n);
     639          38 :           if (!(*tmp & 0x80))
     640             :             {
     641             :               /* Need to extend the sign.  */
     642           6 :               n++;
     643           6 :               extra = 2;
     644             :             }
     645             :         }
     646        2082 :       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         948 :           n++;
     652         948 :           extra = 1;
     653             :         }
     654             : 
     655        2120 :       if (buffer && n > len)
     656             :         {
     657             :           /* The provided buffer is too short. */
     658           0 :           xfree (tmp);
     659           0 :           return GPG_ERR_TOO_SHORT;
     660             :         }
     661        2120 :       if (buffer)
     662             :         {
     663        1060 :           unsigned char *s = buffer;
     664             : 
     665        1060 :           if (extra == 1)
     666         474 :             *s++ = 0;
     667         586 :           else if (extra)
     668           3 :             *s++ = 0xff;
     669        1060 :           memcpy (s, tmp, n-!!extra);
     670             :         }
     671        2120 :       xfree (tmp);
     672        2120 :       *nwritten = n;
     673        2120 :       return 0;
     674             :     }
     675        4168 :   else if (format == GCRYMPI_FMT_USG)
     676             :     {
     677        4021 :       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        4021 :       if (buffer && n > len)
     684           0 :         return GPG_ERR_TOO_SHORT;
     685        4021 :       if (buffer)
     686             :         {
     687             :           unsigned char *tmp;
     688             : 
     689        2230 :           tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
     690        2230 :           if (!tmp)
     691           0 :             return gpg_err_code_from_syserror ();
     692        2230 :           memcpy (buffer, tmp, n);
     693        2230 :           xfree (tmp);
     694             :         }
     695        4021 :       *nwritten = n;
     696        4021 :       return 0;
     697             :     }
     698         147 :   else if (format == GCRYMPI_FMT_PGP)
     699             :     {
     700          39 :       unsigned int n = (nbits + 7)/8;
     701             : 
     702             :       /* The PGP format can only handle unsigned integers.  */
     703          39 :       if (negative)
     704          11 :         return GPG_ERR_INV_ARG;
     705             : 
     706          28 :       if (buffer && n+2 > len)
     707           0 :         return GPG_ERR_TOO_SHORT;
     708             : 
     709          28 :       if (buffer)
     710             :         {
     711             :           unsigned char *tmp;
     712          14 :           unsigned char *s = buffer;
     713             : 
     714          14 :           s[0] = nbits >> 8;
     715          14 :           s[1] = nbits;
     716             : 
     717          14 :           tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
     718          14 :           if (!tmp)
     719           0 :             return gpg_err_code_from_syserror ();
     720          14 :           memcpy (s+2, tmp, n);
     721          14 :           xfree (tmp);
     722             :         }
     723          28 :       *nwritten = n+2;
     724          28 :       return 0;
     725             :     }
     726         108 :   else if (format == GCRYMPI_FMT_SSH)
     727             :     {
     728             :       unsigned char *tmp;
     729          50 :       int extra = 0;
     730             :       unsigned int n;
     731             : 
     732          50 :       tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
     733          50 :       if (!tmp)
     734           0 :         return gpg_err_code_from_syserror ();
     735             : 
     736          50 :       if (negative)
     737             :         {
     738          22 :           twocompl (tmp, n);
     739          22 :           if (!(*tmp & 0x80))
     740             :             {
     741             :               /* Need to extend the sign.  */
     742           6 :               n++;
     743           6 :               extra = 2;
     744             :             }
     745             :         }
     746          28 :       else if (n && (*tmp & 0x80))
     747             :         {
     748           8 :           n++;
     749           8 :           extra=1;
     750             :         }
     751             : 
     752          50 :       if (buffer && n+4 > len)
     753             :         {
     754           0 :           xfree(tmp);
     755           0 :           return GPG_ERR_TOO_SHORT;
     756             :         }
     757             : 
     758          50 :       if (buffer)
     759             :         {
     760          25 :           unsigned char *s = buffer;
     761             : 
     762          25 :           *s++ = n >> 24;
     763          25 :           *s++ = n >> 16;
     764          25 :           *s++ = n >> 8;
     765          25 :           *s++ = n;
     766          25 :           if (extra == 1)
     767           4 :             *s++ = 0;
     768          21 :           else if (extra)
     769           3 :             *s++ = 0xff;
     770          25 :           memcpy (s, tmp, n-!!extra);
     771             :         }
     772          50 :       xfree (tmp);
     773          50 :       *nwritten = 4+n;
     774          50 :       return 0;
     775             :     }
     776          58 :   else if (format == GCRYMPI_FMT_HEX)
     777             :     {
     778             :       unsigned char *tmp;
     779             :       int i;
     780          58 :       int extra = 0;
     781          58 :       unsigned int n = 0;
     782             : 
     783          58 :       tmp = _gcry_mpi_get_buffer (a, 0, &n, NULL);
     784          58 :       if (!tmp)
     785           0 :         return gpg_err_code_from_syserror ();
     786          58 :       if (!n || (*tmp & 0x80))
     787          22 :         extra = 2;
     788             : 
     789          58 :       if (buffer && 2*n + extra + negative + 1 > len)
     790             :         {
     791           0 :           xfree(tmp);
     792           0 :           return GPG_ERR_TOO_SHORT;
     793             :         }
     794          58 :       if (buffer)
     795             :         {
     796          29 :           unsigned char *s = buffer;
     797             : 
     798          29 :           if (negative)
     799          11 :             *s++ = '-';
     800          29 :           if (extra)
     801             :             {
     802          11 :               *s++ = '0';
     803          11 :               *s++ = '0';
     804             :             }
     805             : 
     806         305 :           for (i=0; i < n; i++)
     807             :             {
     808         276 :               unsigned int c = tmp[i];
     809             : 
     810         276 :               *s++ = (c >> 4) < 10? '0'+(c>>4) : 'A'+(c>>4)-10 ;
     811         276 :               c &= 15;
     812         276 :               *s++ = c < 10? '0'+c : 'A'+c-10 ;
     813             :             }
     814          29 :           *s++ = 0;
     815          29 :           *nwritten = s - buffer;
     816             :         }
     817             :       else
     818             :         {
     819          29 :           *nwritten = 2*n + extra + negative + 1;
     820             :         }
     821          58 :       xfree (tmp);
     822          58 :       return 0;
     823             :     }
     824             :   else
     825           0 :     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         129 : _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         129 :   *buffer = NULL;
     843         129 :   rc = _gcry_mpi_print (format, NULL, 0, &n, a);
     844         129 :   if (rc)
     845          11 :     return rc;
     846             : 
     847         118 :   *buffer = mpi_is_secure(a) ? xtrymalloc_secure (n?n:1) : xtrymalloc (n?n:1);
     848         118 :   if (!*buffer)
     849           0 :     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         118 :   if (!n)
     853           6 :     **buffer = 0;
     854         118 :   rc = _gcry_mpi_print( format, *buffer, n, &n, a );
     855         118 :   if (rc)
     856             :     {
     857           0 :       xfree (*buffer);
     858           0 :       *buffer = NULL;
     859             :     }
     860         118 :   else if (nwritten)
     861          81 :     *nwritten = n;
     862         118 :   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        1154 : _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        1154 :   if (!r_frame == !space)
     882           0 :     return GPG_ERR_INV_ARG;  /* Only one may be used.  */
     883             : 
     884        1154 :   if (r_frame)
     885        1070 :     *r_frame = NULL;
     886             : 
     887        1154 :   rc = _gcry_mpi_print (GCRYMPI_FMT_USG, NULL, 0, &nframe, value);
     888        1154 :   if (rc)
     889           0 :     return rc;
     890        1154 :   if (nframe > nbytes)
     891           0 :     return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES.  */
     892             : 
     893        1154 :   noff = (nframe < nbytes)? nbytes - nframe : 0;
     894        1154 :   n = nframe + noff;
     895        1154 :   if (space)
     896          84 :     frame = space;
     897             :   else
     898             :     {
     899        1070 :       frame = mpi_is_secure (value)? xtrymalloc_secure (n) : xtrymalloc (n);
     900        1070 :       if (!frame)
     901             :         {
     902           0 :           rc = gpg_err_code_from_syserror ();
     903           0 :           return rc;
     904             :         }
     905             :     }
     906        1154 :   if (noff)
     907         197 :     memset (frame, 0, noff);
     908        1154 :   nframe += noff;
     909        1154 :   rc = _gcry_mpi_print (GCRYMPI_FMT_USG, frame+noff, nframe-noff, NULL, value);
     910        1154 :   if (rc)
     911             :     {
     912           0 :       xfree (frame);
     913           0 :       return rc;
     914             :     }
     915             : 
     916        1154 :   if (r_frame)
     917        1070 :     *r_frame = frame;
     918        1154 :   return 0;
     919             : }

Generated by: LCOV version 1.11