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

Generated by: LCOV version 1.13